@codemieai/code 0.0.33 → 0.0.35
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 +78 -7
- package/bin/codemie-claude-acp.js +21 -0
- package/bin/codemie-opencode.js +11 -0
- package/bin/codemie.js +13 -0
- package/dist/agents/codemie-code/agent.d.ts +38 -4
- package/dist/agents/codemie-code/agent.d.ts.map +1 -1
- package/dist/agents/codemie-code/agent.js +333 -178
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/index.d.ts +2 -1
- package/dist/agents/codemie-code/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/index.js +36 -7
- package/dist/agents/codemie-code/index.js.map +1 -1
- package/dist/agents/codemie-code/prompts.d.ts +12 -5
- package/dist/agents/codemie-code/prompts.d.ts.map +1 -1
- package/dist/agents/codemie-code/prompts.js +53 -6
- package/dist/agents/codemie-code/prompts.js.map +1 -1
- package/dist/agents/codemie-code/toolMetadata.d.ts.map +1 -1
- package/dist/agents/codemie-code/toolMetadata.js +9 -8
- package/dist/agents/codemie-code/toolMetadata.js.map +1 -1
- package/dist/agents/codemie-code/tools/assistant-invocation.d.ts +47 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.d.ts.map +1 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.js +129 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.js.map +1 -0
- package/dist/agents/codemie-code/tools/index.d.ts +70 -4
- package/dist/agents/codemie-code/tools/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/tools/index.js +57 -44
- package/dist/agents/codemie-code/tools/index.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +6 -5
- package/dist/agents/codemie-code/tools/planning.d.ts.map +1 -1
- package/dist/agents/codemie-code/tools/planning.js +12 -10
- package/dist/agents/codemie-code/tools/planning.js.map +1 -1
- package/dist/agents/codemie-code/types.d.ts +27 -3
- package/dist/agents/codemie-code/types.d.ts.map +1 -1
- package/dist/agents/codemie-code/types.js +24 -0
- package/dist/agents/codemie-code/types.js.map +1 -1
- package/dist/agents/codemie-code/ui/autocomplete.d.ts +98 -0
- package/dist/agents/codemie-code/ui/autocomplete.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/autocomplete.js +145 -0
- package/dist/agents/codemie-code/ui/autocomplete.js.map +1 -0
- package/dist/agents/codemie-code/ui/keyHandlers.d.ts +112 -0
- package/dist/agents/codemie-code/ui/keyHandlers.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/keyHandlers.js +415 -0
- package/dist/agents/codemie-code/ui/keyHandlers.js.map +1 -0
- package/dist/agents/codemie-code/ui/mentions.d.ts +86 -0
- package/dist/agents/codemie-code/ui/mentions.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/mentions.js +122 -0
- package/dist/agents/codemie-code/ui/mentions.js.map +1 -0
- package/dist/agents/codemie-code/ui/terminalCodes.d.ts +38 -0
- package/dist/agents/codemie-code/ui/terminalCodes.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/terminalCodes.js +42 -0
- package/dist/agents/codemie-code/ui/terminalCodes.js.map +1 -0
- package/dist/agents/codemie-code/ui/todoPanel.d.ts.map +1 -1
- package/dist/agents/codemie-code/ui/todoPanel.js +3 -4
- package/dist/agents/codemie-code/ui/todoPanel.js.map +1 -1
- package/dist/agents/codemie-code/ui.d.ts +8 -7
- package/dist/agents/codemie-code/ui.d.ts.map +1 -1
- package/dist/agents/codemie-code/ui.js +87 -145
- package/dist/agents/codemie-code/ui.js.map +1 -1
- package/dist/agents/core/AgentCLI.d.ts +5 -0
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +25 -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 +90 -27
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts +7 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts.map +1 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.js +58 -15
- package/dist/agents/core/extension/BaseExtensionInstaller.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 +62 -0
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude-acp.plugin.d.ts +27 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.js +63 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.js.map +1 -0
- package/dist/agents/plugins/claude/claude-message-types.d.ts +1 -0
- package/dist/agents/plugins/claude/claude-message-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 +263 -12
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.session.js +14 -7
- package/dist/agents/plugins/claude/claude.session.js.map +1 -1
- package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +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 +233 -504
- 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/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +43 -8
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +68 -40
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -1
- 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 +1 -1
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +5 -1
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/assistants/chat.d.ts +11 -0
- package/dist/cli/commands/assistants/chat.d.ts.map +1 -0
- package/dist/cli/commands/assistants/chat.js +201 -0
- package/dist/cli/commands/assistants/chat.js.map +1 -0
- package/dist/cli/commands/assistants/constants.d.ts +81 -0
- package/dist/cli/commands/assistants/constants.d.ts.map +1 -0
- package/dist/cli/commands/assistants/constants.js +75 -0
- package/dist/cli/commands/assistants/constants.js.map +1 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.d.ts +26 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.d.ts.map +1 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.js +115 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.js.map +1 -0
- package/dist/cli/commands/assistants/index.d.ts +11 -0
- package/dist/cli/commands/assistants/index.d.ts.map +1 -0
- package/dist/cli/commands/assistants/index.js +28 -0
- package/dist/cli/commands/assistants/index.js.map +1 -0
- package/dist/cli/commands/assistants/list.d.ts +11 -0
- package/dist/cli/commands/assistants/list.d.ts.map +1 -0
- package/dist/cli/commands/assistants/list.js +323 -0
- package/dist/cli/commands/assistants/list.js.map +1 -0
- 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 +104 -13
- 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/self-update.d.ts +3 -0
- package/dist/cli/commands/self-update.d.ts.map +1 -0
- package/dist/cli/commands/self-update.js +55 -0
- package/dist/cli/commands/self-update.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.d.ts.map +1 -1
- package/dist/cli/index.js +12 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/env/types.d.ts +13 -0
- package/dist/env/types.d.ts.map +1 -1
- package/dist/env/types.js +1 -1
- package/dist/env/types.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/auth.d.ts +22 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +50 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/cli-updater.d.ts +70 -0
- package/dist/utils/cli-updater.d.ts.map +1 -0
- package/dist/utils/cli-updater.js +339 -0
- package/dist/utils/cli-updater.js.map +1 -0
- package/dist/utils/config.d.ts +6 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +13 -0
- package/dist/utils/config.js.map +1 -1
- 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 +225 -0
- package/dist/utils/native-installer.js.map +1 -0
- package/dist/utils/processes.js +1 -1
- package/dist/utils/profile.d.ts +2 -0
- package/dist/utils/profile.d.ts.map +1 -1
- package/dist/utils/profile.js +5 -0
- package/dist/utils/profile.js.map +1 -1
- package/dist/utils/sdk-client.d.ts +15 -0
- package/dist/utils/sdk-client.d.ts.map +1 -0
- package/dist/utils/sdk-client.js +92 -0
- package/dist/utils/sdk-client.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 +11 -3
- 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
- package/dist/agents/plugins/claude/plugin/commands/codemie-pr.md +0 -25
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// src/agents/plugins/opencode/opencode.paths.ts
|
|
2
|
+
// FIXED: Use named imports per repo conventions
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
import { join, dirname } from 'path';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
/**
|
|
8
|
+
* Detect OpenCode storage layout (post-migration vs legacy)
|
|
9
|
+
*
|
|
10
|
+
* Per tech spec ADR-2:
|
|
11
|
+
* - Post-migration: storage/session/, storage/message/, storage/part/
|
|
12
|
+
* - Legacy: project/{projectDir}/storage/session/info/
|
|
13
|
+
* - Migration file: plain text numeric version (not JSON)
|
|
14
|
+
*/
|
|
15
|
+
export async function detectStorageLayout(storagePath) {
|
|
16
|
+
let migrationVersion = 0;
|
|
17
|
+
// Check migration file (numeric string, not just presence)
|
|
18
|
+
const migrationFile = join(storagePath, 'migration');
|
|
19
|
+
if (existsSync(migrationFile)) {
|
|
20
|
+
try {
|
|
21
|
+
const content = await readFile(migrationFile, 'utf-8');
|
|
22
|
+
migrationVersion = parseInt(content.trim(), 10) || 0;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
migrationVersion = 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Post-migration structure check
|
|
29
|
+
const hasPostMigration = (existsSync(join(storagePath, 'session')) &&
|
|
30
|
+
existsSync(join(storagePath, 'message')) &&
|
|
31
|
+
existsSync(join(storagePath, 'part')));
|
|
32
|
+
// Legacy structure check (project directories above storage/)
|
|
33
|
+
const dataDir = dirname(storagePath); // Goes up to ~/.local/share/opencode/
|
|
34
|
+
const projectDir = join(dataDir, 'project');
|
|
35
|
+
const hasLegacy = existsSync(projectDir);
|
|
36
|
+
// Determine layout
|
|
37
|
+
if (migrationVersion >= 1 && hasPostMigration) {
|
|
38
|
+
return { layout: 'post-migration', migrationVersion, postMigrationPath: storagePath };
|
|
39
|
+
}
|
|
40
|
+
if (hasPostMigration && hasLegacy) {
|
|
41
|
+
return { layout: 'mixed', migrationVersion, postMigrationPath: storagePath, legacyPaths: [projectDir] };
|
|
42
|
+
}
|
|
43
|
+
if (hasPostMigration) {
|
|
44
|
+
return { layout: 'post-migration', migrationVersion, postMigrationPath: storagePath };
|
|
45
|
+
}
|
|
46
|
+
if (hasLegacy) {
|
|
47
|
+
return { layout: 'legacy', migrationVersion, legacyPaths: [projectDir] };
|
|
48
|
+
}
|
|
49
|
+
return { layout: 'unknown', migrationVersion };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get OpenCode storage root path based on platform
|
|
53
|
+
*
|
|
54
|
+
* OpenCode uses XDG conventions for data storage:
|
|
55
|
+
* - Linux/WSL: ~/.local/share/opencode/storage/
|
|
56
|
+
* - macOS: ~/Library/Application Support/opencode/storage/
|
|
57
|
+
* - Windows: %LOCALAPPDATA%/opencode/storage/
|
|
58
|
+
*
|
|
59
|
+
* @returns Path to storage root directory or null if not found
|
|
60
|
+
*/
|
|
61
|
+
export function getOpenCodeStoragePath() {
|
|
62
|
+
const home = homedir();
|
|
63
|
+
let storagePath;
|
|
64
|
+
// XDG_DATA_HOME always takes precedence (any platform)
|
|
65
|
+
if (process.env.XDG_DATA_HOME) {
|
|
66
|
+
storagePath = join(process.env.XDG_DATA_HOME, 'opencode', 'storage');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
// Platform-specific defaults
|
|
70
|
+
switch (process.platform) {
|
|
71
|
+
case 'darwin': // macOS
|
|
72
|
+
storagePath = join(home, 'Library', 'Application Support', 'opencode', 'storage');
|
|
73
|
+
break;
|
|
74
|
+
case 'win32': { // Native Windows (WSL reports 'linux')
|
|
75
|
+
const appData = process.env.LOCALAPPDATA;
|
|
76
|
+
storagePath = appData
|
|
77
|
+
? join(appData, 'opencode', 'storage')
|
|
78
|
+
: join(home, '.local', 'share', 'opencode', 'storage');
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
default: // Linux, WSL, other Unix
|
|
82
|
+
storagePath = join(home, '.local', 'share', 'opencode', 'storage');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Return null if path doesn't exist (don't create directories)
|
|
86
|
+
if (!existsSync(storagePath)) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return storagePath;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get OpenCode sessions directory path
|
|
93
|
+
* Sessions are stored at: storage/session/{projectID}/{sessionID}.json
|
|
94
|
+
*
|
|
95
|
+
* @returns Path to sessions directory or null if storage not found
|
|
96
|
+
*/
|
|
97
|
+
export function getOpenCodeSessionsPath() {
|
|
98
|
+
const storagePath = getOpenCodeStoragePath();
|
|
99
|
+
if (!storagePath)
|
|
100
|
+
return null;
|
|
101
|
+
const sessionsPath = join(storagePath, 'session');
|
|
102
|
+
return existsSync(sessionsPath) ? sessionsPath : null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get OpenCode messages directory path
|
|
106
|
+
* Messages are stored at: storage/message/{sessionID}/{messageID}.json
|
|
107
|
+
*
|
|
108
|
+
* @returns Path to messages directory or null if storage not found
|
|
109
|
+
*/
|
|
110
|
+
export function getOpenCodeMessagesPath() {
|
|
111
|
+
const storagePath = getOpenCodeStoragePath();
|
|
112
|
+
if (!storagePath)
|
|
113
|
+
return null;
|
|
114
|
+
const messagesPath = join(storagePath, 'message');
|
|
115
|
+
return existsSync(messagesPath) ? messagesPath : null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get OpenCode parts directory path
|
|
119
|
+
* Parts are stored at: storage/part/{messageID}/{partID}.json
|
|
120
|
+
*
|
|
121
|
+
* @returns Path to parts directory or null if storage not found
|
|
122
|
+
*/
|
|
123
|
+
export function getOpenCodePartsPath() {
|
|
124
|
+
const storagePath = getOpenCodeStoragePath();
|
|
125
|
+
if (!storagePath)
|
|
126
|
+
return null;
|
|
127
|
+
const partsPath = join(storagePath, 'part');
|
|
128
|
+
return existsSync(partsPath) ? partsPath : null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get OpenCode home directory (~/.opencode)
|
|
132
|
+
*/
|
|
133
|
+
export function getOpenCodeHome() {
|
|
134
|
+
return join(homedir(), '.opencode');
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get OpenCode config directory
|
|
138
|
+
*/
|
|
139
|
+
export function getOpenCodeConfigDir() {
|
|
140
|
+
if (process.env.XDG_CONFIG_HOME) {
|
|
141
|
+
return join(process.env.XDG_CONFIG_HOME, 'opencode');
|
|
142
|
+
}
|
|
143
|
+
return join(homedir(), '.config', 'opencode');
|
|
144
|
+
}
|
|
145
|
+
// Legacy alias for backward compatibility
|
|
146
|
+
/** @deprecated Use getOpenCodeStoragePath() instead */
|
|
147
|
+
export const getSessionStoragePath = getOpenCodeStoragePath;
|
|
148
|
+
//# sourceMappingURL=opencode.paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.paths.js","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentMetadata } from '../../core/types.js';
|
|
2
|
+
import { BaseAgentAdapter } from '../../core/BaseAgentAdapter.js';
|
|
3
|
+
import type { SessionAdapter } from '../../core/session/BaseSessionAdapter.js';
|
|
4
|
+
import type { BaseExtensionInstaller } from '../../core/extension/BaseExtensionInstaller.js';
|
|
5
|
+
export declare const OpenCodePluginMetadata: AgentMetadata;
|
|
6
|
+
/**
|
|
7
|
+
* OpenCode agent plugin
|
|
8
|
+
* Phase 1: Core plugin with CLI wrapping and SSO proxy support
|
|
9
|
+
* Phase 2: Session analytics integration
|
|
10
|
+
*/
|
|
11
|
+
export declare class OpenCodePlugin extends BaseAgentAdapter {
|
|
12
|
+
private sessionAdapter;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Check if OpenCode is installed
|
|
16
|
+
* Overridden to provide custom install instructions (AC-1.2)
|
|
17
|
+
*
|
|
18
|
+
* NOTE (GPT-5.5 review): This method should be SIDE-EFFECT FREE.
|
|
19
|
+
* Install instructions are displayed via logger (file-only in non-debug mode)
|
|
20
|
+
* so they appear in logs but don't pollute stdout during programmatic checks
|
|
21
|
+
* like `codemie doctor`. The CLI layer (AgentCLI) handles user-facing output.
|
|
22
|
+
*/
|
|
23
|
+
isInstalled(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Return session adapter for analytics
|
|
26
|
+
* Phase 2: Returns OpenCodeSessionAdapter instance
|
|
27
|
+
*/
|
|
28
|
+
getSessionAdapter(): SessionAdapter;
|
|
29
|
+
/**
|
|
30
|
+
* No extension installer - OpenCode installed manually
|
|
31
|
+
* Returns undefined (interface allows optional return)
|
|
32
|
+
*/
|
|
33
|
+
getExtensionInstaller(): BaseExtensionInstaller | undefined;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=opencode.plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.plugin.d.ts","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,qBAAqB,CAAC;AAMtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AAkH7F,eAAO,MAAM,sBAAsB,EAAE,aA6MpC,CAAC;AAEF;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,OAAO,CAAC,cAAc,CAAiB;;IAQvC;;;;;;;;OAQG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBrC;;;OAGG;IACH,iBAAiB,IAAI,cAAc;IAInC;;;OAGG;IACH,qBAAqB,IAAI,sBAAsB,GAAG,SAAS;CAG5D"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { tmpdir } from 'os';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { writeFileSync, unlinkSync } from 'fs';
|
|
4
|
+
import { logger } from '../../../utils/logger.js';
|
|
5
|
+
import { getModelConfig } from './opencode-model-configs.js';
|
|
6
|
+
import { BaseAgentAdapter } from '../../core/BaseAgentAdapter.js';
|
|
7
|
+
import { commandExists } from '../../../utils/processes.js';
|
|
8
|
+
import { OpenCodeSessionAdapter } from './opencode.session.js';
|
|
9
|
+
const OPENCODE_SUBCOMMANDS = ['run', 'chat', 'config', 'init', 'help', 'version'];
|
|
10
|
+
// Environment variable size limit (conservative - varies by platform)
|
|
11
|
+
// Linux: ~128KB per var, Windows: ~32KB total env block
|
|
12
|
+
const MAX_ENV_SIZE = 32 * 1024;
|
|
13
|
+
// Track temp config files for cleanup on process exit
|
|
14
|
+
const tempConfigFiles = [];
|
|
15
|
+
let cleanupRegistered = false;
|
|
16
|
+
/**
|
|
17
|
+
* Register process exit handler for temp file cleanup (best effort)
|
|
18
|
+
* Only registers once, even if beforeRun is called multiple times
|
|
19
|
+
*/
|
|
20
|
+
function registerCleanupHandler() {
|
|
21
|
+
if (cleanupRegistered)
|
|
22
|
+
return;
|
|
23
|
+
cleanupRegistered = true;
|
|
24
|
+
process.on('exit', () => {
|
|
25
|
+
for (const file of tempConfigFiles) {
|
|
26
|
+
try {
|
|
27
|
+
unlinkSync(file);
|
|
28
|
+
logger.debug(`[opencode] Cleaned up temp config: ${file}`);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Ignore cleanup errors - file may already be deleted
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Write config to temp file as fallback when env var size exceeded
|
|
38
|
+
* Returns the temp file path
|
|
39
|
+
*/
|
|
40
|
+
function writeConfigToTempFile(configJson) {
|
|
41
|
+
const configPath = join(tmpdir(), `codemie-opencode-config-${process.pid}-${Date.now()}.json`);
|
|
42
|
+
writeFileSync(configPath, configJson, 'utf-8');
|
|
43
|
+
tempConfigFiles.push(configPath);
|
|
44
|
+
registerCleanupHandler();
|
|
45
|
+
return configPath;
|
|
46
|
+
}
|
|
47
|
+
// NOTE: dataPaths in AgentMetadata only supports `home` and optional `settings`.
|
|
48
|
+
// OpenCode session storage paths are resolved separately in opencode.paths.ts
|
|
49
|
+
// since they follow XDG conventions and differ from the home directory.
|
|
50
|
+
/**
|
|
51
|
+
* Ensure session metadata file exists for SessionSyncer
|
|
52
|
+
* Creates or updates the session file in ~/.codemie/sessions/
|
|
53
|
+
*/
|
|
54
|
+
async function ensureSessionFile(sessionId, env) {
|
|
55
|
+
try {
|
|
56
|
+
const { SessionStore } = await import('../../core/session/SessionStore.js');
|
|
57
|
+
const sessionStore = new SessionStore();
|
|
58
|
+
// Check if session already exists
|
|
59
|
+
const existing = await sessionStore.loadSession(sessionId);
|
|
60
|
+
if (existing) {
|
|
61
|
+
logger.debug('[opencode] Session file already exists');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Create new session file
|
|
65
|
+
const agentName = env.CODEMIE_AGENT || 'opencode';
|
|
66
|
+
const provider = env.CODEMIE_PROVIDER || 'unknown';
|
|
67
|
+
const project = env.CODEMIE_PROJECT;
|
|
68
|
+
const workingDirectory = process.cwd();
|
|
69
|
+
// Detect git branch
|
|
70
|
+
let gitBranch;
|
|
71
|
+
try {
|
|
72
|
+
const { detectGitBranch } = await import('../../../utils/processes.js');
|
|
73
|
+
gitBranch = await detectGitBranch(workingDirectory);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Git detection optional
|
|
77
|
+
}
|
|
78
|
+
// Estimate startTime from grace period (session ended ~2 seconds ago during grace period)
|
|
79
|
+
// This prevents negative session durations in metrics aggregation
|
|
80
|
+
const estimatedStartTime = Date.now() - 2000;
|
|
81
|
+
const session = {
|
|
82
|
+
sessionId,
|
|
83
|
+
agentName,
|
|
84
|
+
provider,
|
|
85
|
+
...(project && { project }),
|
|
86
|
+
startTime: estimatedStartTime,
|
|
87
|
+
workingDirectory,
|
|
88
|
+
...(gitBranch && { gitBranch }),
|
|
89
|
+
status: 'completed', // Session already ended
|
|
90
|
+
activeDurationMs: 0,
|
|
91
|
+
correlation: {
|
|
92
|
+
status: 'matched',
|
|
93
|
+
agentSessionId: 'unknown', // Will be updated after discovery
|
|
94
|
+
retryCount: 0
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
await sessionStore.saveSession(session);
|
|
98
|
+
logger.debug('[opencode] Created session metadata file');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger.warn('[opencode] Failed to create session file:', error);
|
|
102
|
+
// Don't throw - processing can continue without session file (sync will fail though)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export const OpenCodePluginMetadata = {
|
|
106
|
+
name: 'opencode',
|
|
107
|
+
displayName: 'OpenCode CLI',
|
|
108
|
+
description: 'OpenCode - open-source AI coding assistant',
|
|
109
|
+
npmPackage: 'opencode-ai', // Official npm package (npm i -g opencode-ai)
|
|
110
|
+
cliCommand: process.env.CODEMIE_OPENCODE_BIN || 'opencode',
|
|
111
|
+
dataPaths: {
|
|
112
|
+
home: '.opencode'
|
|
113
|
+
// NOTE: Session storage is NOT in home - it's in XDG_DATA_HOME/opencode/storage/
|
|
114
|
+
// This is handled by getSessionStoragePath() in opencode.paths.ts
|
|
115
|
+
},
|
|
116
|
+
envMapping: {
|
|
117
|
+
baseUrl: [],
|
|
118
|
+
apiKey: [],
|
|
119
|
+
model: []
|
|
120
|
+
},
|
|
121
|
+
supportedProviders: ['litellm', 'ai-run-sso'],
|
|
122
|
+
ssoConfig: { enabled: true, clientType: 'codemie-opencode' },
|
|
123
|
+
lifecycle: {
|
|
124
|
+
// NOTE: beforeRun signature is (env, config) per AgentLifecycle interface
|
|
125
|
+
// Claude plugin only uses (env), but interface supports both
|
|
126
|
+
async beforeRun(env, config) {
|
|
127
|
+
// Create session metadata file at startup (before config setup)
|
|
128
|
+
// This ensures SessionSyncer can sync metrics to v1/metrics API (matching Claude/Gemini)
|
|
129
|
+
const sessionId = env.CODEMIE_SESSION_ID;
|
|
130
|
+
if (sessionId) {
|
|
131
|
+
try {
|
|
132
|
+
logger.debug(`[opencode] Creating session metadata file before startup`);
|
|
133
|
+
await ensureSessionFile(sessionId, env);
|
|
134
|
+
logger.debug(`[opencode] Session metadata file ready for SessionSyncer`);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
logger.error('[opencode] Failed to create session file in beforeRun', { error });
|
|
138
|
+
// Don't throw - let OpenCode run even if session file creation fails
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const proxyUrl = env.CODEMIE_BASE_URL;
|
|
142
|
+
if (!proxyUrl) {
|
|
143
|
+
return env;
|
|
144
|
+
}
|
|
145
|
+
if (!proxyUrl.startsWith('http://') && !proxyUrl.startsWith('https://')) {
|
|
146
|
+
logger.warn(`Invalid CODEMIE_BASE_URL format: ${proxyUrl}`, { agent: 'opencode' });
|
|
147
|
+
return env;
|
|
148
|
+
}
|
|
149
|
+
// Model selection priority: env var > config > default
|
|
150
|
+
const selectedModel = env.CODEMIE_MODEL || config?.model || 'gpt-5-2-2025-12-11';
|
|
151
|
+
const modelConfig = getModelConfig(selectedModel);
|
|
152
|
+
// Extract OpenCode-compatible model config (remove CodeMie-specific fields)
|
|
153
|
+
const { displayName: _displayName, providerOptions, ...opencodeModelConfig } = modelConfig;
|
|
154
|
+
const openCodeConfig = {
|
|
155
|
+
enabled_providers: ['codemie-proxy'],
|
|
156
|
+
provider: {
|
|
157
|
+
'codemie-proxy': {
|
|
158
|
+
npm: '@ai-sdk/openai-compatible',
|
|
159
|
+
name: 'CodeMie SSO',
|
|
160
|
+
options: {
|
|
161
|
+
baseURL: `${proxyUrl}/`,
|
|
162
|
+
apiKey: 'proxy-handled',
|
|
163
|
+
timeout: providerOptions?.timeout ||
|
|
164
|
+
parseInt(env.CODEMIE_TIMEOUT || '600') * 1000,
|
|
165
|
+
...(providerOptions?.headers && {
|
|
166
|
+
headers: providerOptions.headers
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
models: {
|
|
170
|
+
[modelConfig.id]: opencodeModelConfig
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
defaults: {
|
|
175
|
+
model: `codemie-proxy/${modelConfig.id}`
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const configJson = JSON.stringify(openCodeConfig);
|
|
179
|
+
// Config injection strategy:
|
|
180
|
+
// 1. Primary: OPENCODE_CONFIG_CONTENT env var (inline JSON)
|
|
181
|
+
// 2. Fallback: OPENCODE_CONFIG env var pointing to temp file
|
|
182
|
+
// See tech spec ADR-002 and "Fallback Strategy" section
|
|
183
|
+
if (configJson.length > MAX_ENV_SIZE) {
|
|
184
|
+
logger.warn(`Config size (${configJson.length} bytes) exceeds env var limit (${MAX_ENV_SIZE}), using temp file fallback`, {
|
|
185
|
+
agent: 'opencode'
|
|
186
|
+
});
|
|
187
|
+
const configPath = writeConfigToTempFile(configJson);
|
|
188
|
+
logger.debug(`[opencode] Wrote config to temp file: ${configPath}`);
|
|
189
|
+
// OPENCODE_CONFIG is verified in OpenCode source: src/flag/flag.ts
|
|
190
|
+
env.OPENCODE_CONFIG = configPath;
|
|
191
|
+
return env;
|
|
192
|
+
}
|
|
193
|
+
// Primary path: inject config inline via OPENCODE_CONFIG_CONTENT
|
|
194
|
+
// Verified in OpenCode source: src/config/config.ts:93-96
|
|
195
|
+
env.OPENCODE_CONFIG_CONTENT = configJson;
|
|
196
|
+
return env;
|
|
197
|
+
},
|
|
198
|
+
enrichArgs: (args, _config) => {
|
|
199
|
+
if (args.length > 0 && OPENCODE_SUBCOMMANDS.includes(args[0])) {
|
|
200
|
+
return args;
|
|
201
|
+
}
|
|
202
|
+
const taskIndex = args.indexOf('--task');
|
|
203
|
+
if (taskIndex !== -1 && taskIndex < args.length - 1) {
|
|
204
|
+
const taskValue = args[taskIndex + 1];
|
|
205
|
+
const otherArgs = args.filter((arg, i, arr) => {
|
|
206
|
+
if (i === taskIndex || i === taskIndex + 1)
|
|
207
|
+
return false;
|
|
208
|
+
if (arg === '-m' || arg === '--message')
|
|
209
|
+
return false;
|
|
210
|
+
if (i > 0 && (arr[i - 1] === '-m' || arr[i - 1] === '--message'))
|
|
211
|
+
return false;
|
|
212
|
+
return true;
|
|
213
|
+
});
|
|
214
|
+
return ['run', '-m', taskValue, ...otherArgs];
|
|
215
|
+
}
|
|
216
|
+
return args;
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* Process OpenCode session metrics before SessionSyncer runs
|
|
220
|
+
*
|
|
221
|
+
* Called by BaseAgentAdapter when OpenCode session ends, BEFORE SessionSyncer.
|
|
222
|
+
* This hook ensures metrics are written to JSONL in time for SessionSyncer's
|
|
223
|
+
* metrics-sync processor to send them to v1/metrics API.
|
|
224
|
+
*
|
|
225
|
+
* Lifecycle order:
|
|
226
|
+
* 1. OpenCode exits
|
|
227
|
+
* 2. Grace period (wait for file writes)
|
|
228
|
+
* 3. onSessionEnd ← WE ARE HERE (process metrics to JSONL)
|
|
229
|
+
* 4. SessionSyncer runs (reads JSONL, sends to v1/metrics)
|
|
230
|
+
* 5. Proxy stops
|
|
231
|
+
* 6. afterRun (cleanup)
|
|
232
|
+
*
|
|
233
|
+
* This matches Claude/Gemini real-time sync behavior where SessionSyncer
|
|
234
|
+
* automatically sends metrics during the session lifecycle.
|
|
235
|
+
*/
|
|
236
|
+
async onSessionEnd(exitCode, env) {
|
|
237
|
+
const sessionId = env.CODEMIE_SESSION_ID;
|
|
238
|
+
if (!sessionId) {
|
|
239
|
+
logger.debug('[opencode] No CODEMIE_SESSION_ID in environment, skipping metrics processing');
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
logger.info(`[opencode] Processing session metrics before SessionSyncer (code=${exitCode})`);
|
|
244
|
+
// 1. Initialize session adapter
|
|
245
|
+
const adapter = new OpenCodeSessionAdapter(OpenCodePluginMetadata);
|
|
246
|
+
// 2. Discover recent sessions (last 24 hours)
|
|
247
|
+
const sessions = await adapter.discoverSessions({ maxAgeDays: 1 });
|
|
248
|
+
if (sessions.length === 0) {
|
|
249
|
+
logger.warn('[opencode] No recent OpenCode sessions found for processing');
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
// 3. Process the most recent session
|
|
253
|
+
const latestSession = sessions[0];
|
|
254
|
+
logger.debug(`[opencode] Processing latest session: ${latestSession.sessionId}`);
|
|
255
|
+
logger.debug(`[opencode] OpenCode session ID: ${latestSession.sessionId}`);
|
|
256
|
+
logger.debug(`[opencode] CodeMie session ID: ${sessionId}`);
|
|
257
|
+
// 4. Build processing context (same as CLI command)
|
|
258
|
+
const context = {
|
|
259
|
+
sessionId,
|
|
260
|
+
apiBaseUrl: env.CODEMIE_BASE_URL || '',
|
|
261
|
+
cookies: '', // Will be loaded by processors if needed
|
|
262
|
+
clientType: 'codemie-opencode',
|
|
263
|
+
version: env.CODEMIE_CLI_VERSION || '1.0.0',
|
|
264
|
+
dryRun: false
|
|
265
|
+
};
|
|
266
|
+
// 5. Process session (extracts metrics + conversations to JSONL)
|
|
267
|
+
const result = await adapter.processSession(latestSession.filePath, sessionId, context);
|
|
268
|
+
if (result.success) {
|
|
269
|
+
logger.info(`[opencode] Metrics processing complete: ${result.totalRecords} records processed`);
|
|
270
|
+
logger.info(`[opencode] Metrics written to JSONL - SessionSyncer will sync to v1/metrics next`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
logger.warn(`[opencode] Metrics processing had failures: ${result.failedProcessors.join(', ')}`);
|
|
274
|
+
}
|
|
275
|
+
// Note: SessionSyncer runs IMMEDIATELY after this hook completes.
|
|
276
|
+
// It will read the JSONL deltas we just wrote and send them to v1/metrics API.
|
|
277
|
+
// This matches Claude/Gemini real-time sync behavior during session lifecycle.
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
281
|
+
logger.error(`[opencode] Failed to process session metrics automatically: ${errorMessage}`);
|
|
282
|
+
// Don't throw - metrics failure shouldn't block exit
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* OpenCode agent plugin
|
|
289
|
+
* Phase 1: Core plugin with CLI wrapping and SSO proxy support
|
|
290
|
+
* Phase 2: Session analytics integration
|
|
291
|
+
*/
|
|
292
|
+
export class OpenCodePlugin extends BaseAgentAdapter {
|
|
293
|
+
sessionAdapter;
|
|
294
|
+
constructor() {
|
|
295
|
+
super(OpenCodePluginMetadata);
|
|
296
|
+
// Initialize session adapter with metadata for unified session sync
|
|
297
|
+
this.sessionAdapter = new OpenCodeSessionAdapter(OpenCodePluginMetadata);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Check if OpenCode is installed
|
|
301
|
+
* Overridden to provide custom install instructions (AC-1.2)
|
|
302
|
+
*
|
|
303
|
+
* NOTE (GPT-5.5 review): This method should be SIDE-EFFECT FREE.
|
|
304
|
+
* Install instructions are displayed via logger (file-only in non-debug mode)
|
|
305
|
+
* so they appear in logs but don't pollute stdout during programmatic checks
|
|
306
|
+
* like `codemie doctor`. The CLI layer (AgentCLI) handles user-facing output.
|
|
307
|
+
*/
|
|
308
|
+
async isInstalled() {
|
|
309
|
+
// Use metadata.cliCommand which respects CODEMIE_OPENCODE_BIN
|
|
310
|
+
const cliCommand = this.metadata.cliCommand;
|
|
311
|
+
if (!cliCommand)
|
|
312
|
+
return false;
|
|
313
|
+
const installed = await commandExists(cliCommand);
|
|
314
|
+
if (!installed) {
|
|
315
|
+
// Log install guidance to debug log (file-only unless CODEMIE_DEBUG=true)
|
|
316
|
+
// Actual user-facing message is handled by AgentCLI layer
|
|
317
|
+
logger.debug('[opencode-plugin] OpenCode not installed. Install with:');
|
|
318
|
+
logger.debug('[opencode-plugin] codemie install opencode');
|
|
319
|
+
logger.debug('[opencode-plugin] Or directly: npm i -g opencode-ai');
|
|
320
|
+
}
|
|
321
|
+
return installed;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Return session adapter for analytics
|
|
325
|
+
* Phase 2: Returns OpenCodeSessionAdapter instance
|
|
326
|
+
*/
|
|
327
|
+
getSessionAdapter() {
|
|
328
|
+
return this.sessionAdapter;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* No extension installer - OpenCode installed manually
|
|
332
|
+
* Returns undefined (interface allows optional return)
|
|
333
|
+
*/
|
|
334
|
+
getExtensionInstaller() {
|
|
335
|
+
return undefined;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=opencode.plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.plugin.js","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { SessionAdapter, ParsedSession, AggregatedResult, SessionDiscoveryOptions, SessionDescriptor } from '../../core/session/BaseSessionAdapter.js';
|
|
2
|
+
import type { SessionProcessor, ProcessingContext } from '../../core/session/BaseProcessor.js';
|
|
3
|
+
import type { AgentMetadata } from '../../core/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* OpenCode Session Adapter
|
|
6
|
+
*
|
|
7
|
+
* Parses OpenCode session files from ~/.local/share/opencode/storage/
|
|
8
|
+
* Implements SessionAdapter interface with processor chain pattern.
|
|
9
|
+
*/
|
|
10
|
+
export declare class OpenCodeSessionAdapter implements SessionAdapter {
|
|
11
|
+
private readonly metadata;
|
|
12
|
+
readonly agentName = "opencode";
|
|
13
|
+
private processors;
|
|
14
|
+
constructor(metadata: AgentMetadata);
|
|
15
|
+
/**
|
|
16
|
+
* Initialize processors for this adapter.
|
|
17
|
+
* Processors run in priority order: metrics (1), conversations (2)
|
|
18
|
+
*/
|
|
19
|
+
private initializeProcessors;
|
|
20
|
+
/**
|
|
21
|
+
* Register a processor to run during session processing.
|
|
22
|
+
*/
|
|
23
|
+
registerProcessor(processor: SessionProcessor): void;
|
|
24
|
+
/**
|
|
25
|
+
* Parse OpenCode session file to unified ParsedSession format.
|
|
26
|
+
*
|
|
27
|
+
* UPDATED (GPT-5.9): OpenCode uses numeric timestamps (time.created/time.updated)
|
|
28
|
+
* not ISO strings. We convert to ISO for CodeMie's canonical format.
|
|
29
|
+
*/
|
|
30
|
+
parseSessionFile(filePath: string, sessionId: string): Promise<ParsedSession>;
|
|
31
|
+
/**
|
|
32
|
+
* Validate session path has expected structure (GPT-5.8 fix, updated GPT-5.10/5.11)
|
|
33
|
+
* Expected: .../storage/session/{projectId}/{sessionId}.json
|
|
34
|
+
*
|
|
35
|
+
* FIXED (GPT-5.10/5.11): Use path.sep for cross-platform compatibility
|
|
36
|
+
*/
|
|
37
|
+
private isValidSessionPath;
|
|
38
|
+
/**
|
|
39
|
+
* Extract project path from session file path
|
|
40
|
+
* Session path: .../storage/session/{projectId}/{sessionId}.json
|
|
41
|
+
* Project ID is typically git root commit hash
|
|
42
|
+
*
|
|
43
|
+
* FIXED (GPT-5.10/5.11): Use path module for cross-platform compatibility
|
|
44
|
+
* UPDATED (GPT-5.11): Prefer session.directory over path extraction when available
|
|
45
|
+
*/
|
|
46
|
+
private extractProjectPath;
|
|
47
|
+
/**
|
|
48
|
+
* Load messages for a session from message/{sessionId}/*.json
|
|
49
|
+
*
|
|
50
|
+
* Path calculation (FIXED per GPT-5.5 review):
|
|
51
|
+
* - sessionFilePath = .../storage/session/{projectId}/{sessionId}.json
|
|
52
|
+
* - dirname(sessionFilePath) = .../storage/session/{projectId}
|
|
53
|
+
* - dirname(dirname(sessionFilePath)) = .../storage/session
|
|
54
|
+
* - dirname(dirname(dirname(sessionFilePath))) = .../storage ← CORRECT base
|
|
55
|
+
* - messagesDir = .../storage/message/{sessionId}
|
|
56
|
+
*/
|
|
57
|
+
private loadMessages;
|
|
58
|
+
/**
|
|
59
|
+
* Extract metrics from OpenCode messages.
|
|
60
|
+
*
|
|
61
|
+
* UPDATED (GPT-5.9): Use isAssistantMessage type guard for safe access
|
|
62
|
+
* to assistant-specific fields (tokens, cost, etc.)
|
|
63
|
+
*/
|
|
64
|
+
private extractMetrics;
|
|
65
|
+
/**
|
|
66
|
+
* Process session with all registered processors.
|
|
67
|
+
*/
|
|
68
|
+
processSession(filePath: string, sessionId: string, context: ProcessingContext): Promise<AggregatedResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Discover OpenCode sessions with filtering
|
|
71
|
+
*
|
|
72
|
+
* Scans XDG_DATA_HOME/opencode/storage/session/{projectID}/{sessionID}.json
|
|
73
|
+
* Applies 30-day default filter and optional cwd filter.
|
|
74
|
+
*/
|
|
75
|
+
discoverSessions(options?: SessionDiscoveryOptions): Promise<SessionDescriptor[]>;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=opencode.session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.session.d.ts","sourceRoot":"","sources":["../../../../src/agents/plugins/opencode/opencode.session.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC5J,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA2DzD;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAI/C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,QAAQ,CAAC,SAAS,cAAc;IAChC,OAAO,CAAC,UAAU,CAA0B;gBAEf,QAAQ,EAAE,aAAa;IAOpD;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;IAMpD;;;;;OAKG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA+DnF;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;;;;;;;OASG;YACW,YAAY;IA6B1B;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAkCtB;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC;IA6D5B;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAwHxF"}
|