@cluesmith/codev 1.5.27 → 1.5.28

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.
@@ -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 |
@@ -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
- // Show confirmation for builders and shells
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 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