@clubnet/seedclub 0.2.16 → 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 +94 -34
- 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,9 +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
|
+
## What it is
|
|
8
|
+
|
|
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:
|
|
12
|
+
|
|
13
|
+
- GitHub repo: `seedclub/seedclub-agent`
|
|
14
|
+
- npm package: `@clubnet/seedclub`
|
|
15
|
+
- user-facing command: `seedclub`
|
|
16
|
+
|
|
7
17
|
## Install
|
|
8
18
|
|
|
9
19
|
```bash
|
|
@@ -16,7 +26,15 @@ Then:
|
|
|
16
26
|
seedclub
|
|
17
27
|
```
|
|
18
28
|
|
|
19
|
-
|
|
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.
|
|
20
38
|
|
|
21
39
|
### Alternative: curl | bash
|
|
22
40
|
|
|
@@ -24,9 +42,9 @@ Use `/login` to set up your API keys.
|
|
|
24
42
|
curl -fsSL https://raw.githubusercontent.com/seedclub/seedclub-agent/main/install.sh | bash
|
|
25
43
|
```
|
|
26
44
|
|
|
27
|
-
###
|
|
45
|
+
### Internal install auth
|
|
28
46
|
|
|
29
|
-
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.
|
|
30
48
|
|
|
31
49
|
Fast path:
|
|
32
50
|
|
|
@@ -44,15 +62,38 @@ echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
|
|
|
44
62
|
|
|
45
63
|
Then `npm install -g @clubnet/seedclub` works.
|
|
46
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
|
+
|
|
47
74
|
## Commands
|
|
48
75
|
|
|
49
76
|
| Command | What it does |
|
|
50
77
|
|---|---|
|
|
51
|
-
| `/
|
|
52
|
-
| `/
|
|
53
|
-
| `/
|
|
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 |
|
|
54
84
|
| `seedclub setup-auth` | Configure npm auth for npmjs private package access in `~/.npmrc` |
|
|
55
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
|
+
|
|
56
97
|
## How it works
|
|
57
98
|
|
|
58
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.
|
|
@@ -126,10 +167,13 @@ Colors can be hex (`"#00C853"`), 256-color palette index (`242`), a reference to
|
|
|
126
167
|
git clone https://github.com/seedclub/seedclub-agent.git
|
|
127
168
|
cd seedclub-agent
|
|
128
169
|
|
|
129
|
-
# Install locally from the repo
|
|
170
|
+
# Install deps, then install locally from the repo
|
|
171
|
+
npm install
|
|
130
172
|
npm install -g ./
|
|
131
173
|
```
|
|
132
174
|
|
|
175
|
+
For day-to-day work, run `seedclub version` after installing to confirm your shell is using this repo's wrapper build.
|
|
176
|
+
|
|
133
177
|
### Repo structure
|
|
134
178
|
|
|
135
179
|
```
|
|
@@ -152,36 +196,46 @@ The `assets/` directory contains the canonical source for extensions and themes.
|
|
|
152
196
|
|
|
153
197
|
### Updating pi
|
|
154
198
|
|
|
155
|
-
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:
|
|
156
202
|
|
|
157
|
-
1. **
|
|
203
|
+
1. **Update and test locally:**
|
|
158
204
|
```bash
|
|
159
|
-
# Update the dependency
|
|
160
205
|
npm install @mariozechner/pi-coding-agent@NEW_VERSION
|
|
161
206
|
npm install -g ./
|
|
162
|
-
seedclub
|
|
207
|
+
seedclub version
|
|
208
|
+
seedclub
|
|
163
209
|
```
|
|
164
210
|
|
|
165
|
-
|
|
166
|
-
|
|
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.
|
|
167
215
|
```json
|
|
168
216
|
{
|
|
169
217
|
"version": "0.3.0",
|
|
170
218
|
"dependencies": {
|
|
171
|
-
"@mariozechner/pi-coding-agent": "
|
|
219
|
+
"@mariozechner/pi-coding-agent": "NEW_VERSION"
|
|
172
220
|
}
|
|
173
221
|
}
|
|
174
222
|
```
|
|
175
223
|
|
|
176
|
-
3. **
|
|
224
|
+
3. **Push the release:**
|
|
177
225
|
```bash
|
|
178
226
|
git add -A
|
|
179
|
-
git commit -m "bump pi to
|
|
180
|
-
|
|
181
|
-
|
|
227
|
+
git commit -m "bump pi to NEW_VERSION"
|
|
228
|
+
npm version patch|minor|major
|
|
229
|
+
git push --follow-tags
|
|
182
230
|
```
|
|
183
231
|
|
|
184
|
-
Users
|
|
232
|
+
4. **Users pull the update:**
|
|
233
|
+
Users get the newer pi runtime when they run:
|
|
234
|
+
```bash
|
|
235
|
+
seedclub update
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
A fresh `npm install -g @clubnet/seedclub` also installs the new packaged pi version.
|
|
185
239
|
|
|
186
240
|
### Updating extensions
|
|
187
241
|
|
|
@@ -203,25 +257,31 @@ For reproducible extension dependency installs, commit `assets/extensions/seedcl
|
|
|
203
257
|
|
|
204
258
|
### Release process
|
|
205
259
|
|
|
206
|
-
|
|
260
|
+
Publishing is now handled by npm trusted publishing from GitHub Actions.
|
|
261
|
+
|
|
262
|
+
Workflow:
|
|
207
263
|
|
|
208
|
-
1. Create a branch
|
|
264
|
+
1. Create a branch and make changes
|
|
209
265
|
2. Merge to `main`
|
|
210
|
-
3. Pull `main`, run `npm install -g ./`
|
|
211
|
-
4.
|
|
212
|
-
5.
|
|
213
|
-
6.
|
|
266
|
+
3. Pull `main`, run `npm install`, then `npm install -g ./`
|
|
267
|
+
4. Smoke test with `seedclub version` and, if relevant, a quick interactive run
|
|
268
|
+
5. Bump version: `npm version patch|minor|major`
|
|
269
|
+
6. Push commits + tags: `git push --follow-tags`
|
|
270
|
+
7. GitHub Actions publishes the tagged release to npm automatically via `.github/workflows/publish.yml`
|
|
214
271
|
|
|
215
|
-
###
|
|
272
|
+
### Trusted publishing
|
|
216
273
|
|
|
217
|
-
|
|
218
|
-
# One-time setup
|
|
219
|
-
echo "@clubnet:registry=https://registry.npmjs.org/" >> ~/.npmrc
|
|
220
|
-
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
|
|
274
|
+
The npm package is configured to publish from GitHub Actions, not from long-lived local npm tokens.
|
|
221
275
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
276
|
+
Trusted publisher settings for `@clubnet/seedclub`:
|
|
277
|
+
|
|
278
|
+
- Provider: GitHub Actions
|
|
279
|
+
- Organization or user: `seedclub`
|
|
280
|
+
- Repository: `seedclub-agent`
|
|
281
|
+
- Workflow filename: `publish.yml`
|
|
282
|
+
- Environment name: blank
|
|
283
|
+
|
|
284
|
+
Once trusted publishing is working, npm package publishing access should stay on the stricter setting that disallows token-based publishing.
|
|
225
285
|
|
|
226
286
|
## Update
|
|
227
287
|
|
|
@@ -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"
|