@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.
Files changed (55) hide show
  1. package/CHANGELOG.md +225 -0
  2. package/CODE_OF_CONDUCT.md +77 -0
  3. package/CONTRIBUTING.md +176 -0
  4. package/LICENSE +21 -0
  5. package/README.md +211 -0
  6. package/SECURITY.md +69 -0
  7. package/docs/CONFIGURATION.md +283 -0
  8. package/docs/DEVELOPER-VS-USER.md +129 -0
  9. package/docs/IMPROVED-AUTHENTICATION.md +317 -0
  10. package/docs/INSTALLATION-SCRIPTS.md +304 -0
  11. package/docs/PLANNER-AGENT-IMPROVEMENTS.md +88 -0
  12. package/docs/PLUGIN-ARCHITECTURE.md +308 -0
  13. package/docs/QUICKSTART-NON-DEV.md +94 -0
  14. package/docs/README-FOR-HUMANS-AND-AI.md +109 -0
  15. package/docs/README.md +70 -0
  16. package/docs/SKILLS-GAP-ANALYSIS.md +157 -0
  17. package/docs/USER-INTERACTION-MODEL.md +106 -0
  18. package/docs/file-management/2026-04-12-forloop-aivy-documents-sync.md +395 -0
  19. package/docs/file-management/FILE_UPLOAD_ENHANCEMENT.md +431 -0
  20. package/docs/file-management/FILE_UPLOAD_FLOW.md +300 -0
  21. package/docs/images/forloop-opencode-flow.png +0 -0
  22. package/docs/images/forloop-opencode-header.png +0 -0
  23. package/docs/superpowers/plans/2026-05-03-sprint-isolated-directory-structure.md +1450 -0
  24. package/docs/superpowers/plans/2026-05-29-install-system.md +850 -0
  25. package/docs/superpowers/specs/2026-05-03-sprint-isolated-directory-structure-design.md +149 -0
  26. package/docs/superpowers/specs/2026-05-19-opencode-message-recording-design.md +468 -0
  27. package/docs/superpowers/specs/2026-05-29-install-system-design.md +135 -0
  28. package/install.sh +317 -0
  29. package/package.json +87 -0
  30. package/plugins/capabilities/api-client.ts +556 -0
  31. package/plugins/capabilities/auth.ts +120 -0
  32. package/plugins/capabilities/config.ts +195 -0
  33. package/plugins/capabilities/context-resolver.ts +106 -0
  34. package/plugins/capabilities/token-storage.ts +98 -0
  35. package/plugins/forloop-plugin.ts +186 -0
  36. package/plugins/hooks/message-recorder.ts +258 -0
  37. package/plugins/hooks/shell-env.ts +62 -0
  38. package/plugins/tools/agent-sprint-tools.ts +100 -0
  39. package/plugins/tools/agent-suggestion-tools.ts +275 -0
  40. package/plugins/tools/agent-tools.ts +114 -0
  41. package/plugins/tools/ai-trigger-tools.ts +79 -0
  42. package/plugins/tools/developer-status-tool.ts +97 -0
  43. package/plugins/tools/file-tools.ts +240 -0
  44. package/plugins/tools/folder-tools.ts +75 -0
  45. package/plugins/tools/organization-tools.ts +213 -0
  46. package/plugins/tools/schedule-tools.ts +173 -0
  47. package/plugins/tools/sprint-tools.ts +287 -0
  48. package/plugins/tools/story-tools.ts +320 -0
  49. package/plugins/tools/sync-tools.ts +509 -0
  50. package/plugins/tools/template-tools.ts +170 -0
  51. package/plugins/tools/user-tools.ts +146 -0
  52. package/scripts/migrate-tokens.js +90 -0
  53. package/scripts/use-prod.sh +11 -0
  54. package/tsconfig.json +17 -0
  55. package/update.sh +172 -0
@@ -0,0 +1,317 @@
1
+ # Improved Token Authentication System
2
+
3
+ ## Problem Statement
4
+
5
+ The ForLoop opencode plugin runs in **two different execution contexts**:
6
+
7
+ 1. **Local Workspace** (user's machine)
8
+ - User has `floop_*` API key token
9
+ - Token stored in `~/.config/forloop/tokens.json`
10
+ - Used for direct API calls
11
+
12
+ 2. **AWS Lambda** (serverless execution)
13
+ - Client sends JWT Bearer token (from user login)
14
+ - Token passed via EventBridge from `server_lambda`
15
+ - Used for authenticated API calls on behalf of user
16
+
17
+ **Previous Issue**: The `validateToken()` function only accepted `floop_*` tokens, which would reject JWT tokens in Lambda execution.
18
+
19
+ ## Solution: Dual Token Support
20
+
21
+ ### Token Types
22
+
23
+ ```typescript
24
+ export type TokenType = 'api_key' | 'jwt';
25
+
26
+ // API Key: floop_abc123xyz
27
+ // JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM...
28
+ ```
29
+
30
+ ### Detection Logic (`auth.ts:detectTokenType`)
31
+
32
+ ```typescript
33
+ export function detectTokenType(token: string): TokenType | null {
34
+ if (!token) return null;
35
+
36
+ // API Key format: floop_xxx
37
+ if (token.startsWith('floop_')) {
38
+ return 'api_key';
39
+ }
40
+
41
+ // JWT format: xxx.yyy.zzz (base64url.base64url.base64url)
42
+ const parts = token.split('.');
43
+ if (parts.length === 3 && parts.every(p => p.length > 0)) {
44
+ const base64urlRegex = /^[A-Za-z0-9_-]+$/;
45
+ if (parts.every(p => base64urlRegex.test(p))) {
46
+ return 'jwt';
47
+ }
48
+ }
49
+
50
+ return null;
51
+ }
52
+ ```
53
+
54
+ ### Context-Aware Validation
55
+
56
+ **Local Execution:**
57
+ - ✅ Accepts: `floop_*` API keys
58
+ - ❌ Rejects: JWT tokens (with helpful error message)
59
+
60
+ **Lambda Execution:**
61
+ - ✅ Accepts: JWT tokens (from EventBridge)
62
+ - ✅ Accepts: `floop_*` API keys (backward compatible)
63
+
64
+ ```typescript
65
+ export async function validateToken(providedToken?: string): Promise<TokenValidationResult> {
66
+ const token = providedToken || (await getToken());
67
+
68
+ const tokenType = detectTokenType(token);
69
+
70
+ if (!tokenType) {
71
+ return { valid: false, error: 'Unrecognized token format...' };
72
+ }
73
+
74
+ // JWT only allowed in Lambda
75
+ if (tokenType === 'jwt' && !isLambdaExecution()) {
76
+ return {
77
+ valid: false,
78
+ error: 'JWT tokens are only supported in Lambda execution...',
79
+ };
80
+ }
81
+
82
+ return { valid: true, token, tokenType };
83
+ }
84
+ ```
85
+
86
+ ### Lambda Detection (`config.ts`)
87
+
88
+ ```typescript
89
+ export const isLambdaExecution = (): boolean => {
90
+ return !!(
91
+ process.env.AWS_LAMBDA_FUNCTION_NAME ||
92
+ process.env.AWS_EXECUTION_ENV ||
93
+ process.env.LAMBDA_TASK_ROOT
94
+ );
95
+ };
96
+ ```
97
+
98
+ ## HTTP Header Strategy
99
+
100
+ Different token types require different HTTP headers:
101
+
102
+ | Token Type | Header | Example |
103
+ |------------|--------|---------|
104
+ | JWT | `Authorization: Bearer` | `Bearer eyJhbGciOiJIUzI1NiIs...` |
105
+ | API Key | `X-API-Token` | `floop_abc123xyz` |
106
+
107
+ ### Dynamic Header Selection (`api-client.ts`)
108
+
109
+ ```typescript
110
+ export class ForLoopAPIClient {
111
+ private tokenType: TokenType | null;
112
+
113
+ constructor(config: ClientConfig) {
114
+ this.tokenType = detectTokenType(config.token);
115
+ }
116
+
117
+ private getAuthHeaders(): HeadersInit {
118
+ const headers: HeadersInit = {};
119
+
120
+ if (this.tokenType === 'jwt') {
121
+ headers['Authorization'] = `Bearer ${this.config.token}`;
122
+ } else {
123
+ headers['X-API-Token'] = this.config.token;
124
+ }
125
+
126
+ return headers;
127
+ }
128
+
129
+ public async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
130
+ const response = await fetch(url, {
131
+ ...options,
132
+ headers: {
133
+ ...this.defaultHeaders,
134
+ ...this.getAuthHeaders(), // ← Dynamic based on token type
135
+ },
136
+ });
137
+ return response.json();
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Execution Flow
143
+
144
+ ### Local Workspace
145
+ ```
146
+ ┌─────────────────────────────────────┐
147
+ │ User runs opencode locally │
148
+ │ $ opencode run --agent forloop... │
149
+ └─────────────────────────────────────┘
150
+ │
151
+ ▼
152
+ ┌─────────────────────────────────────┐
153
+ │ Plugin loads ~/.config/forloop/ │
154
+ │ tokens.json → gets floop_* token │
155
+ └─────────────────────────────────────┘
156
+ │
157
+ ▼
158
+ ┌─────────────────────────────────────┐
159
+ │ validateToken() checks: │
160
+ │ - isLambdaExecution() = false │
161
+ │ - tokenType = 'api_key' ✓ │
162
+ │ - Returns valid ✓ │
163
+ └─────────────────────────────────────┘
164
+ │
165
+ ▼
166
+ ┌─────────────────────────────────────┐
167
+ │ API calls use header: │
168
+ │ X-API-Token: floop_*** │
169
+ └─────────────────────────────────────┘
170
+ ```
171
+
172
+ ### AWS Lambda
173
+ ```
174
+ ┌─────────────────────────────────────┐
175
+ │ Client sends POST /api/ai/chat │
176
+ │ Authorization: Bearer eyJ... │
177
+ └─────────────────────────────────────┘
178
+ │
179
+ ▼
180
+ ┌─────────────────────────────────────┐
181
+ │ server_lambda extracts JWT, │
182
+ │ includes in EventBridge detail │
183
+ └─────────────────────────────────────┘
184
+ │
185
+ ▼
186
+ ┌─────────────────────────────────────┐
187
+ │ Lambda receives JWT, seeds to │
188
+ │ /tmp/forloop-sandbox/.../tokens.json
189
+ └─────────────────────────────────────┘
190
+ │
191
+ ▼
192
+ ┌─────────────────────────────────────┐
193
+ │ Plugin reads JWT token │
194
+ └─────────────────────────────────────┘
195
+ │
196
+ ▼
197
+ ┌─────────────────────────────────────┐
198
+ │ validateToken() checks: │
199
+ │ - isLambdaExecution() = true │
200
+ │ - tokenType = 'jwt' ✓ │
201
+ │ - JWT allowed in Lambda ✓ │
202
+ │ - Returns valid ✓ │
203
+ └─────────────────────────────────────┘
204
+ │
205
+ ▼
206
+ ┌─────────────────────────────────────┐
207
+ │ API calls use header: │
208
+ │ Authorization: Bearer eyJ... │
209
+ └─────────────────────────────────────┘
210
+ ```
211
+
212
+ ## Error Messages
213
+
214
+ ### Missing Token
215
+ ```
216
+ No API token configured. Please create a token at https://forloop.cc/profile?tab=api-tokens
217
+ ```
218
+
219
+ ### Unrecognized Format
220
+ ```
221
+ Unrecognized token format. Use either a ForLoop API key (floop_*) or a valid JWT token.
222
+ ```
223
+
224
+ ### JWT in Local Context
225
+ ```
226
+ JWT tokens are only supported in Lambda execution. Please use a ForLoop API key (floop_*) for local execution.
227
+ ```
228
+
229
+ ## Backward Compatibility
230
+
231
+ ✅ **Existing functionality preserved:**
232
+ - `floop_*` tokens work in both local and Lambda
233
+ - `X-API-Token` header still used for API keys
234
+ - Token file location unchanged (`~/.config/forloop/tokens.json`)
235
+ - Profile support maintained
236
+
237
+ ✅ **New features:**
238
+ - JWT tokens now accepted in Lambda
239
+ - Automatic header selection based on token type
240
+ - Clear error messages for wrong token type in wrong context
241
+
242
+ ## Testing
243
+
244
+ ### Local Testing with API Key
245
+ ```bash
246
+ # Set API key
247
+ export FORLOOP_API_URL=https://api.forloop.cc
248
+ echo '{"default":"floop_test123"}' > ~/.config/forloop/tokens.json
249
+
250
+ # Run opencode locally
251
+ opencode run --agent forLoopPlanner -- "Create a story..."
252
+ ```
253
+
254
+ ### Lambda Testing with JWT
255
+ ```bash
256
+ # Lambda automatically detects execution context
257
+ # No manual configuration needed
258
+ # JWT passed from client → server_lambda → EventBridge → Lambda
259
+ ```
260
+
261
+ ### Type Detection Unit Test
262
+ ```typescript
263
+ import { detectTokenType } from './auth';
264
+
265
+ describe('detectTokenType', () => {
266
+ it('detects API key', () => {
267
+ expect(detectTokenType('floop_abc123')).toBe('api_key');
268
+ });
269
+
270
+ it('detects JWT', () => {
271
+ const jwt = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U';
272
+ expect(detectTokenType(jwt)).toBe('jwt');
273
+ });
274
+
275
+ it('rejects invalid format', () => {
276
+ expect(detectTokenType('invalid')).toBe(null);
277
+ expect(detectTokenType('')).toBe(null);
278
+ });
279
+ });
280
+ ```
281
+
282
+ ## Security Considerations
283
+
284
+ ### JWT Validation
285
+ - ✅ Format checked (3 parts, base64url encoding)
286
+ - ✅ Context checked (only in Lambda)
287
+ - ⚠️ Signature not validated (done by API server)
288
+ - ⚠️ Expiration not checked (done by API server)
289
+
290
+ ### API Key Validation
291
+ - ✅ Prefix checked (`floop_`)
292
+ - ✅ File permissions (`0o600`)
293
+ - ✅ Isolated in Lambda sandbox
294
+
295
+ ### Token Storage
296
+ - Lambda: Ephemeral `/tmp/` storage (cleared after execution)
297
+ - Local: Persistent `~/.config/forloop/` (user-managed)
298
+
299
+ ## Migration
300
+
301
+ **No migration required** - changes are fully backward compatible.
302
+
303
+ Existing users with `floop_*` tokens will continue to work without any changes.
304
+
305
+ ## Related Files
306
+
307
+ ### Core Authentication
308
+ - `plugins/capabilities/auth.ts` - Token validation and type detection
309
+ - `plugins/capabilities/config.ts` - Lambda detection
310
+ - `plugins/capabilities/api-client.ts` - HTTP client with dynamic headers
311
+ - `plugins/capabilities/token-storage.ts` - Token file management
312
+
313
+ ### Lambda
314
+ - `forloop-opencode-lambda-planner/src/lambda-handler.mjs` - JWT seeding (lines 92-108)
315
+
316
+ ### Tools
317
+ - All tools in `plugins/tools/*.ts` use `validateToken()` for authentication
@@ -0,0 +1,304 @@
1
+ # Installation Scripts Reference
2
+
3
+ This document describes the installation and update scripts for the ForLoop Plugin.
4
+
5
+ ## install.sh
6
+
7
+ One-line installation script for the ForLoop Plugin.
8
+
9
+ ### Quick Install
10
+
11
+ ```bash
12
+ curl -fsSL https://raw.githubusercontent.com/forloop-cc/forloop-opencode-plugin/main/install.sh | bash
13
+ ```
14
+
15
+ ### Usage
16
+
17
+ ```bash
18
+ # Interactive install (asks questions)
19
+ curl -fsSL https://raw.githubusercontent.com/forloop-cc/forloop-opencode-plugin/main/install.sh | bash
20
+
21
+ # Global install (all projects)
22
+ bash install.sh --global
23
+
24
+ # Local install (current project only)
25
+ bash install.sh --local
26
+
27
+ # Custom directory
28
+ bash install.sh --dir /path/to/plugins
29
+
30
+ # Force reinstall (overwrite existing)
31
+ bash install.sh --force
32
+ ```
33
+
34
+ ### Options
35
+
36
+ | Option | Description |
37
+ |--------|-------------|
38
+ | `-g, --global` | Install to `~/.config/opencode` (all projects) |
39
+ | `-l, --local` | Install to `.opencode` (current project) |
40
+ | `-d, --dir PATH` | Install to custom directory |
41
+ | `-f, --force` | Force installation (overwrite without asking) |
42
+ | `-h, --help` | Show help message |
43
+
44
+ ### What It Does
45
+
46
+ 1. **Checks prerequisites**
47
+ - git (required)
48
+ - Node.js (required for npm install)
49
+ - opencode CLI (optional, warns if missing)
50
+
51
+ 2. **Clones the plugin**
52
+ - Git clone from GitHub
53
+ - Shallow clone (faster)
54
+
55
+ 3. **Installs dependencies**
56
+ - Runs `npm install --production`
57
+ - No build step required (TypeScript runs directly)
58
+
59
+ 4. **Sets up token** (interactive only)
60
+ - Guides you through token creation
61
+ - Can optionally save token during install
62
+
63
+ 5. **Verifies installation**
64
+ - Checks entry point exists
65
+ - Provides next steps
66
+
67
+ ### Token Setup
68
+
69
+ During interactive installation, you can set up your API token:
70
+
71
+ 1. Script prompts: "Have you created a token? [y/N]"
72
+ 2. If yes, prompts for token value
73
+ 3. Saves to `~/.config/forloop/tokens.json`
74
+ 4. Sets permissions to `600` (secure)
75
+
76
+ **If you skip token setup:**
77
+ ```bash
78
+ forloopTokenSet --token floop_YOUR_TOKEN_HERE
79
+ ```
80
+
81
+ ### Prerequisites
82
+
83
+ | Requirement | Required? | Why |
84
+ |-------------|-----------|-----|
85
+ | git | ✅ Yes | Clones plugin repository |
86
+ | Node.js 18+ | ✅ Yes | Runs npm install |
87
+ | opencode CLI | ⚠️ Recommended | Using the plugin requires it |
88
+ | ForLoop account | ⚠️ Recommended | Need API token to use features |
89
+
90
+ ### Troubleshooting
91
+
92
+ **"git is required but not installed"**
93
+ ```bash
94
+ # macOS
95
+ brew install git
96
+
97
+ # Ubuntu/Debian
98
+ apt-get install git
99
+
100
+ # Windows
101
+ # Download from https://git-scm.com/download/win
102
+ ```
103
+
104
+ **"Node.js not found"**
105
+ ```bash
106
+ # Install from https://nodejs.org
107
+ # Or use nvm: https://github.com/nvm-sh/nvm
108
+ ```
109
+
110
+ **"Existing forloop plugin found"**
111
+ ```bash
112
+ # Use --force to overwrite
113
+ bash install.sh --force
114
+ ```
115
+
116
+ **Installation failed verification**
117
+ ```bash
118
+ # Check installation directory
119
+ ls -la ~/.config/opencode/plugins/forloop/
120
+ # Or for local:
121
+ ls -la .opencode/plugins/forloop/
122
+
123
+ # Entry point should exist:
124
+ # plugins/forloop/plugins/forloop-plugin.ts
125
+ ```
126
+
127
+ ---
128
+
129
+ ## update.sh
130
+
131
+ Update an existing ForLoop Plugin installation.
132
+
133
+ ### Quick Update
134
+
135
+ ```bash
136
+ # Auto-detect installation location
137
+ bash update.sh
138
+
139
+ # Update global installation
140
+ bash update.sh --global
141
+
142
+ # Update local installation
143
+ bash update.sh --local
144
+
145
+ # Update custom directory
146
+ bash update.sh --dir /path/to/plugins
147
+ ```
148
+
149
+ ### Usage
150
+
151
+ ```bash
152
+ # Check for updates and update if newer
153
+ bash update.sh
154
+
155
+ # Force update to latest version
156
+ bash update.sh --force
157
+
158
+ # Show changelog after update
159
+ bash update.sh --changelog
160
+
161
+ # Update and show changelog
162
+ bash update.sh --global --changelog
163
+ ```
164
+
165
+ ### Options
166
+
167
+ | Option | Description |
168
+ |--------|-------------|
169
+ | `-g, --global` | Update global installation (`~/.config/opencode`) |
170
+ | `-l, --local` | Update local installation (`.opencode`) |
171
+ | `-d, --dir PATH` | Update custom directory |
172
+ | `-f, --force` | Force update even if already up to date |
173
+ | `-c, --changelog` | Show changelog after update |
174
+ | `-h, --help` | Show help message |
175
+
176
+ ### What It Does
177
+
178
+ 1. **Finds installation**
179
+ - Checks global location
180
+ - Checks local location
181
+ - Or uses specified directory
182
+
183
+ 2. **Checks for updates**
184
+ - Fetches latest from git
185
+ - Compares current vs latest version
186
+ - Only updates if newer
187
+
188
+ 3. **Updates plugin**
189
+ - Switches to main branch
190
+ - Pulls latest changes or checks out tag
191
+ - Reinstalls dependencies
192
+
193
+ 4. **Verifies update**
194
+ - Checks entry point exists
195
+ - Shows changelog (if requested)
196
+
197
+ ### Update Behavior
198
+
199
+ **With tags (releases):**
200
+ - Updates to latest tagged version
201
+ - Example: `v2.2.0`
202
+
203
+ **Without tags (development):**
204
+ - Updates to latest commit on main branch
205
+
206
+ **Already up to date:**
207
+ - Script exits with "Already up to date!" message
208
+
209
+ **Force mode:**
210
+ - Reinstalls dependencies
211
+ - Useful if dependencies changed
212
+
213
+ ### Troubleshooting
214
+
215
+ **"No ForLoop plugin installation found"**
216
+ ```bash
217
+ # Specify directory explicitly
218
+ bash update.sh --dir ~/.config/opencode/plugins/forloop
219
+ ```
220
+
221
+ **"Not a git repository"**
222
+ ```bash
223
+ # Directory is not a git clone
224
+ # Reinstall instead:
225
+ bash install.sh --force
226
+ ```
227
+
228
+ **Update fails**
229
+ ```bash
230
+ # Reset to clean state
231
+ cd ~/.config/opencode/plugins/forloop
232
+ git reset --hard HEAD
233
+ git clean -fd
234
+
235
+ # Then update
236
+ bash update.sh --force
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Script Comparison
242
+
243
+ | Feature | install.sh | update.sh |
244
+ |---------|------------|-----------|
245
+ | Clone repository | ✅ Yes | ❌ No (already exists) |
246
+ | Install dependencies | ✅ Yes | ✅ Yes |
247
+ | Setup token | ✅ Interactive | ❌ No |
248
+ | Force mode | ✅ Overwrite | ✅ Reinstall |
249
+ | Find installation | ❌ Specify type | ✅ Auto-detect |
250
+ | Show changelog | ❌ No | ✅ Optional |
251
+ | Verify installation | ✅ Yes | ✅ Yes |
252
+
253
+ ---
254
+
255
+ ## Best Practices
256
+
257
+ ### For Users
258
+
259
+ 1. **Initial install:** Use `install.sh`
260
+ 2. **Updates:** Use `update.sh --changelog` to see what changed
261
+ 3. **Token setup:** Easiest to do during interactive install
262
+ 4. **Global vs Local:**
263
+ - Global: One install, all projects
264
+ - Local: Per-project, can use different versions
265
+
266
+ ### For Developers
267
+
268
+ 1. **Development:** Use `npm run install:local` for linking
269
+ 2. **Testing changes:** Edit files, run tests, then reinstall
270
+ 3. **Publish:** Use `npm publish`, then users can update
271
+
272
+ ### Production Deployments
273
+
274
+ For team deployments:
275
+
276
+ ```bash
277
+ #!/bin/bash
278
+ # deploy-forloop.sh
279
+
280
+ # Install globally on all team machines
281
+ curl -fsSL https://raw.githubusercontent.com/forloop-cc/forloop-opencode-plugin/main/install.sh | bash -s -- --global
282
+
283
+ # Set token (from secret manager)
284
+ export TOKEN=$(aws secretsmanager get-secret-value --secret-id forloop-token)
285
+ forloopTokenSet --token $TOKEN
286
+ ```
287
+
288
+ ---
289
+
290
+ ## Script Locations
291
+
292
+ | Location | Purpose |
293
+ |----------|---------|
294
+ | [install.sh](../install.sh) | Installation script |
295
+ | [update.sh](../update.sh) | Update script |
296
+ | [QUICKSTART-NON-DEV.md](QUICKSTART-NON-DEV.md) | User setup guide |
297
+
298
+ ---
299
+
300
+ ## Getting Help
301
+
302
+ - **Issues:** [GitHub Issues](https://github.com/forloop-cc/forloop-opencode-plugin/issues)
303
+ - **Documentation:** [docs/](../docs/)
304
+ - **Quick Start:** [QUICKSTART-NON-DEV.md](QUICKSTART-NON-DEV.md)
@@ -0,0 +1,88 @@
1
+ # Planner Agent Skill Improvements
2
+
3
+ ## Issues & Fixes
4
+
5
+ ### 1. Plugin Folder Structure ✅ VERIFIED
6
+
7
+ **Current Implementation** (lambda-handler.mjs:58-66):
8
+ ```javascript
9
+ function copyPluginRuntimeAssets(homeDir) {
10
+ copyDirRecursive('/var/task/forloop-opencode-plugin-planner/agent', runtimeAgentDir);
11
+ copyDirRecursive('/var/task/forloop-opencode-plugin-planner/skills', runtimeSkillsDir);
12
+ copyDirRecursive('/var/task/forloop-opencode-plugin-planner/plugins', runtimePluginsDir);
13
+ }
14
+ ```
15
+
16
+ **Target Locations**:
17
+ - Agents: `$HOME/.config/opencode/agent/` ✓ (opencode expects `agent/` not `agents/`)
18
+ - Skills: `$HOME/.config/opencode/skills/` ✓
19
+ - Plugins: `$HOME/.config/opencode/plugins/` ✓
20
+
21
+ **✅ Status**: Copied correctly! The opencode runtime uses `agent/` (singular) not `agents/`.
22
+
23
+ ### 2. Agent Selection (ID vs Name) ⚠️ NEEDS FIX
24
+
25
+ **Current** (lambda-handler.mjs:439):
26
+ ```javascript
27
+ const args = ['run', '--agent', agentId, '--', prompt];
28
+ ```
29
+
30
+ **Opencode expects**: Agent name (from agent definition), not ID
31
+
32
+ **Fix**:
33
+ ```javascript
34
+ // Use agent name from agent definition
35
+ const args = ['run', '--agent', agentName, '--', prompt];
36
+ ```
37
+
38
+ **Agent Definition** (forLoopPlanner.md):
39
+ ```markdown
40
+ ---
41
+ id: forLoopPlanner
42
+ name: ForLoop Planner ← THIS should be passed
43
+ ---
44
+ ```
45
+
46
+ ### 3. S3 Sync on Startup ❌ MISSING
47
+
48
+ **Problem**: `forloop-context` skill only checks local `.forloop/`, doesn't sync from S3 first
49
+
50
+ **Fix**: Update `forloop-context` skill to:
51
+ ```typescript
52
+ 1. Check if .forloop/manifest.json exists
53
+ 2. If NOT exists or empty:
54
+ - Call forloopSprintList to get sprints
55
+ - Call forloopSyncS3ToLocal to sync latest context
56
+ 3. Load context files
57
+ ```
58
+
59
+ ### 4. Story Creation with Doc Folder Link ❌ MISSING
60
+
61
+ **Problem**: `task-tracking` skill creates stories but doesn't link to doc_folder
62
+
63
+ **Fix**: Update `story-creation` and `task-tracking` skills:
64
+ ```typescript
65
+ 1. Before creating stories, get doc_folder ID
66
+ 2. Pass storyId: docFolderId to story creation
67
+ ```
68
+
69
+ ### 5. task.md Updates ❌ NOT TRACKED
70
+
71
+ **Problem**: After stories created, task.md not updated with story IDs
72
+
73
+ **Fix**: Update `task-tracking` skill to:
74
+ ```typescript
75
+ 1. After story creation, update task.md with:
76
+ - Story IDs
77
+ - Story titles
78
+ - Status (todo/in_progress/done)
79
+ 2. Upload updated task.md to S3
80
+ ```
81
+
82
+ ## Implementation Checklist
83
+
84
+ - [ ] Fix Lambda agent invocation (pass name not id)
85
+ - [ ] Update forloop-context skill (sync from S3)
86
+ - [ ] Update task-tracking skill (link doc_folder, update task.md)
87
+ - [ ] Update story-creation tool (accept storyId for linking)
88
+ - [ ] Test end-to-end flow