@clubnet/seedclub 0.2.19 → 0.2.20
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 +3 -14
- package/assets/extensions/seedclub-ui/welcome.ts +30 -18
- package/bin/cli.js +8 -117
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,21 +46,11 @@ curl -fsSL https://raw.githubusercontent.com/seedclub/seedclub-agent/main/instal
|
|
|
46
46
|
|
|
47
47
|
`@clubnet/seedclub` is currently a private npm package. This auth is only for installing or updating the package from npm. It is separate from `/login` and `/connect` inside the app.
|
|
48
48
|
|
|
49
|
-
Fast path:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
SEEDCLUB_NPM_TOKEN=YOUR_NPM_TOKEN curl -fsSL https://raw.githubusercontent.com/seedclub/seedclub-agent/main/install.sh | bash
|
|
53
|
-
seedclub setup-auth
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Manual one-time `.npmrc` setup:
|
|
57
|
-
|
|
58
49
|
```bash
|
|
59
|
-
|
|
60
|
-
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
|
|
50
|
+
npm login
|
|
61
51
|
```
|
|
62
52
|
|
|
63
|
-
Then `npm install -g @clubnet/seedclub`
|
|
53
|
+
Then `npm install -g @clubnet/seedclub` and `seedclub update` work.
|
|
64
54
|
|
|
65
55
|
## Core workflow
|
|
66
56
|
|
|
@@ -80,7 +70,6 @@ The normal interactive flow is:
|
|
|
80
70
|
| `/connect` | Connect your Seed Club account |
|
|
81
71
|
| `/seedclub` | Main menu — connect, inspect access, and jump into CRM/meetings/media/headlines workflows |
|
|
82
72
|
| `/transcripts` | Export transcript VTT files with filters (date, person, time, output dir) |
|
|
83
|
-
| `seedclub setup-auth` | Configure npm auth for npmjs private package access in `~/.npmrc` |
|
|
84
73
|
|
|
85
74
|
Natural-language transcript retrieval is also supported (no slash command required). Examples: `download vibhu transcripts from 11am`, `i need transcripts for all guests on 11am last week`. Seed Club will run metadata-first export confirmation and then write VTT files.
|
|
86
75
|
|
|
@@ -147,7 +136,7 @@ seedclub pins versions in `package.json`:
|
|
|
147
136
|
|
|
148
137
|
```json
|
|
149
138
|
{
|
|
150
|
-
"version": "0.2.
|
|
139
|
+
"version": "0.2.19",
|
|
151
140
|
"dependencies": {
|
|
152
141
|
"@mariozechner/pi-coding-agent": "0.65.2"
|
|
153
142
|
}
|
|
@@ -451,32 +451,44 @@ export default function (pi: ExtensionAPI, options?: { enableFrame?: boolean })
|
|
|
451
451
|
loaderTimer.unref?.();
|
|
452
452
|
tuiRef?.requestRender();
|
|
453
453
|
|
|
454
|
+
const todayPromise = fetchTodayOn11am();
|
|
454
455
|
void Promise.all([
|
|
455
456
|
getData(),
|
|
456
|
-
withTimeout(
|
|
457
|
+
withTimeout(todayPromise, TODAY_PREFETCH_TIMEOUT_MS, null),
|
|
457
458
|
]).then(([{ weather, market }, todayOn11am]) => {
|
|
458
459
|
clearInterval(loaderTimer);
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
460
|
+
const renderReadyHeader = (today: TodayOn11am | null) => {
|
|
461
|
+
const theme = ctx.ui.theme;
|
|
462
|
+
const weatherLine = ` ${weather.icon} ${theme.fg("text", weather.temp)} ${theme.fg("dim", weather.condition)} ${theme.fg("dim", "·")} ${theme.fg("dim", weather.location)}`;
|
|
463
|
+
const marketLine = ` ${market.map((quote) => formatQuote(quote, theme)).join(` ${theme.fg("dim", "·")} `)}`;
|
|
464
|
+
const todayLines = renderTodayOn11amLines(today, theme);
|
|
465
|
+
uiState.todayOn11am = today;
|
|
466
|
+
headerLines = [
|
|
467
|
+
"",
|
|
468
|
+
renderTitle(theme),
|
|
469
|
+
"",
|
|
470
|
+
weatherLine,
|
|
471
|
+
marketLine,
|
|
472
|
+
"",
|
|
473
|
+
...todayLines,
|
|
474
|
+
...(todayLines.length ? [""] : []),
|
|
475
|
+
...setupLines,
|
|
476
|
+
"",
|
|
477
|
+
];
|
|
478
|
+
};
|
|
464
479
|
|
|
465
|
-
|
|
466
|
-
"",
|
|
467
|
-
renderTitle(theme),
|
|
468
|
-
"",
|
|
469
|
-
weatherLine,
|
|
470
|
-
marketLine,
|
|
471
|
-
"",
|
|
472
|
-
...todayLines,
|
|
473
|
-
...(todayLines.length ? [""] : []),
|
|
474
|
-
...setupLines,
|
|
475
|
-
"",
|
|
476
|
-
];
|
|
480
|
+
renderReadyHeader(todayOn11am);
|
|
477
481
|
uiState.ready = true;
|
|
478
482
|
ctx.ui.setEditorText("");
|
|
479
483
|
tuiRef?.requestRender();
|
|
484
|
+
|
|
485
|
+
if (!todayOn11am?.guests.length) {
|
|
486
|
+
void todayPromise.then((freshToday) => {
|
|
487
|
+
if (!freshToday?.guests.length) return;
|
|
488
|
+
renderReadyHeader(freshToday);
|
|
489
|
+
tuiRef?.requestRender();
|
|
490
|
+
}).catch(() => {});
|
|
491
|
+
}
|
|
480
492
|
}).catch(() => {
|
|
481
493
|
clearInterval(loaderTimer);
|
|
482
494
|
headerLines = [
|
package/bin/cli.js
CHANGED
|
@@ -2,120 +2,22 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const { execFileSync, spawn } = require("child_process");
|
|
5
|
-
const { readFileSync, existsSync, writeFileSync,
|
|
5
|
+
const { readFileSync, existsSync, writeFileSync, mkdirSync } = require("fs");
|
|
6
6
|
const { join, dirname, basename } = require("path");
|
|
7
7
|
const { homedir } = require("os");
|
|
8
|
-
const readline = require("readline");
|
|
9
8
|
|
|
10
9
|
const SC_DIR = join(homedir(), ".seedclub", "agent");
|
|
11
10
|
const VERSION_FILE = join(SC_DIR, ".seedclub-version");
|
|
12
11
|
const SETTINGS_FILE = join(SC_DIR, "settings.json");
|
|
13
12
|
const PI_MAIN_LAUNCHER = join(__dirname, "pi-main-launcher.js");
|
|
14
13
|
process.title = "seedclub";
|
|
15
|
-
const SEEDCLUB_ENV_EXCLUDE = new Set(["
|
|
14
|
+
const SEEDCLUB_ENV_EXCLUDE = new Set(["SEEDCLUB_PI_MAIN"]);
|
|
16
15
|
|
|
17
16
|
function printPrivateRegistryHint() {
|
|
18
17
|
console.error("seedclub: install/update failed.");
|
|
19
|
-
console.error("
|
|
20
|
-
console.error("
|
|
21
|
-
console.error(" seedclub
|
|
22
|
-
console.error("Or run with an ephemeral token:");
|
|
23
|
-
console.error(" SEEDCLUB_NPM_TOKEN=YOUR_NPM_TOKEN seedclub update");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function upsertLine(lines, prefix, value) {
|
|
27
|
-
const idx = lines.findIndex((line) => line.trim().startsWith(prefix));
|
|
28
|
-
if (idx >= 0) {
|
|
29
|
-
lines[idx] = value;
|
|
30
|
-
} else {
|
|
31
|
-
lines.push(value);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function readNpmrcLines(path) {
|
|
36
|
-
if (!existsSync(path)) return [];
|
|
37
|
-
const raw = readFileSync(path, "utf-8");
|
|
38
|
-
if (!raw.trim()) return [];
|
|
39
|
-
return raw.split(/\r?\n/).filter((line) => line.length > 0);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function askHidden(prompt) {
|
|
43
|
-
return new Promise((resolve, reject) => {
|
|
44
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
45
|
-
return reject(new Error("Interactive prompt requires a TTY"));
|
|
46
|
-
}
|
|
47
|
-
const rl = readline.createInterface({
|
|
48
|
-
input: process.stdin,
|
|
49
|
-
output: process.stdout,
|
|
50
|
-
terminal: true,
|
|
51
|
-
});
|
|
52
|
-
const onData = (char) => {
|
|
53
|
-
const ch = String(char);
|
|
54
|
-
if (ch === "\n" || ch === "\r" || ch === "\u0004") {
|
|
55
|
-
process.stdout.write("\n");
|
|
56
|
-
} else if (ch === "\u0003") {
|
|
57
|
-
process.stdout.write("^C\n");
|
|
58
|
-
} else {
|
|
59
|
-
process.stdout.write("\x1b[2K\x1b[200D" + prompt + "*".repeat(rl.line.length));
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
process.stdin.on("data", onData);
|
|
63
|
-
rl.question(prompt, (value) => {
|
|
64
|
-
process.stdin.removeListener("data", onData);
|
|
65
|
-
rl.close();
|
|
66
|
-
resolve(value.trim());
|
|
67
|
-
});
|
|
68
|
-
rl.on("SIGINT", () => {
|
|
69
|
-
process.stdin.removeListener("data", onData);
|
|
70
|
-
rl.close();
|
|
71
|
-
reject(new Error("Cancelled"));
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function setupAuth() {
|
|
77
|
-
const npmrcPath = join(homedir(), ".npmrc");
|
|
78
|
-
let token = process.env.SEEDCLUB_NPM_TOKEN || process.env.NPM_TOKEN || "";
|
|
79
|
-
if (!token) {
|
|
80
|
-
try {
|
|
81
|
-
token = await askHidden("npm token: ");
|
|
82
|
-
} catch (err) {
|
|
83
|
-
console.error(`seedclub: ${err.message}`);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (!token) {
|
|
88
|
-
console.error("seedclub: no token provided.");
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const lines = readNpmrcLines(npmrcPath);
|
|
93
|
-
upsertLine(lines, "@clubnet:registry=", "@clubnet:registry=https://registry.npmjs.org/");
|
|
94
|
-
upsertLine(lines, "//registry.npmjs.org/:_authToken=", `//registry.npmjs.org/:_authToken=${token}`);
|
|
95
|
-
writeFileSync(npmrcPath, lines.join("\n") + "\n", { mode: 0o600 });
|
|
96
|
-
|
|
97
|
-
console.log(`Wrote npm auth config to ${npmrcPath}`);
|
|
98
|
-
console.log("You can now run:");
|
|
99
|
-
console.log(" npm install -g @clubnet/seedclub");
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function withOptionalEphemeralNpmrc(run) {
|
|
103
|
-
const token = process.env.SEEDCLUB_NPM_TOKEN || process.env.NPM_TOKEN;
|
|
104
|
-
if (!token) return run([]);
|
|
105
|
-
|
|
106
|
-
const npmrcPath = join(SC_DIR, ".npmrc.tmp");
|
|
107
|
-
try {
|
|
108
|
-
writeFileSync(
|
|
109
|
-
npmrcPath,
|
|
110
|
-
`@clubnet:registry=https://registry.npmjs.org/\n//registry.npmjs.org/:_authToken=${token}\n`,
|
|
111
|
-
{ mode: 0o600 },
|
|
112
|
-
);
|
|
113
|
-
return run(["--userconfig", npmrcPath]);
|
|
114
|
-
} finally {
|
|
115
|
-
try {
|
|
116
|
-
unlinkSync(npmrcPath);
|
|
117
|
-
} catch {}
|
|
118
|
-
}
|
|
18
|
+
console.error("If npm reports a private package or permission error, run:");
|
|
19
|
+
console.error(" npm login");
|
|
20
|
+
console.error(" seedclub update");
|
|
119
21
|
}
|
|
120
22
|
|
|
121
23
|
function findPackageRoot(fromFile, expectedName) {
|
|
@@ -533,19 +435,10 @@ if (cmd === "theme") {
|
|
|
533
435
|
process.exit(0);
|
|
534
436
|
}
|
|
535
437
|
|
|
536
|
-
if (cmd === "setup-auth") {
|
|
537
|
-
setupAuth().catch((err) => {
|
|
538
|
-
console.error(`seedclub: ${err instanceof Error ? err.message : String(err)}`);
|
|
539
|
-
process.exit(1);
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
|
|
543
438
|
if (cmd === "update") {
|
|
544
439
|
try {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
stdio: "inherit",
|
|
548
|
-
});
|
|
440
|
+
execFileSync("npm", ["install", "-g", "@clubnet/seedclub@latest"], {
|
|
441
|
+
stdio: "inherit",
|
|
549
442
|
});
|
|
550
443
|
} catch {
|
|
551
444
|
printPrivateRegistryHint();
|
|
@@ -554,8 +447,7 @@ if (cmd === "update") {
|
|
|
554
447
|
process.exit(0);
|
|
555
448
|
}
|
|
556
449
|
|
|
557
|
-
|
|
558
|
-
// ── Resolve pi binary ───────────────────────────────────────────────────
|
|
450
|
+
// ── Resolve pi binary ───────────────────────────────────────────────────
|
|
559
451
|
|
|
560
452
|
let piBin;
|
|
561
453
|
let piEntry;
|
|
@@ -618,4 +510,3 @@ if (cmd !== "setup-auth") {
|
|
|
618
510
|
}
|
|
619
511
|
});
|
|
620
512
|
});
|
|
621
|
-
}
|
package/package.json
CHANGED