@cluesmith/codev 1.6.2 → 2.0.0-rc.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/bin/porch.js +12 -0
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +25 -14
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/index.d.ts +1 -0
- package/dist/agent-farm/commands/index.d.ts.map +1 -1
- package/dist/agent-farm/commands/index.js +1 -0
- package/dist/agent-farm/commands/index.js.map +1 -1
- package/dist/agent-farm/commands/kickoff.d.ts +20 -0
- package/dist/agent-farm/commands/kickoff.d.ts.map +1 -0
- package/dist/agent-farm/commands/kickoff.js +273 -0
- package/dist/agent-farm/commands/kickoff.js.map +1 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +30 -96
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/start.d.ts.map +1 -1
- package/dist/agent-farm/commands/start.js +8 -50
- package/dist/agent-farm/commands/start.js.map +1 -1
- package/dist/agent-farm/servers/dashboard-server.js +0 -14
- package/dist/agent-farm/servers/dashboard-server.js.map +1 -1
- package/dist/agent-farm/state.d.ts +0 -10
- package/dist/agent-farm/state.d.ts.map +1 -1
- package/dist/agent-farm/state.js +0 -24
- package/dist/agent-farm/state.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +17 -1
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +2 -1
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +17 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/porch/checks.d.ts +29 -0
- package/dist/commands/porch/checks.d.ts.map +1 -0
- package/dist/commands/porch/checks.js +141 -0
- package/dist/commands/porch/checks.js.map +1 -0
- package/dist/commands/porch/claude.d.ts +29 -0
- package/dist/commands/porch/claude.d.ts.map +1 -0
- package/dist/commands/porch/claude.js +79 -0
- package/dist/commands/porch/claude.js.map +1 -0
- package/dist/commands/porch/index.d.ts +38 -0
- package/dist/commands/porch/index.d.ts.map +1 -0
- package/dist/commands/porch/index.js +524 -0
- package/dist/commands/porch/index.js.map +1 -0
- package/dist/commands/porch/plan.d.ts +60 -0
- package/dist/commands/porch/plan.d.ts.map +1 -0
- package/dist/commands/porch/plan.js +162 -0
- package/dist/commands/porch/plan.js.map +1 -0
- package/dist/commands/porch/prompts.d.ts +19 -0
- package/dist/commands/porch/prompts.d.ts.map +1 -0
- package/dist/commands/porch/prompts.js +259 -0
- package/dist/commands/porch/prompts.js.map +1 -0
- package/dist/commands/porch/protocol.d.ts +57 -0
- package/dist/commands/porch/protocol.d.ts.map +1 -0
- package/dist/commands/porch/protocol.js +250 -0
- package/dist/commands/porch/protocol.js.map +1 -0
- package/dist/commands/porch/repl.d.ts +33 -0
- package/dist/commands/porch/repl.d.ts.map +1 -0
- package/dist/commands/porch/repl.js +206 -0
- package/dist/commands/porch/repl.js.map +1 -0
- package/dist/commands/porch/run.d.ts +15 -0
- package/dist/commands/porch/run.d.ts.map +1 -0
- package/dist/commands/porch/run.js +551 -0
- package/dist/commands/porch/run.js.map +1 -0
- package/dist/commands/porch/signals.d.ts +35 -0
- package/dist/commands/porch/signals.d.ts.map +1 -0
- package/dist/commands/porch/signals.js +76 -0
- package/dist/commands/porch/signals.js.map +1 -0
- package/dist/commands/porch/state.d.ts +40 -0
- package/dist/commands/porch/state.d.ts.map +1 -0
- package/dist/commands/porch/state.js +153 -0
- package/dist/commands/porch/state.js.map +1 -0
- package/dist/commands/porch/types.d.ts +124 -0
- package/dist/commands/porch/types.d.ts.map +1 -0
- package/dist/commands/porch/types.js +8 -0
- package/dist/commands/porch/types.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +19 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/scaffold.d.ts +24 -0
- package/dist/lib/scaffold.d.ts.map +1 -1
- package/dist/lib/scaffold.js +78 -0
- package/dist/lib/scaffold.js.map +1 -1
- package/package.json +6 -2
- package/skeleton/porch/prompts/defend.md +103 -0
- package/skeleton/porch/prompts/diagnose.md +70 -0
- package/skeleton/porch/prompts/evaluate.md +132 -0
- package/skeleton/porch/prompts/fix.md +59 -0
- package/skeleton/porch/prompts/implement.md +79 -0
- package/skeleton/porch/prompts/plan.md +74 -0
- package/skeleton/porch/prompts/pr.md +84 -0
- package/skeleton/porch/prompts/review.md +179 -0
- package/skeleton/porch/prompts/specify.md +53 -0
- package/skeleton/porch/prompts/test.md +63 -0
- package/skeleton/porch/prompts/understand.md +61 -0
- package/skeleton/porch/prompts/verify.md +58 -0
- package/skeleton/protocols/bugfix/protocol.json +127 -0
- package/skeleton/protocols/protocol-schema.json +237 -0
- package/skeleton/protocols/spider/prompts/defend.md +215 -0
- package/skeleton/protocols/spider/prompts/evaluate.md +241 -0
- package/skeleton/protocols/spider/prompts/implement.md +149 -0
- package/skeleton/protocols/spider/prompts/plan.md +214 -0
- package/skeleton/protocols/spider/prompts/review.md +217 -0
- package/skeleton/protocols/spider/prompts/specify.md +174 -0
- package/skeleton/protocols/spider/protocol.json +136 -0
- package/skeleton/protocols/spider/templates/plan.md +14 -0
- package/skeleton/protocols/tick/protocol.json +151 -0
- package/skeleton/roles/architect.md +40 -48
- package/skeleton/roles/builder.md +152 -29
- package/templates/dashboard/index.html +0 -27
- package/templates/dashboard/js/utils.js +0 -86
- package/dist/agent-farm/commands/rename.d.ts +0 -13
- package/dist/agent-farm/commands/rename.d.ts.map +0 -1
- package/dist/agent-farm/commands/rename.js +0 -33
- package/dist/agent-farm/commands/rename.js.map +0 -1
- package/templates/dashboard/css/activity.css +0 -151
- package/templates/dashboard/js/activity.js +0 -112
|
@@ -41,39 +41,102 @@ You are expected to **adhere FULLY to the protocol**. Before starting:
|
|
|
41
41
|
- TICK: `codev/protocols/tick/protocol.md`
|
|
42
42
|
3. Follow every phase and produce all required artifacts
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
## CRITICAL: Porch Protocol Enforcement
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
**You are operating under protocol orchestration. Porch is the gatekeeper.**
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
Porch (`porch`) is the authoritative source of truth for your current state, what to do next, and whether you can advance. You MUST follow porch's instructions.
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
### MANDATORY BEHAVIORS
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
1. **FIRST ACTION**: Run `porch status {PROJECT_ID}` to see your current state
|
|
53
|
+
2. **BEFORE ANY WORK**: Read porch's instructions carefully
|
|
54
|
+
3. **AFTER COMPLETING WORK**: Run `porch check {PROJECT_ID}` to verify criteria
|
|
55
|
+
4. **TO ADVANCE**: Run `porch done {PROJECT_ID}` - porch will verify and advance
|
|
56
|
+
5. **AT GATES**: Run `porch gate {PROJECT_ID}` and **STOP**. Wait for human.
|
|
57
|
+
|
|
58
|
+
### PORCH IS AUTHORITATIVE
|
|
59
|
+
|
|
60
|
+
- Porch tells you what phase you're in
|
|
61
|
+
- Porch tells you what to do next
|
|
62
|
+
- Porch runs the checks that determine if you're done
|
|
63
|
+
- Porch controls advancement between phases
|
|
64
|
+
- You CANNOT skip phases or ignore porch
|
|
65
|
+
|
|
66
|
+
### WHEN PORCH SAYS STOP, YOU STOP
|
|
67
|
+
|
|
68
|
+
If porch output contains **"STOP"** or **"WAIT"**, you must stop working and wait for human intervention. Do not try to proceed.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
GATE: spec_approval
|
|
72
|
+
|
|
73
|
+
Human approval required. STOP and wait.
|
|
74
|
+
Do not proceed until gate is approved.
|
|
75
|
+
|
|
76
|
+
STATUS: WAITING FOR HUMAN APPROVAL
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When you see output like this, **STOP IMMEDIATELY**. Output a message indicating you're waiting for approval and do not continue until the gate is approved.
|
|
80
|
+
|
|
81
|
+
### Porch Command Reference
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
porch status <id> # See current state and instructions
|
|
85
|
+
porch check <id> # Run checks for current phase
|
|
86
|
+
porch done <id> # Advance to next phase (if checks pass)
|
|
87
|
+
porch gate <id> # Request human approval
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Example Workflow
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Start of session - check where you are
|
|
94
|
+
porch status 0074
|
|
95
|
+
|
|
96
|
+
# After implementing code
|
|
97
|
+
porch check 0074
|
|
98
|
+
|
|
99
|
+
# If checks pass, advance
|
|
100
|
+
porch done 0074
|
|
101
|
+
|
|
102
|
+
# If gate is required
|
|
103
|
+
porch gate 0074
|
|
104
|
+
# OUTPUT: "STOP and wait" → STOP HERE, wait for human
|
|
105
|
+
|
|
106
|
+
# After human approves, continue
|
|
107
|
+
porch status 0074
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### SPIDER Protocol Execution
|
|
111
|
+
|
|
112
|
+
As a builder with porch, you execute the **full SPIDER protocol**:
|
|
113
|
+
|
|
114
|
+
1. **Specify**: Write the spec (`codev/specs/XXXX-name.md`)
|
|
115
|
+
- Write the spec with all required sections
|
|
116
|
+
- **Run 3-way consultation** and add a `## Consultation` section summarizing findings:
|
|
56
117
|
```bash
|
|
57
|
-
consult --model gemini --type
|
|
58
|
-
consult --model codex --type
|
|
118
|
+
consult --model gemini --type spec-review spec XXXX
|
|
119
|
+
consult --model codex --type spec-review spec XXXX
|
|
120
|
+
consult --model claude --type spec-review spec XXXX
|
|
59
121
|
```
|
|
60
|
-
-
|
|
122
|
+
- **NO phases in spec** - phases belong in the plan, not the spec
|
|
123
|
+
- **COMMIT** the spec file
|
|
124
|
+
- Run `porch done` → hits `spec_approval` gate
|
|
125
|
+
- Run `porch gate` → **STOP and wait for human**
|
|
126
|
+
|
|
127
|
+
2. **Plan**: Write the plan (`codev/plans/XXXX-name.md`)
|
|
128
|
+
- Write the plan with numbered phases and a JSON phases block
|
|
129
|
+
- **Run 3-way consultation** and add a `## Consultation` section
|
|
130
|
+
- **COMMIT** the plan file
|
|
131
|
+
- Run `porch done` → hits `plan_approval` gate
|
|
132
|
+
- Run `porch gate` → **STOP and wait for human**
|
|
61
133
|
|
|
62
|
-
|
|
134
|
+
3-5. **Implement → Defend → Evaluate** (per plan phase): See detailed section below
|
|
135
|
+
|
|
136
|
+
6. **Review** - Document lessons learned, run 3-way review, create PR
|
|
63
137
|
- Write the review document (`codev/reviews/XXXX-spec-name.md`)
|
|
64
138
|
- **Run 3-way parallel review focused on IMPLEMENTATION quality**:
|
|
65
139
|
```bash
|
|
66
|
-
QUERY="Review Spec XXXX implementation. Branch: builder/XXXX-...
|
|
67
|
-
|
|
68
|
-
Focus on:
|
|
69
|
-
- Implementation quality and correctness
|
|
70
|
-
- Test coverage and quality
|
|
71
|
-
- Adherence to spec requirements
|
|
72
|
-
- Code patterns and best practices
|
|
73
|
-
- Edge cases and error handling
|
|
74
|
-
|
|
75
|
-
Give verdict: APPROVE or REQUEST_CHANGES."
|
|
76
|
-
|
|
77
140
|
consult --model gemini --type pr-ready pr $PR_NUMBER &
|
|
78
141
|
consult --model codex --type pr-ready pr $PR_NUMBER &
|
|
79
142
|
consult --model claude --type pr-ready pr $PR_NUMBER &
|
|
@@ -84,13 +147,71 @@ SPIDER works in phases. The Builder is responsible for **IDER** (the Architect h
|
|
|
84
147
|
|
|
85
148
|
**Note**: The Architect will run a separate 3-way review focused on **integration** concerns.
|
|
86
149
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
150
|
+
### 🚨 CRITICAL: Implement → Defend → Evaluate Cycle 🚨
|
|
151
|
+
|
|
152
|
+
**For EACH plan phase (phase_1, phase_2, etc.), you MUST complete the full I→D→E cycle WITH commits and porch calls.**
|
|
153
|
+
|
|
154
|
+
**This is NOT optional. Porch runs phase completion checks that verify your commit.**
|
|
155
|
+
|
|
156
|
+
#### The Required Workflow (for each plan phase):
|
|
157
|
+
|
|
93
158
|
```
|
|
159
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
160
|
+
│ PHASE N: [Title from plan] │
|
|
161
|
+
├─────────────────────────────────────────────────────────────┤
|
|
162
|
+
│ 1. IMPLEMENT │
|
|
163
|
+
│ - Write the code for this phase │
|
|
164
|
+
│ - Run `porch done XXXX` → advances to defend │
|
|
165
|
+
│ │
|
|
166
|
+
│ 2. DEFEND │
|
|
167
|
+
│ - Write tests for the code │
|
|
168
|
+
│ - Run `porch done XXXX` → advances to evaluate │
|
|
169
|
+
│ │
|
|
170
|
+
│ 3. EVALUATE │
|
|
171
|
+
│ - Run 3-way consultation on implementation │
|
|
172
|
+
│ - Address any feedback │
|
|
173
|
+
│ - **COMMIT everything** (code + tests + consultation) │
|
|
174
|
+
│ - Run `porch done XXXX` → runs PHASE COMPLETION CHECKS │
|
|
175
|
+
│ │
|
|
176
|
+
│ Phase completion checks verify your commit has: │
|
|
177
|
+
│ ✓ Build passes │
|
|
178
|
+
│ ✓ Tests pass │
|
|
179
|
+
│ ✓ Commit includes code files │
|
|
180
|
+
│ ✓ Commit includes test files │
|
|
181
|
+
│ ✓ Commit message mentions 3-way review │
|
|
182
|
+
│ │
|
|
183
|
+
│ If checks fail → FIX and try `porch done` again │
|
|
184
|
+
│ If checks pass → Advances to next phase │
|
|
185
|
+
└─────────────────────────────────────────────────────────────┘
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Example Commit Message (end of phase):
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
[Spec 0074][Phase 1] Remove backend activity code
|
|
192
|
+
|
|
193
|
+
- Removed ActivitySummary types and interfaces
|
|
194
|
+
- Removed getGitCommits, getModifiedFiles, getGitHubPRs functions
|
|
195
|
+
- Removed /api/activity-summary endpoint
|
|
196
|
+
- Added tests for remaining endpoints
|
|
197
|
+
|
|
198
|
+
3-way review: Gemini APPROVE, Codex APPROVE, Claude APPROVE
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### What Happens If You Skip This
|
|
202
|
+
|
|
203
|
+
If you do NOT call `porch done` after each stage:
|
|
204
|
+
- Porch doesn't know you finished
|
|
205
|
+
- Phase completion checks never run
|
|
206
|
+
- Your work is not validated
|
|
207
|
+
- The Architect will reject your PR
|
|
208
|
+
|
|
209
|
+
**DO NOT just implement everything and skip porch calls.**
|
|
210
|
+
|
|
211
|
+
Each `porch done` is a checkpoint that:
|
|
212
|
+
1. Validates your work meets criteria
|
|
213
|
+
2. Records your progress
|
|
214
|
+
3. Ensures quality gates are enforced
|
|
94
215
|
|
|
95
216
|
### TICK Protocol Summary
|
|
96
217
|
|
|
@@ -275,3 +396,5 @@ gh pr view <PR_NUMBER> --web
|
|
|
275
396
|
- **Don't spawn other Builders** - Only Architects spawn Builders
|
|
276
397
|
- **Keep worktree clean** - No untracked files, no debug code
|
|
277
398
|
- **Follow the protocol** - All phases, all artifacts
|
|
399
|
+
- **NEVER edit status.yaml directly** - Only porch commands modify project state
|
|
400
|
+
- **NEVER call porch approve unless explicitly told to by the human** - Gates require human instruction to approve
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
<link rel="stylesheet" href="/dashboard/css/tabs.css">
|
|
11
11
|
<link rel="stylesheet" href="/dashboard/css/statusbar.css">
|
|
12
12
|
<link rel="stylesheet" href="/dashboard/css/dialogs.css">
|
|
13
|
-
<link rel="stylesheet" href="/dashboard/css/activity.css">
|
|
14
13
|
<link rel="stylesheet" href="/dashboard/css/projects.css">
|
|
15
14
|
<link rel="stylesheet" href="/dashboard/css/files.css">
|
|
16
15
|
<link rel="stylesheet" href="/dashboard/css/utilities.css">
|
|
@@ -18,11 +17,6 @@
|
|
|
18
17
|
<body>
|
|
19
18
|
<header class="header">
|
|
20
19
|
<h1>Agent Farm - {{PROJECT_NAME}}</h1>
|
|
21
|
-
<div class="header-actions">
|
|
22
|
-
<button class="btn activity-summary-btn" onclick="showActivitySummary()" title="What did I do today?">
|
|
23
|
-
🕐 Today
|
|
24
|
-
</button>
|
|
25
|
-
</div>
|
|
26
20
|
</header>
|
|
27
21
|
|
|
28
22
|
<main class="main">
|
|
@@ -123,26 +117,6 @@
|
|
|
123
117
|
<!-- Toast container -->
|
|
124
118
|
<div class="toast-container" id="toast-container"></div>
|
|
125
119
|
|
|
126
|
-
<!-- Activity Summary Modal (Spec 0059) -->
|
|
127
|
-
<div class="dialog-overlay hidden" id="activity-modal">
|
|
128
|
-
<div class="dialog activity-dialog">
|
|
129
|
-
<div class="activity-dialog-header">
|
|
130
|
-
<h3>Today's Summary</h3>
|
|
131
|
-
<button class="activity-close-btn" onclick="closeActivityModal()" title="Close (Esc)">×</button>
|
|
132
|
-
</div>
|
|
133
|
-
<div class="activity-dialog-content" id="activity-content">
|
|
134
|
-
<div class="activity-loading">
|
|
135
|
-
<span class="activity-spinner"></span>
|
|
136
|
-
Loading activity...
|
|
137
|
-
</div>
|
|
138
|
-
</div>
|
|
139
|
-
<div class="activity-dialog-footer">
|
|
140
|
-
<button class="btn" onclick="copyActivitySummary()">📋 Copy to Clipboard</button>
|
|
141
|
-
<button class="btn" onclick="closeActivityModal()">Close</button>
|
|
142
|
-
</div>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
|
|
146
120
|
<!-- File search palette (Cmd+P) - Spec 0058 -->
|
|
147
121
|
<div id="file-palette" class="file-palette hidden">
|
|
148
122
|
<div class="file-palette-backdrop" onclick="closePalette()"></div>
|
|
@@ -169,7 +143,6 @@
|
|
|
169
143
|
<script src="/dashboard/js/dialogs.js"></script>
|
|
170
144
|
<script src="/dashboard/js/projects.js"></script>
|
|
171
145
|
<script src="/dashboard/js/files.js"></script>
|
|
172
|
-
<script src="/dashboard/js/activity.js"></script>
|
|
173
146
|
<script src="/dashboard/js/main.js"></script>
|
|
174
147
|
</body>
|
|
175
148
|
</html>
|
|
@@ -168,89 +168,3 @@ function handleMenuKeydown(event, menuId, itemClass, hideFunction, options = {})
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
/**
|
|
172
|
-
* Format ISO time string for display
|
|
173
|
-
* Used by activity rendering
|
|
174
|
-
*/
|
|
175
|
-
function formatActivityTime(isoString) {
|
|
176
|
-
if (!isoString) return '--';
|
|
177
|
-
const date = new Date(isoString);
|
|
178
|
-
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Render activity summary content
|
|
183
|
-
* Consolidates duplicate code from renderActivityTabContent and renderActivitySummary
|
|
184
|
-
*
|
|
185
|
-
* @param {Object} data - Activity data
|
|
186
|
-
* @param {Object} options - Render options
|
|
187
|
-
* @param {boolean} options.isTab - Whether rendering for tab (includes wrapper and copy button)
|
|
188
|
-
* @returns {string} HTML content
|
|
189
|
-
*/
|
|
190
|
-
function renderActivityContentHtml(data, options = {}) {
|
|
191
|
-
const { isTab = false } = options;
|
|
192
|
-
|
|
193
|
-
if (data.commits.length === 0 && data.prs.length === 0 && data.builders.length === 0) {
|
|
194
|
-
return `
|
|
195
|
-
<div class="activity-empty">
|
|
196
|
-
<p>No activity recorded today</p>
|
|
197
|
-
<p style="font-size: 12px; margin-top: 8px;">Make some commits or create PRs to see your daily summary!</p>
|
|
198
|
-
</div>
|
|
199
|
-
`;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const hours = Math.floor(data.timeTracking.activeMinutes / 60);
|
|
203
|
-
const mins = data.timeTracking.activeMinutes % 60;
|
|
204
|
-
const uniqueBranches = new Set(data.commits.map(c => c.branch)).size;
|
|
205
|
-
const mergedPrs = data.prs.filter(p => p.state === 'MERGED').length;
|
|
206
|
-
|
|
207
|
-
let html = isTab ? '<div class="activity-tab-container"><div class="activity-summary">' : '<div class="activity-summary">';
|
|
208
|
-
|
|
209
|
-
if (data.aiSummary) {
|
|
210
|
-
html += `<div class="activity-ai-summary">${escapeHtml(data.aiSummary)}</div>`;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
html += `
|
|
214
|
-
<div class="activity-section">
|
|
215
|
-
<h4>Activity</h4>
|
|
216
|
-
<ul>
|
|
217
|
-
<li>${data.commits.length} commits across ${uniqueBranches} branch${uniqueBranches !== 1 ? 'es' : ''}</li>
|
|
218
|
-
<li>${data.files.length} files modified</li>
|
|
219
|
-
<li>${data.prs.length} PR${data.prs.length !== 1 ? 's' : ''} created${mergedPrs > 0 ? `, ${mergedPrs} merged` : ''}</li>
|
|
220
|
-
</ul>
|
|
221
|
-
</div>
|
|
222
|
-
`;
|
|
223
|
-
|
|
224
|
-
if (data.projectChanges && data.projectChanges.length > 0) {
|
|
225
|
-
html += `
|
|
226
|
-
<div class="activity-section">
|
|
227
|
-
<h4>Projects Touched</h4>
|
|
228
|
-
<ul>
|
|
229
|
-
${data.projectChanges.map(p => `<li>${escapeHtml(p.id)}: ${escapeHtml(p.title)} (${escapeHtml(p.oldStatus)} → ${escapeHtml(p.newStatus)})</li>`).join('')}
|
|
230
|
-
</ul>
|
|
231
|
-
</div>
|
|
232
|
-
`;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
html += `
|
|
236
|
-
<div class="activity-section">
|
|
237
|
-
<h4>Time</h4>
|
|
238
|
-
<p><span class="activity-time-value">~${hours}h ${mins}m</span> active time</p>
|
|
239
|
-
<p>First activity: ${formatActivityTime(data.timeTracking.firstActivity)}</p>
|
|
240
|
-
<p>Last activity: ${formatActivityTime(data.timeTracking.lastActivity)}</p>
|
|
241
|
-
</div>
|
|
242
|
-
`;
|
|
243
|
-
|
|
244
|
-
if (isTab) {
|
|
245
|
-
html += `
|
|
246
|
-
<div class="activity-actions">
|
|
247
|
-
<button class="btn" onclick="copyActivityToClipboard()">Copy to Clipboard</button>
|
|
248
|
-
</div>
|
|
249
|
-
`;
|
|
250
|
-
html += '</div></div>';
|
|
251
|
-
} else {
|
|
252
|
-
html += '</div>';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return html;
|
|
256
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rename command - rename a builder or utility terminal
|
|
3
|
-
*/
|
|
4
|
-
interface RenameOptions {
|
|
5
|
-
id: string;
|
|
6
|
-
name: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Rename a builder or utility terminal
|
|
10
|
-
*/
|
|
11
|
-
export declare function rename(options: RenameOptions): void;
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=rename.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rename.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/commands/rename.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CA2BnD"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rename command - rename a builder or utility terminal
|
|
3
|
-
*/
|
|
4
|
-
import { renameBuilder, renameUtil } from '../state.js';
|
|
5
|
-
import { logger, fatal } from '../utils/logger.js';
|
|
6
|
-
/**
|
|
7
|
-
* Rename a builder or utility terminal
|
|
8
|
-
*/
|
|
9
|
-
export function rename(options) {
|
|
10
|
-
const { id, name } = options;
|
|
11
|
-
if (!name.trim()) {
|
|
12
|
-
fatal('Name cannot be empty');
|
|
13
|
-
}
|
|
14
|
-
// Try to rename as builder first
|
|
15
|
-
const oldBuilderName = renameBuilder(id, name);
|
|
16
|
-
if (oldBuilderName !== null) {
|
|
17
|
-
logger.success(`Renamed builder "${id}"`);
|
|
18
|
-
logger.kv('Old name', oldBuilderName);
|
|
19
|
-
logger.kv('New name', name);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
// Try to rename as util
|
|
23
|
-
const oldUtilName = renameUtil(id, name);
|
|
24
|
-
if (oldUtilName !== null) {
|
|
25
|
-
logger.success(`Renamed utility "${id}"`);
|
|
26
|
-
logger.kv('Old name', oldUtilName);
|
|
27
|
-
logger.kv('New name', name);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
// Not found
|
|
31
|
-
fatal(`No builder or utility found with ID: ${id}`);
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=rename.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../../src/agent-farm/commands/rename.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAOnD;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,OAAsB;IAC3C,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAE7B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAChC,CAAC;IAED,iCAAiC;IACjC,MAAM,cAAc,GAAG,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC/C,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,wBAAwB;IACxB,MAAM,WAAW,GAAG,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACnC,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,YAAY;IACZ,KAAK,CAAC,wCAAwC,EAAE,EAAE,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/* Activity Summary Modal and Tab (Spec 0059) */
|
|
2
|
-
|
|
3
|
-
/* Activity Summary Modal */
|
|
4
|
-
.activity-dialog {
|
|
5
|
-
width: 600px;
|
|
6
|
-
max-width: 90vw;
|
|
7
|
-
max-height: 80vh;
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: column;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.activity-dialog-header {
|
|
13
|
-
display: flex;
|
|
14
|
-
justify-content: space-between;
|
|
15
|
-
align-items: center;
|
|
16
|
-
margin-bottom: 16px;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.activity-dialog-header h3 {
|
|
20
|
-
margin: 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.activity-close-btn {
|
|
24
|
-
background: none;
|
|
25
|
-
border: none;
|
|
26
|
-
font-size: 24px;
|
|
27
|
-
color: var(--text-muted);
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
padding: 0 8px;
|
|
30
|
-
line-height: 1;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.activity-close-btn:hover {
|
|
34
|
-
color: var(--text-primary);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.activity-dialog-content {
|
|
38
|
-
flex: 1;
|
|
39
|
-
overflow-y: auto;
|
|
40
|
-
max-height: 50vh;
|
|
41
|
-
margin-bottom: 16px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.activity-loading {
|
|
45
|
-
display: flex;
|
|
46
|
-
align-items: center;
|
|
47
|
-
justify-content: center;
|
|
48
|
-
gap: 12px;
|
|
49
|
-
padding: 40px 20px;
|
|
50
|
-
color: var(--text-muted);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.activity-spinner {
|
|
54
|
-
width: 20px;
|
|
55
|
-
height: 20px;
|
|
56
|
-
border: 2px solid var(--border);
|
|
57
|
-
border-top-color: var(--accent);
|
|
58
|
-
border-radius: 50%;
|
|
59
|
-
animation: spin 1s linear infinite;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@keyframes spin {
|
|
63
|
-
to { transform: rotate(360deg); }
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.activity-empty {
|
|
67
|
-
text-align: center;
|
|
68
|
-
padding: 40px 20px;
|
|
69
|
-
color: var(--text-muted);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.activity-error {
|
|
73
|
-
text-align: center;
|
|
74
|
-
padding: 40px 20px;
|
|
75
|
-
color: #ef4444;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.activity-summary {
|
|
79
|
-
line-height: 1.6;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.activity-ai-summary {
|
|
83
|
-
background: var(--bg-tertiary);
|
|
84
|
-
border-left: 3px solid var(--accent);
|
|
85
|
-
padding: 12px 16px;
|
|
86
|
-
margin-bottom: 20px;
|
|
87
|
-
font-style: italic;
|
|
88
|
-
color: var(--text-secondary);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.activity-section {
|
|
92
|
-
margin-bottom: 16px;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.activity-section h4 {
|
|
96
|
-
font-size: 13px;
|
|
97
|
-
text-transform: uppercase;
|
|
98
|
-
color: var(--text-muted);
|
|
99
|
-
margin: 0 0 8px 0;
|
|
100
|
-
letter-spacing: 0.5px;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.activity-section ul {
|
|
104
|
-
margin: 0;
|
|
105
|
-
padding-left: 20px;
|
|
106
|
-
color: var(--text-secondary);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.activity-section li {
|
|
110
|
-
margin-bottom: 4px;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.activity-section p {
|
|
114
|
-
margin: 4px 0;
|
|
115
|
-
color: var(--text-secondary);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.activity-time-value {
|
|
119
|
-
font-size: 18px;
|
|
120
|
-
font-weight: 500;
|
|
121
|
-
color: var(--text-primary);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.activity-dialog-footer {
|
|
125
|
-
display: flex;
|
|
126
|
-
justify-content: flex-end;
|
|
127
|
-
gap: 8px;
|
|
128
|
-
padding-top: 12px;
|
|
129
|
-
border-top: 1px solid var(--border);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/* Activity Tab Styles */
|
|
133
|
-
.activity-tab-container {
|
|
134
|
-
padding: 24px;
|
|
135
|
-
max-width: 700px;
|
|
136
|
-
margin: 0 auto;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.activity-tab-container .activity-summary {
|
|
140
|
-
background: var(--bg-secondary);
|
|
141
|
-
border-radius: 8px;
|
|
142
|
-
padding: 20px;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.activity-tab-container .activity-actions {
|
|
146
|
-
margin-top: 20px;
|
|
147
|
-
padding-top: 16px;
|
|
148
|
-
border-top: 1px solid var(--border);
|
|
149
|
-
display: flex;
|
|
150
|
-
justify-content: flex-end;
|
|
151
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// Activity Summary Functions (Spec 0059)
|
|
2
|
-
|
|
3
|
-
// Show activity summary - creates tab if needed
|
|
4
|
-
async function showActivitySummary() {
|
|
5
|
-
let activityTab = tabs.find(t => t.type === 'activity');
|
|
6
|
-
|
|
7
|
-
if (!activityTab) {
|
|
8
|
-
activityTab = {
|
|
9
|
-
id: 'activity-today',
|
|
10
|
-
type: 'activity',
|
|
11
|
-
name: 'Today'
|
|
12
|
-
};
|
|
13
|
-
tabs.push(activityTab);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
activeTabId = activityTab.id;
|
|
17
|
-
currentTabType = null;
|
|
18
|
-
renderTabs();
|
|
19
|
-
renderTabContent();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Render the activity tab content
|
|
23
|
-
async function renderActivityTab() {
|
|
24
|
-
const content = document.getElementById('tab-content');
|
|
25
|
-
|
|
26
|
-
content.innerHTML = `
|
|
27
|
-
<div class="activity-tab-container">
|
|
28
|
-
<div class="activity-loading">
|
|
29
|
-
<span class="activity-spinner"></span>
|
|
30
|
-
Loading activity...
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
`;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const response = await fetch('/api/activity-summary');
|
|
37
|
-
if (!response.ok) {
|
|
38
|
-
throw new Error(await response.text());
|
|
39
|
-
}
|
|
40
|
-
activityData = await response.json();
|
|
41
|
-
renderActivityTabContent(activityData);
|
|
42
|
-
} catch (err) {
|
|
43
|
-
content.innerHTML = `
|
|
44
|
-
<div class="activity-tab-container">
|
|
45
|
-
<div class="activity-error">
|
|
46
|
-
Failed to load activity: ${escapeHtml(err.message)}
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
`;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Render activity tab content
|
|
54
|
-
// Uses shared renderActivityContentHtml from utils.js (Maintenance Run 0004)
|
|
55
|
-
function renderActivityTabContent(data) {
|
|
56
|
-
const content = document.getElementById('tab-content');
|
|
57
|
-
content.innerHTML = renderActivityContentHtml(data, { isTab: true });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Render activity summary content (for modal)
|
|
61
|
-
// Uses shared renderActivityContentHtml from utils.js (Maintenance Run 0004)
|
|
62
|
-
function renderActivitySummary(data) {
|
|
63
|
-
const content = document.getElementById('activity-content');
|
|
64
|
-
content.innerHTML = renderActivityContentHtml(data, { isTab: false });
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Close activity modal
|
|
68
|
-
function closeActivityModal() {
|
|
69
|
-
document.getElementById('activity-modal').classList.add('hidden');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Copy activity summary to clipboard (shared by tab and modal)
|
|
73
|
-
function copyActivityToClipboard() {
|
|
74
|
-
copyActivitySummary();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function copyActivitySummary() {
|
|
78
|
-
if (!activityData) return;
|
|
79
|
-
|
|
80
|
-
const hours = Math.floor(activityData.timeTracking.activeMinutes / 60);
|
|
81
|
-
const mins = activityData.timeTracking.activeMinutes % 60;
|
|
82
|
-
const uniqueBranches = new Set(activityData.commits.map(c => c.branch)).size;
|
|
83
|
-
const mergedPrs = activityData.prs.filter(p => p.state === 'MERGED').length;
|
|
84
|
-
|
|
85
|
-
let markdown = `## Today's Summary\n\n`;
|
|
86
|
-
|
|
87
|
-
if (activityData.aiSummary) {
|
|
88
|
-
markdown += `${activityData.aiSummary}\n\n`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
markdown += `### Activity\n`;
|
|
92
|
-
markdown += `- ${activityData.commits.length} commits across ${uniqueBranches} branches\n`;
|
|
93
|
-
markdown += `- ${activityData.files.length} files modified\n`;
|
|
94
|
-
markdown += `- ${activityData.prs.length} PRs${mergedPrs > 0 ? ` (${mergedPrs} merged)` : ''}\n\n`;
|
|
95
|
-
|
|
96
|
-
if (activityData.projectChanges && activityData.projectChanges.length > 0) {
|
|
97
|
-
markdown += `### Projects Touched\n`;
|
|
98
|
-
activityData.projectChanges.forEach(p => {
|
|
99
|
-
markdown += `- ${p.id}: ${p.title} (${p.oldStatus} → ${p.newStatus})\n`;
|
|
100
|
-
});
|
|
101
|
-
markdown += '\n';
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
markdown += `### Time\n`;
|
|
105
|
-
markdown += `Active time: ~${hours}h ${mins}m\n`;
|
|
106
|
-
|
|
107
|
-
navigator.clipboard.writeText(markdown).then(() => {
|
|
108
|
-
showToast('Copied to clipboard', 'success');
|
|
109
|
-
}).catch(() => {
|
|
110
|
-
showToast('Failed to copy', 'error');
|
|
111
|
-
});
|
|
112
|
-
}
|