oh-my-claudecode-opencode 0.6.2 → 0.6.3
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.
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: version
|
|
3
|
+
description: Check OMCO plugin version and update status
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Version Check Skill
|
|
8
|
+
|
|
9
|
+
Display the current OMCO plugin version and check for updates.
|
|
10
|
+
|
|
11
|
+
## What to Do
|
|
12
|
+
|
|
13
|
+
When user invokes this skill, run the following checks:
|
|
14
|
+
|
|
15
|
+
### 1. Check Installed Version
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Read version from installed location
|
|
19
|
+
cat ~/.config/opencode/node_modules/oh-my-claudecode-opencode/package.json 2>/dev/null | grep '"version"' | head -1
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 2. Check Development Version (if in dev directory)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# If in oh-my-claudecode-opencode project directory
|
|
26
|
+
cat package.json 2>/dev/null | grep '"version"' | head -1
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 3. Check Latest Version on npm
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm view oh-my-claudecode-opencode version 2>/dev/null
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
Present the information in a clear table:
|
|
38
|
+
|
|
39
|
+
| Location | Version |
|
|
40
|
+
|----------|---------|
|
|
41
|
+
| Installed | X.X.X |
|
|
42
|
+
| Development | X.X.X (if applicable) |
|
|
43
|
+
| npm Latest | X.X.X |
|
|
44
|
+
|
|
45
|
+
### Status Indicators
|
|
46
|
+
|
|
47
|
+
- **Up to date**: Installed version matches npm latest
|
|
48
|
+
- **Update available**: npm has newer version
|
|
49
|
+
- **Ahead of npm**: Local version is higher (pre-release or unpublished)
|
|
50
|
+
- **Mismatch**: Development and installed versions differ
|
|
51
|
+
|
|
52
|
+
## Update Instructions
|
|
53
|
+
|
|
54
|
+
If update is available:
|
|
55
|
+
```bash
|
|
56
|
+
cd ~/.config/opencode && npm install oh-my-claudecode-opencode@latest
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If development version differs from installed:
|
|
60
|
+
```bash
|
|
61
|
+
# From development directory
|
|
62
|
+
bun run build
|
|
63
|
+
cp -r dist/ ~/.config/opencode/node_modules/oh-my-claudecode-opencode/dist/
|
|
64
|
+
cp package.json ~/.config/opencode/node_modules/oh-my-claudecode-opencode/package.json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## After Update
|
|
68
|
+
|
|
69
|
+
Remind users to restart OpenCode for changes to take effect.
|
|
@@ -22,13 +22,29 @@ export interface ModelResolutionResult {
|
|
|
22
22
|
source: "per-agent-override" | "tier-default" | "hardcoded-fallback";
|
|
23
23
|
originalTier?: ModelTier;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Default tier-to-model mapping.
|
|
27
|
+
* These use generic names - configure model_mapping.tierDefaults in
|
|
28
|
+
* ~/.config/opencode/oh-my-opencode.json for your specific provider.
|
|
29
|
+
*
|
|
30
|
+
* Example config:
|
|
31
|
+
* {
|
|
32
|
+
* "model_mapping": {
|
|
33
|
+
* "tierDefaults": {
|
|
34
|
+
* "haiku": "google/gemini-2.0-flash",
|
|
35
|
+
* "sonnet": "anthropic/claude-sonnet-4",
|
|
36
|
+
* "opus": "anthropic/claude-opus-4"
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
*/
|
|
25
41
|
export declare const HARDCODED_TIER_DEFAULTS: TierModelMapping;
|
|
26
42
|
/**
|
|
27
|
-
* Check if model follows "provider/model-name" pattern
|
|
43
|
+
* Check if model follows "provider/model-name" pattern or is a simple tier name
|
|
28
44
|
*/
|
|
29
45
|
export declare function isValidModelFormat(model: string): boolean;
|
|
30
46
|
/**
|
|
31
|
-
* Log warning if invalid format
|
|
47
|
+
* Log warning if invalid format (skip for simple tier names)
|
|
32
48
|
*/
|
|
33
49
|
export declare function validateModelFormat(model: string, context: string): void;
|
|
34
50
|
export declare class ModelResolver {
|
package/dist/index.js
CHANGED
|
@@ -9221,7 +9221,7 @@ class Doc {
|
|
|
9221
9221
|
var version = {
|
|
9222
9222
|
major: 4,
|
|
9223
9223
|
minor: 3,
|
|
9224
|
-
patch:
|
|
9224
|
+
patch: 5
|
|
9225
9225
|
};
|
|
9226
9226
|
|
|
9227
9227
|
// node_modules/zod/v4/core/schemas.js
|
|
@@ -10507,7 +10507,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
|
|
|
10507
10507
|
if (keyResult instanceof Promise) {
|
|
10508
10508
|
throw new Error("Async schemas not supported in object keys currently");
|
|
10509
10509
|
}
|
|
10510
|
-
const checkNumericKey = typeof key === "string" && number.test(key) && keyResult.issues.length;
|
|
10510
|
+
const checkNumericKey = typeof key === "string" && number.test(key) && keyResult.issues.length && keyResult.issues.some((iss) => iss.code === "invalid_type" && iss.expected === "number");
|
|
10511
10511
|
if (checkNumericKey) {
|
|
10512
10512
|
const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);
|
|
10513
10513
|
if (retryResult instanceof Promise) {
|
|
@@ -17878,7 +17878,7 @@ function finalize(ctx, schema) {
|
|
|
17878
17878
|
}
|
|
17879
17879
|
}
|
|
17880
17880
|
}
|
|
17881
|
-
if (refSchema.$ref
|
|
17881
|
+
if (refSchema.$ref) {
|
|
17882
17882
|
for (const key in schema2) {
|
|
17883
17883
|
if (key === "$ref" || key === "allOf")
|
|
17884
17884
|
continue;
|
|
@@ -21672,6 +21672,7 @@ function generateTaskId() {
|
|
|
21672
21672
|
function createBackgroundManager(ctx, config2) {
|
|
21673
21673
|
const tasks = new Map;
|
|
21674
21674
|
const defaultConcurrency = config2?.defaultConcurrency ?? 5;
|
|
21675
|
+
const modelCache = new Map;
|
|
21675
21676
|
const getRunningCount = (parentSessionID) => {
|
|
21676
21677
|
let count = 0;
|
|
21677
21678
|
for (const task of tasks.values()) {
|
|
@@ -21683,7 +21684,34 @@ function createBackgroundManager(ctx, config2) {
|
|
|
21683
21684
|
}
|
|
21684
21685
|
return count;
|
|
21685
21686
|
};
|
|
21686
|
-
const
|
|
21687
|
+
const getParentSessionModel = async (parentSessionID) => {
|
|
21688
|
+
if (modelCache.has(parentSessionID)) {
|
|
21689
|
+
return modelCache.get(parentSessionID);
|
|
21690
|
+
}
|
|
21691
|
+
try {
|
|
21692
|
+
const messagesResp = await ctx.client.session.messages({
|
|
21693
|
+
path: { id: parentSessionID },
|
|
21694
|
+
query: { directory: ctx.directory }
|
|
21695
|
+
});
|
|
21696
|
+
const messages = messagesResp.data;
|
|
21697
|
+
const assistantMsg = messages?.find((m) => m.info.role === "assistant" && m.info.providerID && m.info.modelID);
|
|
21698
|
+
if (assistantMsg?.info.providerID && assistantMsg?.info.modelID) {
|
|
21699
|
+
const model = {
|
|
21700
|
+
providerID: assistantMsg.info.providerID,
|
|
21701
|
+
modelID: assistantMsg.info.modelID
|
|
21702
|
+
};
|
|
21703
|
+
modelCache.set(parentSessionID, model);
|
|
21704
|
+
log(`Got parent session model from messages`, { parentSessionID, ...model });
|
|
21705
|
+
return model;
|
|
21706
|
+
}
|
|
21707
|
+
log(`Parent session has no assistant messages with model info`, { parentSessionID });
|
|
21708
|
+
return;
|
|
21709
|
+
} catch (err) {
|
|
21710
|
+
log(`Failed to get parent session model`, { parentSessionID, error: String(err) });
|
|
21711
|
+
return;
|
|
21712
|
+
}
|
|
21713
|
+
};
|
|
21714
|
+
const createTask = async (parentSessionID, description, prompt, agent, model) => {
|
|
21687
21715
|
const runningCount = getRunningCount();
|
|
21688
21716
|
if (runningCount >= defaultConcurrency) {
|
|
21689
21717
|
throw new Error(`Max concurrent tasks (${defaultConcurrency}) reached. Wait for some to complete.`);
|
|
@@ -21698,6 +21726,7 @@ function createBackgroundManager(ctx, config2) {
|
|
|
21698
21726
|
};
|
|
21699
21727
|
tasks.set(taskId, task);
|
|
21700
21728
|
log(`Background task created`, { taskId, description, agent });
|
|
21729
|
+
const resolvedModel = model || await getParentSessionModel(parentSessionID);
|
|
21701
21730
|
(async () => {
|
|
21702
21731
|
try {
|
|
21703
21732
|
const sessionResp = await ctx.client.session.create({
|
|
@@ -21717,19 +21746,28 @@ function createBackgroundManager(ctx, config2) {
|
|
|
21717
21746
|
const fullPrompt = systemPrompt ? `${systemPrompt}
|
|
21718
21747
|
|
|
21719
21748
|
${prompt}` : prompt;
|
|
21720
|
-
|
|
21749
|
+
const promptBody = {
|
|
21750
|
+
parts: [{ type: "text", text: fullPrompt }]
|
|
21751
|
+
};
|
|
21752
|
+
if (resolvedModel) {
|
|
21753
|
+
promptBody.model = resolvedModel;
|
|
21754
|
+
log(`Using parent model for subagent`, { taskId, ...resolvedModel });
|
|
21755
|
+
}
|
|
21756
|
+
const promptResp = await ctx.client.session.prompt({
|
|
21721
21757
|
path: { id: sessionID },
|
|
21722
|
-
body:
|
|
21723
|
-
parts: [{ type: "text", text: fullPrompt }]
|
|
21724
|
-
},
|
|
21758
|
+
body: promptBody,
|
|
21725
21759
|
query: { directory: ctx.directory }
|
|
21726
21760
|
});
|
|
21727
|
-
const
|
|
21728
|
-
|
|
21729
|
-
|
|
21730
|
-
|
|
21731
|
-
|
|
21732
|
-
|
|
21761
|
+
const promptData = promptResp.data;
|
|
21762
|
+
if (promptResp.error) {
|
|
21763
|
+
throw new Error(`Prompt failed: ${JSON.stringify(promptResp.error)}`);
|
|
21764
|
+
}
|
|
21765
|
+
if (promptData?.info?.error) {
|
|
21766
|
+
const err = promptData.info.error;
|
|
21767
|
+
const errMsg = err.data?.message || err.name || "Unknown error";
|
|
21768
|
+
throw new Error(`[${err.name}] ${errMsg}`);
|
|
21769
|
+
}
|
|
21770
|
+
const result = promptData?.parts?.filter((p) => p.type === "text" && p.text).map((p) => p.text).join(`
|
|
21733
21771
|
`) || "";
|
|
21734
21772
|
task.result = result;
|
|
21735
21773
|
task.status = "completed";
|
|
@@ -21770,6 +21808,14 @@ ${prompt}` : prompt;
|
|
|
21770
21808
|
return false;
|
|
21771
21809
|
task.status = "cancelled";
|
|
21772
21810
|
task.completedAt = Date.now();
|
|
21811
|
+
if (task.sessionID) {
|
|
21812
|
+
ctx.client.session.abort({
|
|
21813
|
+
path: { id: task.sessionID },
|
|
21814
|
+
query: { directory: ctx.directory }
|
|
21815
|
+
}).catch((err) => {
|
|
21816
|
+
log(`Failed to abort session for task ${taskId}`, { error: String(err) });
|
|
21817
|
+
});
|
|
21818
|
+
}
|
|
21773
21819
|
log(`Background task cancelled`, { taskId });
|
|
21774
21820
|
return true;
|
|
21775
21821
|
};
|
|
@@ -21781,6 +21827,14 @@ ${prompt}` : prompt;
|
|
|
21781
21827
|
task.status = "cancelled";
|
|
21782
21828
|
task.completedAt = Date.now();
|
|
21783
21829
|
count++;
|
|
21830
|
+
if (task.sessionID) {
|
|
21831
|
+
ctx.client.session.abort({
|
|
21832
|
+
path: { id: task.sessionID },
|
|
21833
|
+
query: { directory: ctx.directory }
|
|
21834
|
+
}).catch((err) => {
|
|
21835
|
+
log(`Failed to abort session for task ${task.id}`, { error: String(err) });
|
|
21836
|
+
});
|
|
21837
|
+
}
|
|
21784
21838
|
}
|
|
21785
21839
|
}
|
|
21786
21840
|
}
|
|
@@ -21808,7 +21862,8 @@ ${prompt}` : prompt;
|
|
|
21808
21862
|
getTasksByParentSession,
|
|
21809
21863
|
cancelTask,
|
|
21810
21864
|
cancelAllTasks,
|
|
21811
|
-
waitForTask
|
|
21865
|
+
waitForTask,
|
|
21866
|
+
getParentSessionModel
|
|
21812
21867
|
};
|
|
21813
21868
|
}
|
|
21814
21869
|
|
|
@@ -34237,8 +34292,9 @@ Prompts MUST be in English. Use \`background_output\` for async results.`,
|
|
|
34237
34292
|
---
|
|
34238
34293
|
|
|
34239
34294
|
${prompt}`;
|
|
34295
|
+
const parentModel = await manager.getParentSessionModel(context.sessionID);
|
|
34240
34296
|
if (run_in_background) {
|
|
34241
|
-
const task = await manager.createTask(context.sessionID, description, enhancedPrompt, subagent_type);
|
|
34297
|
+
const task = await manager.createTask(context.sessionID, description, enhancedPrompt, subagent_type, parentModel);
|
|
34242
34298
|
return JSON.stringify({
|
|
34243
34299
|
task_id: task.id,
|
|
34244
34300
|
session_id: task.sessionID,
|
|
@@ -34257,19 +34313,36 @@ ${prompt}`;
|
|
|
34257
34313
|
const sessionID = sessionResp.data?.id ?? sessionResp.id;
|
|
34258
34314
|
if (!sessionID)
|
|
34259
34315
|
throw new Error("Failed to create session");
|
|
34260
|
-
|
|
34316
|
+
const promptBody = {
|
|
34317
|
+
parts: [{ type: "text", text: enhancedPrompt }]
|
|
34318
|
+
};
|
|
34319
|
+
if (parentModel) {
|
|
34320
|
+
promptBody.model = parentModel;
|
|
34321
|
+
log(`Using parent model for sync agent call`, { subagent_type, ...parentModel });
|
|
34322
|
+
}
|
|
34323
|
+
const promptResp = await ctx.client.session.prompt({
|
|
34261
34324
|
path: { id: sessionID },
|
|
34262
|
-
body:
|
|
34263
|
-
parts: [{ type: "text", text: enhancedPrompt }]
|
|
34264
|
-
},
|
|
34325
|
+
body: promptBody,
|
|
34265
34326
|
query: { directory: ctx.directory }
|
|
34266
34327
|
});
|
|
34267
|
-
|
|
34268
|
-
|
|
34269
|
-
|
|
34270
|
-
|
|
34271
|
-
|
|
34272
|
-
|
|
34328
|
+
if (promptResp.error) {
|
|
34329
|
+
return JSON.stringify({
|
|
34330
|
+
session_id: sessionID,
|
|
34331
|
+
status: "failed",
|
|
34332
|
+
error: `Prompt failed: ${JSON.stringify(promptResp.error)}`
|
|
34333
|
+
});
|
|
34334
|
+
}
|
|
34335
|
+
const promptData = promptResp.data;
|
|
34336
|
+
if (promptData?.info?.error) {
|
|
34337
|
+
const err = promptData.info.error;
|
|
34338
|
+
const errMsg = err.data?.message || err.name || "Unknown error";
|
|
34339
|
+
return JSON.stringify({
|
|
34340
|
+
session_id: sessionID,
|
|
34341
|
+
status: "failed",
|
|
34342
|
+
error: `[${err.name}] ${errMsg}`
|
|
34343
|
+
});
|
|
34344
|
+
}
|
|
34345
|
+
const result = promptData?.parts?.filter((p) => p.type === "text" && p.text).map((p) => p.text).join(`
|
|
34273
34346
|
`) || "";
|
|
34274
34347
|
return JSON.stringify({
|
|
34275
34348
|
session_id: sessionID,
|
|
@@ -34288,16 +34361,20 @@ ${prompt}`;
|
|
|
34288
34361
|
|
|
34289
34362
|
// src/config/model-resolver.ts
|
|
34290
34363
|
var HARDCODED_TIER_DEFAULTS = {
|
|
34291
|
-
haiku: "
|
|
34292
|
-
sonnet: "
|
|
34293
|
-
opus: "
|
|
34364
|
+
haiku: "haiku",
|
|
34365
|
+
sonnet: "sonnet",
|
|
34366
|
+
opus: "opus"
|
|
34294
34367
|
};
|
|
34368
|
+
var SIMPLE_TIER_NAMES = new Set(["haiku", "sonnet", "opus"]);
|
|
34295
34369
|
function isValidModelFormat(model) {
|
|
34370
|
+
if (SIMPLE_TIER_NAMES.has(model.toLowerCase())) {
|
|
34371
|
+
return true;
|
|
34372
|
+
}
|
|
34296
34373
|
return /^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test(model);
|
|
34297
34374
|
}
|
|
34298
34375
|
function validateModelFormat(model, context) {
|
|
34299
34376
|
if (!isValidModelFormat(model)) {
|
|
34300
|
-
warn(`[model-resolver] [${context}] Model "${model}" does not follow "provider/model-name" format`);
|
|
34377
|
+
warn(`[model-resolver] [${context}] Model "${model}" does not follow "provider/model-name" format. Configure model_mapping.tierDefaults in oh-my-opencode.json`);
|
|
34301
34378
|
}
|
|
34302
34379
|
}
|
|
34303
34380
|
|
|
@@ -38229,6 +38306,19 @@ function getAgentEmoji(agentName) {
|
|
|
38229
38306
|
return emojiMap[agentName] || "\uD83E\uDD16";
|
|
38230
38307
|
}
|
|
38231
38308
|
|
|
38309
|
+
// src/state/session-pause-state.ts
|
|
38310
|
+
var pauseStates = new Map;
|
|
38311
|
+
function isSessionPaused(sessionId) {
|
|
38312
|
+
return pauseStates.get(sessionId)?.isPaused ?? false;
|
|
38313
|
+
}
|
|
38314
|
+
function resumeSession(sessionId) {
|
|
38315
|
+
const state = pauseStates.get(sessionId);
|
|
38316
|
+
if (state?.isPaused) {
|
|
38317
|
+
log(`Session resumed`, { sessionId, wasPausedFor: Date.now() - (state.pausedAt ?? 0) });
|
|
38318
|
+
}
|
|
38319
|
+
pauseStates.delete(sessionId);
|
|
38320
|
+
}
|
|
38321
|
+
|
|
38232
38322
|
// src/index.ts
|
|
38233
38323
|
var OmoOmcsPlugin = async (ctx) => {
|
|
38234
38324
|
const pluginConfig = loadConfig(ctx.directory);
|
|
@@ -38335,6 +38425,10 @@ var OmoOmcsPlugin = async (ctx) => {
|
|
|
38335
38425
|
} else {
|
|
38336
38426
|
systemPromptInjector.clearSkillInjection(input.sessionID);
|
|
38337
38427
|
}
|
|
38428
|
+
if (isSessionPaused(input.sessionID)) {
|
|
38429
|
+
resumeSession(input.sessionID);
|
|
38430
|
+
log("[session] Auto-resumed on user prompt", { sessionID: input.sessionID });
|
|
38431
|
+
}
|
|
38338
38432
|
await autopilot["chat.message"](input, output);
|
|
38339
38433
|
await ultraqaLoop["chat.message"](input, output);
|
|
38340
38434
|
},
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared session pause state for coordinating abort handling across hooks.
|
|
3
|
+
* When user presses ESC (triggers MessageAbortedError), the session is paused
|
|
4
|
+
* and remains paused until explicitly resumed or user sends a new prompt.
|
|
5
|
+
*/
|
|
6
|
+
interface SessionPauseState {
|
|
7
|
+
isPaused: boolean;
|
|
8
|
+
pausedAt: number | null;
|
|
9
|
+
pauseReason: 'user_abort' | 'error' | 'explicit' | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pause a session, preventing automatic continuations.
|
|
13
|
+
* Called when MessageAbortedError is detected (user pressed ESC).
|
|
14
|
+
*/
|
|
15
|
+
export declare function pauseSession(sessionId: string, reason?: SessionPauseState['pauseReason']): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a session is currently paused.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isSessionPaused(sessionId: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Get the pause state for a session.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getSessionPauseState(sessionId: string): SessionPauseState | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Resume a session, allowing automatic continuations.
|
|
26
|
+
* Called when user sends a new prompt or explicitly resumes.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resumeSession(sessionId: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Clear session state when session is deleted.
|
|
31
|
+
*/
|
|
32
|
+
export declare function clearSessionPauseState(sessionId: string): void;
|
|
33
|
+
export {};
|
|
@@ -11,12 +11,17 @@ export interface BackgroundTask {
|
|
|
11
11
|
startedAt: number;
|
|
12
12
|
completedAt?: number;
|
|
13
13
|
}
|
|
14
|
+
export interface ModelConfig {
|
|
15
|
+
providerID: string;
|
|
16
|
+
modelID: string;
|
|
17
|
+
}
|
|
14
18
|
export interface BackgroundManager {
|
|
15
|
-
createTask: (parentSessionID: string, description: string, prompt: string, agent: string) => Promise<BackgroundTask>;
|
|
19
|
+
createTask: (parentSessionID: string, description: string, prompt: string, agent: string, model?: ModelConfig) => Promise<BackgroundTask>;
|
|
16
20
|
getTask: (taskId: string) => BackgroundTask | undefined;
|
|
17
21
|
getTasksByParentSession: (sessionID: string) => BackgroundTask[];
|
|
18
22
|
cancelTask: (taskId: string) => boolean;
|
|
19
23
|
cancelAllTasks: (parentSessionID?: string) => number;
|
|
20
24
|
waitForTask: (taskId: string, timeoutMs?: number) => Promise<BackgroundTask>;
|
|
25
|
+
getParentSessionModel: (parentSessionID: string) => Promise<ModelConfig | undefined>;
|
|
21
26
|
}
|
|
22
27
|
export declare function createBackgroundManager(ctx: PluginInput, config?: BackgroundTaskConfig): BackgroundManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-claudecode-opencode",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "OpenCode port of oh-my-claudecode - Multi-agent orchestration plugin (omco)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"prepublishOnly": "bun run clean && bun run build",
|
|
29
29
|
"typecheck": "tsc --noEmit",
|
|
30
30
|
"test": "bun test",
|
|
31
|
+
"test:e2e": "vitest run --config tests/e2e/vitest.config.ts",
|
|
32
|
+
"test:e2e:server": "vitest run --config tests/e2e/vitest.config.ts --testNamePattern 'Server'",
|
|
33
|
+
"test:all": "bun test && vitest run --config tests/e2e/vitest.config.ts",
|
|
31
34
|
"lint": "eslint src --ext .ts"
|
|
32
35
|
},
|
|
33
36
|
"keywords": [
|