@codemieai/code 0.0.33 → 0.0.34
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/README.md +73 -7
- package/bin/codemie-opencode.js +11 -0
- package/dist/agents/codemie-code/agent.d.ts +17 -1
- package/dist/agents/codemie-code/agent.d.ts.map +1 -1
- package/dist/agents/codemie-code/agent.js +62 -3
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/index.d.ts +1 -0
- package/dist/agents/codemie-code/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/index.js +28 -2
- package/dist/agents/codemie-code/index.js.map +1 -1
- package/dist/agents/codemie-code/prompts.d.ts +12 -3
- package/dist/agents/codemie-code/prompts.d.ts.map +1 -1
- package/dist/agents/codemie-code/prompts.js +25 -5
- package/dist/agents/codemie-code/prompts.js.map +1 -1
- package/dist/agents/codemie-code/types.d.ts +3 -0
- package/dist/agents/codemie-code/types.d.ts.map +1 -1
- package/dist/agents/codemie-code/types.js.map +1 -1
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +3 -1
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +33 -0
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/session/BaseSessionAdapter.d.ts +25 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
- package/dist/agents/core/session/discovery-types.d.ts +53 -0
- package/dist/agents/core/session/discovery-types.d.ts.map +1 -0
- package/dist/agents/core/session/discovery-types.js +8 -0
- package/dist/agents/core/session/discovery-types.js.map +1 -0
- package/dist/agents/core/types.d.ts +45 -0
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts +44 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +214 -0
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/claude/plugin/README.md +40 -2
- package/dist/agents/plugins/claude/plugin/claude-templates/README.md +5 -5
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +177 -436
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +49 -82
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/refactor-cleaner-agent.md.template +337 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +129 -419
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +146 -693
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +110 -138
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/architecture.md.template +197 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +171 -91
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +219 -131
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +223 -98
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +131 -95
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +247 -75
- package/dist/agents/plugins/claude/plugin/commands/README.md +133 -0
- package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +336 -544
- package/dist/agents/plugins/claude/plugin/commands/codemie-subagents.md +232 -503
- package/dist/agents/plugins/claude/plugin/commands/memory-add.md +311 -30
- package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +218 -39
- package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/gemini/gemini.plugin.js +0 -3
- package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
- package/dist/agents/plugins/opencode/index.d.ts +8 -0
- package/dist/agents/plugins/opencode/index.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/index.js +12 -0
- package/dist/agents/plugins/opencode/index.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts +207 -0
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode-message-types.js +59 -0
- package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.d.ts +65 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.js +184 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.paths.d.ts +62 -0
- package/dist/agents/plugins/opencode/opencode.paths.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.paths.js +148 -0
- package/dist/agents/plugins/opencode/opencode.paths.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.plugin.d.ts +35 -0
- package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.plugin.js +338 -0
- package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.session.d.ts +77 -0
- package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.session.js +424 -0
- package/dist/agents/plugins/opencode/opencode.session.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts +25 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.js +96 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts +30 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js +116 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +102 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +584 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -0
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +2 -0
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +5 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/AgentsCheck.js +29 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +86 -7
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/opencode-metrics.d.ts +13 -0
- package/dist/cli/commands/opencode-metrics.d.ts.map +1 -0
- package/dist/cli/commands/opencode-metrics.js +200 -0
- package/dist/cli/commands/opencode-metrics.js.map +1 -0
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +113 -0
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/skill.d.ts +6 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +196 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +34 -6
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/migrations/003-remove-hooks-node.migration.d.ts +22 -0
- package/dist/migrations/003-remove-hooks-node.migration.d.ts.map +1 -0
- package/dist/migrations/003-remove-hooks-node.migration.js +103 -0
- package/dist/migrations/003-remove-hooks-node.migration.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +1 -1
- package/dist/migrations/index.js.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js +2 -2
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.setup-steps.js +14 -10
- package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
- package/dist/skills/core/SkillDiscovery.d.ts +83 -0
- package/dist/skills/core/SkillDiscovery.d.ts.map +1 -0
- package/dist/skills/core/SkillDiscovery.js +237 -0
- package/dist/skills/core/SkillDiscovery.js.map +1 -0
- package/dist/skills/core/SkillManager.d.ts +86 -0
- package/dist/skills/core/SkillManager.d.ts.map +1 -0
- package/dist/skills/core/SkillManager.js +155 -0
- package/dist/skills/core/SkillManager.js.map +1 -0
- package/dist/skills/core/types.d.ts +120 -0
- package/dist/skills/core/types.d.ts.map +1 -0
- package/dist/skills/core/types.js +20 -0
- package/dist/skills/core/types.js.map +1 -0
- package/dist/skills/index.d.ts +12 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +12 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/utils/content-loader.d.ts +25 -0
- package/dist/skills/utils/content-loader.d.ts.map +1 -0
- package/dist/skills/utils/content-loader.js +161 -0
- package/dist/skills/utils/content-loader.js.map +1 -0
- package/dist/skills/utils/frontmatter.d.ts +60 -0
- package/dist/skills/utils/frontmatter.d.ts.map +1 -0
- package/dist/skills/utils/frontmatter.js +114 -0
- package/dist/skills/utils/frontmatter.js.map +1 -0
- package/dist/skills/utils/pattern-matcher.d.ts +60 -0
- package/dist/skills/utils/pattern-matcher.d.ts.map +1 -0
- package/dist/skills/utils/pattern-matcher.js +97 -0
- package/dist/skills/utils/pattern-matcher.js.map +1 -0
- package/dist/utils/installation-detector.d.ts +22 -0
- package/dist/utils/installation-detector.d.ts.map +1 -0
- package/dist/utils/installation-detector.js +49 -0
- package/dist/utils/installation-detector.js.map +1 -0
- package/dist/utils/native-installer.d.ts +49 -0
- package/dist/utils/native-installer.d.ts.map +1 -0
- package/dist/utils/native-installer.js +194 -0
- package/dist/utils/native-installer.js.map +1 -0
- package/dist/utils/version-utils.d.ts +50 -0
- package/dist/utils/version-utils.d.ts.map +1 -0
- package/dist/utils/version-utils.js +92 -0
- package/dist/utils/version-utils.js.map +1 -0
- package/package.json +5 -2
- package/scripts/copy-mr-skill-to-global.ts +252 -0
- package/scripts/demo-hooks.sh +125 -0
- package/scripts/test-hooks.sh +196 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/INDEX.md +0 -205
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/TEMPLATE_SIZES.md +0 -74
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/layered-architecture.md.template +0 -143
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/project-structure.md.template +0 -127
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
// src/agents/plugins/opencode/opencode.session.ts
|
|
2
|
+
import { readFile, readdir, stat } from 'fs/promises';
|
|
3
|
+
import { join, dirname, sep } from 'path';
|
|
4
|
+
import { existsSync } from 'fs';
|
|
5
|
+
import { getOpenCodeSessionsPath } from './opencode.paths.js';
|
|
6
|
+
import { logger } from '../../../utils/logger.js';
|
|
7
|
+
import { OpenCodeMetricsProcessor } from './session/processors/opencode.metrics-processor.js';
|
|
8
|
+
import { OpenCodeConversationsProcessor } from './session/processors/opencode.conversations-processor.js';
|
|
9
|
+
// Retry config per tech spec "F10 FIX" (FIXED per GPT-5.5 review):
|
|
10
|
+
// - 1 initial read + 3 retries = 4 total read attempts
|
|
11
|
+
// - Retry on ENOENT (file not found during concurrent write) and SyntaxError (partial JSON)
|
|
12
|
+
// - Sleep delays AFTER each failed attempt: 50ms, 100ms, 200ms
|
|
13
|
+
// - Total budget ~350ms (50+100+200 = 350ms of sleep time)
|
|
14
|
+
const RETRY_CONFIG = {
|
|
15
|
+
maxAttempts: 4, // 1 initial + 3 retries
|
|
16
|
+
delays: [50, 100, 200], // Sleep after attempts 1, 2, 3 (not after attempt 4)
|
|
17
|
+
};
|
|
18
|
+
function sleep(ms) {
|
|
19
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read JSON file with retry on concurrent write errors
|
|
23
|
+
* Per tech spec "F10 FIX" (FIXED per GPT-5.5 review):
|
|
24
|
+
* - 1 initial + 3 retries = 4 total attempts
|
|
25
|
+
* - Sleep 50/100/200ms after each failed attempt (except last)
|
|
26
|
+
*/
|
|
27
|
+
async function readJsonWithRetry(filePath) {
|
|
28
|
+
for (let attempt = 0; attempt < RETRY_CONFIG.maxAttempts; attempt++) {
|
|
29
|
+
try {
|
|
30
|
+
const content = await readFile(filePath, 'utf-8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const err = error;
|
|
35
|
+
// Check for retryable errors:
|
|
36
|
+
// - ENOENT: file temporarily missing during concurrent write
|
|
37
|
+
// - SyntaxError: partial JSON from interrupted write
|
|
38
|
+
const isRetryable = err.code === 'ENOENT' || err.name === 'SyntaxError';
|
|
39
|
+
if (!isRetryable) {
|
|
40
|
+
// Non-retryable error, fail immediately
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
// Sleep before next attempt (if not last attempt)
|
|
44
|
+
// attempt 0 -> sleep 50ms, attempt 1 -> sleep 100ms, attempt 2 -> sleep 200ms
|
|
45
|
+
if (attempt < RETRY_CONFIG.maxAttempts - 1) {
|
|
46
|
+
await sleep(RETRY_CONFIG.delays[attempt]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// All 4 attempts exhausted
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* OpenCode Session Adapter
|
|
55
|
+
*
|
|
56
|
+
* Parses OpenCode session files from ~/.local/share/opencode/storage/
|
|
57
|
+
* Implements SessionAdapter interface with processor chain pattern.
|
|
58
|
+
*/
|
|
59
|
+
export class OpenCodeSessionAdapter {
|
|
60
|
+
metadata;
|
|
61
|
+
agentName = 'opencode';
|
|
62
|
+
processors = [];
|
|
63
|
+
constructor(metadata) {
|
|
64
|
+
this.metadata = metadata;
|
|
65
|
+
if (!metadata.dataPaths?.home) {
|
|
66
|
+
throw new Error('Agent metadata must provide dataPaths.home');
|
|
67
|
+
}
|
|
68
|
+
this.initializeProcessors();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Initialize processors for this adapter.
|
|
72
|
+
* Processors run in priority order: metrics (1), conversations (2)
|
|
73
|
+
*/
|
|
74
|
+
initializeProcessors() {
|
|
75
|
+
this.registerProcessor(new OpenCodeMetricsProcessor());
|
|
76
|
+
this.registerProcessor(new OpenCodeConversationsProcessor());
|
|
77
|
+
logger.debug(`[opencode-adapter] Initialized ${this.processors.length} processors`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Register a processor to run during session processing.
|
|
81
|
+
*/
|
|
82
|
+
registerProcessor(processor) {
|
|
83
|
+
this.processors.push(processor);
|
|
84
|
+
this.processors.sort((a, b) => a.priority - b.priority);
|
|
85
|
+
logger.debug(`[opencode-adapter] Registered processor: ${processor.name} (priority: ${processor.priority})`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Parse OpenCode session file to unified ParsedSession format.
|
|
89
|
+
*
|
|
90
|
+
* UPDATED (GPT-5.9): OpenCode uses numeric timestamps (time.created/time.updated)
|
|
91
|
+
* not ISO strings. We convert to ISO for CodeMie's canonical format.
|
|
92
|
+
*/
|
|
93
|
+
async parseSessionFile(filePath, sessionId) {
|
|
94
|
+
try {
|
|
95
|
+
// Validate path shape before proceeding (GPT-5.8 fix)
|
|
96
|
+
// Expected: .../storage/session/{projectId}/{sessionId}.json
|
|
97
|
+
if (!this.isValidSessionPath(filePath)) {
|
|
98
|
+
logger.warn(`[opencode-adapter] Unexpected session path format: ${filePath}`);
|
|
99
|
+
// Continue anyway, but path calculations may fail
|
|
100
|
+
}
|
|
101
|
+
// Read session JSON
|
|
102
|
+
const session = await readJsonWithRetry(filePath);
|
|
103
|
+
if (!session) {
|
|
104
|
+
throw new Error(`Failed to read session file: ${filePath}`);
|
|
105
|
+
}
|
|
106
|
+
// Load messages from message/{sessionId}/*.json
|
|
107
|
+
const messages = await this.loadMessages(filePath, session.id);
|
|
108
|
+
// Extract metrics from messages
|
|
109
|
+
const metrics = this.extractMetrics(messages);
|
|
110
|
+
logger.debug(`[opencode-adapter] Parsed session ${sessionId}: ${messages.length} messages, ` +
|
|
111
|
+
`${metrics?.tokens?.input || 0} input tokens, ${metrics?.tokens?.output || 0} output tokens`);
|
|
112
|
+
// UPDATED (GPT-5.9): Convert numeric timestamps to ISO strings
|
|
113
|
+
// OpenCode uses time.created/time.updated (numbers in ms)
|
|
114
|
+
// CodeMie ParsedSession expects ISO strings
|
|
115
|
+
// UPDATED (GPT-5.11): Use session.directory if available for projectPath
|
|
116
|
+
// UPDATED (tech-spec ADR-1): Add storagePath and openCodeSessionId for metrics processor
|
|
117
|
+
const storagePath = dirname(dirname(dirname(filePath)));
|
|
118
|
+
// Build metadata with OpenCode-specific extensions (ADR-1)
|
|
119
|
+
// Cast to `any` to allow custom fields within OpenCode plugin boundary
|
|
120
|
+
const metadata = {
|
|
121
|
+
// Prefer session.directory (actual path) over extracted projectId (hash)
|
|
122
|
+
projectPath: session.directory || this.extractProjectPath(filePath),
|
|
123
|
+
createdAt: session.time?.created
|
|
124
|
+
? new Date(session.time.created).toISOString()
|
|
125
|
+
: undefined,
|
|
126
|
+
updatedAt: session.time?.updated
|
|
127
|
+
? new Date(session.time.updated).toISOString()
|
|
128
|
+
: undefined,
|
|
129
|
+
// Per tech spec ADR-1: Expose storage path and OpenCode session ID for metrics processor
|
|
130
|
+
storagePath,
|
|
131
|
+
openCodeSessionId: session.id,
|
|
132
|
+
openCodeVersion: session.version
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
sessionId,
|
|
136
|
+
agentName: this.metadata.displayName || 'opencode',
|
|
137
|
+
metadata,
|
|
138
|
+
messages, // Raw messages for processors
|
|
139
|
+
metrics
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
logger.error(`[opencode-adapter] Failed to parse session file ${filePath}:`, error);
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Validate session path has expected structure (GPT-5.8 fix, updated GPT-5.10/5.11)
|
|
149
|
+
* Expected: .../storage/session/{projectId}/{sessionId}.json
|
|
150
|
+
*
|
|
151
|
+
* FIXED (GPT-5.10/5.11): Use path.sep for cross-platform compatibility
|
|
152
|
+
*/
|
|
153
|
+
isValidSessionPath(filePath) {
|
|
154
|
+
// Handle both platform-specific separators and forward slashes
|
|
155
|
+
const parts = filePath.split(sep);
|
|
156
|
+
const partsAlt = filePath.split('/');
|
|
157
|
+
const effectiveParts = parts.length > partsAlt.length ? parts : partsAlt;
|
|
158
|
+
// Should have at least: .../, storage, session, {projectId}, {sessionId}.json
|
|
159
|
+
const sessionIdx = effectiveParts.indexOf('session');
|
|
160
|
+
if (sessionIdx === -1)
|
|
161
|
+
return false;
|
|
162
|
+
// session should be followed by projectId and sessionId.json
|
|
163
|
+
return effectiveParts.length > sessionIdx + 2;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Extract project path from session file path
|
|
167
|
+
* Session path: .../storage/session/{projectId}/{sessionId}.json
|
|
168
|
+
* Project ID is typically git root commit hash
|
|
169
|
+
*
|
|
170
|
+
* FIXED (GPT-5.10/5.11): Use path module for cross-platform compatibility
|
|
171
|
+
* UPDATED (GPT-5.11): Prefer session.directory over path extraction when available
|
|
172
|
+
*/
|
|
173
|
+
extractProjectPath(filePath) {
|
|
174
|
+
// Handle both platform-specific separators and forward slashes
|
|
175
|
+
const parts = filePath.split(sep);
|
|
176
|
+
const partsAlt = filePath.split('/');
|
|
177
|
+
const effectiveParts = parts.length > partsAlt.length ? parts : partsAlt;
|
|
178
|
+
const sessionIdx = effectiveParts.indexOf('session');
|
|
179
|
+
if (sessionIdx !== -1 && effectiveParts.length > sessionIdx + 1) {
|
|
180
|
+
// Return projectId (may be git hash or 'global')
|
|
181
|
+
return effectiveParts[sessionIdx + 1];
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Load messages for a session from message/{sessionId}/*.json
|
|
187
|
+
*
|
|
188
|
+
* Path calculation (FIXED per GPT-5.5 review):
|
|
189
|
+
* - sessionFilePath = .../storage/session/{projectId}/{sessionId}.json
|
|
190
|
+
* - dirname(sessionFilePath) = .../storage/session/{projectId}
|
|
191
|
+
* - dirname(dirname(sessionFilePath)) = .../storage/session
|
|
192
|
+
* - dirname(dirname(dirname(sessionFilePath))) = .../storage ← CORRECT base
|
|
193
|
+
* - messagesDir = .../storage/message/{sessionId}
|
|
194
|
+
*/
|
|
195
|
+
async loadMessages(sessionFilePath, sessionId) {
|
|
196
|
+
// Go up THREE levels from session/{projectId}/{sessionId}.json to get to storage/
|
|
197
|
+
const storagePath = dirname(dirname(dirname(sessionFilePath)));
|
|
198
|
+
const messagesDir = join(storagePath, 'message', sessionId);
|
|
199
|
+
if (!existsSync(messagesDir)) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
const messages = [];
|
|
203
|
+
try {
|
|
204
|
+
const files = await readdir(messagesDir);
|
|
205
|
+
for (const file of files) {
|
|
206
|
+
if (!file.endsWith('.json'))
|
|
207
|
+
continue;
|
|
208
|
+
const msg = await readJsonWithRetry(join(messagesDir, file));
|
|
209
|
+
if (msg)
|
|
210
|
+
messages.push(msg);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
logger.debug(`[opencode-adapter] No messages directory: ${messagesDir}`);
|
|
215
|
+
}
|
|
216
|
+
// UPDATED (GPT-5.9): Sort by time.created (numeric timestamp)
|
|
217
|
+
return messages.sort((a, b) => {
|
|
218
|
+
const aTime = a.time?.created || 0;
|
|
219
|
+
const bTime = b.time?.created || 0;
|
|
220
|
+
return aTime - bTime;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Extract metrics from OpenCode messages.
|
|
225
|
+
*
|
|
226
|
+
* UPDATED (GPT-5.9): Use isAssistantMessage type guard for safe access
|
|
227
|
+
* to assistant-specific fields (tokens, cost, etc.)
|
|
228
|
+
*/
|
|
229
|
+
extractMetrics(messages) {
|
|
230
|
+
let inputTokens = 0;
|
|
231
|
+
let outputTokens = 0;
|
|
232
|
+
let cacheReadTokens = 0;
|
|
233
|
+
let cacheWriteTokens = 0;
|
|
234
|
+
const toolCounts = {};
|
|
235
|
+
for (const msg of messages) {
|
|
236
|
+
// UPDATED (GPT-5.9): Type-safe access to assistant message fields
|
|
237
|
+
if (msg.role === 'assistant') {
|
|
238
|
+
const assistantMsg = msg;
|
|
239
|
+
if (assistantMsg.tokens) {
|
|
240
|
+
inputTokens += assistantMsg.tokens.input || 0;
|
|
241
|
+
outputTokens += assistantMsg.tokens.output || 0;
|
|
242
|
+
cacheReadTokens += assistantMsg.tokens.cache?.read || 0;
|
|
243
|
+
cacheWriteTokens += assistantMsg.tokens.cache?.write || 0;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Tool counting would require loading parts - defer to processor
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
tokens: {
|
|
250
|
+
input: inputTokens,
|
|
251
|
+
output: outputTokens,
|
|
252
|
+
cacheRead: cacheReadTokens,
|
|
253
|
+
cacheWrite: cacheWriteTokens
|
|
254
|
+
},
|
|
255
|
+
tools: toolCounts,
|
|
256
|
+
toolStatus: {},
|
|
257
|
+
fileOperations: []
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Process session with all registered processors.
|
|
262
|
+
*/
|
|
263
|
+
async processSession(filePath, sessionId, context) {
|
|
264
|
+
try {
|
|
265
|
+
logger.debug(`[opencode-adapter] Processing session ${sessionId} with ${this.processors.length} processors`);
|
|
266
|
+
// 1. Parse session once
|
|
267
|
+
const parsedSession = await this.parseSessionFile(filePath, sessionId);
|
|
268
|
+
// 2. Run processors in priority order
|
|
269
|
+
const processorResults = {};
|
|
270
|
+
const failedProcessors = [];
|
|
271
|
+
let totalRecords = 0;
|
|
272
|
+
for (const processor of this.processors) {
|
|
273
|
+
try {
|
|
274
|
+
if (!processor.shouldProcess(parsedSession)) {
|
|
275
|
+
logger.debug(`[opencode-adapter] Processor ${processor.name} skipped`);
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
logger.debug(`[opencode-adapter] Running processor: ${processor.name}`);
|
|
279
|
+
const result = await processor.process(parsedSession, context);
|
|
280
|
+
processorResults[processor.name] = {
|
|
281
|
+
success: result.success,
|
|
282
|
+
message: result.message,
|
|
283
|
+
recordsProcessed: result.metadata?.recordsProcessed
|
|
284
|
+
};
|
|
285
|
+
if (!result.success) {
|
|
286
|
+
failedProcessors.push(processor.name);
|
|
287
|
+
logger.warn(`[opencode-adapter] Processor ${processor.name} failed: ${result.message}`);
|
|
288
|
+
}
|
|
289
|
+
const recordsProcessed = result.metadata?.recordsProcessed;
|
|
290
|
+
if (typeof recordsProcessed === 'number') {
|
|
291
|
+
totalRecords += recordsProcessed;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
296
|
+
logger.error(`[opencode-adapter] Processor ${processor.name} threw:`, error);
|
|
297
|
+
processorResults[processor.name] = { success: false, message: errorMessage };
|
|
298
|
+
failedProcessors.push(processor.name);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
success: failedProcessors.length === 0,
|
|
303
|
+
processors: processorResults,
|
|
304
|
+
totalRecords,
|
|
305
|
+
failedProcessors
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
logger.error(`[opencode-adapter] Session processing failed:`, error);
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Discover OpenCode sessions with filtering
|
|
315
|
+
*
|
|
316
|
+
* Scans XDG_DATA_HOME/opencode/storage/session/{projectID}/{sessionID}.json
|
|
317
|
+
* Applies 30-day default filter and optional cwd filter.
|
|
318
|
+
*/
|
|
319
|
+
async discoverSessions(options) {
|
|
320
|
+
const sessionsPath = getOpenCodeSessionsPath();
|
|
321
|
+
if (!sessionsPath) {
|
|
322
|
+
logger.debug('[opencode-discovery] Sessions path not found (OpenCode not installed?)');
|
|
323
|
+
return [];
|
|
324
|
+
}
|
|
325
|
+
// Calculate cutoff timestamp
|
|
326
|
+
const maxAgeDays = options?.maxAgeDays ?? 30; // Default: 30 days
|
|
327
|
+
const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
|
|
328
|
+
const cutoffTimestamp = Date.now() - maxAgeMs;
|
|
329
|
+
// Normalize cwd for comparison (remove trailing slash)
|
|
330
|
+
const normalizedCwd = options?.cwd?.replace(/\/+$/, '');
|
|
331
|
+
const results = [];
|
|
332
|
+
try {
|
|
333
|
+
// Scan project directories
|
|
334
|
+
const projectDirs = await readdir(sessionsPath);
|
|
335
|
+
for (const projectId of projectDirs) {
|
|
336
|
+
const projectPath = join(sessionsPath, projectId);
|
|
337
|
+
// Skip non-directories
|
|
338
|
+
try {
|
|
339
|
+
const projectStat = await stat(projectPath);
|
|
340
|
+
if (!projectStat.isDirectory())
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
// Scan session files in project directory
|
|
347
|
+
let sessionFiles;
|
|
348
|
+
try {
|
|
349
|
+
sessionFiles = await readdir(projectPath);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
for (const file of sessionFiles) {
|
|
355
|
+
// Only process .json files
|
|
356
|
+
if (!file.endsWith('.json'))
|
|
357
|
+
continue;
|
|
358
|
+
const filePath = join(projectPath, file);
|
|
359
|
+
const sessionId = file.replace('.json', '');
|
|
360
|
+
try {
|
|
361
|
+
// Read session file with retry (handles concurrent writes)
|
|
362
|
+
const session = await readJsonWithRetry(filePath);
|
|
363
|
+
if (!session) {
|
|
364
|
+
logger.debug(`[opencode-discovery] Skipping unreadable session: ${sessionId}`);
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
// Extract timestamp (OpenCode uses numeric milliseconds)
|
|
368
|
+
const createdAt = session.time?.created;
|
|
369
|
+
const updatedAt = session.time?.updated;
|
|
370
|
+
// Skip sessions without timestamps (unless explicitly included)
|
|
371
|
+
if (typeof createdAt !== 'number') {
|
|
372
|
+
if (!options?.includeTimestampless) {
|
|
373
|
+
logger.debug(`[opencode-discovery] Skipping session without timestamp: ${sessionId}`);
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Apply 30-day filter
|
|
378
|
+
if (typeof createdAt === 'number' && createdAt < cutoffTimestamp) {
|
|
379
|
+
logger.debug(`[opencode-discovery] Skipping old session: ${sessionId} (created: ${new Date(createdAt).toISOString()})`);
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
// Apply cwd filter using session.directory
|
|
383
|
+
if (normalizedCwd && session.directory) {
|
|
384
|
+
const normalizedDir = session.directory.replace(/\/+$/, '');
|
|
385
|
+
if (normalizedDir !== normalizedCwd) {
|
|
386
|
+
logger.debug(`[opencode-discovery] Skipping session from different cwd: ${sessionId} (${normalizedDir} !== ${normalizedCwd})`);
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// Add to results
|
|
391
|
+
results.push({
|
|
392
|
+
sessionId,
|
|
393
|
+
filePath,
|
|
394
|
+
projectPath: session.directory,
|
|
395
|
+
createdAt: createdAt ?? 0,
|
|
396
|
+
updatedAt: typeof updatedAt === 'number' ? updatedAt : undefined,
|
|
397
|
+
agentName: 'opencode'
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
// Skip sessions that fail to parse
|
|
402
|
+
logger.debug(`[opencode-discovery] Error parsing session ${sessionId}:`, error);
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Sort by createdAt descending (newest first)
|
|
408
|
+
results.sort((a, b) => b.createdAt - a.createdAt);
|
|
409
|
+
// Apply limit
|
|
410
|
+
if (options?.limit && options.limit > 0) {
|
|
411
|
+
const limited = results.slice(0, options.limit);
|
|
412
|
+
logger.debug(`[opencode-discovery] Found ${results.length} sessions, returning ${limited.length} (limit: ${options.limit})`);
|
|
413
|
+
return limited;
|
|
414
|
+
}
|
|
415
|
+
logger.debug(`[opencode-discovery] Found ${results.length} sessions`);
|
|
416
|
+
return results;
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
logger.error('[opencode-discovery] Failed to scan sessions directory:', error);
|
|
420
|
+
return [];
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
//# sourceMappingURL=opencode.session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.session.js","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Storage Utilities
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for reading OpenCode storage files.
|
|
5
|
+
* Used by both session adapter and metrics processor to avoid coupling.
|
|
6
|
+
* Per tech spec ADR-11.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Read JSON file with retry on transient errors (ENOENT, SyntaxError from partial write).
|
|
10
|
+
* Shared by session adapter and metrics processor.
|
|
11
|
+
*
|
|
12
|
+
* Per tech spec "F10 FIX":
|
|
13
|
+
* - 1 initial + 3 retries = 4 total attempts
|
|
14
|
+
* - Sleep 50/100/200ms after each failed attempt (except last)
|
|
15
|
+
*/
|
|
16
|
+
export declare function readJsonWithRetry<T>(filePath: string, maxRetries?: number, retryDelayMs?: number): Promise<T | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Tolerant JSONL reading - skips corrupted lines instead of failing.
|
|
19
|
+
* Per tech spec ADR-5 for deduplication robustness.
|
|
20
|
+
*
|
|
21
|
+
* @param filePath Path to JSONL file
|
|
22
|
+
* @returns Array of parsed records (corrupted lines skipped)
|
|
23
|
+
*/
|
|
24
|
+
export declare function readJsonlTolerant<T>(filePath: string): Promise<T[]>;
|
|
25
|
+
//# sourceMappingURL=opencode.storage-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.storage-utils.d.ts","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.storage-utils.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AAkBH;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,UAAU,SAA2B,EACrC,YAAY,SAAyB,GACpC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA6BnB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CA6BzE"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// src/agents/plugins/opencode/opencode.storage-utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* OpenCode Storage Utilities
|
|
4
|
+
*
|
|
5
|
+
* Shared utilities for reading OpenCode storage files.
|
|
6
|
+
* Used by both session adapter and metrics processor to avoid coupling.
|
|
7
|
+
* Per tech spec ADR-11.
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from 'fs/promises';
|
|
10
|
+
import { logger } from '../../../utils/logger.js';
|
|
11
|
+
// Retry config per tech spec "F10 FIX":
|
|
12
|
+
// - 1 initial read + 3 retries = 4 total read attempts
|
|
13
|
+
// - Retry on ENOENT (file not found during concurrent write) and SyntaxError (partial JSON)
|
|
14
|
+
// - Sleep delays AFTER each failed attempt: 50ms, 100ms, 200ms
|
|
15
|
+
const RETRY_CONFIG = {
|
|
16
|
+
maxAttempts: 4, // 1 initial + 3 retries
|
|
17
|
+
delays: [50, 100, 200], // Sleep after attempts 1, 2, 3 (not after attempt 4)
|
|
18
|
+
};
|
|
19
|
+
function sleep(ms) {
|
|
20
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read JSON file with retry on transient errors (ENOENT, SyntaxError from partial write).
|
|
24
|
+
* Shared by session adapter and metrics processor.
|
|
25
|
+
*
|
|
26
|
+
* Per tech spec "F10 FIX":
|
|
27
|
+
* - 1 initial + 3 retries = 4 total attempts
|
|
28
|
+
* - Sleep 50/100/200ms after each failed attempt (except last)
|
|
29
|
+
*/
|
|
30
|
+
export async function readJsonWithRetry(filePath, maxRetries = RETRY_CONFIG.maxAttempts, retryDelayMs = RETRY_CONFIG.delays[0]) {
|
|
31
|
+
const delays = [retryDelayMs, retryDelayMs * 2, retryDelayMs * 4];
|
|
32
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
33
|
+
try {
|
|
34
|
+
const content = await readFile(filePath, 'utf-8');
|
|
35
|
+
return JSON.parse(content);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const err = error;
|
|
39
|
+
// Check for retryable errors:
|
|
40
|
+
// - ENOENT: file temporarily missing during concurrent write
|
|
41
|
+
// - SyntaxError: partial JSON from interrupted write
|
|
42
|
+
const isRetryable = err.code === 'ENOENT' || err.name === 'SyntaxError';
|
|
43
|
+
if (!isRetryable) {
|
|
44
|
+
// Non-retryable error, fail immediately
|
|
45
|
+
logger.debug(`[opencode-storage] Failed to read ${filePath}: ${err.message}`);
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// Sleep before next attempt (if not last attempt)
|
|
49
|
+
if (attempt < maxRetries - 1) {
|
|
50
|
+
await sleep(delays[attempt] || delays[delays.length - 1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// All attempts exhausted
|
|
55
|
+
logger.debug(`[opencode-storage] All ${maxRetries} attempts exhausted for ${filePath}`);
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Tolerant JSONL reading - skips corrupted lines instead of failing.
|
|
60
|
+
* Per tech spec ADR-5 for deduplication robustness.
|
|
61
|
+
*
|
|
62
|
+
* @param filePath Path to JSONL file
|
|
63
|
+
* @returns Array of parsed records (corrupted lines skipped)
|
|
64
|
+
*/
|
|
65
|
+
export async function readJsonlTolerant(filePath) {
|
|
66
|
+
try {
|
|
67
|
+
const content = await readFile(filePath, 'utf-8');
|
|
68
|
+
const lines = content.trim().split('\n');
|
|
69
|
+
const results = [];
|
|
70
|
+
let corruptedCount = 0;
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
if (!line.trim())
|
|
73
|
+
continue;
|
|
74
|
+
try {
|
|
75
|
+
results.push(JSON.parse(line));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
corruptedCount++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (corruptedCount > 0) {
|
|
82
|
+
logger.warn(`[opencode-storage] Skipped ${corruptedCount} corrupted JSONL lines in ${filePath}`);
|
|
83
|
+
}
|
|
84
|
+
return results;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const err = error;
|
|
88
|
+
if (err.code === 'ENOENT') {
|
|
89
|
+
// File doesn't exist, return empty array
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
logger.debug(`[opencode-storage] Failed to read JSONL ${filePath}: ${err.message}`);
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=opencode.storage-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.storage-utils.js","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.storage-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SessionProcessor, ProcessingContext, ProcessingResult } from '../../../../core/session/BaseProcessor.js';
|
|
2
|
+
import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.js';
|
|
3
|
+
/**
|
|
4
|
+
* OpenCode Conversations Processor
|
|
5
|
+
*
|
|
6
|
+
* Normalizes OpenCode messages and parts into unified conversation format.
|
|
7
|
+
* Implements SessionProcessor interface for processor chain.
|
|
8
|
+
*/
|
|
9
|
+
export declare class OpenCodeConversationsProcessor implements SessionProcessor {
|
|
10
|
+
readonly name = "opencode-conversations";
|
|
11
|
+
readonly priority = 2;
|
|
12
|
+
/**
|
|
13
|
+
* Check if session has data to process
|
|
14
|
+
*/
|
|
15
|
+
shouldProcess(session: ParsedSession): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Process session to normalize conversations
|
|
18
|
+
*/
|
|
19
|
+
process(session: ParsedSession, _context: ProcessingContext): Promise<ProcessingResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Process parts for a message (helper for full implementation)
|
|
22
|
+
* Parts are loaded from part/{messageID}/*.json
|
|
23
|
+
*
|
|
24
|
+
* UPDATED (GPT-5.9): Use new part schema:
|
|
25
|
+
* - Tool parts: callID, tool, state.input, state (not toolName, toolInput, toolOutput)
|
|
26
|
+
* - File parts: mime, url, source, filename (not filePath, content)
|
|
27
|
+
*/
|
|
28
|
+
private processParts;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=opencode.conversations-processor.d.ts.map
|
package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.conversations-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAuCpF;;;;;GAKG;AACH,qBAAa,8BAA+B,YAAW,gBAAgB;IACrE,QAAQ,CAAC,IAAI,4BAA4B;IACzC,QAAQ,CAAC,QAAQ,KAAK;IAEtB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAI9C;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoD7F;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;CA2CrB"}
|