@forloop-cc/forloop-opencode-plugin-planner 2.2.1
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/CHANGELOG.md +225 -0
- package/CODE_OF_CONDUCT.md +77 -0
- package/CONTRIBUTING.md +176 -0
- package/LICENSE +21 -0
- package/README.md +211 -0
- package/SECURITY.md +69 -0
- package/docs/CONFIGURATION.md +283 -0
- package/docs/DEVELOPER-VS-USER.md +129 -0
- package/docs/IMPROVED-AUTHENTICATION.md +317 -0
- package/docs/INSTALLATION-SCRIPTS.md +304 -0
- package/docs/PLANNER-AGENT-IMPROVEMENTS.md +88 -0
- package/docs/PLUGIN-ARCHITECTURE.md +308 -0
- package/docs/QUICKSTART-NON-DEV.md +94 -0
- package/docs/README-FOR-HUMANS-AND-AI.md +109 -0
- package/docs/README.md +70 -0
- package/docs/SKILLS-GAP-ANALYSIS.md +157 -0
- package/docs/USER-INTERACTION-MODEL.md +106 -0
- package/docs/file-management/2026-04-12-forloop-aivy-documents-sync.md +395 -0
- package/docs/file-management/FILE_UPLOAD_ENHANCEMENT.md +431 -0
- package/docs/file-management/FILE_UPLOAD_FLOW.md +300 -0
- package/docs/images/forloop-opencode-flow.png +0 -0
- package/docs/images/forloop-opencode-header.png +0 -0
- package/docs/superpowers/plans/2026-05-03-sprint-isolated-directory-structure.md +1450 -0
- package/docs/superpowers/plans/2026-05-29-install-system.md +850 -0
- package/docs/superpowers/specs/2026-05-03-sprint-isolated-directory-structure-design.md +149 -0
- package/docs/superpowers/specs/2026-05-19-opencode-message-recording-design.md +468 -0
- package/docs/superpowers/specs/2026-05-29-install-system-design.md +135 -0
- package/install.sh +317 -0
- package/package.json +87 -0
- package/plugins/capabilities/api-client.ts +556 -0
- package/plugins/capabilities/auth.ts +120 -0
- package/plugins/capabilities/config.ts +195 -0
- package/plugins/capabilities/context-resolver.ts +106 -0
- package/plugins/capabilities/token-storage.ts +98 -0
- package/plugins/forloop-plugin.ts +186 -0
- package/plugins/hooks/message-recorder.ts +258 -0
- package/plugins/hooks/shell-env.ts +62 -0
- package/plugins/tools/agent-sprint-tools.ts +100 -0
- package/plugins/tools/agent-suggestion-tools.ts +275 -0
- package/plugins/tools/agent-tools.ts +114 -0
- package/plugins/tools/ai-trigger-tools.ts +79 -0
- package/plugins/tools/developer-status-tool.ts +97 -0
- package/plugins/tools/file-tools.ts +240 -0
- package/plugins/tools/folder-tools.ts +75 -0
- package/plugins/tools/organization-tools.ts +213 -0
- package/plugins/tools/schedule-tools.ts +173 -0
- package/plugins/tools/sprint-tools.ts +287 -0
- package/plugins/tools/story-tools.ts +320 -0
- package/plugins/tools/sync-tools.ts +509 -0
- package/plugins/tools/template-tools.ts +170 -0
- package/plugins/tools/user-tools.ts +146 -0
- package/scripts/migrate-tokens.js +90 -0
- package/scripts/use-prod.sh +11 -0
- package/tsconfig.json +17 -0
- package/update.sh +172 -0
|
@@ -0,0 +1,1450 @@
|
|
|
1
|
+
# Sprint-Isolated Directory Structure Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Migrate all sprint-specific files from flat `~/.forloop/` to `~/.forloop/sprint-{id}/` subdirectories while keeping the shared manifest at `~/.forloop/manifest.json`.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Add sprint-aware path resolution to `context-resolver.ts`, update `sync-tools.ts` to create/use sprint subdirectories, update all agent/skill documentation to reference new paths, and update tests accordingly. Backward compatible with v1 manifests.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Vitest, Node.js fs/path modules
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## File Structure
|
|
14
|
+
|
|
15
|
+
| File | Responsibility |
|
|
16
|
+
|------|---------------|
|
|
17
|
+
| `plugins/capabilities/context-resolver.ts` | Add `getSprintDir()`, `getForloopRoot()`, `getManifestPath()` |
|
|
18
|
+
| `plugins/tools/sync-tools.ts` | Update `resolveForloopRoot()`, `ensureForloopStructure()`, file mappings |
|
|
19
|
+
| `agent/forLoopPlanner.md` | Update all path references and permission blocks |
|
|
20
|
+
| `agent/forLoopStoryEvaluator.md` | Update permission blocks |
|
|
21
|
+
| `skills/forloop-context/SKILL.md` | Update paths and manifest format |
|
|
22
|
+
| `skills/knowledge-management/SKILL.md` | Update file paths |
|
|
23
|
+
| `skills/plan-documentation/SKILL.md` | Update file paths |
|
|
24
|
+
| `skills/task-tracking/SKILL.md` | Update file paths |
|
|
25
|
+
| `skills/aivy-documents-sync/SKILL.md` | Update path references |
|
|
26
|
+
| `skills/sprint-planning/SKILL.md` | Update path references |
|
|
27
|
+
| `test/suites/unit/context-resolver.test.ts` | New test file for context resolver |
|
|
28
|
+
| `test/suites/unit/sync-tools.test.ts` | Update existing tests for sprint subdirs |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### Task 1: Add Sprint-Aware Path Resolution Functions
|
|
33
|
+
|
|
34
|
+
**Files:**
|
|
35
|
+
- Modify: `forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts`
|
|
36
|
+
- Create: `forloop-opencode-plugin-planner/test/suites/unit/context-resolver.test.ts`
|
|
37
|
+
|
|
38
|
+
- [ ] **Step 1: Write failing tests for `getSprintDir`**
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// forloop-opencode-plugin-planner/test/suites/unit/context-resolver.test.ts
|
|
42
|
+
import { describe, it, expect } from 'vitest';
|
|
43
|
+
import { getSprintDir, getForloopRoot, getManifestPath } from '../../../plugins/capabilities/context-resolver';
|
|
44
|
+
|
|
45
|
+
describe('Context Resolver - Sprint Paths', () => {
|
|
46
|
+
const originalHome = process.env.HOME;
|
|
47
|
+
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
process.env.HOME = originalHome;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('getSprintDir', () => {
|
|
53
|
+
it('returns sprint-14 for sprintId 14', () => {
|
|
54
|
+
expect(getSprintDir(14)).toBe('sprint-14');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('returns sprint-1 for sprintId 1', () => {
|
|
58
|
+
expect(getSprintDir(1)).toBe('sprint-1');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('returns sprint-999 for sprintId 999', () => {
|
|
62
|
+
expect(getSprintDir(999)).toBe('sprint-999');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- [ ] **Step 2: Run test to verify it fails**
|
|
69
|
+
|
|
70
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getSprintDir"`
|
|
71
|
+
Expected: FAIL with "getSprintDir is not a function" or import error
|
|
72
|
+
|
|
73
|
+
- [ ] **Step 3: Implement `getSprintDir`**
|
|
74
|
+
|
|
75
|
+
Add to end of `forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts`:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
export function getSprintDir(sprintId: number): string {
|
|
79
|
+
return `sprint-${sprintId}`;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- [ ] **Step 4: Run test to verify it passes**
|
|
84
|
+
|
|
85
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getSprintDir"`
|
|
86
|
+
Expected: PASS
|
|
87
|
+
|
|
88
|
+
- [ ] **Step 5: Write failing tests for `getForloopRoot`**
|
|
89
|
+
|
|
90
|
+
Append to `forloop-opencode-plugin-planner/test/suites/unit/context-resolver.test.ts`:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
describe('getForloopRoot', () => {
|
|
94
|
+
beforeEach(() => {
|
|
95
|
+
process.env.HOME = '/tmp/test-home';
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('returns root when no sprintId', () => {
|
|
99
|
+
expect(getForloopRoot()).toBe('/tmp/test-home/.forloop');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('returns sprint subdir when sprintId provided', () => {
|
|
103
|
+
expect(getForloopRoot(14)).toBe('/tmp/test-home/.forloop/sprint-14');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('uses default HOME when env HOME not set', () => {
|
|
107
|
+
process.env.HOME = undefined;
|
|
108
|
+
expect(getForloopRoot()).toBe('/tmp/home/.forloop');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('uses default HOME with sprintId when env HOME not set', () => {
|
|
112
|
+
process.env.HOME = undefined;
|
|
113
|
+
expect(getForloopRoot(7)).toBe('/tmp/home/.forloop/sprint-7');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- [ ] **Step 6: Run test to verify it fails**
|
|
119
|
+
|
|
120
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getForloopRoot"`
|
|
121
|
+
Expected: FAIL with "getForloopRoot is not a function"
|
|
122
|
+
|
|
123
|
+
- [ ] **Step 7: Implement `getForloopRoot`**
|
|
124
|
+
|
|
125
|
+
Add to `forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts` after `getSprintDir`:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
export function getForloopRoot(sprintId?: number): string {
|
|
129
|
+
const home = process.env.HOME || '/tmp/home';
|
|
130
|
+
const root = path.join(home, '.forloop');
|
|
131
|
+
if (sprintId !== undefined) {
|
|
132
|
+
return path.join(root, getSprintDir(sprintId));
|
|
133
|
+
}
|
|
134
|
+
return root;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- [ ] **Step 8: Run test to verify it passes**
|
|
139
|
+
|
|
140
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getForloopRoot"`
|
|
141
|
+
Expected: PASS
|
|
142
|
+
|
|
143
|
+
- [ ] **Step 9: Write failing tests for `getManifestPath`**
|
|
144
|
+
|
|
145
|
+
Append to `forloop-opencode-plugin-planner/test/suites/unit/context-resolver.test.ts`:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
describe('getManifestPath', () => {
|
|
149
|
+
beforeEach(() => {
|
|
150
|
+
process.env.HOME = '/tmp/test-home';
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('returns manifest path at root', () => {
|
|
154
|
+
expect(getManifestPath()).toBe('/tmp/test-home/.forloop/manifest.json');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('returns same path regardless of sprintId', () => {
|
|
158
|
+
expect(getManifestPath(14)).toBe('/tmp/test-home/.forloop/manifest.json');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
- [ ] **Step 10: Run test to verify it fails**
|
|
164
|
+
|
|
165
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getManifestPath"`
|
|
166
|
+
Expected: FAIL with "getManifestPath is not a function"
|
|
167
|
+
|
|
168
|
+
- [ ] **Step 11: Implement `getManifestPath`**
|
|
169
|
+
|
|
170
|
+
Add to `forloop-opencode-plugin-planner/plugins/capabilities/context-resolver.ts` after `getForloopRoot`:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
export function getManifestPath(): string {
|
|
174
|
+
const home = process.env.HOME || '/tmp/home';
|
|
175
|
+
return path.join(home, '.forloop', 'manifest.json');
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
- [ ] **Step 12: Run test to verify it passes**
|
|
180
|
+
|
|
181
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/context-resolver.test.ts -t "getManifestPath"`
|
|
182
|
+
Expected: PASS
|
|
183
|
+
|
|
184
|
+
- [ ] **Step 13: Commit**
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cd forloop-opencode-plugin-planner
|
|
188
|
+
git add plugins/capabilities/context-resolver.ts test/suites/unit/context-resolver.test.ts
|
|
189
|
+
git commit -m "feat: add sprint-aware path resolution functions (getSprintDir, getForloopRoot, getManifestPath)"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Task 2: Update sync-tools.ts to Use Sprint Subdirectories
|
|
195
|
+
|
|
196
|
+
**Files:**
|
|
197
|
+
- Modify: `forloop-opencode-plugin-planner/plugins/tools/sync-tools.ts`
|
|
198
|
+
|
|
199
|
+
- [ ] **Step 1: Import new functions and update `resolveForloopRoot`**
|
|
200
|
+
|
|
201
|
+
Modify `forloop-opencode-plugin-planner/plugins/tools/sync-tools.ts`:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { ForLoopAPIClient } from '../capabilities/api-client';
|
|
205
|
+
import { validateToken } from '../capabilities/auth';
|
|
206
|
+
import { resolveSprintId, getForloopRoot as getForloopRootPath } from '../capabilities/context-resolver';
|
|
207
|
+
import * as fs from 'fs';
|
|
208
|
+
import * as path from 'path';
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Replace the existing `resolveForloopRoot` function:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
function resolveForloopRoot(contextDir?: string, sprintId?: number): string {
|
|
215
|
+
if (sprintId !== undefined) {
|
|
216
|
+
return getForloopRootPath(sprintId);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (contextDir) {
|
|
220
|
+
const local = path.join(contextDir, '.forloop');
|
|
221
|
+
if (fs.existsSync(local) && fs.statSync(local).isDirectory()) return local;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return getForloopRootPath();
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- [ ] **Step 2: Update `ensureForloopStructure` to accept sprintId**
|
|
229
|
+
|
|
230
|
+
Replace the existing `ensureForloopStructure` function:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
function ensureForloopStructure(forloopRoot: string, sprintId?: number) {
|
|
234
|
+
fs.mkdirSync(forloopRoot, { recursive: true });
|
|
235
|
+
|
|
236
|
+
if (sprintId !== undefined) {
|
|
237
|
+
fs.mkdirSync(path.join(forloopRoot, 'knowledge'), { recursive: true });
|
|
238
|
+
fs.mkdirSync(path.join(forloopRoot, 'plan'), { recursive: true });
|
|
239
|
+
fs.mkdirSync(path.join(forloopRoot, 'task'), { recursive: true });
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
fs.mkdirSync(path.join(getForloopRootPath(), 'sync'), { recursive: true });
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
- [ ] **Step 3: Update `getSyncManifestPath` to use shared sync directory**
|
|
247
|
+
|
|
248
|
+
Replace the existing `getSyncManifestPath` function:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
function getSyncManifestPath(forloopRoot?: string): string {
|
|
252
|
+
const syncRoot = path.join(getForloopRootPath(), 'sync');
|
|
253
|
+
return path.join(syncRoot, 'manifest.json');
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
- [ ] **Step 4: Update `createS3ToLocalSyncTool` to pass sprintId**
|
|
258
|
+
|
|
259
|
+
In the `createS3ToLocalSyncTool` execute function, replace these lines:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
const forloopRoot = resolveForloopRoot(context.directory);
|
|
263
|
+
ensureForloopStructure(forloopRoot);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
With:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
const forloopRoot = resolveForloopRoot(context.directory, resolution.sprintId);
|
|
270
|
+
ensureForloopStructure(forloopRoot, resolution.sprintId);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- [ ] **Step 5: Update `createLocalToS3SyncTool` to pass sprintId**
|
|
274
|
+
|
|
275
|
+
In the `createLocalToS3SyncTool` execute function, replace these lines:
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
const forloopRoot = resolveForloopRoot(context.directory);
|
|
279
|
+
ensureForloopStructure(forloopRoot);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
With:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const forloopRoot = resolveForloopRoot(context.directory, resolution.sprintId);
|
|
286
|
+
ensureForloopStructure(forloopRoot, resolution.sprintId);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
- [ ] **Step 6: Verify all functions in sync-tools.ts are consistent**
|
|
290
|
+
|
|
291
|
+
The file should now import from `context-resolver.ts`:
|
|
292
|
+
```typescript
|
|
293
|
+
import { resolveSprintId, getForloopRoot as getForloopRootPath } from '../capabilities/context-resolver';
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
- [ ] **Step 7: Commit**
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
cd forloop-opencode-plugin-planner
|
|
300
|
+
git add plugins/tools/sync-tools.ts
|
|
301
|
+
git commit -m "feat: update sync-tools to use sprint subdirectories"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
### Task 3: Update sync-tools Unit Tests
|
|
307
|
+
|
|
308
|
+
**Files:**
|
|
309
|
+
- Modify: `forloop-opencode-plugin-planner/test/suites/unit/sync-tools.test.ts`
|
|
310
|
+
|
|
311
|
+
- [ ] **Step 1: Update test paths from flat to sprint subdir format**
|
|
312
|
+
|
|
313
|
+
In `forloop-opencode-plugin-planner/test/suites/unit/sync-tools.test.ts`, update the `it('syncs local file to S3 with folder inference and mapping replacement', ...)` test.
|
|
314
|
+
|
|
315
|
+
Replace:
|
|
316
|
+
```typescript
|
|
317
|
+
const forloopRoot = path.join(tmpHome, '.forloop');
|
|
318
|
+
const filePath = path.join(forloopRoot, 'knowledge', 'knowledge-test-1.md');
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
With:
|
|
322
|
+
```typescript
|
|
323
|
+
const forloopRoot = path.join(tmpHome, '.forloop', 'sprint-14');
|
|
324
|
+
const filePath = path.join(forloopRoot, 'knowledge', 'knowledge-test-1.md');
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
- [ ] **Step 2: Update manifest path in the same test**
|
|
328
|
+
|
|
329
|
+
Replace:
|
|
330
|
+
```typescript
|
|
331
|
+
const manifestPath = path.join(forloopRoot, 'sync', 'manifest.json');
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
With:
|
|
335
|
+
```typescript
|
|
336
|
+
const manifestPath = path.join(tmpHome, '.forloop', 'sync', 'manifest.json');
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
- [ ] **Step 3: Update delete test paths**
|
|
340
|
+
|
|
341
|
+
In the `it('deletes remote mapping on local delete action', ...)` test, replace:
|
|
342
|
+
```typescript
|
|
343
|
+
const forloopRoot = path.join(tmpHome, '.forloop');
|
|
344
|
+
const filePath = path.join(forloopRoot, 'plan', 'plan-14-20260412-000000.md');
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
With:
|
|
348
|
+
```typescript
|
|
349
|
+
const forloopRoot = path.join(tmpHome, '.forloop', 'sprint-14');
|
|
350
|
+
const filePath = path.join(forloopRoot, 'plan', 'plan-14-20260412-000000.md');
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
And update manifest path:
|
|
354
|
+
```typescript
|
|
355
|
+
const manifestPath = path.join(tmpHome, '.forloop', 'sync', 'manifest.json');
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
- [ ] **Step 4: Update s3-to-local test path assertion**
|
|
359
|
+
|
|
360
|
+
In the `it('syncs remote knowledge file to local', ...)` test, replace:
|
|
361
|
+
```typescript
|
|
362
|
+
const localPath = path.join(tmpHome, '.forloop', 'knowledge', 'knowledge-abc-20260412-000000.md');
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
With:
|
|
366
|
+
```typescript
|
|
367
|
+
const localPath = path.join(tmpHome, '.forloop', 'sprint-14', 'knowledge', 'knowledge-abc-20260412-000000.md');
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
- [ ] **Step 5: Run tests to verify they pass**
|
|
371
|
+
|
|
372
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/sync-tools.test.ts -v`
|
|
373
|
+
Expected: All sync tool tests PASS
|
|
374
|
+
|
|
375
|
+
- [ ] **Step 6: Commit**
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
cd forloop-opencode-plugin-planner
|
|
379
|
+
git add test/suites/unit/sync-tools.test.ts
|
|
380
|
+
git commit -m "test: update sync-tools tests for sprint subdirectories"
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
### Task 4: Update forLoopPlanner.md Agent Definition
|
|
386
|
+
|
|
387
|
+
**Files:**
|
|
388
|
+
- Modify: `forloop-opencode-plugin-planner/agent/forLoopPlanner.md`
|
|
389
|
+
|
|
390
|
+
- [ ] **Step 1: Update permission block**
|
|
391
|
+
|
|
392
|
+
Replace lines 13-17:
|
|
393
|
+
```yaml
|
|
394
|
+
permission:
|
|
395
|
+
"*": allow
|
|
396
|
+
external_directory:
|
|
397
|
+
"/tmp/home/.forloop/**": allow
|
|
398
|
+
"/tmp/home/.config/opencode/**": allow
|
|
399
|
+
"~/.forloop/**": allow
|
|
400
|
+
"~/.config/forloop/**": allow
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
With:
|
|
404
|
+
```yaml
|
|
405
|
+
permission:
|
|
406
|
+
"*": allow
|
|
407
|
+
external_directory:
|
|
408
|
+
"/tmp/home/.forloop/**": allow
|
|
409
|
+
"/tmp/home/.forloop/sprint-*/**": allow
|
|
410
|
+
"/tmp/home/.config/opencode/**": allow
|
|
411
|
+
"~/.forloop/**": allow
|
|
412
|
+
"~/.forloop/sprint-*/**": allow
|
|
413
|
+
"~/.config/forloop/**": allow
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
- [ ] **Step 2: Update Step 0 runtime path section**
|
|
417
|
+
|
|
418
|
+
Replace lines 100-103:
|
|
419
|
+
```markdown
|
|
420
|
+
**IMPORTANT: Runtime Path**
|
|
421
|
+
- The .forloop/ folder is located at `/tmp/home/.forloop/` (NOT in current directory)
|
|
422
|
+
- HOME directory is `/tmp/home` in Lambda environment
|
|
423
|
+
- Use `$HOME/.forloop/` or `/tmp/home/.forloop/` for all paths
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
With:
|
|
427
|
+
```markdown
|
|
428
|
+
**IMPORTANT: Runtime Path**
|
|
429
|
+
- The .forloop/ folder is located at `/tmp/home/.forloop/` (NOT in current directory)
|
|
430
|
+
- Sprint files are in `/tmp/home/.forloop/sprint-{sprintId}/` (e.g., `sprint-14/`)
|
|
431
|
+
- HOME directory is `/tmp/home` in Lambda environment
|
|
432
|
+
- Use `$HOME/.forloop/sprint-{sprintId}/` or `/tmp/home/.forloop/sprint-{sprintId}/` for sprint files
|
|
433
|
+
- Manifest is always at `$HOME/.forloop/manifest.json` (shared across sprints)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
- [ ] **Step 3: Update manifest check instructions**
|
|
437
|
+
|
|
438
|
+
Replace lines 106-117:
|
|
439
|
+
```markdown
|
|
440
|
+
1. **Quick check** for `$HOME/.forloop/manifest.json` (NOT `/var/task/.forloop/`)
|
|
441
|
+
2. **IF manifest exists and has activeSprintId:**
|
|
442
|
+
- Load knowledge, plans, and tasks from $HOME/.forloop/
|
|
443
|
+
- Present context summary to user
|
|
444
|
+
- Confirm active sprint
|
|
445
|
+
3. **IF manifest missing or empty:**
|
|
446
|
+
- ⚠️ **STOP searching immediately**
|
|
447
|
+
- ✅ **Call `forloopSprintList` to get sprints from API**
|
|
448
|
+
- ✅ **Call `forloopUserProfile` to get user info from API**
|
|
449
|
+
- Ask user to select/confirm sprint
|
|
450
|
+
- Create `$HOME/.forloop/manifest.json` after selection
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
With:
|
|
454
|
+
```markdown
|
|
455
|
+
1. **Quick check** for `$HOME/.forloop/manifest.json` (NOT `/var/task/.forloop/`)
|
|
456
|
+
2. **IF manifest exists and has activeSprintId:**
|
|
457
|
+
- Load knowledge, plans, and tasks from `$HOME/.forloop/sprint-{activeSprintId}/`
|
|
458
|
+
- Present context summary to user
|
|
459
|
+
- Confirm active sprint
|
|
460
|
+
3. **IF manifest missing or empty:**
|
|
461
|
+
- ⚠️ **STOP searching immediately**
|
|
462
|
+
- ✅ **Call `forloopSprintList` to get sprints from API**
|
|
463
|
+
- ✅ **Call `forloopUserProfile` to get user info from API**
|
|
464
|
+
- Ask user to select/confirm sprint
|
|
465
|
+
- Create `$HOME/.forloop/manifest.json` after selection
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
- [ ] **Step 4: Update correct path examples**
|
|
469
|
+
|
|
470
|
+
Replace lines 142-151:
|
|
471
|
+
```markdown
|
|
472
|
+
**Correct Path Examples:**
|
|
473
|
+
```bash
|
|
474
|
+
✅ ls -la /tmp/home/.forloop/
|
|
475
|
+
✅ ls -la $HOME/.forloop/
|
|
476
|
+
✅ cat /tmp/home/.forloop/manifest.json
|
|
477
|
+
|
|
478
|
+
❌ ls -la /var/task/.forloop/ # WRONG location
|
|
479
|
+
❌ ls -la ./.forloop/ # WRONG relative path
|
|
480
|
+
❌ ls -la ~/.forloop/ # ~ might not work
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
With:
|
|
484
|
+
```markdown
|
|
485
|
+
**Correct Path Examples:**
|
|
486
|
+
```bash
|
|
487
|
+
✅ ls -la /tmp/home/.forloop/
|
|
488
|
+
✅ ls -la /tmp/home/.forloop/sprint-14/
|
|
489
|
+
✅ ls -la $HOME/.forloop/sprint-$SPRINT_ID/
|
|
490
|
+
✅ cat /tmp/home/.forloop/manifest.json
|
|
491
|
+
|
|
492
|
+
❌ ls -la /var/task/.forloop/ # WRONG location
|
|
493
|
+
❌ ls -la ./.forloop/ # WRONG relative path
|
|
494
|
+
❌ ls -la ~/.forloop/ # ~ might not work
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
- [ ] **Step 5: Update sync download paths**
|
|
498
|
+
|
|
499
|
+
Replace lines 132-135:
|
|
500
|
+
```markdown
|
|
501
|
+
- Downloads `project/plans/*` → `~/.forloop/plan/`
|
|
502
|
+
- Downloads `project/tasks/*` → `~/.forloop/task/`
|
|
503
|
+
- Downloads `project/knowledge/*` → `~/.forloop/knowledge/`
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
With:
|
|
507
|
+
```markdown
|
|
508
|
+
- Downloads `project/plans/*` → `~/.forloop/sprint-{sprintId}/plan/`
|
|
509
|
+
- Downloads `project/tasks/*` → `~/.forloop/sprint-{sprintId}/task/`
|
|
510
|
+
- Downloads `project/knowledge/*` → `~/.forloop/sprint-{sprintId}/knowledge/`
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
- [ ] **Step 6: Update Capabilities section**
|
|
514
|
+
|
|
515
|
+
Replace lines 189-194:
|
|
516
|
+
```markdown
|
|
517
|
+
- **NEW:** Load persistent context from .forloop/ folder on session start
|
|
518
|
+
- **NEW:** Manage .forloop/manifest.json for deterministic sprint resume
|
|
519
|
+
- Discover current sprint context and sprint contents
|
|
520
|
+
- Ask clarifying questions and confirm requirements
|
|
521
|
+
- **NEW:** Auto-capture knowledge to .forloop/knowledge/
|
|
522
|
+
- **NEW:** Generate plan files in .forloop/plan/
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
With:
|
|
526
|
+
```markdown
|
|
527
|
+
- **NEW:** Load persistent context from .forloop/sprint-{id}/ folder on session start
|
|
528
|
+
- **NEW:** Manage .forloop/manifest.json for deterministic sprint resume
|
|
529
|
+
- Discover current sprint context and sprint contents
|
|
530
|
+
- Ask clarifying questions and confirm requirements
|
|
531
|
+
- **NEW:** Auto-capture knowledge to .forloop/sprint-{id}/knowledge/
|
|
532
|
+
- **NEW:** Generate plan files in .forloop/sprint-{id}/plan/
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
- [ ] **Step 7: Update manifest update references**
|
|
536
|
+
|
|
537
|
+
Replace lines 194:
|
|
538
|
+
```markdown
|
|
539
|
+
- **NEW:** Update .forloop/manifest.json after plan/task creation
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
With:
|
|
543
|
+
```markdown
|
|
544
|
+
- **NEW:** Update .forloop/manifest.json after plan/task creation (manifest stays at root, file paths reference sprint subdirs)
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
- [ ] **Step 8: Update Safety Boundary section**
|
|
548
|
+
|
|
549
|
+
Replace lines 288-293:
|
|
550
|
+
```markdown
|
|
551
|
+
- The only files you may create/edit are:
|
|
552
|
+
- Knowledge files in `.forloop/knowledge/`
|
|
553
|
+
- Plan files in `.forloop/plan/`
|
|
554
|
+
- Task files in `.forloop/task/`
|
|
555
|
+
- Manifest file `.forloop/manifest.json`
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
With:
|
|
559
|
+
```markdown
|
|
560
|
+
- The only files you may create/edit are:
|
|
561
|
+
- Knowledge files in `.forloop/sprint-{id}/knowledge/`
|
|
562
|
+
- Plan files in `.forloop/sprint-{id}/plan/`
|
|
563
|
+
- Task files in `.forloop/sprint-{id}/task/`
|
|
564
|
+
- Manifest file `.forloop/manifest.json` (at root, shared across sprints)
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
- [ ] **Step 9: Update Folder Mapping table**
|
|
568
|
+
|
|
569
|
+
Replace lines 259-263:
|
|
570
|
+
```markdown
|
|
571
|
+
| Local Path | S3 Folder | Parameter |
|
|
572
|
+
|------------|-----------|-----------|
|
|
573
|
+
| `.forloop/plan/*` | `project/plans/` | `--folder project/plans` |
|
|
574
|
+
| `.forloop/task/*` | `project/tasks/` | `--folder project/tasks` |
|
|
575
|
+
| `.forloop/knowledge/*` | `project/knowledge/` | `--folder project/knowledge` |
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
With:
|
|
579
|
+
```markdown
|
|
580
|
+
| Local Path | S3 Folder | Parameter |
|
|
581
|
+
|------------|-----------|-----------|
|
|
582
|
+
| `.forloop/sprint-{id}/plan/*` | `project/plans/` | `--folder project/plans` |
|
|
583
|
+
| `.forloop/sprint-{id}/task/*` | `project/tasks/` | `--folder project/tasks` |
|
|
584
|
+
| `.forloop/sprint-{id}/knowledge/*` | `project/knowledge/` | `--folder project/knowledge` |
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
- [ ] **Step 10: Update all remaining path references in examples**
|
|
588
|
+
|
|
589
|
+
Replace in the Example sections:
|
|
590
|
+
- `.forloop/knowledge/` → `.forloop/sprint-{id}/knowledge/`
|
|
591
|
+
- `.forloop/plan/` → `.forloop/sprint-{id}/plan/`
|
|
592
|
+
- `.forloop/task/` → `.forloop/sprint-{id}/task/`
|
|
593
|
+
|
|
594
|
+
Specifically update lines 328-335, 344-366, 389-402, 469-481, 487-497.
|
|
595
|
+
|
|
596
|
+
For example, replace line 333:
|
|
597
|
+
```bash
|
|
598
|
+
forloopSyncLocalToS3 --filePath .forloop/knowledge/knowledge-{topic}-{datetime}.md --sprintId {sprintId} --folder project/knowledge --storyId {docFolderId}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
With:
|
|
602
|
+
```bash
|
|
603
|
+
forloopSyncLocalToS3 --filePath .forloop/sprint-{sprintId}/knowledge/knowledge-{topic}-{datetime}.md --sprintId {sprintId} --folder project/knowledge --storyId {docFolderId}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
Replace line 362:
|
|
607
|
+
```bash
|
|
608
|
+
--filePath .forloop/plan/plan-{sprintId}-{datetime}.md \
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
With:
|
|
612
|
+
```bash
|
|
613
|
+
--filePath .forloop/sprint-{sprintId}/plan/plan-{sprintId}-{datetime}.md \
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
Replace line 394:
|
|
617
|
+
```bash
|
|
618
|
+
--filePath .forloop/task/task-{sprintId}-{datetime}.md \
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
With:
|
|
622
|
+
```bash
|
|
623
|
+
--filePath .forloop/sprint-{sprintId}/task/task-{sprintId}-{datetime}.md \
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
- [ ] **Step 11: Commit**
|
|
627
|
+
|
|
628
|
+
```bash
|
|
629
|
+
cd forloop-opencode-plugin-planner
|
|
630
|
+
git add agent/forLoopPlanner.md
|
|
631
|
+
git commit -m "docs: update forLoopPlanner agent paths for sprint subdirectories"
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
### Task 5: Update forLoopStoryEvaluator.md Permission Block
|
|
637
|
+
|
|
638
|
+
**Files:**
|
|
639
|
+
- Modify: `forloop-opencode-plugin-planner/agent/forLoopStoryEvaluator.md`
|
|
640
|
+
|
|
641
|
+
- [ ] **Step 1: Update permission block**
|
|
642
|
+
|
|
643
|
+
Replace lines 12-17:
|
|
644
|
+
```yaml
|
|
645
|
+
permission:
|
|
646
|
+
"*": allow
|
|
647
|
+
external_directory:
|
|
648
|
+
"/tmp/home/.forloop/**": allow
|
|
649
|
+
"/tmp/home/.config/opencode/**": allow
|
|
650
|
+
"~/.forloop/**": allow
|
|
651
|
+
"~/.config/forloop/**": allow
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
With:
|
|
655
|
+
```yaml
|
|
656
|
+
permission:
|
|
657
|
+
"*": allow
|
|
658
|
+
external_directory:
|
|
659
|
+
"/tmp/home/.forloop/**": allow
|
|
660
|
+
"/tmp/home/.forloop/sprint-*/**": allow
|
|
661
|
+
"/tmp/home/.config/opencode/**": allow
|
|
662
|
+
"~/.forloop/**": allow
|
|
663
|
+
"~/.forloop/sprint-*/**": allow
|
|
664
|
+
"~/.config/forloop/**": allow
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
- [ ] **Step 2: Commit**
|
|
668
|
+
|
|
669
|
+
```bash
|
|
670
|
+
cd forloop-opencode-plugin-planner
|
|
671
|
+
git add agent/forLoopStoryEvaluator.md
|
|
672
|
+
git commit -m "docs: update forLoopStoryEvaluator permission paths for sprint subdirectories"
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
---
|
|
676
|
+
|
|
677
|
+
### Task 6: Update forloop-context Skill
|
|
678
|
+
|
|
679
|
+
**Files:**
|
|
680
|
+
- Modify: `forloop-opencode-plugin-planner/skills/forloop-context/SKILL.md`
|
|
681
|
+
|
|
682
|
+
- [ ] **Step 1: Update Step 1 - Resolve Context Directory**
|
|
683
|
+
|
|
684
|
+
Replace lines 69-81:
|
|
685
|
+
```markdown
|
|
686
|
+
### Step 1: Resolve Context Directory
|
|
687
|
+
|
|
688
|
+
Use this location order:
|
|
689
|
+
|
|
690
|
+
1. `./.forloop/` (project-local)
|
|
691
|
+
2. `~/.forloop/` (user-global fallback)
|
|
692
|
+
|
|
693
|
+
If neither exists, create `~/.forloop/` and its subfolders.
|
|
694
|
+
|
|
695
|
+
**Outcomes:**
|
|
696
|
+
|
|
697
|
+
- **Exists:** Continue to load context
|
|
698
|
+
- **Not exists:** Create structure, inform user of fresh start
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
With:
|
|
702
|
+
```markdown
|
|
703
|
+
### Step 1: Resolve Context Directory
|
|
704
|
+
|
|
705
|
+
The manifest is always at `~/.forloop/manifest.json`.
|
|
706
|
+
Sprint files are at `~/.forloop/sprint-{sprintId}/`.
|
|
707
|
+
|
|
708
|
+
1. Check `~/.forloop/manifest.json` for `activeSprintId`
|
|
709
|
+
2. If manifest has active sprint, use `~/.forloop/sprint-{activeSprintId}/`
|
|
710
|
+
3. If no sprint selected, work at `~/.forloop/` root only
|
|
711
|
+
|
|
712
|
+
If `~/.forloop/` doesn't exist, create it.
|
|
713
|
+
|
|
714
|
+
**Outcomes:**
|
|
715
|
+
|
|
716
|
+
- **Manifest exists with active sprint:** Load from `~/.forloop/sprint-{id}/`
|
|
717
|
+
- **Manifest exists, no sprint:** Create structure, inform user of fresh start
|
|
718
|
+
- **No manifest:** Create `~/.forloop/` and manifest, inform user of fresh start
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
- [ ] **Step 2: Update Step 2 - Check Manifest format**
|
|
722
|
+
|
|
723
|
+
Replace lines 85-106:
|
|
724
|
+
```markdown
|
|
725
|
+
**Expected manifest structure:**
|
|
726
|
+
|
|
727
|
+
```json
|
|
728
|
+
{
|
|
729
|
+
"version": 1,
|
|
730
|
+
"activeSprintId": 14,
|
|
731
|
+
"sprints": {
|
|
732
|
+
"14": {
|
|
733
|
+
"plan": {
|
|
734
|
+
"file": "~/.forloop/plan/plan-14-20260410-093015.md",
|
|
735
|
+
"createdAt": "2026-04-10T09:30:15Z"
|
|
736
|
+
},
|
|
737
|
+
"tasks": {
|
|
738
|
+
"file": "~/.forloop/task/task-14-20260410-093530.md",
|
|
739
|
+
"storyIds": ["123", "124", "125"]
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
With:
|
|
747
|
+
```markdown
|
|
748
|
+
**Expected manifest structure (v2):**
|
|
749
|
+
|
|
750
|
+
```json
|
|
751
|
+
{
|
|
752
|
+
"version": 2,
|
|
753
|
+
"activeSprintId": 14,
|
|
754
|
+
"sprints": {
|
|
755
|
+
"14": {
|
|
756
|
+
"sprintDir": "sprint-14",
|
|
757
|
+
"plan": {
|
|
758
|
+
"file": "sprint-14/plan/plan-14-20260410-093015.md",
|
|
759
|
+
"createdAt": "2026-04-10T09:30:15Z"
|
|
760
|
+
},
|
|
761
|
+
"tasks": {
|
|
762
|
+
"file": "sprint-14/task/task-14-20260410-093530.md",
|
|
763
|
+
"storyIds": ["123", "124", "125"]
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
- [ ] **Step 3: Update Step 3 - Scan Folders**
|
|
771
|
+
|
|
772
|
+
Replace lines 118-125:
|
|
773
|
+
```markdown
|
|
774
|
+
If manifest is missing/invalid, scan:
|
|
775
|
+
|
|
776
|
+
- `knowledge/` (latest 3)
|
|
777
|
+
- `plan/` (latest 1)
|
|
778
|
+
- `task/` (latest 1)
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
With:
|
|
782
|
+
```markdown
|
|
783
|
+
If manifest is missing/invalid, scan:
|
|
784
|
+
|
|
785
|
+
- `sprint-{id}/knowledge/` (latest 3) if sprint is known
|
|
786
|
+
- `sprint-{id}/plan/` (latest 1) if sprint is known
|
|
787
|
+
- `sprint-{id}/task/` (latest 1) if sprint is known
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
- [ ] **Step 4: Update Fresh Session section**
|
|
791
|
+
|
|
792
|
+
Replace lines 253-289:
|
|
793
|
+
```markdown
|
|
794
|
+
## Fresh Session (No .forloop)
|
|
795
|
+
|
|
796
|
+
**If no .forloop directory:**
|
|
797
|
+
|
|
798
|
+
```
|
|
799
|
+
📁 No Previous Context Found
|
|
800
|
+
|
|
801
|
+
This appears to be a fresh project. I'll create the
|
|
802
|
+
.forloop folder structure for future sessions.
|
|
803
|
+
|
|
804
|
+
Created:
|
|
805
|
+
.forloop/knowledge/
|
|
806
|
+
.forloop/plan/
|
|
807
|
+
.forloop/task/
|
|
808
|
+
|
|
809
|
+
How would you like to get started?
|
|
810
|
+
|
|
811
|
+
1. Create a new sprint plan
|
|
812
|
+
2. Connect to existing ForLoop sprint
|
|
813
|
+
3. Learn about your project
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
**Create structure:**
|
|
817
|
+
|
|
818
|
+
```bash
|
|
819
|
+
mkdir -p .forloop/knowledge .forloop/plan .forloop/task
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
**Initialize empty manifest:**
|
|
823
|
+
|
|
824
|
+
```json
|
|
825
|
+
{
|
|
826
|
+
"version": 1,
|
|
827
|
+
"activeSprintId": null,
|
|
828
|
+
"sprints": {}
|
|
829
|
+
}
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
With:
|
|
833
|
+
```markdown
|
|
834
|
+
## Fresh Session (No .forloop)
|
|
835
|
+
|
|
836
|
+
**If no .forloop directory:**
|
|
837
|
+
|
|
838
|
+
```
|
|
839
|
+
📁 No Previous Context Found
|
|
840
|
+
|
|
841
|
+
This appears to be a fresh project. I'll create the
|
|
842
|
+
.forloop folder structure for future sessions.
|
|
843
|
+
|
|
844
|
+
Created:
|
|
845
|
+
.forloop/manifest.json
|
|
846
|
+
.forloop/sync/
|
|
847
|
+
|
|
848
|
+
Sprint directories will be created when a sprint is selected:
|
|
849
|
+
.forloop/sprint-{id}/knowledge/
|
|
850
|
+
.forloop/sprint-{id}/plan/
|
|
851
|
+
.forloop/sprint-{id}/task/
|
|
852
|
+
|
|
853
|
+
How would you like to get started?
|
|
854
|
+
|
|
855
|
+
1. Create a new sprint plan
|
|
856
|
+
2. Connect to existing ForLoop sprint
|
|
857
|
+
3. Learn about your project
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Create structure:**
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
mkdir -p .forloop/sync
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
**Initialize empty manifest:**
|
|
867
|
+
|
|
868
|
+
```json
|
|
869
|
+
{
|
|
870
|
+
"version": 2,
|
|
871
|
+
"activeSprintId": null,
|
|
872
|
+
"sprints": {}
|
|
873
|
+
}
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
- [ ] **Step 5: Update Anti-Patterns table**
|
|
877
|
+
|
|
878
|
+
Replace anti-pattern #1:
|
|
879
|
+
```markdown
|
|
880
|
+
| 1 | Skip context check at session start | Always check ~/.forloop/ first |
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
With:
|
|
884
|
+
```markdown
|
|
885
|
+
| 1 | Skip context check at session start | Always check ~/.forloop/manifest.json first, then load sprint subdir |
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
- [ ] **Step 6: Update Quality Gates**
|
|
889
|
+
|
|
890
|
+
Replace lines 466-471:
|
|
891
|
+
```markdown
|
|
892
|
+
## Quality Gates
|
|
893
|
+
|
|
894
|
+
- [ ] ~/.forloop/ directory checked (or created)
|
|
895
|
+
- [ ] manifest.json loaded and validated (or fallback scan used)
|
|
896
|
+
```
|
|
897
|
+
|
|
898
|
+
With:
|
|
899
|
+
```markdown
|
|
900
|
+
## Quality Gates
|
|
901
|
+
|
|
902
|
+
- [ ] ~/.forloop/ directory and manifest.json checked (or created)
|
|
903
|
+
- [ ] manifest.json loaded and validated (v2 format with sprintDir)
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
- [ ] **Step 7: Commit**
|
|
907
|
+
|
|
908
|
+
```bash
|
|
909
|
+
cd forloop-opencode-plugin-planner
|
|
910
|
+
git add skills/forloop-context/SKILL.md
|
|
911
|
+
git commit -m "docs: update forloop-context skill for sprint subdirectories"
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
---
|
|
915
|
+
|
|
916
|
+
### Task 7: Update knowledge-management Skill
|
|
917
|
+
|
|
918
|
+
**Files:**
|
|
919
|
+
- Modify: `forloop-opencode-plugin-planner/skills/knowledge-management/SKILL.md`
|
|
920
|
+
|
|
921
|
+
- [ ] **Step 1: Update storage path in front matter**
|
|
922
|
+
|
|
923
|
+
Replace line 15:
|
|
924
|
+
```yaml
|
|
925
|
+
storage: ~/.forloop/knowledge/
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
With:
|
|
929
|
+
```yaml
|
|
930
|
+
storage: ~/.forloop/sprint-{id}/knowledge/
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
- [ ] **Step 2: Update Step 4 - Create Knowledge File location**
|
|
934
|
+
|
|
935
|
+
Replace line 125:
|
|
936
|
+
```markdown
|
|
937
|
+
**Location:** `.forloop/knowledge/knowledge-{topic}-{datetime}.md`
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
With:
|
|
941
|
+
```markdown
|
|
942
|
+
**Location:** `.forloop/sprint-{sprintId}/knowledge/knowledge-{topic}-{datetime}.md`
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
- [ ] **Step 3: Update Step 5 - Upload path**
|
|
946
|
+
|
|
947
|
+
Replace line 181:
|
|
948
|
+
```bash
|
|
949
|
+
--filePath .forloop/knowledge/knowledge-{topic}-{datetime}.md \
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
With:
|
|
953
|
+
```bash
|
|
954
|
+
--filePath .forloop/sprint-{sprintId}/knowledge/knowledge-{topic}-{datetime}.md \
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
- [ ] **Step 4: Update Deduplication Check**
|
|
958
|
+
|
|
959
|
+
Replace line 291:
|
|
960
|
+
```bash
|
|
961
|
+
ls .forloop/knowledge/ | grep -i "{topic}"
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
With:
|
|
965
|
+
```bash
|
|
966
|
+
ls .forloop/sprint-{sprintId}/knowledge/ | grep -i "{topic}"
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
- [ ] **Step 5: Update Quality Gates**
|
|
970
|
+
|
|
971
|
+
Replace line 351:
|
|
972
|
+
```markdown
|
|
973
|
+
- [ ] File created at `.forloop/knowledge/knowledge-{topic}-{datetime}.md`
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
With:
|
|
977
|
+
```markdown
|
|
978
|
+
- [ ] File created at `.forloop/sprint-{sprintId}/knowledge/knowledge-{topic}-{datetime}.md`
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
- [ ] **Step 6: Update Anti-Pattern #1**
|
|
982
|
+
|
|
983
|
+
Replace:
|
|
984
|
+
```markdown
|
|
985
|
+
| 1 | Capture without writing to ~/.forloop/knowledge/ | Create file with knowledge-{topic}-{datetime}.md format |
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
With:
|
|
989
|
+
```markdown
|
|
990
|
+
| 1 | Capture without writing to ~/.forloop/sprint-{id}/knowledge/ | Create file with sprint subdir and knowledge-{topic}-{datetime}.md format |
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
- [ ] **Step 7: Commit**
|
|
994
|
+
|
|
995
|
+
```bash
|
|
996
|
+
cd forloop-opencode-plugin-planner
|
|
997
|
+
git add skills/knowledge-management/SKILL.md
|
|
998
|
+
git commit -m "docs: update knowledge-management skill for sprint subdirectories"
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
---
|
|
1002
|
+
|
|
1003
|
+
### Task 8: Update plan-documentation Skill
|
|
1004
|
+
|
|
1005
|
+
**Files:**
|
|
1006
|
+
- Modify: `forloop-opencode-plugin-planner/skills/plan-documentation/SKILL.md`
|
|
1007
|
+
|
|
1008
|
+
- [ ] **Step 1: Update storage path in front matter**
|
|
1009
|
+
|
|
1010
|
+
Replace line 15:
|
|
1011
|
+
```yaml
|
|
1012
|
+
storage: ~/.forloop/plan/
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
With:
|
|
1016
|
+
```yaml
|
|
1017
|
+
storage: ~/.forloop/sprint-{id}/plan/
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
- [ ] **Step 2: Update manifest path reference**
|
|
1021
|
+
|
|
1022
|
+
Replace line 87:
|
|
1023
|
+
```markdown
|
|
1024
|
+
Check manifest first: `~/.forloop/manifest.json`.
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
With:
|
|
1028
|
+
```markdown
|
|
1029
|
+
Check manifest first: `~/.forloop/manifest.json`. If valid, load plan from `~/.forloop/sprint-{activeSprintId}/plan/`.
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
- [ ] **Step 3: Update Step 1 - Check Existing Plans fallback**
|
|
1033
|
+
|
|
1034
|
+
Replace line 93:
|
|
1035
|
+
```markdown
|
|
1036
|
+
If no manifest, scan `~/.forloop/plan/` for the most recent plan for the sprint.
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
With:
|
|
1040
|
+
```markdown
|
|
1041
|
+
If no manifest, scan `~/.forloop/sprint-{sprintId}/plan/` for the most recent plan for the sprint.
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
- [ ] **Step 4: Update Step 5 - Write Plan File location**
|
|
1045
|
+
|
|
1046
|
+
Replace line 158:
|
|
1047
|
+
```markdown
|
|
1048
|
+
**Location:** `.forloop/plan/plan-{sprintId}-{datetime}.md`
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
With:
|
|
1052
|
+
```markdown
|
|
1053
|
+
**Location:** `.forloop/sprint-{sprintId}/plan/plan-{sprintId}-{datetime}.md`
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
- [ ] **Step 5: Update Step 6 - Update Active Manifest**
|
|
1057
|
+
|
|
1058
|
+
Replace the manifest JSON example (lines 245-258):
|
|
1059
|
+
```json
|
|
1060
|
+
{
|
|
1061
|
+
"version": 1,
|
|
1062
|
+
"activeSprintId": {sprintId},
|
|
1063
|
+
"sprints": {
|
|
1064
|
+
"{sprintId}": {
|
|
1065
|
+
"plan": {
|
|
1066
|
+
"file": ".forloop/plan/plan-{sprintId}-{datetime}.md",
|
|
1067
|
+
"createdAt": "{datetime}"
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
With:
|
|
1075
|
+
```json
|
|
1076
|
+
{
|
|
1077
|
+
"version": 2,
|
|
1078
|
+
"activeSprintId": {sprintId},
|
|
1079
|
+
"sprints": {
|
|
1080
|
+
"{sprintId}": {
|
|
1081
|
+
"sprintDir": "sprint-{sprintId}",
|
|
1082
|
+
"plan": {
|
|
1083
|
+
"file": "sprint-{sprintId}/plan/plan-{sprintId}-{datetime}.md",
|
|
1084
|
+
"createdAt": "{datetime}"
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
- [ ] **Step 6: Update Step 7 - Upload path**
|
|
1092
|
+
|
|
1093
|
+
Replace line 280:
|
|
1094
|
+
```bash
|
|
1095
|
+
--filePath .forloop/plan/plan-{sprintId}-{datetime}.md \
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
With:
|
|
1099
|
+
```bash
|
|
1100
|
+
--filePath .forloop/sprint-{sprintId}/plan/plan-{sprintId}-{datetime}.md \
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
- [ ] **Step 7: Update Anti-Patterns and Quality Gates**
|
|
1104
|
+
|
|
1105
|
+
Replace:
|
|
1106
|
+
```markdown
|
|
1107
|
+
| 4 | Skip manifest update | Update `~/.forloop/manifest.json` with new plan path |
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
With:
|
|
1111
|
+
```markdown
|
|
1112
|
+
| 4 | Skip manifest update | Update `~/.forloop/manifest.json` with v2 format (include sprintDir) |
|
|
1113
|
+
```
|
|
1114
|
+
|
|
1115
|
+
Replace quality gate:
|
|
1116
|
+
```markdown
|
|
1117
|
+
- [ ] Plan file created at `.forloop/plan/plan-{sprintId}-{datetime}.md`
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
With:
|
|
1121
|
+
```markdown
|
|
1122
|
+
- [ ] Plan file created at `.forloop/sprint-{sprintId}/plan/plan-{sprintId}-{datetime}.md`
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
- [ ] **Step 8: Commit**
|
|
1126
|
+
|
|
1127
|
+
```bash
|
|
1128
|
+
cd forloop-opencode-plugin-planner
|
|
1129
|
+
git add skills/plan-documentation/SKILL.md
|
|
1130
|
+
git commit -m "docs: update plan-documentation skill for sprint subdirectories"
|
|
1131
|
+
```
|
|
1132
|
+
|
|
1133
|
+
---
|
|
1134
|
+
|
|
1135
|
+
### Task 9: Update task-tracking Skill
|
|
1136
|
+
|
|
1137
|
+
**Files:**
|
|
1138
|
+
- Modify: `forloop-opencode-plugin-planner/skills/task-tracking/SKILL.md`
|
|
1139
|
+
|
|
1140
|
+
- [ ] **Step 1: Update storage path in front matter**
|
|
1141
|
+
|
|
1142
|
+
Replace line 16:
|
|
1143
|
+
```yaml
|
|
1144
|
+
storage: ~/.forloop/task/
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
With:
|
|
1148
|
+
```yaml
|
|
1149
|
+
storage: ~/.forloop/sprint-{id}/task/
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
- [ ] **Step 2: Update Step 1 - Read Plan File**
|
|
1153
|
+
|
|
1154
|
+
Replace line 77-79:
|
|
1155
|
+
```markdown
|
|
1156
|
+
Check manifest first: `~/.forloop/manifest.json`.
|
|
1157
|
+
|
|
1158
|
+
Get plan file from manifest. If missing, scan `~/.forloop/plan/` for the latest `plan-{sprintId}-*.md`.
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
With:
|
|
1162
|
+
```markdown
|
|
1163
|
+
Check manifest first: `~/.forloop/manifest.json`.
|
|
1164
|
+
|
|
1165
|
+
Get plan file from manifest. If missing, scan `~/.forloop/sprint-{sprintId}/plan/` for the latest `plan-{sprintId}-*.md`.
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
- [ ] **Step 3: Update Step 7 - Write Task List File location**
|
|
1169
|
+
|
|
1170
|
+
Replace line 231:
|
|
1171
|
+
```markdown
|
|
1172
|
+
**Location:** `.forloop/task/task-{sprintId}-{datetime}.md`
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
With:
|
|
1176
|
+
```markdown
|
|
1177
|
+
**Location:** `.forloop/sprint-{sprintId}/task/task-{sprintId}-{datetime}.md`
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
- [ ] **Step 4: Update Step 8 - Update Manifest**
|
|
1181
|
+
|
|
1182
|
+
Replace the manifest JSON example (lines 276-290):
|
|
1183
|
+
```json
|
|
1184
|
+
{
|
|
1185
|
+
"version": 1,
|
|
1186
|
+
"activeSprintId": {sprintId},
|
|
1187
|
+
"sprints": {
|
|
1188
|
+
"{sprintId}": {
|
|
1189
|
+
"plan": { ... },
|
|
1190
|
+
"tasks": {
|
|
1191
|
+
"file": ".forloop/task/task-{sprintId}-{datetime}.md",
|
|
1192
|
+
"storyIds": ["201", "202", "203"]
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
```
|
|
1198
|
+
|
|
1199
|
+
With:
|
|
1200
|
+
```json
|
|
1201
|
+
{
|
|
1202
|
+
"version": 2,
|
|
1203
|
+
"activeSprintId": {sprintId},
|
|
1204
|
+
"sprints": {
|
|
1205
|
+
"{sprintId}": {
|
|
1206
|
+
"sprintDir": "sprint-{sprintId}",
|
|
1207
|
+
"plan": { ... },
|
|
1208
|
+
"tasks": {
|
|
1209
|
+
"file": "sprint-{sprintId}/task/task-{sprintId}-{datetime}.md",
|
|
1210
|
+
"storyIds": ["201", "202", "203"]
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
- [ ] **Step 5: Update Step 9 - Upload path**
|
|
1218
|
+
|
|
1219
|
+
Replace line 307:
|
|
1220
|
+
```bash
|
|
1221
|
+
--filePath .forloop/task/task-{sprintId}-{datetime}.md \
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
With:
|
|
1225
|
+
```bash
|
|
1226
|
+
--filePath .forloop/sprint-{sprintId}/task/task-{sprintId}-{datetime}.md \
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
- [ ] **Step 6: Update File Organization - Folder Mapping**
|
|
1230
|
+
|
|
1231
|
+
Replace lines 414-420:
|
|
1232
|
+
```markdown
|
|
1233
|
+
| Local Path | S3 Folder | Parameter |
|
|
1234
|
+
|------------|-----------|-----------|
|
|
1235
|
+
| `.forloop/plan/*` | `project/plans/` | `--folder project/plans` |
|
|
1236
|
+
| `.forloop/knowledge/*` | `project/knowledge/` | `--folder project/knowledge` |
|
|
1237
|
+
| `.forloop/task/*` | `project/tasks/` | `--folder project/tasks` |
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
With:
|
|
1241
|
+
```markdown
|
|
1242
|
+
| Local Path | S3 Folder | Parameter |
|
|
1243
|
+
|------------|-----------|-----------|
|
|
1244
|
+
| `.forloop/sprint-{id}/plan/*` | `project/plans/` | `--folder project/plans` |
|
|
1245
|
+
| `.forloop/sprint-{id}/knowledge/*` | `project/knowledge/` | `--folder project/knowledge` |
|
|
1246
|
+
| `.forloop/sprint-{id}/task/*` | `project/tasks/` | `--folder project/tasks` |
|
|
1247
|
+
```
|
|
1248
|
+
|
|
1249
|
+
- [ ] **Step 7: Update Quality Gates**
|
|
1250
|
+
|
|
1251
|
+
Replace:
|
|
1252
|
+
```markdown
|
|
1253
|
+
- [ ] Task file written to `.forloop/task/task-{sprintId}-{datetime}.md`
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
With:
|
|
1257
|
+
```markdown
|
|
1258
|
+
- [ ] Task file written to `.forloop/sprint-{sprintId}/task/task-{sprintId}-{datetime}.md`
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
- [ ] **Step 8: Update Anti-Pattern #7**
|
|
1262
|
+
|
|
1263
|
+
Replace:
|
|
1264
|
+
```markdown
|
|
1265
|
+
| 7 | Skip manifest update | Always update `~/.forloop/manifest.json` |
|
|
1266
|
+
```
|
|
1267
|
+
|
|
1268
|
+
With:
|
|
1269
|
+
```markdown
|
|
1270
|
+
| 7 | Skip manifest update | Always update `~/.forloop/manifest.json` with v2 format |
|
|
1271
|
+
```
|
|
1272
|
+
|
|
1273
|
+
- [ ] **Step 9: Commit**
|
|
1274
|
+
|
|
1275
|
+
```bash
|
|
1276
|
+
cd forloop-opencode-plugin-planner
|
|
1277
|
+
git add skills/task-tracking/SKILL.md
|
|
1278
|
+
git commit -m "docs: update task-tracking skill for sprint subdirectories"
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
---
|
|
1282
|
+
|
|
1283
|
+
### Task 10: Update aivy-documents-sync and sprint-planning Skills
|
|
1284
|
+
|
|
1285
|
+
**Files:**
|
|
1286
|
+
- Modify: `forloop-opencode-plugin-planner/skills/aivy-documents-sync/SKILL.md`
|
|
1287
|
+
- Modify: `forloop-opencode-plugin-planner/skills/sprint-planning/SKILL.md`
|
|
1288
|
+
|
|
1289
|
+
- [ ] **Step 1: Update aivy-documents-sync**
|
|
1290
|
+
|
|
1291
|
+
Replace line 15:
|
|
1292
|
+
```yaml
|
|
1293
|
+
storage: ~/.forloop/
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
With:
|
|
1297
|
+
```yaml
|
|
1298
|
+
storage: ~/.forloop/sprint-{id}/
|
|
1299
|
+
```
|
|
1300
|
+
|
|
1301
|
+
Replace lines 41-45:
|
|
1302
|
+
```markdown
|
|
1303
|
+
- `.forloop/knowledge/*`
|
|
1304
|
+
- `.forloop/plan/*`
|
|
1305
|
+
- `.forloop/task/*`
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
With:
|
|
1309
|
+
```markdown
|
|
1310
|
+
- `.forloop/sprint-{id}/knowledge/*`
|
|
1311
|
+
- `.forloop/sprint-{id}/plan/*`
|
|
1312
|
+
- `.forloop/sprint-{id}/task/*`
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1315
|
+
Replace line 60:
|
|
1316
|
+
```markdown
|
|
1317
|
+
- Files under `project/knowledge`, `project/plans`, and `project/tasks` are synced to local `knowledge/`, `plan/`, and `task/`.
|
|
1318
|
+
```
|
|
1319
|
+
|
|
1320
|
+
With:
|
|
1321
|
+
```markdown
|
|
1322
|
+
- Files under `project/knowledge`, `project/plans`, and `project/tasks` are synced to local `sprint-{id}/knowledge/`, `sprint-{id}/plan/`, and `sprint-{id}/task/`.
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
- [ ] **Step 2: Update sprint-planning**
|
|
1326
|
+
|
|
1327
|
+
Replace line 6:
|
|
1328
|
+
```yaml
|
|
1329
|
+
Integrates with ~/.forloop/ for persistent context.
|
|
1330
|
+
```
|
|
1331
|
+
|
|
1332
|
+
With:
|
|
1333
|
+
```yaml
|
|
1334
|
+
Integrates with ~/.forloop/sprint-{id}/ for persistent context.
|
|
1335
|
+
```
|
|
1336
|
+
|
|
1337
|
+
Replace line 71-73:
|
|
1338
|
+
```markdown
|
|
1339
|
+
- [ ] Run forloop-context skill to load `~/.forloop/` context
|
|
1340
|
+
- [ ] Check manifest.json for active sprint
|
|
1341
|
+
- [ ] Review loaded knowledge, plans, and tasks
|
|
1342
|
+
```
|
|
1343
|
+
|
|
1344
|
+
With:
|
|
1345
|
+
```markdown
|
|
1346
|
+
- [ ] Run forloop-context skill to load `~/.forloop/manifest.json` context
|
|
1347
|
+
- [ ] Check manifest.json for active sprint
|
|
1348
|
+
- [ ] Review loaded knowledge, plans, and tasks from `~/.forloop/sprint-{id}/`
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
Replace line 91:
|
|
1352
|
+
```markdown
|
|
1353
|
+
- [ ] Update `~/.forloop/manifest.json`
|
|
1354
|
+
```
|
|
1355
|
+
|
|
1356
|
+
With:
|
|
1357
|
+
```markdown
|
|
1358
|
+
- [ ] Update `~/.forloop/manifest.json` (v2 format with sprintDir)
|
|
1359
|
+
```
|
|
1360
|
+
|
|
1361
|
+
Replace line 134:
|
|
1362
|
+
```markdown
|
|
1363
|
+
- Load knowledge, plans, and tasks
|
|
1364
|
+
```
|
|
1365
|
+
|
|
1366
|
+
With:
|
|
1367
|
+
```markdown
|
|
1368
|
+
- Load knowledge, plans, and tasks from `~/.forloop/sprint-{id}/`
|
|
1369
|
+
```
|
|
1370
|
+
|
|
1371
|
+
- [ ] **Step 3: Commit**
|
|
1372
|
+
|
|
1373
|
+
```bash
|
|
1374
|
+
cd forloop-opencode-plugin-planner
|
|
1375
|
+
git add skills/aivy-documents-sync/SKILL.md skills/sprint-planning/SKILL.md
|
|
1376
|
+
git commit -m "docs: update aivy-documents-sync and sprint-planning skills for sprint subdirectories"
|
|
1377
|
+
```
|
|
1378
|
+
|
|
1379
|
+
---
|
|
1380
|
+
|
|
1381
|
+
### Task 11: Run Full Test Suite and Fix Any Failures
|
|
1382
|
+
|
|
1383
|
+
**Files:**
|
|
1384
|
+
- Various test files may need minor adjustments
|
|
1385
|
+
|
|
1386
|
+
- [ ] **Step 1: Run typecheck**
|
|
1387
|
+
|
|
1388
|
+
Run: `cd forloop-opencode-plugin-planner && npx tsc --noEmit`
|
|
1389
|
+
Expected: No type errors
|
|
1390
|
+
|
|
1391
|
+
- [ ] **Step 2: Run all unit tests**
|
|
1392
|
+
|
|
1393
|
+
Run: `cd forloop-opencode-plugin-planner && npx vitest run test/suites/unit/ -v`
|
|
1394
|
+
Expected: All tests PASS
|
|
1395
|
+
|
|
1396
|
+
- [ ] **Step 3: Fix any test failures**
|
|
1397
|
+
|
|
1398
|
+
If any tests fail due to path changes, update them to use sprint subdirectory format. Common fixes:
|
|
1399
|
+
- Update `path.join(tmpHome, '.forloop', 'knowledge')` → `path.join(tmpHome, '.forloop', 'sprint-14', 'knowledge')`
|
|
1400
|
+
- Update `path.join(tmpHome, '.forloop', 'sync', 'manifest.json')` stays the same (sync manifest is shared)
|
|
1401
|
+
- Update manifest version expectations from 1 to 2 where applicable
|
|
1402
|
+
|
|
1403
|
+
- [ ] **Step 4: Run lint check**
|
|
1404
|
+
|
|
1405
|
+
Run: `cd forloop-opencode-plugin-planner && npm run lint`
|
|
1406
|
+
Expected: No lint errors
|
|
1407
|
+
|
|
1408
|
+
- [ ] **Step 5: Commit any fixes**
|
|
1409
|
+
|
|
1410
|
+
```bash
|
|
1411
|
+
cd forloop-opencode-plugin-planner
|
|
1412
|
+
git add -A
|
|
1413
|
+
git commit -m "test: fix remaining test path assertions for sprint subdirectories"
|
|
1414
|
+
```
|
|
1415
|
+
|
|
1416
|
+
---
|
|
1417
|
+
|
|
1418
|
+
## Spec Coverage Check
|
|
1419
|
+
|
|
1420
|
+
| Spec Requirement | Task |
|
|
1421
|
+
|-----------------|------|
|
|
1422
|
+
| `getSprintDir()` function | Task 1 |
|
|
1423
|
+
| `getForloopRoot()` function | Task 1 |
|
|
1424
|
+
| `getManifestPath()` function | Task 1 |
|
|
1425
|
+
| sync-tools uses sprint subdirs | Task 2 |
|
|
1426
|
+
| sync-tests updated | Task 3 |
|
|
1427
|
+
| forLoopPlanner.md paths | Task 4 |
|
|
1428
|
+
| forLoopStoryEvaluator.md paths | Task 5 |
|
|
1429
|
+
| forloop-context skill | Task 6 |
|
|
1430
|
+
| knowledge-management skill | Task 7 |
|
|
1431
|
+
| plan-documentation skill | Task 8 |
|
|
1432
|
+
| task-tracking skill | Task 9 |
|
|
1433
|
+
| aivy-documents-sync skill | Task 10 |
|
|
1434
|
+
| sprint-planning skill | Task 10 |
|
|
1435
|
+
| Full test suite passes | Task 11 |
|
|
1436
|
+
| Backward compatibility (v1→v2 manifest) | Implicit - tools check version field, create sprintDir when missing |
|
|
1437
|
+
| Manifest stays at root | All tasks preserve `~/.forloop/manifest.json` location |
|
|
1438
|
+
| Sprint-specific subdirs | All file operations use `sprint-{id}/` prefix |
|
|
1439
|
+
|
|
1440
|
+
## Placeholder Scan
|
|
1441
|
+
|
|
1442
|
+
No placeholders found. All steps contain exact code, paths, and commands.
|
|
1443
|
+
|
|
1444
|
+
## Type Consistency Check
|
|
1445
|
+
|
|
1446
|
+
- `getSprintDir(sprintId: number): string` - consistent across all references
|
|
1447
|
+
- `getForloopRoot(sprintId?: number): string` - consistent
|
|
1448
|
+
- `getManifestPath(): string` - consistent
|
|
1449
|
+
- Manifest version: 2 (all manifest examples use v2)
|
|
1450
|
+
- All file paths use `sprint-{id}/` prefix consistently
|