agor-live 0.3.7 → 0.3.10
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 +23 -143
- package/dist/cli/commands/config/get.js +5 -11
- package/dist/cli/commands/config/index.d.ts +1 -1
- package/dist/cli/commands/config/index.js +4 -25
- package/dist/cli/commands/config/set.js +4 -6
- package/dist/cli/commands/config/unset.js +7 -9
- package/dist/cli/commands/session/load-claude.js +0 -1
- package/dist/cli/commands/{repo/worktree → worktree}/add.d.ts +1 -1
- package/dist/cli/commands/{repo/worktree → worktree}/add.js +13 -22
- package/dist/cli/commands/worktree/env/restart.d.ts +15 -0
- package/dist/cli/commands/worktree/env/restart.js +90 -0
- package/dist/cli/commands/worktree/env/start.d.ts +15 -0
- package/dist/cli/commands/worktree/env/start.js +95 -0
- package/dist/cli/commands/worktree/env/status.d.ts +19 -0
- package/dist/cli/commands/worktree/env/status.js +155 -0
- package/dist/cli/commands/worktree/env/stop.d.ts +15 -0
- package/dist/cli/commands/worktree/env/stop.js +83 -0
- package/dist/cli/commands/{repo/worktree → worktree}/list.d.ts +2 -6
- package/dist/cli/commands/worktree/list.js +133 -0
- package/dist/cli/commands/worktree/rm.d.ts +18 -0
- package/dist/cli/commands/worktree/rm.js +118 -0
- package/dist/cli/commands/worktree/show.d.ts +19 -0
- package/dist/cli/commands/worktree/show.js +185 -0
- package/dist/cli/commands/worktree/update.d.ts +20 -0
- package/dist/cli/commands/worktree/update.js +111 -0
- package/dist/core/api/index.d.cts +53 -2
- package/dist/core/api/index.d.ts +53 -2
- package/dist/core/config/browser.d.cts +3 -24
- package/dist/core/config/browser.d.ts +3 -24
- package/dist/core/config/index.cjs +16 -107
- package/dist/core/config/index.d.cts +3 -85
- package/dist/core/config/index.d.ts +3 -85
- package/dist/core/config/index.js +15 -98
- package/dist/core/db/index.cjs +10 -35
- package/dist/core/db/index.d.cts +3 -3
- package/dist/core/db/index.d.ts +3 -3
- package/dist/core/db/index.js +10 -35
- package/dist/core/environment/variable-resolver.d.cts +1 -1
- package/dist/core/environment/variable-resolver.d.ts +1 -1
- package/dist/core/index.cjs +24 -140
- package/dist/core/index.d.cts +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +24 -132
- package/dist/core/package.json +50 -94
- package/dist/core/{repo-CnvJ0B6-.d.ts → repo-BoA8D6Uf.d.ts} +0 -10
- package/dist/core/{repo-3CUrCRbq.d.cts → repo-Dr--T0wp.d.cts} +0 -10
- package/dist/core/tools/index.cjs +723 -705
- package/dist/core/tools/index.d.cts +2 -17
- package/dist/core/tools/index.d.ts +2 -17
- package/dist/core/tools/index.js +723 -705
- package/dist/core/types/index.d.cts +1 -1
- package/dist/core/types/index.d.ts +1 -1
- package/dist/core/{dist/worktrees-BzIxB1U6.d.cts → worktrees-04Oos4ql.d.cts} +2 -12
- package/dist/core/{dist/worktrees-CYem1ya2.d.ts → worktrees-BK_zQmrd.d.ts} +2 -12
- package/dist/daemon/index.js +0 -16
- package/dist/daemon/services/worktrees.d.ts +0 -8
- package/dist/daemon/services/worktrees.js +0 -16
- package/dist/ui/assets/{index-KfIu8v4V.js → index-BAYihef5.js} +21 -21
- package/dist/ui/index.html +1 -1
- package/package.json +3 -3
- package/scripts/postinstall.js +39 -0
- package/dist/cli/commands/config/clear.d.ts +0 -13
- package/dist/cli/commands/config/clear.js +0 -21
- package/dist/cli/commands/repo/worktree/list.js +0 -136
- package/dist/core/dist/agentic-tool-B_gFNpk5.d.ts +0 -33
- package/dist/core/dist/agentic-tool-DsyX8diw.d.cts +0 -33
- package/dist/core/dist/api/index.cjs +0 -98
- package/dist/core/dist/api/index.d.cts +0 -174
- package/dist/core/dist/api/index.d.ts +0 -174
- package/dist/core/dist/api/index.js +0 -62
- package/dist/core/dist/board-comment-BUm0fpmD.d.cts +0 -134
- package/dist/core/dist/board-comment-gC_-twPx.d.ts +0 -134
- package/dist/core/dist/claude/index.cjs +0 -673
- package/dist/core/dist/claude/index.d.cts +0 -124
- package/dist/core/dist/claude/index.d.ts +0 -124
- package/dist/core/dist/claude/index.js +0 -629
- package/dist/core/dist/config/browser.cjs +0 -165
- package/dist/core/dist/config/browser.d.cts +0 -289
- package/dist/core/dist/config/browser.d.ts +0 -289
- package/dist/core/dist/config/browser.js +0 -131
- package/dist/core/dist/config/index.cjs +0 -518
- package/dist/core/dist/config/index.d.cts +0 -246
- package/dist/core/dist/config/index.d.ts +0 -246
- package/dist/core/dist/config/index.js +0 -451
- package/dist/core/dist/db/index.cjs +0 -3726
- package/dist/core/dist/db/index.d.cts +0 -631
- package/dist/core/dist/db/index.d.ts +0 -631
- package/dist/core/dist/db/index.js +0 -3649
- package/dist/core/dist/environment/variable-resolver.cjs +0 -92
- package/dist/core/dist/environment/variable-resolver.d.cts +0 -52
- package/dist/core/dist/environment/variable-resolver.d.ts +0 -52
- package/dist/core/dist/environment/variable-resolver.js +0 -53
- package/dist/core/dist/feathers/index.cjs +0 -66
- package/dist/core/dist/feathers/index.d.cts +0 -7
- package/dist/core/dist/feathers/index.d.ts +0 -7
- package/dist/core/dist/feathers/index.js +0 -25
- package/dist/core/dist/feathers-BzHEPnpl.d.cts +0 -228
- package/dist/core/dist/feathers-BzHEPnpl.d.ts +0 -228
- package/dist/core/dist/git/index.cjs +0 -302
- package/dist/core/dist/git/index.d.cts +0 -137
- package/dist/core/dist/git/index.d.ts +0 -137
- package/dist/core/dist/git/index.js +0 -260
- package/dist/core/dist/id-DMqyogFB.d.cts +0 -131
- package/dist/core/dist/id-DMqyogFB.d.ts +0 -131
- package/dist/core/dist/index.cjs +0 -4653
- package/dist/core/dist/index.d.cts +0 -23
- package/dist/core/dist/index.d.ts +0 -23
- package/dist/core/dist/index.js +0 -4509
- package/dist/core/dist/message-BoxZISHg.d.cts +0 -120
- package/dist/core/dist/message-DvBzHu7V.d.ts +0 -120
- package/dist/core/dist/permissions/index.cjs +0 -112
- package/dist/core/dist/permissions/index.d.cts +0 -81
- package/dist/core/dist/permissions/index.d.ts +0 -81
- package/dist/core/dist/permissions/index.js +0 -85
- package/dist/core/dist/repo-3CUrCRbq.d.cts +0 -405
- package/dist/core/dist/repo-CnvJ0B6-.d.ts +0 -405
- package/dist/core/dist/session-BPjJlVdZ.d.cts +0 -429
- package/dist/core/dist/session-wAzjHatv.d.ts +0 -429
- package/dist/core/dist/task-BIEgT1DK.d.cts +0 -163
- package/dist/core/dist/task-DuIfiUbW.d.ts +0 -163
- package/dist/core/dist/templates/handlebars-helpers.cjs +0 -156
- package/dist/core/dist/templates/handlebars-helpers.d.cts +0 -45
- package/dist/core/dist/templates/handlebars-helpers.d.ts +0 -45
- package/dist/core/dist/templates/handlebars-helpers.js +0 -119
- package/dist/core/dist/tools/claude/models.cjs +0 -70
- package/dist/core/dist/tools/claude/models.d.cts +0 -27
- package/dist/core/dist/tools/claude/models.d.ts +0 -27
- package/dist/core/dist/tools/claude/models.js +0 -44
- package/dist/core/dist/tools/index.cjs +0 -3367
- package/dist/core/dist/tools/index.d.cts +0 -967
- package/dist/core/dist/tools/index.d.ts +0 -967
- package/dist/core/dist/tools/index.js +0 -3314
- package/dist/core/dist/tools/models.cjs +0 -119
- package/dist/core/dist/tools/models.d.cts +0 -47
- package/dist/core/dist/tools/models.d.ts +0 -47
- package/dist/core/dist/tools/models.js +0 -86
- package/dist/core/dist/types/index.cjs +0 -152
- package/dist/core/dist/types/index.d.cts +0 -214
- package/dist/core/dist/types/index.d.ts +0 -214
- package/dist/core/dist/types/index.js +0 -112
- package/dist/core/dist/user-BmL3kFol.d.ts +0 -50
- package/dist/core/dist/user-eUuKj7yM.d.cts +0 -50
- package/dist/core/dist/utils/pricing.cjs +0 -102
- package/dist/core/dist/utils/pricing.d.cts +0 -43
- package/dist/core/dist/utils/pricing.d.ts +0 -43
- package/dist/core/dist/utils/pricing.js +0 -75
- package/dist/core/worktrees-BzIxB1U6.d.cts +0 -2745
- package/dist/core/worktrees-CYem1ya2.d.ts +0 -2745
package/README.md
CHANGED
|
@@ -1,163 +1,43 @@
|
|
|
1
|
-
|
|
1
|
+
# agor-live
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Multiplayer canvas for orchestrating AI coding sessions**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Agor is a real-time collaborative platform for managing Claude Code, Codex, and Gemini AI coding sessions. Visualize work on spatial boards, track git worktrees, and collaborate with your team.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Quick Start
|
|
12
|
-
|
|
13
|
-
**Install globally (recommended):**
|
|
7
|
+
## Installation
|
|
14
8
|
|
|
15
9
|
```bash
|
|
16
10
|
npm install -g agor-live
|
|
17
|
-
agor daemon start
|
|
18
|
-
agor ui open
|
|
19
11
|
```
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
[](https://codespaces.new/mistercrunch/agor?quickstart=1&devcontainer_path=.devcontainer%2Fplayground%2Fdevcontainer.json)
|
|
24
|
-
|
|
25
|
-
**Or run with Docker** (for contributing):
|
|
13
|
+
## Quick Start
|
|
26
14
|
|
|
27
15
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# Login: admin@agor.live / admin
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Screenshots
|
|
36
|
-
|
|
37
|
-

|
|
38
|
-
|
|
39
|
-
_Multiplayer spatial canvas with zones, real-time cursors, and session organization_
|
|
40
|
-
|
|
41
|
-
<div align="center">
|
|
42
|
-
<table>
|
|
43
|
-
<tr>
|
|
44
|
-
<td width="50%">
|
|
45
|
-
|
|
46
|
-

|
|
47
|
-
|
|
48
|
-
<p align="center"><em>Task-centric conversation UI</em></p>
|
|
49
|
-
|
|
50
|
-
</td>
|
|
51
|
-
<td width="50%">
|
|
52
|
-
|
|
53
|
-

|
|
54
|
-
|
|
55
|
-
<p align="center"><em>MCP server and worktree management</em></p>
|
|
56
|
-
|
|
57
|
-
</td>
|
|
58
|
-
</tr>
|
|
59
|
-
<tr>
|
|
60
|
-
<td width="50%">
|
|
61
|
-
|
|
62
|
-

|
|
63
|
-
|
|
64
|
-
<p align="center"><em>Session creation with agent selection</em></p>
|
|
65
|
-
|
|
66
|
-
</td>
|
|
67
|
-
<td width="50%">
|
|
68
|
-
|
|
69
|
-

|
|
70
|
-
|
|
71
|
-
<p align="center"><em>Zone trigger configuration</em></p>
|
|
72
|
-
|
|
73
|
-
</td>
|
|
74
|
-
</tr>
|
|
75
|
-
</table>
|
|
76
|
-
</div>
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## What It Does
|
|
81
|
-
|
|
82
|
-
- **Agent orchestration** - Run Claude Code, Codex, Gemini from one interface
|
|
83
|
-
- **Git worktree management** - Isolated workspaces per session, no branch conflicts
|
|
84
|
-
- **Real-time board** - Drag sessions around, organize by project/phase/zone
|
|
85
|
-
- **Session tracking** - Every AI conversation is stored, searchable, forkable
|
|
86
|
-
- **MCP integration** - Configure MCP servers once, use across all agents
|
|
87
|
-
- **Multiplayer** - See teammates' sessions, share environments, async handoffs
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Core Concepts
|
|
92
|
-
|
|
93
|
-
**Sessions** - Container for agent interactions with git state, tasks, genealogy
|
|
94
|
-
**Worktrees** - Git worktrees managed by Agor, isolated per session
|
|
95
|
-
**Boards** - Spatial canvas for organizing sessions (like Trello for AI work)
|
|
96
|
-
**Zones** - Areas on board that trigger templated prompts when sessions dropped
|
|
97
|
-
**Tasks** - User prompts tracked as first-class work units
|
|
16
|
+
# Start the daemon
|
|
17
|
+
agor daemon start
|
|
98
18
|
|
|
99
|
-
|
|
19
|
+
# Initialize / configure
|
|
20
|
+
agor daemon init
|
|
100
21
|
|
|
101
|
-
|
|
22
|
+
# Open UI in browser
|
|
23
|
+
agor ui open
|
|
102
24
|
|
|
103
25
|
```
|
|
104
|
-
Frontend (React + Ant Design)
|
|
105
|
-
↓ WebSocket
|
|
106
|
-
Daemon (FeathersJS)
|
|
107
|
-
↓
|
|
108
|
-
Database (LibSQL) + Git Worktrees
|
|
109
|
-
↓
|
|
110
|
-
Agent SDKs (Claude, Codex, Gemini)
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Stack:** FeathersJS, Drizzle ORM, LibSQL, React Flow, Ant Design
|
|
114
|
-
|
|
115
|
-
See [Architecture Guide](https://mistercrunch.github.io/agor/guide/architecture) for details.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Key Features
|
|
120
|
-
|
|
121
|
-
### Git Worktree Management
|
|
122
26
|
|
|
123
|
-
|
|
27
|
+
## Features
|
|
124
28
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
Drop sessions on zones to trigger templated workflows (analyze → develop → review → deploy).
|
|
132
|
-
|
|
133
|
-
### Session Genealogy
|
|
134
|
-
|
|
135
|
-
Fork sessions to explore alternatives. Spawn subsessions with fresh context. Full ancestry tracking.
|
|
136
|
-
|
|
137
|
-
### Multi-Agent Support
|
|
138
|
-
|
|
139
|
-
Swap between Claude/Codex/Gemini mid-task. Compare outputs. Hand off when one model stalls.
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Development
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
# Terminal 1: Daemon
|
|
147
|
-
cd apps/agor-daemon && pnpm dev # :3030
|
|
148
|
-
|
|
149
|
-
# Terminal 2: UI
|
|
150
|
-
cd apps/agor-ui && pnpm dev # :5173
|
|
151
|
-
```
|
|
29
|
+
- **Multi-Agent Support**: Claude Code, OpenAI Codex, Google Gemini
|
|
30
|
+
- **Git Integration**: Worktree-based workflows with branch management
|
|
31
|
+
- **Spatial Boards**: Visual canvas for organizing sessions and tasks
|
|
32
|
+
- **Real-time Collaboration**: WebSocket-powered multiplayer features
|
|
33
|
+
- **Task Tracking**: First-class task primitives with genealogy
|
|
34
|
+
- **MCP Integration**: Model Context Protocol server management
|
|
152
35
|
|
|
153
|
-
|
|
36
|
+
## Documentation
|
|
154
37
|
|
|
155
|
-
|
|
38
|
+
- **GitHub**: https://github.com/agorapp/agor
|
|
39
|
+
- **Docs**: https://agor.live
|
|
156
40
|
|
|
157
|
-
##
|
|
41
|
+
## License
|
|
158
42
|
|
|
159
|
-
-
|
|
160
|
-
- Bring Your Own IDE (VSCode/Cursor remote connection)
|
|
161
|
-
- Session forking UI with genealogy visualization
|
|
162
|
-
- Automated reports after task completion
|
|
163
|
-
- Context management system (modular markdown files)
|
|
43
|
+
BSL-1.1
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// src/commands/config/get.ts
|
|
2
|
-
import { getConfigValue
|
|
2
|
+
import { getConfigValue } from "@agor/core/config";
|
|
3
3
|
import { Args, Command } from "@oclif/core";
|
|
4
4
|
var ConfigGet = class _ConfigGet extends Command {
|
|
5
5
|
static description = "Get a configuration value";
|
|
6
6
|
static examples = [
|
|
7
|
-
"<%= config.bin %> <%= command.id %> board",
|
|
8
|
-
"<%= config.bin %> <%= command.id %>
|
|
7
|
+
"<%= config.bin %> <%= command.id %> defaults.board",
|
|
8
|
+
"<%= config.bin %> <%= command.id %> defaults.agent",
|
|
9
9
|
"<%= config.bin %> <%= command.id %> credentials.ANTHROPIC_API_KEY",
|
|
10
10
|
"<%= config.bin %> <%= command.id %> daemon.port"
|
|
11
11
|
];
|
|
12
12
|
static args = {
|
|
13
13
|
key: Args.string({
|
|
14
|
-
description: "Configuration key (e.g.,
|
|
14
|
+
description: "Configuration key in format: section.key (e.g., daemon.port, credentials.ANTHROPIC_API_KEY)",
|
|
15
15
|
required: true
|
|
16
16
|
})
|
|
17
17
|
};
|
|
@@ -19,13 +19,7 @@ var ConfigGet = class _ConfigGet extends Command {
|
|
|
19
19
|
const { args } = await this.parse(_ConfigGet);
|
|
20
20
|
const key = args.key;
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
const contextKeys = ["board", "session", "repo", "agent"];
|
|
24
|
-
if (contextKeys.includes(key)) {
|
|
25
|
-
value = await getContext(key);
|
|
26
|
-
} else {
|
|
27
|
-
value = await getConfigValue(key);
|
|
28
|
-
}
|
|
22
|
+
const value = await getConfigValue(key);
|
|
29
23
|
if (value !== void 0) {
|
|
30
24
|
this.log(String(value));
|
|
31
25
|
} else {
|
|
@@ -1,32 +1,16 @@
|
|
|
1
1
|
// src/commands/config/index.ts
|
|
2
|
-
import { getConfigPath,
|
|
2
|
+
import { getConfigPath, getDefaultConfig, loadConfig } from "@agor/core/config";
|
|
3
3
|
import { Command } from "@oclif/core";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
var ConfigIndex = class extends Command {
|
|
6
|
-
static description = "Show current configuration
|
|
6
|
+
static description = "Show current configuration";
|
|
7
7
|
static examples = ["<%= config.bin %> <%= command.id %>"];
|
|
8
8
|
async run() {
|
|
9
9
|
try {
|
|
10
10
|
const config = await loadConfig();
|
|
11
|
-
const
|
|
11
|
+
const defaults = getDefaultConfig();
|
|
12
12
|
this.log(chalk.bold("\nCurrent Configuration"));
|
|
13
13
|
this.log(chalk.dim("\u2500".repeat(50)));
|
|
14
|
-
this.log(chalk.bold("\nActive Context:"));
|
|
15
|
-
if (effective.board) {
|
|
16
|
-
this.log(` board: ${chalk.cyan(effective.board)}`);
|
|
17
|
-
}
|
|
18
|
-
if (effective.session) {
|
|
19
|
-
this.log(` session: ${chalk.cyan(effective.session)}`);
|
|
20
|
-
}
|
|
21
|
-
if (effective.repo) {
|
|
22
|
-
this.log(` repo: ${chalk.cyan(effective.repo)}`);
|
|
23
|
-
}
|
|
24
|
-
if (effective.agent) {
|
|
25
|
-
this.log(` agent: ${chalk.cyan(effective.agent)}`);
|
|
26
|
-
}
|
|
27
|
-
if (!effective.board && !effective.session && !effective.repo && !effective.agent) {
|
|
28
|
-
this.log(chalk.dim(" (no active context)"));
|
|
29
|
-
}
|
|
30
14
|
this.log(chalk.bold("\nGlobal Defaults:"));
|
|
31
15
|
if (config.defaults?.board) {
|
|
32
16
|
this.log(` default board: ${chalk.gray(config.defaults.board)}`);
|
|
@@ -54,8 +38,6 @@ var ConfigIndex = class extends Command {
|
|
|
54
38
|
}
|
|
55
39
|
}
|
|
56
40
|
}
|
|
57
|
-
const { getDefaultConfig } = await import("@agor/core/config");
|
|
58
|
-
const defaults = getDefaultConfig();
|
|
59
41
|
const daemonConfig = { ...defaults.daemon, ...config.daemon };
|
|
60
42
|
if (daemonConfig) {
|
|
61
43
|
this.log(chalk.bold("\nDaemon Settings:"));
|
|
@@ -86,9 +68,6 @@ var ConfigIndex = class extends Command {
|
|
|
86
68
|
this.log(chalk.bold("\nAvailable Configuration Keys:"));
|
|
87
69
|
this.log(chalk.dim(" Use `agor config set <key> <value>` to set any of these:"));
|
|
88
70
|
this.log("");
|
|
89
|
-
this.log(chalk.cyan(" Context (temporary, cleared with `agor config clear`):"));
|
|
90
|
-
this.log(" board, session, repo, agent");
|
|
91
|
-
this.log("");
|
|
92
71
|
this.log(chalk.cyan(" Defaults:"));
|
|
93
72
|
this.log(" defaults.board, defaults.agent");
|
|
94
73
|
this.log("");
|
|
@@ -99,7 +78,7 @@ var ConfigIndex = class extends Command {
|
|
|
99
78
|
this.log(" credentials.ANTHROPIC_API_KEY");
|
|
100
79
|
this.log(" credentials.OPENAI_API_KEY");
|
|
101
80
|
this.log(" credentials.CURSOR_API_KEY");
|
|
102
|
-
this.log(" credentials.
|
|
81
|
+
this.log(" credentials.GEMINI_API_KEY");
|
|
103
82
|
this.log("");
|
|
104
83
|
this.log(chalk.cyan(" Daemon:"));
|
|
105
84
|
this.log(" daemon.port, daemon.host");
|
|
@@ -5,16 +5,14 @@ import chalk from "chalk";
|
|
|
5
5
|
var ConfigSet = class _ConfigSet extends Command {
|
|
6
6
|
static description = "Set a configuration value";
|
|
7
7
|
static examples = [
|
|
8
|
-
"<%= config.bin %> <%= command.id %> board experiments",
|
|
9
|
-
"<%= config.bin %> <%= command.id %>
|
|
10
|
-
"<%= config.bin %> <%= command.id %> repo anthropics/agor:main",
|
|
11
|
-
"<%= config.bin %> <%= command.id %> agent claude-code",
|
|
8
|
+
"<%= config.bin %> <%= command.id %> defaults.board experiments",
|
|
9
|
+
"<%= config.bin %> <%= command.id %> defaults.agent claude-code",
|
|
12
10
|
"<%= config.bin %> <%= command.id %> credentials.ANTHROPIC_API_KEY sk-ant-...",
|
|
13
|
-
"<%= config.bin %> <%= command.id %>
|
|
11
|
+
"<%= config.bin %> <%= command.id %> daemon.port 4000"
|
|
14
12
|
];
|
|
15
13
|
static args = {
|
|
16
14
|
key: Args.string({
|
|
17
|
-
description: "Configuration key (
|
|
15
|
+
description: "Configuration key in format: section.key (e.g., daemon.port, credentials.ANTHROPIC_API_KEY)",
|
|
18
16
|
required: true
|
|
19
17
|
}),
|
|
20
18
|
value: Args.string({
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
// src/commands/config/unset.ts
|
|
2
|
-
import {
|
|
2
|
+
import { unsetConfigValue } from "@agor/core/config";
|
|
3
3
|
import { Args, Command } from "@oclif/core";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
var ConfigUnset = class _ConfigUnset extends Command {
|
|
6
6
|
static description = "Unset (clear) a configuration value";
|
|
7
7
|
static examples = [
|
|
8
|
-
"<%= config.bin %> <%= command.id %> board",
|
|
9
|
-
"<%= config.bin %> <%= command.id %>
|
|
10
|
-
"<%= config.bin %> <%= command.id %>
|
|
11
|
-
"<%= config.bin %> <%= command.id %> agent"
|
|
8
|
+
"<%= config.bin %> <%= command.id %> defaults.board",
|
|
9
|
+
"<%= config.bin %> <%= command.id %> defaults.agent",
|
|
10
|
+
"<%= config.bin %> <%= command.id %> credentials.ANTHROPIC_API_KEY"
|
|
12
11
|
];
|
|
13
12
|
static args = {
|
|
14
13
|
key: Args.string({
|
|
15
|
-
description: "Configuration key
|
|
16
|
-
required: true
|
|
17
|
-
options: ["board", "session", "repo", "agent"]
|
|
14
|
+
description: "Configuration key in format: section.key (e.g., defaults.board)",
|
|
15
|
+
required: true
|
|
18
16
|
})
|
|
19
17
|
};
|
|
20
18
|
async run() {
|
|
21
19
|
const { args } = await this.parse(_ConfigUnset);
|
|
22
20
|
const key = args.key;
|
|
23
21
|
try {
|
|
24
|
-
await
|
|
22
|
+
await unsetConfigValue(key);
|
|
25
23
|
this.log(`${chalk.green("\u2713")} Unset ${chalk.cyan(key)}`);
|
|
26
24
|
} catch (error) {
|
|
27
25
|
this.error(
|
|
@@ -92,7 +92,6 @@ ${chalk.blue("\u25CF")} Loading Claude Code session: ${chalk.cyan(sessionId)}
|
|
|
92
92
|
// Will be auto-assigned by service hook
|
|
93
93
|
path: absoluteProjectDir,
|
|
94
94
|
new_branch: false,
|
|
95
|
-
sessions: [],
|
|
96
95
|
last_used: (/* @__PURE__ */ new Date()).toISOString(),
|
|
97
96
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
98
97
|
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5,10 +5,10 @@ declare class WorktreeAdd extends Command {
|
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
7
7
|
static args: {
|
|
8
|
-
repoSlug: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
|
|
9
8
|
name: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
|
|
10
9
|
};
|
|
11
10
|
static flags: {
|
|
11
|
+
'repo-id': _oclif_core_interfaces.OptionFlag<string, _oclif_core_interfaces.CustomOptions>;
|
|
12
12
|
branch: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
|
|
13
13
|
checkout: _oclif_core_interfaces.BooleanFlag<boolean>;
|
|
14
14
|
ref: _oclif_core_interfaces.OptionFlag<string | undefined, _oclif_core_interfaces.CustomOptions>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/commands/
|
|
1
|
+
// src/commands/worktree/add.ts
|
|
2
2
|
import { createClient, isDaemonRunning } from "@agor/core/api";
|
|
3
3
|
import { getDaemonUrl } from "@agor/core/config";
|
|
4
4
|
import { Args, Command, Flags } from "@oclif/core";
|
|
@@ -7,27 +7,27 @@ var WorktreeAdd = class _WorktreeAdd extends Command {
|
|
|
7
7
|
static description = "Create a git worktree for isolated development";
|
|
8
8
|
static examples = [
|
|
9
9
|
// Case 1: Create new branch (worktree name = branch name)
|
|
10
|
-
"<%= config.bin %> <%= command.id %>
|
|
10
|
+
"<%= config.bin %> <%= command.id %> feature-auth --repo-id 01933e4a",
|
|
11
11
|
// Case 2: Create new branch with different name
|
|
12
|
-
"<%= config.bin %> <%= command.id %>
|
|
12
|
+
"<%= config.bin %> <%= command.id %> my-experiment --repo-id 01933e4a --branch feature-x",
|
|
13
13
|
// Case 3: Checkout existing branch
|
|
14
|
-
"<%= config.bin %> <%= command.id %>
|
|
14
|
+
"<%= config.bin %> <%= command.id %> fix-api --repo-id 01933e4a --checkout",
|
|
15
15
|
// Case 4: Checkout specific ref
|
|
16
|
-
"<%= config.bin %> <%= command.id %>
|
|
16
|
+
"<%= config.bin %> <%= command.id %> debug-session --repo-id 01933e4a --ref abc123def",
|
|
17
17
|
// Case 5: Create branch from specific base
|
|
18
|
-
"<%= config.bin %> <%= command.id %>
|
|
18
|
+
"<%= config.bin %> <%= command.id %> feature-y --repo-id 01933e4a --from develop"
|
|
19
19
|
];
|
|
20
20
|
static args = {
|
|
21
|
-
repoSlug: Args.string({
|
|
22
|
-
description: "Repository slug",
|
|
23
|
-
required: true
|
|
24
|
-
}),
|
|
25
21
|
name: Args.string({
|
|
26
22
|
description: "Worktree name (becomes branch name if creating new)",
|
|
27
23
|
required: true
|
|
28
24
|
})
|
|
29
25
|
};
|
|
30
26
|
static flags = {
|
|
27
|
+
"repo-id": Flags.string({
|
|
28
|
+
description: "Repository ID",
|
|
29
|
+
required: true
|
|
30
|
+
}),
|
|
31
31
|
branch: Flags.string({
|
|
32
32
|
char: "b",
|
|
33
33
|
description: "Branch name (defaults to same as worktree name)"
|
|
@@ -62,16 +62,7 @@ var WorktreeAdd = class _WorktreeAdd extends Command {
|
|
|
62
62
|
try {
|
|
63
63
|
const client = createClient(daemonUrl);
|
|
64
64
|
const reposService = client.service("repos");
|
|
65
|
-
const
|
|
66
|
-
query: { slug: args.repoSlug, $limit: 1 }
|
|
67
|
-
});
|
|
68
|
-
const reposList = Array.isArray(repos) ? repos : repos.data;
|
|
69
|
-
if (!reposList || reposList.length === 0) {
|
|
70
|
-
this.error(
|
|
71
|
-
`Repository '${args.repoSlug}' not found. Use ${chalk.cyan("agor repo list")} to see available repos.`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
const repo = reposList[0];
|
|
65
|
+
const repo = await reposService.get(flags["repo-id"]);
|
|
75
66
|
const worktreesService = client.service("worktrees");
|
|
76
67
|
const existingWorktrees = await worktreesService.find({
|
|
77
68
|
query: {
|
|
@@ -86,7 +77,7 @@ var WorktreeAdd = class _WorktreeAdd extends Command {
|
|
|
86
77
|
this.log("");
|
|
87
78
|
this.log(
|
|
88
79
|
chalk.bold(
|
|
89
|
-
`Creating worktree ${chalk.cyan(args.name)} in repository ${chalk.cyan(
|
|
80
|
+
`Creating worktree ${chalk.cyan(args.name)} in repository ${chalk.cyan(flags["repo-id"])}...`
|
|
90
81
|
)
|
|
91
82
|
);
|
|
92
83
|
this.log("");
|
|
@@ -128,7 +119,7 @@ var WorktreeAdd = class _WorktreeAdd extends Command {
|
|
|
128
119
|
this.log(chalk.bold("Next steps:"));
|
|
129
120
|
this.log(` ${chalk.dim("cd")} ${newWorktree.path}`);
|
|
130
121
|
this.log(
|
|
131
|
-
` ${chalk.dim("or start session:")} ${chalk.cyan(`agor session start --repo ${
|
|
122
|
+
` ${chalk.dim("or start session:")} ${chalk.cyan(`agor session start --repo ${flags["repo-id"]} --worktree ${args.name}`)}`
|
|
132
123
|
);
|
|
133
124
|
this.log("");
|
|
134
125
|
client.io.close();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as _oclif_core_interfaces from '@oclif/core/interfaces';
|
|
2
|
+
import { BaseCommand } from '../../../base-command.js';
|
|
3
|
+
import '@agor/core/api';
|
|
4
|
+
import '@oclif/core';
|
|
5
|
+
|
|
6
|
+
declare class WorktreeEnvRestart extends BaseCommand {
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static args: {
|
|
10
|
+
worktreeId: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { WorktreeEnvRestart as default };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// src/commands/worktree/env/restart.ts
|
|
2
|
+
import { formatShortId } from "@agor/core/db";
|
|
3
|
+
import { Args } from "@oclif/core";
|
|
4
|
+
import chalk2 from "chalk";
|
|
5
|
+
|
|
6
|
+
// src/base-command.ts
|
|
7
|
+
import { createClient, isDaemonRunning } from "@agor/core/api";
|
|
8
|
+
import { getDaemonUrl } from "@agor/core/config";
|
|
9
|
+
import { Command } from "@oclif/core";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
var BaseCommand = class extends Command {
|
|
12
|
+
daemonUrl = null;
|
|
13
|
+
/**
|
|
14
|
+
* Connect to daemon (checks if running first)
|
|
15
|
+
*
|
|
16
|
+
* @returns Feathers client instance
|
|
17
|
+
*/
|
|
18
|
+
async connectToDaemon() {
|
|
19
|
+
this.daemonUrl = await getDaemonUrl();
|
|
20
|
+
const running = await isDaemonRunning(this.daemonUrl);
|
|
21
|
+
if (!running) {
|
|
22
|
+
this.log(
|
|
23
|
+
chalk.red("\u2717 Daemon not running") + "\n\n" + chalk.bold("To start the daemon:") + "\n " + chalk.cyan("cd apps/agor-daemon && pnpm dev") + "\n\n" + chalk.bold("To configure daemon URL:") + "\n " + chalk.cyan("agor config set daemon.url <url>") + "\n " + chalk.gray(`Current: ${this.daemonUrl}`)
|
|
24
|
+
);
|
|
25
|
+
this.exit(1);
|
|
26
|
+
}
|
|
27
|
+
return createClient(this.daemonUrl, true, { verbose: false });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Cleanup client connection
|
|
31
|
+
*
|
|
32
|
+
* Ensures socket is properly closed to prevent hanging processes
|
|
33
|
+
*/
|
|
34
|
+
async cleanupClient(client) {
|
|
35
|
+
await new Promise((resolve) => {
|
|
36
|
+
client.io.once("disconnect", () => resolve());
|
|
37
|
+
client.io.removeAllListeners("connect");
|
|
38
|
+
client.io.removeAllListeners("connect_error");
|
|
39
|
+
client.io.close();
|
|
40
|
+
setTimeout(resolve, 1e3);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/commands/worktree/env/restart.ts
|
|
46
|
+
var WorktreeEnvRestart = class _WorktreeEnvRestart extends BaseCommand {
|
|
47
|
+
static description = "Restart worktree environment";
|
|
48
|
+
static examples = [
|
|
49
|
+
"<%= config.bin %> <%= command.id %> abc123",
|
|
50
|
+
"<%= config.bin %> <%= command.id %> 01933e4a-b2c1-7890-a456-789012345678"
|
|
51
|
+
];
|
|
52
|
+
static args = {
|
|
53
|
+
worktreeId: Args.string({
|
|
54
|
+
description: "Worktree ID (full UUID or short ID)",
|
|
55
|
+
required: true
|
|
56
|
+
})
|
|
57
|
+
};
|
|
58
|
+
async run() {
|
|
59
|
+
const { args } = await this.parse(_WorktreeEnvRestart);
|
|
60
|
+
const client = await this.connectToDaemon();
|
|
61
|
+
try {
|
|
62
|
+
const worktreesService = client.service("worktrees");
|
|
63
|
+
const worktree = await worktreesService.get(args.worktreeId);
|
|
64
|
+
this.log("");
|
|
65
|
+
this.log(`Restarting environment for ${chalk2.cyan(worktree.name)}...`);
|
|
66
|
+
this.log(` ID: ${chalk2.dim(formatShortId(worktree.worktree_id))}`);
|
|
67
|
+
this.log("");
|
|
68
|
+
const updated = await worktreesService.restartEnvironment(worktree.worktree_id);
|
|
69
|
+
this.log(`${chalk2.green("\u2713")} Environment restarted`);
|
|
70
|
+
if (updated.environment_instance?.access_urls) {
|
|
71
|
+
this.log("");
|
|
72
|
+
this.log(chalk2.bold("Access URLs:"));
|
|
73
|
+
for (const url of updated.environment_instance.access_urls) {
|
|
74
|
+
this.log(` ${url.name}: ${chalk2.blue(url.url)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
this.log("");
|
|
78
|
+
await this.cleanupClient(client);
|
|
79
|
+
process.exit(0);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
await this.cleanupClient(client);
|
|
82
|
+
this.error(
|
|
83
|
+
`Failed to restart environment: ${error instanceof Error ? error.message : String(error)}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export {
|
|
89
|
+
WorktreeEnvRestart as default
|
|
90
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as _oclif_core_interfaces from '@oclif/core/interfaces';
|
|
2
|
+
import { BaseCommand } from '../../../base-command.js';
|
|
3
|
+
import '@agor/core/api';
|
|
4
|
+
import '@oclif/core';
|
|
5
|
+
|
|
6
|
+
declare class WorktreeEnvStart extends BaseCommand {
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static args: {
|
|
10
|
+
worktreeId: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { WorktreeEnvStart as default };
|