@forloop-cc/forloop-opencode-plugin-planner 2.2.8 → 2.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@forloop-cc/forloop-opencode-plugin-planner",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.10",
|
|
5
5
|
"description": "ForLoop integration plugin for opencode — Sprint, story, and agent tools for the ForLoop platform",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"prepublishOnly": "npm run typecheck && npm run lint",
|
|
63
63
|
"preversion": "npm run lint",
|
|
64
64
|
"version": "git add -A package.json",
|
|
65
|
-
"postversion": "
|
|
65
|
+
"postversion": "echo skip postversion"
|
|
66
66
|
},
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"access": "public"
|
|
@@ -309,6 +309,19 @@ export class ForLoopAPIClient {
|
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
async addStoryComment(storyId: number, body: string): Promise<any> {
|
|
313
|
+
return this.request(`/api/opencode/stories/${storyId}/comments`, {
|
|
314
|
+
method: 'POST',
|
|
315
|
+
body: JSON.stringify({ body }),
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async summarizeConversation(sprintId: number): Promise<any> {
|
|
320
|
+
return this.request(`/api/opencode/sprints/${sprintId}/summarize`, {
|
|
321
|
+
method: 'POST',
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
312
325
|
async listTemplates(): Promise<Template[]> {
|
|
313
326
|
return this.request('/api/opencode/templates');
|
|
314
327
|
}
|
|
@@ -67,17 +67,9 @@ import { createDeveloperStatusTool } from './tools/developer-status-tool';
|
|
|
67
67
|
import { injectEnvironment } from './hooks/shell-env';
|
|
68
68
|
import { createChatMessageHook, createEventHook } from './hooks/message-recorder';
|
|
69
69
|
|
|
70
|
-
// Named re-exports
|
|
71
|
-
|
|
72
|
-
export
|
|
73
|
-
export { getConfig, isLambdaExecution, PROD_API_URL, DEV_API_URL } from './capabilities/config';
|
|
74
|
-
export type { ForLoopConfig } from './capabilities/config';
|
|
75
|
-
export { getToken, setToken, clearToken } from './capabilities/token-storage';
|
|
76
|
-
export type { TokenProfile } from './capabilities/token-storage';
|
|
77
|
-
export { validateToken, detectTokenType } from './capabilities/auth';
|
|
78
|
-
export type { TokenValidationResult } from './capabilities/auth';
|
|
79
|
-
export { resolveSprintId, getCurrentBranch, resolveSprintFromBranch, getForloopRoot, getManifestPath } from './capabilities/context-resolver';
|
|
80
|
-
export type { ContextResolution } from './capabilities/context-resolver';
|
|
70
|
+
// Named re-exports moved to plugins/exports.ts because Bun's TypeScript
|
|
71
|
+
// transpiler in opencode-ai@1.15.6 fails when a file has both
|
|
72
|
+
// `export default async` and additional `export { }` / `export type { }` lines.
|
|
81
73
|
|
|
82
74
|
export default async (ctx: any) => {
|
|
83
75
|
const config = getConfig();
|
|
@@ -21,7 +21,9 @@ function normalizeAgentKey(agent: string): string {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function buildConversationId(sprintId: number, agent: string, sessionId: string): string {
|
|
24
|
-
|
|
24
|
+
const senderType = process.env.FORLOOP_SENDER_TYPE || 'user';
|
|
25
|
+
const senderId = process.env.FORLOOP_SENDER_ID || 'unknown';
|
|
26
|
+
return `sprint:${sprintId}:agent:${agent}:${senderType}:${senderId}`;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
function readActiveSprintId(): number | null {
|
|
@@ -49,12 +51,14 @@ async function recordAssistantMessage(
|
|
|
49
51
|
await new Promise((resolve) => setTimeout(resolve, 600 * i));
|
|
50
52
|
}
|
|
51
53
|
const result = await client.recordMessage(data);
|
|
52
|
-
// "no matching user message" is expected in Lambda — the server's
|
|
53
|
-
// handleAICallback creates the full Conversation record separately.
|
|
54
54
|
if (result?.message === 'no matching user message to update') {
|
|
55
|
-
console.log(`[ForLoop] No matching user message
|
|
55
|
+
console.log(`[ForLoop] No matching user message — user message may not be recorded yet`);
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
+
// After recording, try summarization (no-op if < 30 rounds)
|
|
59
|
+
client.summarizeConversation(data.sprintId).catch((err: Error) => {
|
|
60
|
+
console.warn('[ForLoop] Summarization trigger failed:', err.message);
|
|
61
|
+
});
|
|
58
62
|
return;
|
|
59
63
|
} catch (err: any) {
|
|
60
64
|
console.warn(`[ForLoop] Attempt ${i + 1}/${attempts} failed:`, err.message);
|
|
@@ -90,8 +94,6 @@ export function createChatMessageHook(client: ForLoopAPIClient) {
|
|
|
90
94
|
preview: content.substring(0, 300),
|
|
91
95
|
});
|
|
92
96
|
}
|
|
93
|
-
// Only record on user's local machine; Lambda records via its own system
|
|
94
|
-
if (isLambdaExecution()) return;
|
|
95
97
|
|
|
96
98
|
// Only record messages with a model (indicates actual LLM processing,
|
|
97
99
|
// not system events like context compaction or summary generation)
|
|
@@ -227,9 +229,7 @@ export function createEventHook(client: ForLoopAPIClient) {
|
|
|
227
229
|
return;
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
//
|
|
231
|
-
if (isLambda) return;
|
|
232
|
-
|
|
232
|
+
// Record messages (works for local and Lambda)
|
|
233
233
|
switch (event.type) {
|
|
234
234
|
case 'message.part.updated': {
|
|
235
235
|
const part = event.properties?.part;
|