@popoverinstall/cli 0.5.0 → 0.6.1
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 +48 -0
- package/README.md +8 -5
- 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 +11 -0
- 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 +81 -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 +24 -0
- package/dist/welcome.d.ts.map +1 -0
- package/dist/welcome.js +159 -0
- package/dist/welcome.js.map +1 -0
- package/package.json +3 -3
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +11 -1
- package/plugin/commands/fork.md +118 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAE/C,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE;IAClC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,OAAO,CACZ,OAAO,CAAC,GAAG,CAAC,UAAU;YACpB,OAAO,CAAC,GAAG,CAAC,YAAY;YACxB,OAAO,CAAC,GAAG,CAAC,UAAU;YACtB,OAAO,CAAC,GAAG,CAAC,MAAM,CACrB,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACpF,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;IAClB,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;IAC9C,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACpC,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;QAAE,OAAO,gBAAgB,CAAC;IACxE,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC,EAAE,CAAC;AAEL,2DAA2D;AAC3D,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE;IACrB,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;IAC9C,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACpC,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;QAAE,OAAO,gBAAgB,CAAC;IACxE,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC,EAAE,CAAC;AAEL;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAC/B,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;AAEnC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;AAEvB,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAC7C,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAC9C,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAChD,GAAG,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAC9C,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAC/C,0EAA0E;IAC1E,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;IAC3D,8EAA8E;IAC9E,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE;CAClD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,IAAI,GAAG,CAAC;IACtC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,GAAW;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,OAAO;YAAE,OAAO,GAAG,IAAI,CAAC;aACxB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG;YAAE,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;aACnE,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,cAAc;IACjC,CAAC,CAAC;QACE,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,GAAG;QACZ,IAAI,EAAE,GAAG;QACT,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,GAAG;QAChB,cAAc,EAAE,GAAG;QACnB,aAAa,EAAE,GAAG;QAClB,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;KACX;IACH,CAAC,CAAC;QACE,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,GAAG;QACZ,IAAI,EAAE,GAAG;QACT,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,GAAG;QAChB,cAAc,EAAE,GAAG;QACnB,aAAa,EAAE,GAAG;QAClB,IAAI,EAAE,GAAG;QACT,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,GAAG;KACX,CAAC;AAEN,MAAM,cAAc,GAAG,cAAc;IACnC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACpD,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE1B,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAErD,+DAA+D;AAC/D,MAAM,UAAU,KAAK;IACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,IAAI,CAAC,IAAI,GAAG,EAAE;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,4CAA4C;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACpD,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,EAAc;IAC5D,MAAM,GAAG,GAAG,CAAC,CAAC;IACd,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CACtB,QAAQ,EACR,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAChB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC9B,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CACT,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG;QACjE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,CACxE,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,cAAc,CAAC,CACjF,CAAC;AACJ,CAAC;AAWD;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,CAAC;QACd,OAAO;YACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;gBACb,IAAI,IAAI;oBAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;YACD,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAE,CAAC,CAAC;QACzE,KAAK,CAAC,WAAW,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QACrC,KAAK,IAAI,CAAC,CAAC;IACb,CAAC,CAAC;IAEF,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,uDAAuD;IAC3E,MAAM,EAAE,CAAC;IACT,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IAEhB,MAAM,GAAG,GAAG,GAAG,EAAE;QACf,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,GAAG,KAAK,CAAC;QACb,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACf,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE;YAC7C,GAAG,EAAE,CAAC;YACN,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,EAAE,GAAG;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The whole of a first run: wire the machine up, then offer to log it in.
|
|
3
|
+
*
|
|
4
|
+
* The aardvark, a box saying what this is, and a single question — log in? — that Enter
|
|
5
|
+
* answers. Everything past that point is the existing device flow in `login.ts`; this
|
|
6
|
+
* module owns the framing and the one keypress, not the protocol.
|
|
7
|
+
*
|
|
8
|
+
* What it must never do: **block a non-interactive run.** This is a real command and can be
|
|
9
|
+
* piped or run in CI, so with no TTY it says what to run next and exits 0 rather than waiting
|
|
10
|
+
* on a keypress nobody is there to give.
|
|
11
|
+
*
|
|
12
|
+
* What it is allowed to do, and this changed when it took on the wiring: fail. Declining the
|
|
13
|
+
* login is still a fine outcome — a machine with popover on it and no session is a normal place
|
|
14
|
+
* to stop, and `popover login` finishes later. But a machine whose Claude Code plugin could not
|
|
15
|
+
* be registered cannot publish a session at all, so that exits non-zero and says why, rather
|
|
16
|
+
* than reporting a successful first run that quietly does nothing.
|
|
17
|
+
*/
|
|
18
|
+
/** Re-exported from where they now live, alongside the send-off that uses them. */
|
|
19
|
+
export { BRAND, TAGLINE, TAGLINE_SECONDARY } from "./next-steps.js";
|
|
20
|
+
export interface WelcomeOptions {
|
|
21
|
+
apiUrl: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function welcome({ apiUrl }: WelcomeOptions): Promise<number>;
|
|
24
|
+
//# sourceMappingURL=welcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../src/welcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,mFAAmF;AACnF,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFzE"}
|
package/dist/welcome.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The whole of a first run: wire the machine up, then offer to log it in.
|
|
3
|
+
*
|
|
4
|
+
* The aardvark, a box saying what this is, and a single question — log in? — that Enter
|
|
5
|
+
* answers. Everything past that point is the existing device flow in `login.ts`; this
|
|
6
|
+
* module owns the framing and the one keypress, not the protocol.
|
|
7
|
+
*
|
|
8
|
+
* What it must never do: **block a non-interactive run.** This is a real command and can be
|
|
9
|
+
* piped or run in CI, so with no TTY it says what to run next and exits 0 rather than waiting
|
|
10
|
+
* on a keypress nobody is there to give.
|
|
11
|
+
*
|
|
12
|
+
* What it is allowed to do, and this changed when it took on the wiring: fail. Declining the
|
|
13
|
+
* login is still a fine outcome — a machine with popover on it and no session is a normal place
|
|
14
|
+
* to stop, and `popover login` finishes later. But a machine whose Claude Code plugin could not
|
|
15
|
+
* be registered cannot publish a session at all, so that exits non-zero and says why, rather
|
|
16
|
+
* than reporting a successful first run that quietly does nothing.
|
|
17
|
+
*/
|
|
18
|
+
import { loadCredentials } from "@popoverinstall/shared";
|
|
19
|
+
import { aardvarkLines } from "./aardvark.js";
|
|
20
|
+
import { sceneLines } from "./scene.js";
|
|
21
|
+
import { login } from "./login.js";
|
|
22
|
+
import { setup } from "./setup.js";
|
|
23
|
+
import { BRAND, TAGLINE, TAGLINE_SECONDARY, nextSteps } from "./next-steps.js";
|
|
24
|
+
import { badge, box, glyph, line, step, style, trunk, wrap } from "./theme.js";
|
|
25
|
+
/** Re-exported from where they now live, alongside the send-off that uses them. */
|
|
26
|
+
export { BRAND, TAGLINE, TAGLINE_SECONDARY } from "./next-steps.js";
|
|
27
|
+
export async function welcome({ apiUrl }) {
|
|
28
|
+
const alreadyConnected = Boolean(loadCredentials());
|
|
29
|
+
console.log("");
|
|
30
|
+
// The full scene where there is room for it, the aardvark on its own where there is not.
|
|
31
|
+
for (const row of sceneLines() ?? aardvarkLines())
|
|
32
|
+
console.log(row);
|
|
33
|
+
// Wrapped before styling, and to the window rather than to a fixed number: the second
|
|
34
|
+
// line is long enough that an 80-column terminal is the tight case, not the roomy one.
|
|
35
|
+
const room = Math.max(28, (process.stdout.columns ?? 80) - 8);
|
|
36
|
+
box({
|
|
37
|
+
title: badge(`Welcome to ${BRAND}`),
|
|
38
|
+
lines: [
|
|
39
|
+
"",
|
|
40
|
+
...wrap(TAGLINE, room).map(style.bold),
|
|
41
|
+
...wrap(TAGLINE_SECONDARY, room).map(style.dim),
|
|
42
|
+
"",
|
|
43
|
+
],
|
|
44
|
+
// Keeps the box at least as wide as the aardvark above it, so the two read as one block.
|
|
45
|
+
minWidth: 36,
|
|
46
|
+
});
|
|
47
|
+
/*
|
|
48
|
+
* The wiring, before anything is offered.
|
|
49
|
+
*
|
|
50
|
+
* `npm install -g` places files and stops. It cannot register a Claude Code plugin or tell the
|
|
51
|
+
* plugin's hooks where the daemon went, and it deliberately does not try — `setup.ts` explains
|
|
52
|
+
* why a postinstall hook is the wrong place for that. Which left this command greeting someone
|
|
53
|
+
* warmly and then logging them into a product whose plugin was never registered: `/popover:team`
|
|
54
|
+
* would not exist, and nothing in the greeting would have hinted at why.
|
|
55
|
+
*
|
|
56
|
+
* So welcome is the whole of a first run — wiring included — and `popover setup` remains the
|
|
57
|
+
* same operation on its own, for `update` to re-run. It is idempotent, so paying for it here
|
|
58
|
+
* costs a re-run, not a duplicate.
|
|
59
|
+
*/
|
|
60
|
+
trunk();
|
|
61
|
+
step("Connecting to Claude Code…");
|
|
62
|
+
const wired = await setup();
|
|
63
|
+
if (wired !== 0) {
|
|
64
|
+
/*
|
|
65
|
+
* Stop rather than press on to the login.
|
|
66
|
+
*
|
|
67
|
+
* setup() has already said exactly what is wrong and what to install. Logging in after this
|
|
68
|
+
* would report success for a machine that cannot actually publish a session, which is a
|
|
69
|
+
* worse outcome than stopping on a message that can be acted on.
|
|
70
|
+
*/
|
|
71
|
+
trunk();
|
|
72
|
+
step("Fix that, then run this again:");
|
|
73
|
+
line(style.bold("popover welcome"));
|
|
74
|
+
return wired;
|
|
75
|
+
}
|
|
76
|
+
if (alreadyConnected) {
|
|
77
|
+
trunk();
|
|
78
|
+
step("This machine is already connected.");
|
|
79
|
+
nextSteps();
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
// No terminal to ask into: say what to run and get out of the way.
|
|
83
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
84
|
+
trunk();
|
|
85
|
+
step(`Log in to ${BRAND}:`);
|
|
86
|
+
line(style.bold("popover login"));
|
|
87
|
+
nextSteps();
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
trunk();
|
|
91
|
+
const answer = await ask(`Log in to ${BRAND} ${style.dim("(opens browser)")}`);
|
|
92
|
+
trunk();
|
|
93
|
+
if (answer === "skip") {
|
|
94
|
+
step("Skipped. Run this when you are ready:");
|
|
95
|
+
line(style.bold("popover login"));
|
|
96
|
+
nextSteps();
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
const code = await login(apiUrl, { framed: true });
|
|
100
|
+
if (code === 0)
|
|
101
|
+
nextSteps();
|
|
102
|
+
return code;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The one question in the flow.
|
|
106
|
+
*
|
|
107
|
+
* Enter is the answer — the prompt is phrased as the action rather than a yes/no, so a bare
|
|
108
|
+
* Enter means "do it". `s`, `n` and `q` skip, which covers "skip", "no" and "quit" without a
|
|
109
|
+
* menu. Ctrl-C, Escape and a closed stdin all resolve to a skip rather than throwing,
|
|
110
|
+
* because the installer is the parent process and a half-finished login is not a failure.
|
|
111
|
+
*
|
|
112
|
+
* Read raw rather than through readline, for two reasons. A single keypress is what "just
|
|
113
|
+
* hit enter" means — with readline, `s` would need an Enter after it. And readline owns the
|
|
114
|
+
* cursor on the line it prompted on: it repositions after the echoed newline, so the next
|
|
115
|
+
* thing printed lands on the prompt line instead of below it.
|
|
116
|
+
*/
|
|
117
|
+
function ask(question) {
|
|
118
|
+
step(style.bold(question));
|
|
119
|
+
// The one instruction on screen, so it is the one thing not dimmed: bright white against a
|
|
120
|
+
// flow that is otherwise deliberately quiet.
|
|
121
|
+
const hint = `${style.white("press enter")}${style.dim(" to continue")}` +
|
|
122
|
+
`${style.dim(` ${glyph.dot} s to skip`)}`;
|
|
123
|
+
process.stdout.write(`${style.dim(glyph.trunk)} ${hint} `);
|
|
124
|
+
const stdin = process.stdin;
|
|
125
|
+
const wasRaw = stdin.isRaw;
|
|
126
|
+
return new Promise((resolve) => {
|
|
127
|
+
let settled = false;
|
|
128
|
+
const done = (result) => {
|
|
129
|
+
if (settled)
|
|
130
|
+
return;
|
|
131
|
+
settled = true;
|
|
132
|
+
stdin.removeListener("data", onData);
|
|
133
|
+
stdin.removeListener("end", onEnd);
|
|
134
|
+
stdin.setRawMode?.(wasRaw ?? false);
|
|
135
|
+
stdin.pause();
|
|
136
|
+
// Raw mode swallowed the echo of whatever ended this, so close the line ourselves.
|
|
137
|
+
console.log("");
|
|
138
|
+
resolve(result);
|
|
139
|
+
};
|
|
140
|
+
const onData = (chunk) => {
|
|
141
|
+
for (const key of chunk) {
|
|
142
|
+
if (key === "\r" || key === "\n")
|
|
143
|
+
return done("go");
|
|
144
|
+
// Ctrl-C, Ctrl-D and Escape: in raw mode these arrive as bytes, not as signals.
|
|
145
|
+
if (key === "\x03" || key === "\x04" || key === "\x1b")
|
|
146
|
+
return done("skip");
|
|
147
|
+
if (/[nsq]/i.test(key))
|
|
148
|
+
return done("skip");
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const onEnd = () => done("skip");
|
|
152
|
+
stdin.setRawMode?.(true);
|
|
153
|
+
stdin.setEncoding("utf8");
|
|
154
|
+
stdin.resume();
|
|
155
|
+
stdin.on("data", onData);
|
|
156
|
+
stdin.on("end", onEnd);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=welcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../src/welcome.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popoverinstall/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "See your teammates' active Claude Code agents and ask them questions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"prepack": "node ../../scripts/stage-plugin.mjs && tsc -b"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@popoverinstall/daemon": "0.
|
|
45
|
-
"@popoverinstall/shared": "0.
|
|
44
|
+
"@popoverinstall/daemon": "0.6.1",
|
|
45
|
+
"@popoverinstall/shared": "0.6.1"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "popover",
|
|
4
4
|
"displayName": "Popover",
|
|
5
5
|
"description": "See your teammates' active Claude Code agents and ask them questions. A read-only fork answers from the agent's full context without interrupting your teammate.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.6.1",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Quolabs"
|
|
9
9
|
},
|
package/plugin/README.md
CHANGED
|
@@ -5,12 +5,22 @@ Installed into Claude Code; see the repo root README for the whole system.
|
|
|
5
5
|
```
|
|
6
6
|
.claude-plugin/plugin.json metadata only
|
|
7
7
|
commands/team.md the /team command
|
|
8
|
+
commands/fork.md the /fork command
|
|
8
9
|
hooks/hooks.json status feed (auto-discovered)
|
|
9
10
|
.mcp.json bundled MCP server (auto-discovered)
|
|
10
|
-
mcp/index.mjs team_list + team_ask, zero dependencies
|
|
11
|
+
mcp/index.mjs team_list + team_ask + team_tell, zero dependencies
|
|
11
12
|
scripts/ hook handlers, zero dependencies
|
|
12
13
|
```
|
|
13
14
|
|
|
15
|
+
`/team` reaches the daemon through the MCP server. `/fork` deliberately does not: it shells
|
|
16
|
+
out to the `popover` binary instead, because opening a fork has to work for someone who is
|
|
17
|
+
not signed in and may have no daemon running at all. That also means it adds nothing to the
|
|
18
|
+
IPC protocol, and cannot regress asks, tells, or the roster.
|
|
19
|
+
|
|
20
|
+
It is the one command that needs to know which session it is in, which it gets from
|
|
21
|
+
`${CLAUDE_SESSION_ID}` — substituted into the command body by Claude Code, so there is no
|
|
22
|
+
guessing at "the newest transcript in this directory".
|
|
23
|
+
|
|
14
24
|
## Three things that will bite you
|
|
15
25
|
|
|
16
26
|
**Do not declare `hooks` or `mcpServers` in `plugin.json`.** Both `hooks/hooks.json` and
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Share this conversation as a fork a teammate can carry on, or open one you were sent
|
|
3
|
+
# Quoted because an unquoted value starting with `[` is parsed as a YAML flow sequence,
|
|
4
|
+
# which fails and silently drops EVERY field here, allowed-tools included.
|
|
5
|
+
argument-hint: "[create|open] [code]"
|
|
6
|
+
allowed-tools: Bash(popover fork *), AskUserQuestion
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Fork this conversation
|
|
10
|
+
|
|
11
|
+
The user ran `/popover:fork`. Arguments, which may be empty: **$ARGUMENTS**
|
|
12
|
+
|
|
13
|
+
This session's id is `${CLAUDE_SESSION_ID}`. You will need it for `create`.
|
|
14
|
+
|
|
15
|
+
A fork is not an ask. An ask sends a teammate's question to a read-only copy of someone's
|
|
16
|
+
session and brings back one answer. A fork hands over **the whole conversation**, frozen at
|
|
17
|
+
the moment it was made, and the person who opens it gets their own local chat that continues
|
|
18
|
+
from there. Nothing they do in it comes back here.
|
|
19
|
+
|
|
20
|
+
The first word of the arguments chooses what to do. Follow exactly one of these paths.
|
|
21
|
+
|
|
22
|
+
## 1. `create` — freeze this conversation and get a code
|
|
23
|
+
|
|
24
|
+
Run:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
popover fork create --session ${CLAUDE_SESSION_ID} --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
On `ok: true`, show the user the code on its own line so it is easy to copy, then tell them,
|
|
31
|
+
briefly and in this order:
|
|
32
|
+
|
|
33
|
+
- Who it is for and how they open it: `popover fork open <code>`, or
|
|
34
|
+
`npx @popoverinstall/cli fork open <code>` if they do not have popover yet.
|
|
35
|
+
- That the code stops working in 24 hours, but a chat someone has already opened does not —
|
|
36
|
+
it is theirs from then on.
|
|
37
|
+
- That it is frozen at `last_turn_at`, so nothing said after this point is included. If they
|
|
38
|
+
keep working and want the newer state shared, they run `create` again for a new code.
|
|
39
|
+
- That this sends the entire conversation, including the contents of every file read into
|
|
40
|
+
it. Say it plainly, once. It is a much larger disclosure than an ask and the user should
|
|
41
|
+
make it deliberately.
|
|
42
|
+
|
|
43
|
+
On `ok: false`, relay `message` and the `hints` verbatim. Do not retry with different flags.
|
|
44
|
+
|
|
45
|
+
## 2. `open <code>` — take delivery of a fork
|
|
46
|
+
|
|
47
|
+
Run:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
popover fork open <the code they typed> --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
On `ok: false`, relay `message` and `hints` and stop.
|
|
54
|
+
|
|
55
|
+
On `ok: true`, tell them what arrived: who shared it, the title if there is one,
|
|
56
|
+
`entry_count` messages, when it was frozen, and which repo it came from. Then surface
|
|
57
|
+
whatever the output flags:
|
|
58
|
+
|
|
59
|
+
- `repo_match: "different"` — say which repo it came from and which one they are in, and
|
|
60
|
+
that the conversation will refer to files they may not have.
|
|
61
|
+
- `repo_match: "unknown"` — they are not in a git repository, so paths in it may not resolve.
|
|
62
|
+
- `version_skew` — relay it as a note, not a blocker.
|
|
63
|
+
- `claude_problem` — this one *is* a blocker. Relay it and stop.
|
|
64
|
+
|
|
65
|
+
Then explain why this needs a window of its own, and offer the choice.
|
|
66
|
+
|
|
67
|
+
**A fork cannot open inside this chat.** A running Claude Code session cannot become a
|
|
68
|
+
different session — one chat holds one conversation, and this one already has its own. So
|
|
69
|
+
the fork starts as a second session in a new window. If this conversation has real context
|
|
70
|
+
in it already, say that plainly; if the user only just started here, one short line is
|
|
71
|
+
enough.
|
|
72
|
+
|
|
73
|
+
Then call `AskUserQuestion` with exactly these two options, so Esc cancels:
|
|
74
|
+
|
|
75
|
+
- **Open a new window** — "Start the fork in its own terminal window"
|
|
76
|
+
- **Print the command** — "Show the command and let me run it myself"
|
|
77
|
+
|
|
78
|
+
If they choose to open a new window, run:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
popover fork launch <stage_id> --json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then report what happened: `opened: true` means a window is on its way, and it is worth
|
|
85
|
+
adding that the fork may take a moment to appear. `opened: false` is not a failure — it
|
|
86
|
+
happens over SSH, in a container, and anywhere there is no window to open — so show them
|
|
87
|
+
`command` and the `cwd` to run it in.
|
|
88
|
+
|
|
89
|
+
If they choose to print the command, run the same thing with `--here` instead of no flag,
|
|
90
|
+
and show them the `command` it prints. `--here` writes the fork without trying to open
|
|
91
|
+
anything.
|
|
92
|
+
|
|
93
|
+
If they press Esc, stop. Nothing has been written to their machine yet, and there is nothing
|
|
94
|
+
to clean up.
|
|
95
|
+
|
|
96
|
+
## 3. No arguments, or anything else
|
|
97
|
+
|
|
98
|
+
Say what the two halves do in two lines, and stop:
|
|
99
|
+
|
|
100
|
+
`/popover:fork create` · `/popover:fork open PQRS-2345-BCDF-7892`
|
|
101
|
+
|
|
102
|
+
Do not create a fork on the user's behalf just because they ran the command with no
|
|
103
|
+
arguments. Sharing a conversation is a disclosure, and it should always be something they
|
|
104
|
+
asked for in as many words.
|
|
105
|
+
|
|
106
|
+
## Rules
|
|
107
|
+
|
|
108
|
+
- Never invent or guess at a code. If what they typed is rejected, relay that and let them
|
|
109
|
+
paste it again — a code is 16 characters in four groups and is easy to truncate.
|
|
110
|
+
- Never print a code the user has not seen; it is the entire credential and the decryption
|
|
111
|
+
key for the conversation behind it.
|
|
112
|
+
- A fork is one-way. If the user seems to want an answer rather than to hand over the whole
|
|
113
|
+
conversation, say that `/popover:team ask` is the cheaper thing and offer it instead.
|
|
114
|
+
- Do not run `create` and then immediately `open` the result to "test" it. Every open counts
|
|
115
|
+
against what the sharer sees, and the fork is already verified by the command exiting
|
|
116
|
+
cleanly.
|
|
117
|
+
- `popover fork revoke <code>` destroys a snapshot early. It cannot recall a copy someone
|
|
118
|
+
has already opened; if the user is worried about that, say so rather than reassuring them.
|