@clubnet/seedclub 0.2.17 → 0.2.18
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 +64 -23
- package/assets/extensions/seedclub/commands/add.ts +1 -1
- package/assets/extensions/seedclub/commands/sort.ts +2 -2
- package/assets/extensions/seedclub/dia-cookies.ts +3 -3
- package/assets/extensions/seedclub/extraction/capture.ts +1 -1
- package/assets/extensions/seedclub/twitter-client.ts +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# seedclub
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A branded command-line agent wrapper around pi, with integrated Seed Club commands, tools, and app actions.
|
|
4
4
|
|
|
5
5
|
Requirements: Node.js 22+
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## What it is
|
|
8
8
|
|
|
9
|
-
This repo
|
|
9
|
+
`seedclub` is the Seed Club distribution of pi. This repo provides the `seedclub` launcher, installs the Seed Club theme and extensions, and adds Seed Club-specific workflows for connecting your account, capturing signals, sorting them, and interacting with Seed Club-backed app surfaces.
|
|
10
|
+
|
|
11
|
+
This repo is the source of truth for the published package:
|
|
10
12
|
|
|
11
13
|
- GitHub repo: `seedclub/seedclub-agent`
|
|
12
14
|
- npm package: `@clubnet/seedclub`
|
|
13
15
|
- user-facing command: `seedclub`
|
|
14
16
|
|
|
15
|
-
This is the Pi wrapper repo, not the older extracted full-agent monorepo.
|
|
16
|
-
|
|
17
17
|
## Install
|
|
18
18
|
|
|
19
19
|
```bash
|
|
@@ -26,7 +26,15 @@ Then:
|
|
|
26
26
|
seedclub
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
### First run
|
|
30
|
+
|
|
31
|
+
On a fresh install, the normal setup flow is:
|
|
32
|
+
|
|
33
|
+
1. `/login` to sign in to a model provider such as Anthropic, OpenAI, or Gemini
|
|
34
|
+
2. `/model` to choose the model you want to use
|
|
35
|
+
3. `/connect` to connect your Seed Club account
|
|
36
|
+
|
|
37
|
+
After that, run `/seedclub` to open the main Seed Club menu.
|
|
30
38
|
|
|
31
39
|
### Alternative: curl | bash
|
|
32
40
|
|
|
@@ -34,9 +42,9 @@ Use `/login` to set up your API keys.
|
|
|
34
42
|
curl -fsSL https://raw.githubusercontent.com/seedclub/seedclub-agent/main/install.sh | bash
|
|
35
43
|
```
|
|
36
44
|
|
|
37
|
-
###
|
|
45
|
+
### Internal install auth
|
|
38
46
|
|
|
39
|
-
seedclub is
|
|
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.
|
|
40
48
|
|
|
41
49
|
Fast path:
|
|
42
50
|
|
|
@@ -54,15 +62,38 @@ echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
|
|
|
54
62
|
|
|
55
63
|
Then `npm install -g @clubnet/seedclub` works.
|
|
56
64
|
|
|
65
|
+
## Core workflow
|
|
66
|
+
|
|
67
|
+
The normal interactive flow is:
|
|
68
|
+
|
|
69
|
+
1. Start the app with `seedclub`
|
|
70
|
+
2. Complete `/login`, `/model`, and `/connect` if this is your first run
|
|
71
|
+
3. Open `/seedclub`
|
|
72
|
+
4. Choose whether to add signals or sort unsorted signals
|
|
73
|
+
|
|
57
74
|
## Commands
|
|
58
75
|
|
|
59
76
|
| Command | What it does |
|
|
60
77
|
|---|---|
|
|
61
|
-
| `/
|
|
62
|
-
| `/
|
|
63
|
-
| `/
|
|
78
|
+
| `/login` | Sign in to a model provider for the underlying agent |
|
|
79
|
+
| `/model` | Choose which model to use |
|
|
80
|
+
| `/connect` | Connect your Seed Club account |
|
|
81
|
+
| `/seedclub` | Open the main Seed Club menu; if not connected yet, it starts the connect flow |
|
|
82
|
+
| `/add <url|@handle|query>` | Add signals from URLs, X handles, bookmarks, likes, following, or search |
|
|
83
|
+
| `/sort` | Review unsorted signals and sort them automatically, in the browser, or delete them |
|
|
64
84
|
| `seedclub setup-auth` | Configure npm auth for npmjs private package access in `~/.npmrc` |
|
|
65
85
|
|
|
86
|
+
## Auth
|
|
87
|
+
|
|
88
|
+
There are two separate auth layers in the product:
|
|
89
|
+
|
|
90
|
+
1. Model auth: `/login`
|
|
91
|
+
This signs you into the LLM provider you want the agent to use.
|
|
92
|
+
2. Seed Club auth: `/connect`
|
|
93
|
+
This connects the CLI to your Seed Club account so Seed Club tools and commands can read and write account data.
|
|
94
|
+
|
|
95
|
+
`/seedclub` is the main entry point for Seed Club actions. If you are not connected yet, it will start the Seed Club connect flow automatically.
|
|
96
|
+
|
|
66
97
|
## How it works
|
|
67
98
|
|
|
68
99
|
seedclub is an npm package (`@clubnet/seedclub`) that wraps [pi](https://github.com/badlogic/pi-mono) as a dependency. Installing the package globally gives you the `seedclub` command.
|
|
@@ -165,36 +196,46 @@ The `assets/` directory contains the canonical source for extensions and themes.
|
|
|
165
196
|
|
|
166
197
|
### Updating pi
|
|
167
198
|
|
|
168
|
-
When a new pi version comes out
|
|
199
|
+
When a new pi version comes out, upgrading it for Seed Club users means shipping a new `@clubnet/seedclub` package that depends on the newer pi release.
|
|
200
|
+
|
|
201
|
+
Recommended flow:
|
|
169
202
|
|
|
170
|
-
1. **
|
|
203
|
+
1. **Update and test locally:**
|
|
171
204
|
```bash
|
|
172
|
-
# Update the dependency
|
|
173
205
|
npm install @mariozechner/pi-coding-agent@NEW_VERSION
|
|
174
206
|
npm install -g ./
|
|
175
|
-
seedclub
|
|
207
|
+
seedclub version
|
|
208
|
+
seedclub
|
|
176
209
|
```
|
|
177
210
|
|
|
178
|
-
|
|
179
|
-
|
|
211
|
+
Verify the wrapper still launches, the Seed Club UI loads, and the core flows you care about still work.
|
|
212
|
+
|
|
213
|
+
2. **Commit the dependency change and bump the package version:**
|
|
214
|
+
The pi version is carried by this package, so users only receive it once the Seed Club package version is bumped and released.
|
|
180
215
|
```json
|
|
181
216
|
{
|
|
182
217
|
"version": "0.3.0",
|
|
183
218
|
"dependencies": {
|
|
184
|
-
"@mariozechner/pi-coding-agent": "
|
|
219
|
+
"@mariozechner/pi-coding-agent": "NEW_VERSION"
|
|
185
220
|
}
|
|
186
221
|
}
|
|
187
222
|
```
|
|
188
223
|
|
|
189
|
-
3. **
|
|
224
|
+
3. **Push the release:**
|
|
190
225
|
```bash
|
|
191
226
|
git add -A
|
|
192
|
-
git commit -m "bump pi to
|
|
193
|
-
|
|
194
|
-
|
|
227
|
+
git commit -m "bump pi to NEW_VERSION"
|
|
228
|
+
npm version patch|minor|major
|
|
229
|
+
git push --follow-tags
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
4. **Users pull the update:**
|
|
233
|
+
Users get the newer pi runtime when they run:
|
|
234
|
+
```bash
|
|
235
|
+
seedclub update
|
|
195
236
|
```
|
|
196
237
|
|
|
197
|
-
|
|
238
|
+
A fresh `npm install -g @clubnet/seedclub` also installs the new packaged pi version.
|
|
198
239
|
|
|
199
240
|
### Updating extensions
|
|
200
241
|
|
|
@@ -218,7 +218,7 @@ function parseTwitterQuery(input: string): TwitterQuery | null {
|
|
|
218
218
|
if (s.match(/likes?/)) {
|
|
219
219
|
const since = parseDateFilter(s);
|
|
220
220
|
const author = parseAuthorFilter(s);
|
|
221
|
-
// Only grab a number as count if it
|
|
221
|
+
// Only grab a number as count if it is not a year and not part of "N months/weeks"
|
|
222
222
|
const countMatch = s.match(/(?:last\s+)?(\d+)\s*(?:likes?|bookmarks?)/);
|
|
223
223
|
const count = since ? 200 : countMatch ? parseInt(countMatch[1], 10) : 20;
|
|
224
224
|
return { action: "likes", count, since, author };
|
|
@@ -72,7 +72,7 @@ export function registerSortCommand(pi: ExtensionAPI) {
|
|
|
72
72
|
|
|
73
73
|
async function autoSort(pi: ExtensionAPI) {
|
|
74
74
|
pi.sendUserMessage(
|
|
75
|
-
"Sort my unsorted signals. Call leaf_get_unsorted_signals first. Then score signals in batches of 20 — for each batch, call leaf_submit_sort_scores immediately before moving to the next batch. Score each signal across all 10 buckets (0-1) based on its description/content. If the user has an angel.md, weight toward their thesis. Work fast,
|
|
75
|
+
"Sort my unsorted signals. Call leaf_get_unsorted_signals first. Then score signals in batches of 20 — for each batch, call leaf_submit_sort_scores immediately before moving to the next batch. Score each signal across all 10 buckets (0-1) based on its description/content. If the user has an angel.md, weight toward their thesis. Work fast, do not explain each score.",
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -86,6 +86,6 @@ async function manualSort(pi: ExtensionAPI, ctx: any) {
|
|
|
86
86
|
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
87
87
|
|
|
88
88
|
pi.exec(openCmd, [url]).catch(() => {
|
|
89
|
-
ctx.ui.notify(`
|
|
89
|
+
ctx.ui.notify(`Could not open browser. Visit:\n${url}`, "warning");
|
|
90
90
|
});
|
|
91
91
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Read Twitter cookies directly from Dia browser
|
|
2
|
+
* Read Twitter cookies directly from the Dia browser cookie database.
|
|
3
3
|
*
|
|
4
|
-
* Dia is Chromium-based (The Browser Company) but sweet-cookie
|
|
4
|
+
* Dia is Chromium-based (The Browser Company) but sweet-cookie does not
|
|
5
5
|
* know about it. We read the encrypted cookies and decrypt them using
|
|
6
6
|
* the macOS Keychain password, same as Chrome does.
|
|
7
7
|
*/
|
|
@@ -52,7 +52,7 @@ function decryptValue(encrypted: Buffer, key: Buffer): string | null {
|
|
|
52
52
|
const unpadded = padByte > 0 && padByte <= 16 ? result.subarray(0, result.length - padByte) : result;
|
|
53
53
|
|
|
54
54
|
// The first block (16 bytes) may be garbled due to IV mismatch.
|
|
55
|
-
// Extract the longest trailing run of printable ASCII — that
|
|
55
|
+
// Extract the longest trailing run of printable ASCII — that is the cookie value.
|
|
56
56
|
const raw = unpadded.toString("binary");
|
|
57
57
|
const match = raw.match(/[\x20-\x7e]+$/);
|
|
58
58
|
return match ? match[0] : null;
|
|
@@ -148,7 +148,7 @@ async function resolveTwitterCredentials(): Promise<{
|
|
|
148
148
|
const allWarnings: string[] = [];
|
|
149
149
|
const defaultBrowser = detectDefaultBrowser();
|
|
150
150
|
|
|
151
|
-
// Dia: sweet-cookie
|
|
151
|
+
// Dia: sweet-cookie does not support it, so we read cookies directly
|
|
152
152
|
if (defaultBrowser?.bundleId === "company.thebrowser.dia" || (!defaultBrowser && isDiaAvailable())) {
|
|
153
153
|
const dia = readDiaTwitterCookies();
|
|
154
154
|
if (dia) {
|
|
@@ -170,7 +170,7 @@ async function resolveTwitterCredentials(): Promise<{
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
// If we know the default browser, try
|
|
173
|
+
// If we know the default browser, try only that browser cookie set.
|
|
174
174
|
if (defaultBrowser) {
|
|
175
175
|
const result = await tryBrowserInfo(defaultBrowser);
|
|
176
176
|
if (result) return result;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clubnet/seedclub",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.18",
|
|
4
|
+
"description": "A branded command-line agent wrapper around pi, with integrated Seed Club commands, tools, and app actions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"postinstall": "node postinstall.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@mariozechner/pi-coding-agent": "0.
|
|
20
|
+
"@mariozechner/pi-coding-agent": "0.65.2"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=22.0.0"
|