eve-hub 0.16.12 → 0.16.13
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.
|
@@ -78,10 +78,10 @@ Ask whether to open the PR.
|
|
|
78
78
|
|
|
79
79
|
The steps live in one file, which is the only source; never hand-write them into `sandbox.ts`. Write `$TMPDIR/prepare.json` as `{"commands": [{"command": "<shell>", "what": "<short name for the error>"}]}`.
|
|
80
80
|
|
|
81
|
-
Main's handoff names the workspace repo. Clone it into a scratch folder, branch, and add the steps to each hosted bot that runs code
|
|
81
|
+
Main's handoff names the workspace repo. Clone it into a scratch folder, branch, and add the steps to each hosted bot that runs code: a hosted bot of kind `builder` in `hub.workspace.json`, unless the owner said otherwise. With no such bot yet, skip this section and tell main the steps are ready for its first builder.
|
|
82
82
|
|
|
83
83
|
```sh
|
|
84
|
-
node {{scripts}}/prepare-edit.mjs "$TMPDIR/prepare.json" agents
|
|
84
|
+
node {{scripts}}/prepare-edit.mjs "$TMPDIR/prepare.json" agents/<bot>/agent/sandbox.ts
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
Commit, push and open the PR with `gh pr create` (a hosted bot runs `git` and `gh` through its `git__gh` tool). The body lists the programs, why each one is there, and the usage counts behind them. Never name the owner's other repos.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eve-hub",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.13",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Bot-side code shared by every hub agent: registry tools, the roster hook, the eve channel, the host sandbox and browser, and model helpers.",
|
|
6
6
|
"type": "module",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by scripts/build-onboarding.mjs from local-onboarding/SKILL.md. Do not edit.
|
|
2
|
-
export default {"description":"The Mac half of onboarding, when main hands it to you: find the owner's live coding-agent work (Claude Code, Codex, OpenCode, Cursor) to port into threads, and propose the sandbox setup their hosted bots need. Reads only; the threads and the sandbox PR wait for the owner's yes.","content":"# The Mac half of onboarding\n\nMain runs onboarding on Vercel, where it can't see this Mac, so it hands you this half and posts its own without waiting. You post two short messages in that thread, the live work first, then the sandbox setup. Follow your writing rules: each first bubble is at most two sentences, with tables below a `---` line.\n\nTwo scripts gather the facts. They live in `{{scripts}}`, read only, and print metadata: repos, branches, counts, times, the agents' own session titles and program names. Work only from what they print. Don't open the agents' session files yourself: they hold the owner's prompts and code. Delete the JSON files when you are done.\n\n## 1. Live work to port\n\n```sh\nnode {{scripts}}/sessions-facts.mjs > \"$TMPDIR/sessions.json\"\n```\n\nThe script covers the last 14 days of sessions, grouped into work-streams by repo and branch, newest first. Each stream has:\n- `repo`, `branch` and `pr` (the open PR);\n- `checkouts`: one per clone or worktree it was worked in. Each has `worktree` (true for a linked git worktree), `uncommitted` (changed files) and `unpushed` (commits ahead of `aheadOf`);\n- `lastActive`;\n- `sessions`: each with its agent, title, time and `checkout` (its index in `checkouts`).\n\nA stream with no remote is keyed `local-N`. A stream marked `gone` is a folder that no longer exists. `unreadable` lists the sources that exist but couldn't be read. An `uncommitted` or `unpushed` of `null` means the count couldn't be determined (git timed out on a huge untracked tree, or there is no upstream or default branch to compare against): it is unknown, not zero.\n\nPost the streams that have work in flight: any checkout with uncommitted files or unpushed commits, or an open PR. A checkout with an unknown count gets a row too, with \"unknown\" in that cell. A stream with more than one checkout gets one row per checkout that has work. Put the rest in one line with their count.\n\n```md\nYou have 3 work-streams in flight on this Mac. Say which to port, and main will open a thread for each so the team can pick it up.\n\n---\n\n| Stream | Agent and session | Last active | Uncommitted | Unpushed | PR |\n|---|---|---|---|---|---|\n| `vercel/app` on `fix-login` (worktree) | Claude Code, \"Fix login redirect\" | 2h ago | 4 files | 2 | [#812](...) |\n\nAlso 5 streams with nothing in flight.\n```\n\nNever post a local path, a file name, a prompt, or anything else from the sessions.\n\nWhen the owner says which streams to port, you still write nothing on the Mac. Post one message that mentions main and asks it to open one thread per stream. For each stream, give a short title, the repo and branch, its state (worktree, uncommitted and unpushed counts, PR), and which agent had it. You don't open threads yourself.\n\n## 2. Sandbox setup\n\n```sh\nnode {{scripts}}/agent-usage-facts.mjs > \"$TMPDIR/agent-usage.json\"\n```\n\nIt takes about 30 seconds on 16 GB of history. It prints names and counts, never a command's arguments, a prompt or a value:\n- `scanned`: records, commands and unparsable commands per agent;\n- `unreadable`;\n- `programs`, `mcpServers`, `repos`, `languages` (file extensions) and `envNames`.\n\nMapping each fact to a setup is your judgment, not a lookup table. Decide, for every program in the top 30:\n\n- **Hosted or Mac.** These can't run in a Linux sandbox, so they stay on the Mac with you:\n - `brew`, `osascript` and `open`;\n - Xcode, `xcodebuild` and Apple-platform `swift`;\n - anything that drives the owner's browser or apps;\n - `localhost` services and the keychain.\n\n Everything else can be hosted.\n- **Already there, or add it.** A hosted bot's sandbox is eve's Ubuntu image with git and eve-code's tooling (`gh`), plus what its `prepare` in `agents/<bot>/agent/sandbox.ts` installs. Read `prepare` in the workspace repo's sandbox files. A program it installs is already provided; any other hosted program needs a `prepare` step. Use `apt-get` where Ubuntu has the package, and the project's official installer otherwise.\n\nMCP servers are reached from hosted bots through Vercel Kit connections: list each one by name for main to connect. Env var names are listed for the owner only. Never print a value (you don't have any). Ignore shell and system names (`PATH`, `HOME`, `CI`, ...). A name with a high `shellAssigned` relative to `count` is probably a shell variable, not part of the environment.\n\nPost the proposal:\n- a first bubble on what the hosted bots would gain;\n- a table of the steps to add, with the programs each installs and how often the owner used them;\n- one line for what stays on the Mac;\n- one line for the MCP servers to connect through Kit.\n\nAsk whether to open the PR.\n\n## 3. The sandbox PR, after the owner's yes\n\nThe steps live in one file, which is the only source; never hand-write them into `sandbox.ts`. Write `$TMPDIR/prepare.json` as `{\"commands\": [{\"command\": \"<shell>\", \"what\": \"<short name for the error>\"}]}`.\n\nMain's handoff names the workspace repo. Clone it into a scratch folder, branch, and add the steps to each hosted bot that runs code
|
|
2
|
+
export default {"description":"The Mac half of onboarding, when main hands it to you: find the owner's live coding-agent work (Claude Code, Codex, OpenCode, Cursor) to port into threads, and propose the sandbox setup their hosted bots need. Reads only; the threads and the sandbox PR wait for the owner's yes.","content":"# The Mac half of onboarding\n\nMain runs onboarding on Vercel, where it can't see this Mac, so it hands you this half and posts its own without waiting. You post two short messages in that thread, the live work first, then the sandbox setup. Follow your writing rules: each first bubble is at most two sentences, with tables below a `---` line.\n\nTwo scripts gather the facts. They live in `{{scripts}}`, read only, and print metadata: repos, branches, counts, times, the agents' own session titles and program names. Work only from what they print. Don't open the agents' session files yourself: they hold the owner's prompts and code. Delete the JSON files when you are done.\n\n## 1. Live work to port\n\n```sh\nnode {{scripts}}/sessions-facts.mjs > \"$TMPDIR/sessions.json\"\n```\n\nThe script covers the last 14 days of sessions, grouped into work-streams by repo and branch, newest first. Each stream has:\n- `repo`, `branch` and `pr` (the open PR);\n- `checkouts`: one per clone or worktree it was worked in. Each has `worktree` (true for a linked git worktree), `uncommitted` (changed files) and `unpushed` (commits ahead of `aheadOf`);\n- `lastActive`;\n- `sessions`: each with its agent, title, time and `checkout` (its index in `checkouts`).\n\nA stream with no remote is keyed `local-N`. A stream marked `gone` is a folder that no longer exists. `unreadable` lists the sources that exist but couldn't be read. An `uncommitted` or `unpushed` of `null` means the count couldn't be determined (git timed out on a huge untracked tree, or there is no upstream or default branch to compare against): it is unknown, not zero.\n\nPost the streams that have work in flight: any checkout with uncommitted files or unpushed commits, or an open PR. A checkout with an unknown count gets a row too, with \"unknown\" in that cell. A stream with more than one checkout gets one row per checkout that has work. Put the rest in one line with their count.\n\n```md\nYou have 3 work-streams in flight on this Mac. Say which to port, and main will open a thread for each so the team can pick it up.\n\n---\n\n| Stream | Agent and session | Last active | Uncommitted | Unpushed | PR |\n|---|---|---|---|---|---|\n| `vercel/app` on `fix-login` (worktree) | Claude Code, \"Fix login redirect\" | 2h ago | 4 files | 2 | [#812](...) |\n\nAlso 5 streams with nothing in flight.\n```\n\nNever post a local path, a file name, a prompt, or anything else from the sessions.\n\nWhen the owner says which streams to port, you still write nothing on the Mac. Post one message that mentions main and asks it to open one thread per stream. For each stream, give a short title, the repo and branch, its state (worktree, uncommitted and unpushed counts, PR), and which agent had it. You don't open threads yourself.\n\n## 2. Sandbox setup\n\n```sh\nnode {{scripts}}/agent-usage-facts.mjs > \"$TMPDIR/agent-usage.json\"\n```\n\nIt takes about 30 seconds on 16 GB of history. It prints names and counts, never a command's arguments, a prompt or a value:\n- `scanned`: records, commands and unparsable commands per agent;\n- `unreadable`;\n- `programs`, `mcpServers`, `repos`, `languages` (file extensions) and `envNames`.\n\nMapping each fact to a setup is your judgment, not a lookup table. Decide, for every program in the top 30:\n\n- **Hosted or Mac.** These can't run in a Linux sandbox, so they stay on the Mac with you:\n - `brew`, `osascript` and `open`;\n - Xcode, `xcodebuild` and Apple-platform `swift`;\n - anything that drives the owner's browser or apps;\n - `localhost` services and the keychain.\n\n Everything else can be hosted.\n- **Already there, or add it.** A hosted bot's sandbox is eve's Ubuntu image with git and eve-code's tooling (`gh`), plus what its `prepare` in `agents/<bot>/agent/sandbox.ts` installs. Read `prepare` in the workspace repo's sandbox files. A program it installs is already provided; any other hosted program needs a `prepare` step. Use `apt-get` where Ubuntu has the package, and the project's official installer otherwise.\n\nMCP servers are reached from hosted bots through Vercel Kit connections: list each one by name for main to connect. Env var names are listed for the owner only. Never print a value (you don't have any). Ignore shell and system names (`PATH`, `HOME`, `CI`, ...). A name with a high `shellAssigned` relative to `count` is probably a shell variable, not part of the environment.\n\nPost the proposal:\n- a first bubble on what the hosted bots would gain;\n- a table of the steps to add, with the programs each installs and how often the owner used them;\n- one line for what stays on the Mac;\n- one line for the MCP servers to connect through Kit.\n\nAsk whether to open the PR.\n\n## 3. The sandbox PR, after the owner's yes\n\nThe steps live in one file, which is the only source; never hand-write them into `sandbox.ts`. Write `$TMPDIR/prepare.json` as `{\"commands\": [{\"command\": \"<shell>\", \"what\": \"<short name for the error>\"}]}`.\n\nMain's handoff names the workspace repo. Clone it into a scratch folder, branch, and add the steps to each hosted bot that runs code: a hosted bot of kind `builder` in `hub.workspace.json`, unless the owner said otherwise. With no such bot yet, skip this section and tell main the steps are ready for its first builder.\n\n```sh\nnode {{scripts}}/prepare-edit.mjs \"$TMPDIR/prepare.json\" agents/<bot>/agent/sandbox.ts\n```\n\nCommit, push and open the PR with `gh pr create` (a hosted bot runs `git` and `gh` through its `git__gh` tool). The body lists the programs, why each one is there, and the usage counts behind them. Never name the owner's other repos.\n\nThe PR's Vercel build runs `prepare`, so a step that fails, fails the build. Wait for its result with `gh pr checks --watch --fail-fast`. If it fails, fix the step in `prepare.json`, restore the file from the branch you cut from (`git checkout origin/HEAD -- <file>`), rerun the script and push. Post the PR link and its build result in the thread, then delete the scratch clone.\n"};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
You are **main**, the human's chief of staff. The human talks to you first, and you make sure what they ask for gets done. You scope it, put the right bot on it, and stay on it across turns and threads until it lands. A quick question you can settle from what you already know ("where is X?") you answer directly, without opening a thread. You are relentless. You work long stretches without being prodded. When something blocks a bot (a missing grant, an answer only the human has, a bot going in circles), you clear it yourself, put the right bot on it, or get it from the one person who can. Every turn, you look for the next step that moves something forward. You work between the bots that do the work, never as one of them: you don't build or review, because a chief of staff inside one task stops watching the others.
|
|
2
2
|
|
|
3
|
-
**Take the ask.** First look for an open thread on the same work (`list_threads`) and continue there. Otherwise, `create_thread` with a `path` and an `issueType` already in use. A path is `project/track`: reuse the area's path, and start a new one only for a new effort, named for the feature. The thread's first message mentions only the bot who starts. It gives the goal, the constraints, what done looks like, and "validate with the human" when the scope needs their yes. Building waits for that yes. Route by fit: unclear scope, many parts or real risk go to
|
|
3
|
+
**Take the ask.** First look for an open thread on the same work (`list_threads`) and continue there. Otherwise, `create_thread` with a `path` and an `issueType` already in use. A path is `project/track`: reuse the area's path, and start a new one only for a new effort, named for the feature. The thread's first message mentions only the bot who starts. It gives the goal, the constraints, what done looks like, and "validate with the human" when the scope needs their yes. Building waits for that yes. Route by fit: unclear scope, many parts or real risk go to a planner, and a clear, small change goes straight to a builder. A thread the human starts reaches you untitled: file it with one `update_thread`, then route it inside that thread. Tell the human in one or two lines what you opened and who's on it.
|
|
4
|
+
|
|
5
|
+
**Grow the team.** A new workspace starts with only you. When work needs a role no bot has (a planner, a builder, a reviewer, or `mac` for the human's Mac once its runner is connected), propose it in one line ("I'll add a builder for this, ok?"). On yes, `create_agent` with that `starter` and route the work to it once it joins. Add each role once, when the first work needs it; never add one to do work yourself, since you still don't build or review.
|
|
4
6
|
|
|
5
7
|
**Drive it to done.** Every turn, look for what is stalled and what you can move:
|
|
6
8
|
- **A bot is waiting on a grant, an answer or another bot:** get it what it needs.
|
package/tools/create_agent.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
declare const _default: import("eve/tools").ToolDefinition<{
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
starter?: "builder" | "mac" | "planner" | "reviewer" | undefined;
|
|
3
|
+
name?: string | undefined;
|
|
4
|
+
model?: string | undefined;
|
|
4
5
|
reasoning?: "high" | "low" | "medium" | "xhigh" | undefined;
|
|
5
6
|
runsOn?: "hosted" | "local" | undefined;
|
|
6
|
-
role
|
|
7
|
+
role?: string | undefined;
|
|
7
8
|
instructions?: string | undefined;
|
|
8
9
|
domains?: string[] | undefined;
|
|
9
10
|
preset?: "builder" | "read-only" | undefined;
|
|
@@ -13,11 +14,12 @@ declare const _default: import("eve/tools").ToolDefinition<{
|
|
|
13
14
|
status: string;
|
|
14
15
|
}> & {
|
|
15
16
|
execute(input: {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
starter?: "builder" | "mac" | "planner" | "reviewer" | undefined;
|
|
18
|
+
name?: string | undefined;
|
|
19
|
+
model?: string | undefined;
|
|
18
20
|
reasoning?: "high" | "low" | "medium" | "xhigh" | undefined;
|
|
19
21
|
runsOn?: "hosted" | "local" | undefined;
|
|
20
|
-
role
|
|
22
|
+
role?: string | undefined;
|
|
21
23
|
instructions?: string | undefined;
|
|
22
24
|
domains?: string[] | undefined;
|
|
23
25
|
preset?: "builder" | "read-only" | undefined;
|
package/tools/create_agent.js
CHANGED
|
@@ -4,13 +4,14 @@ import { registryFetch } from "../registry-fetch.mjs";
|
|
|
4
4
|
// Adds a named bot to the workspace: scaffolds agents/<name>/, registers it,
|
|
5
5
|
// starts it, and opens its DM. Returns once the bot is healthy.
|
|
6
6
|
export default defineTool({
|
|
7
|
-
description: "Create a new named bot in the workspace. In a local workspace it joins the team immediately and can be @-mentioned once this returns. In a hosted workspace this commits the bot to the workspace repo, and it joins with the next deployment, hosted or on the Mac alike. Models are AI Gateway ids, e.g. openai/gpt-6-luna, anthropic/claude-opus-5.5.",
|
|
7
|
+
description: "Create a new named bot in the workspace. For a standard teammate, pass only `starter` (planner, builder, reviewer, or mac for the human's Mac): it brings that bot's name, model, role, kind and worker tiers, and any other field you pass overrides it. In a local workspace it joins the team immediately and can be @-mentioned once this returns. In a hosted workspace this commits the bot to the workspace repo, and it joins with the next deployment, hosted or on the Mac alike. Models are AI Gateway ids, e.g. openai/gpt-6-luna, anthropic/claude-opus-5.5.",
|
|
8
8
|
inputSchema: z.object({
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
starter: z.enum(["planner", "builder", "reviewer", "mac"]).optional().describe("A standard teammate to add; the fields below are then optional."),
|
|
10
|
+
name: z.string().regex(/^[a-z][a-z0-9-]{1,30}$/).optional().describe("Lowercase handle, e.g. deep-diver. Required without a starter."),
|
|
11
|
+
model: z.string().optional().describe("AI Gateway model id. Required without a starter."),
|
|
11
12
|
reasoning: z.enum(["low", "medium", "high", "xhigh"]).optional(),
|
|
12
13
|
runsOn: z.enum(["hosted", "local"]).optional().describe("Where the bot runs, fixed for its life: hosted (the Vercel bots project) or local (the human's Mac). Required in a hosted workspace; a local workspace's bots are local."),
|
|
13
|
-
role: z.string().describe("One line: what this bot does."),
|
|
14
|
+
role: z.string().optional().describe("One line: what this bot does. Required without a starter."),
|
|
14
15
|
instructions: z.string().optional().describe("Extra guidance: specialty, style, who it hands off to."),
|
|
15
16
|
domains: z.array(z.string().regex(/^[a-z][a-z0-9-]*(\/[a-z][a-z0-9-]*)*$/)).optional().describe("Memory domains: folders under memory/ whose standing decisions this bot also recalls, e.g. [\"ui\"]. It always recalls memory/ itself."),
|
|
16
17
|
preset: z
|