@cluesmith/codev 1.5.27 → 1.6.0
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/dist/agent-farm/commands/tower.d.ts.map +1 -1
- package/dist/agent-farm/commands/tower.js +93 -7
- package/dist/agent-farm/commands/tower.js.map +1 -1
- package/dist/agent-farm/servers/dashboard-server.js +102 -0
- package/dist/agent-farm/servers/dashboard-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +37 -5
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +94 -22
- package/dist/commands/doctor.js.map +1 -1
- package/dist/lib/scaffold.js +1 -1
- package/dist/lib/scaffold.js.map +1 -1
- package/package.json +1 -1
- package/skeleton/roles/architect.md +39 -22
- package/skeleton/roles/builder.md +174 -98
- package/skeleton/templates/cheatsheet.md +170 -0
- package/skeleton/templates/lifecycle.md +147 -0
- package/templates/dashboard/css/files.css +10 -0
- package/templates/dashboard/css/layout.css +9 -0
- package/templates/dashboard/index.html +17 -0
- package/templates/dashboard/js/dialogs.js +86 -2
- package/templates/dashboard/js/main.js +5 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Codev Project Lifecycle
|
|
2
|
+
|
|
3
|
+
Every project in Codev flows through a series of stages from idea to production. This document explains each stage and how projects progress through the lifecycle.
|
|
4
|
+
|
|
5
|
+
## Lifecycle Overview
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
conceived → specified → planned → implementing → implemented → committed → integrated
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Stages
|
|
12
|
+
|
|
13
|
+
### 1. Conceived
|
|
14
|
+
|
|
15
|
+
**What it means:** An idea has been captured. A spec file may exist but hasn't been approved yet.
|
|
16
|
+
|
|
17
|
+
**Who does it:** Anyone can conceive a project by describing what they want to build.
|
|
18
|
+
|
|
19
|
+
**What happens next:** The Architect (AI) writes a specification. The human reviews and approves it.
|
|
20
|
+
|
|
21
|
+
**Artifact:** Draft specification in `codev/specs/NNNN-name.md`
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
### 2. Specified
|
|
26
|
+
|
|
27
|
+
**What it means:** The specification has been approved by a human.
|
|
28
|
+
|
|
29
|
+
**Who does it:** Only a human can approve a specification and mark it as specified.
|
|
30
|
+
|
|
31
|
+
**What happens next:** The Architect creates an implementation plan.
|
|
32
|
+
|
|
33
|
+
**Artifact:** Approved specification in `codev/specs/NNNN-name.md`
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### 3. Planned
|
|
38
|
+
|
|
39
|
+
**What it means:** An implementation plan exists that describes how to build the feature.
|
|
40
|
+
|
|
41
|
+
**Who does it:** The Architect (AI) creates the plan, human reviews it.
|
|
42
|
+
|
|
43
|
+
**What happens next:** A Builder is spawned to implement the plan.
|
|
44
|
+
|
|
45
|
+
**Artifact:** Implementation plan in `codev/plans/NNNN-name.md`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### 4. Implementing
|
|
50
|
+
|
|
51
|
+
**What it means:** Active development is in progress. A Builder is working on the code.
|
|
52
|
+
|
|
53
|
+
**Who does it:** A Builder (AI agent) in an isolated git worktree.
|
|
54
|
+
|
|
55
|
+
**What happens next:** Builder completes implementation and creates a PR.
|
|
56
|
+
|
|
57
|
+
**Artifact:** Code changes in a builder worktree, work in progress
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### 5. Implemented
|
|
62
|
+
|
|
63
|
+
**What it means:** Code is complete, tests pass, and a Pull Request has been created.
|
|
64
|
+
|
|
65
|
+
**Who does it:** The Builder creates the PR after completing implementation.
|
|
66
|
+
|
|
67
|
+
**What happens next:** The Architect reviews the PR, Builder addresses feedback, then merges.
|
|
68
|
+
|
|
69
|
+
**Artifact:** Open Pull Request ready for review
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### 6. Committed
|
|
74
|
+
|
|
75
|
+
**What it means:** The PR has been merged to the main branch.
|
|
76
|
+
|
|
77
|
+
**Who does it:** The Builder merges after approval from the Architect's review.
|
|
78
|
+
|
|
79
|
+
**What happens next:** Human validates in production and marks as integrated.
|
|
80
|
+
|
|
81
|
+
**Artifact:** Merged PR, code on main branch
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### 7. Integrated
|
|
86
|
+
|
|
87
|
+
**What it means:** The feature has been validated in production and the project is complete.
|
|
88
|
+
|
|
89
|
+
**Who does it:** Only a human can mark a project as integrated after validating it works.
|
|
90
|
+
|
|
91
|
+
**What happens next:** Nothing - the project is complete! A review document captures lessons learned.
|
|
92
|
+
|
|
93
|
+
**Artifact:** Review document in `codev/reviews/NNNN-name.md`
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Terminal States
|
|
98
|
+
|
|
99
|
+
Projects can also end up in terminal states if they won't be completed:
|
|
100
|
+
|
|
101
|
+
### Abandoned
|
|
102
|
+
|
|
103
|
+
The project was canceled or rejected. It will not be implemented. The notes field in `projectlist.md` should explain why.
|
|
104
|
+
|
|
105
|
+
### On-Hold
|
|
106
|
+
|
|
107
|
+
The project is temporarily paused but may resume later. The notes field should explain the reason and any conditions for resuming.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Human Approval Gates
|
|
112
|
+
|
|
113
|
+
Two stages require explicit human approval - AI agents cannot bypass these:
|
|
114
|
+
|
|
115
|
+
| Gate | Transition | Why |
|
|
116
|
+
|------|------------|-----|
|
|
117
|
+
| **Spec Approval** | conceived → specified | Humans must approve what gets built |
|
|
118
|
+
| **Production Validation** | committed → integrated | Humans must verify it works in production |
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
conceived → [HUMAN APPROVES] → specified → planned → implementing → implemented → committed → [HUMAN VALIDATES] → integrated
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Managing Projects
|
|
127
|
+
|
|
128
|
+
All project tracking happens in `codev/projectlist.md`. To manage projects:
|
|
129
|
+
|
|
130
|
+
- **Add a project:** Tell the Architect what you want to build
|
|
131
|
+
- **Update status:** Ask the Architect to update the project status
|
|
132
|
+
- **Approve stages:** Review the spec/plan and tell the Architect to mark it approved
|
|
133
|
+
- **View progress:** Check the Projects tab in the dashboard or read `projectlist.md`
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Quick Reference
|
|
138
|
+
|
|
139
|
+
| Stage | Artifact | Who Advances |
|
|
140
|
+
|-------|----------|--------------|
|
|
141
|
+
| Conceived | Draft spec | AI writes, human approves |
|
|
142
|
+
| Specified | Approved spec | AI creates plan |
|
|
143
|
+
| Planned | Implementation plan | AI spawns builder |
|
|
144
|
+
| Implementing | WIP code | Builder completes |
|
|
145
|
+
| Implemented | Open PR | Architect reviews, Builder merges |
|
|
146
|
+
| Committed | Merged PR | Human validates |
|
|
147
|
+
| Integrated | Review doc | Complete |
|
|
@@ -182,6 +182,16 @@
|
|
|
182
182
|
color: var(--text-primary);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
.dashboard-section-header .header-actions .btn-create {
|
|
186
|
+
color: var(--accent);
|
|
187
|
+
font-weight: 500;
|
|
188
|
+
border-style: dashed;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.dashboard-section-header .header-actions .btn-create:hover {
|
|
192
|
+
border-color: var(--accent);
|
|
193
|
+
}
|
|
194
|
+
|
|
185
195
|
.dashboard-section-content {
|
|
186
196
|
flex: 1;
|
|
187
197
|
overflow-y: auto;
|
|
@@ -43,6 +43,15 @@
|
|
|
43
43
|
background: rgba(239, 68, 68, 0.1);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
.btn-primary {
|
|
47
|
+
border-color: var(--accent);
|
|
48
|
+
color: var(--accent);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.btn-primary:hover {
|
|
52
|
+
background: rgba(59, 130, 246, 0.1);
|
|
53
|
+
}
|
|
54
|
+
|
|
46
55
|
/* Main content area */
|
|
47
56
|
.main {
|
|
48
57
|
display: flex;
|
|
@@ -82,6 +82,23 @@
|
|
|
82
82
|
</div>
|
|
83
83
|
</div>
|
|
84
84
|
|
|
85
|
+
<!-- Create file dialog (Bugfix #131) -->
|
|
86
|
+
<div class="dialog-overlay hidden" id="create-file-dialog">
|
|
87
|
+
<div class="dialog">
|
|
88
|
+
<h3>Create New File</h3>
|
|
89
|
+
<div class="quick-paths">
|
|
90
|
+
<button class="quick-path" onclick="setCreateFilePath('codev/specs/')">codev/specs/</button>
|
|
91
|
+
<button class="quick-path" onclick="setCreateFilePath('codev/plans/')">codev/plans/</button>
|
|
92
|
+
<button class="quick-path" onclick="setCreateFilePath('src/')">src/</button>
|
|
93
|
+
</div>
|
|
94
|
+
<input type="text" id="create-file-path-input" placeholder="Enter file path (e.g., src/utils/helper.ts)" />
|
|
95
|
+
<div class="dialog-actions">
|
|
96
|
+
<button class="btn" onclick="hideCreateFileDialog()">Cancel</button>
|
|
97
|
+
<button class="btn btn-primary" onclick="createFile()">Create</button>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
85
102
|
<!-- Close confirmation dialog -->
|
|
86
103
|
<div class="dialog-overlay hidden" id="close-dialog">
|
|
87
104
|
<div class="dialog">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Dialog, Context Menu, and Tab Close Functions
|
|
2
2
|
|
|
3
3
|
// Close tab
|
|
4
|
-
function closeTab(tabId, event) {
|
|
4
|
+
async function closeTab(tabId, event) {
|
|
5
5
|
const tab = tabs.find(t => t.id === tabId);
|
|
6
6
|
if (!tab) return;
|
|
7
7
|
|
|
@@ -17,7 +17,23 @@ function closeTab(tabId, event) {
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// Check if process is still running before showing confirmation (Bugfix #132)
|
|
21
|
+
// If the shell/builder already exited, close immediately without confirmation
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(`/api/tabs/${encodeURIComponent(tabId)}/running`);
|
|
24
|
+
if (response.ok) {
|
|
25
|
+
const { running } = await response.json();
|
|
26
|
+
if (!running) {
|
|
27
|
+
// Process already exited, close without confirmation
|
|
28
|
+
doCloseTab(tabId);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// On error, fall through to show confirmation (safer default)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Show confirmation for builders and shells with running processes
|
|
21
37
|
pendingCloseTabId = tabId;
|
|
22
38
|
const dialog = document.getElementById('close-dialog');
|
|
23
39
|
const title = document.getElementById('close-dialog-title');
|
|
@@ -164,6 +180,74 @@ async function openFile() {
|
|
|
164
180
|
await openFileTab(path, { onSuccess: hideFileDialog });
|
|
165
181
|
}
|
|
166
182
|
|
|
183
|
+
// ========================================
|
|
184
|
+
// Create File Dialog (Bugfix #131)
|
|
185
|
+
// ========================================
|
|
186
|
+
|
|
187
|
+
// Show create file dialog
|
|
188
|
+
function showCreateFileDialog() {
|
|
189
|
+
document.getElementById('create-file-dialog').classList.remove('hidden');
|
|
190
|
+
const input = document.getElementById('create-file-path-input');
|
|
191
|
+
input.value = '';
|
|
192
|
+
input.focus();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Hide create file dialog
|
|
196
|
+
function hideCreateFileDialog() {
|
|
197
|
+
document.getElementById('create-file-dialog').classList.add('hidden');
|
|
198
|
+
document.getElementById('create-file-path-input').value = '';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Set quick path for create file dialog
|
|
202
|
+
function setCreateFilePath(path) {
|
|
203
|
+
const input = document.getElementById('create-file-path-input');
|
|
204
|
+
input.value = path;
|
|
205
|
+
input.focus();
|
|
206
|
+
// Move cursor to end
|
|
207
|
+
input.setSelectionRange(path.length, path.length);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Create a new file
|
|
211
|
+
async function createFile() {
|
|
212
|
+
const input = document.getElementById('create-file-path-input');
|
|
213
|
+
const filePath = input.value.trim();
|
|
214
|
+
|
|
215
|
+
if (!filePath) {
|
|
216
|
+
showToast('Please enter a file path', 'error');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Basic validation - prevent absolute paths and path traversal
|
|
221
|
+
if (filePath.startsWith('/') || filePath.includes('..')) {
|
|
222
|
+
showToast('Invalid file path', 'error');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const response = await fetch('/api/files', {
|
|
228
|
+
method: 'POST',
|
|
229
|
+
headers: { 'Content-Type': 'application/json' },
|
|
230
|
+
body: JSON.stringify({ path: filePath, content: '' })
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const result = await response.json();
|
|
234
|
+
|
|
235
|
+
if (!response.ok) {
|
|
236
|
+
showToast(result.error || 'Failed to create file', 'error');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
hideCreateFileDialog();
|
|
241
|
+
showToast(`Created ${filePath}`, 'success');
|
|
242
|
+
|
|
243
|
+
// Refresh files tree and open the new file
|
|
244
|
+
await refreshFilesTree();
|
|
245
|
+
await openFileTab(filePath, { showSwitchToast: false });
|
|
246
|
+
} catch (err) {
|
|
247
|
+
showToast('Network error: ' + err.message, 'error');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
167
251
|
// Spawn worktree builder
|
|
168
252
|
async function spawnBuilder() {
|
|
169
253
|
try {
|
|
@@ -128,6 +128,7 @@ function renderDashboardTabContent() {
|
|
|
128
128
|
<div class="dashboard-section-header" onclick="toggleSection('files')">
|
|
129
129
|
<h3><span class="collapse-icon">▼</span> Files</h3>
|
|
130
130
|
<div class="header-actions" onclick="event.stopPropagation()">
|
|
131
|
+
<button class="btn-create" onclick="showCreateFileDialog()" title="Create New File">+</button>
|
|
131
132
|
<button onclick="refreshFilesTree()" title="Refresh">↻</button>
|
|
132
133
|
<button onclick="collapseAllFolders()" title="Collapse All">⊟</button>
|
|
133
134
|
<button onclick="expandAllFolders()" title="Expand All">⊞</button>
|
|
@@ -243,6 +244,7 @@ function setupKeyboardShortcuts() {
|
|
|
243
244
|
if (e.key === 'Escape') {
|
|
244
245
|
hideFileDialog();
|
|
245
246
|
hideCloseDialog();
|
|
247
|
+
hideCreateFileDialog();
|
|
246
248
|
hideContextMenu();
|
|
247
249
|
hideOverflowMenu();
|
|
248
250
|
const activityModal = document.getElementById('activity-modal');
|
|
@@ -259,6 +261,9 @@ function setupKeyboardShortcuts() {
|
|
|
259
261
|
if (!document.getElementById('file-dialog').classList.contains('hidden')) {
|
|
260
262
|
openFile();
|
|
261
263
|
}
|
|
264
|
+
if (!document.getElementById('create-file-dialog').classList.contains('hidden')) {
|
|
265
|
+
createFile();
|
|
266
|
+
}
|
|
262
267
|
}
|
|
263
268
|
|
|
264
269
|
// Ctrl+Tab / Ctrl+Shift+Tab to switch tabs
|