oh-my-opencode-slim 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +80 -78
- package/dist/cli/providers.d.ts +1 -1
- package/dist/cli/skills.d.ts +17 -0
- package/dist/hooks/autopilot/index.d.ts +43 -0
- package/dist/hooks/delegate-task-retry/guidance.d.ts +2 -0
- package/dist/hooks/delegate-task-retry/hook.d.ts +8 -0
- package/dist/hooks/delegate-task-retry/index.d.ts +4 -0
- package/dist/hooks/delegate-task-retry/patterns.d.ts +11 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +18 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/index.js +214 -11
- package/package.json +1 -1
- package/dist/tools/quota/api.d.ts +0 -5
- package/dist/tools/quota/command.d.ts +0 -1
- package/dist/tools/quota/index.d.ts +0 -21
- package/dist/tools/quota/types.d.ts +0 -41
package/dist/cli/index.js
CHANGED
|
@@ -80,11 +80,11 @@ function pickSupportChutesModel(models, primaryModel) {
|
|
|
80
80
|
}
|
|
81
81
|
// src/cli/config-io.ts
|
|
82
82
|
import {
|
|
83
|
-
copyFileSync,
|
|
84
|
-
existsSync as
|
|
83
|
+
copyFileSync as copyFileSync2,
|
|
84
|
+
existsSync as existsSync3,
|
|
85
85
|
readFileSync,
|
|
86
86
|
renameSync,
|
|
87
|
-
statSync,
|
|
87
|
+
statSync as statSync2,
|
|
88
88
|
writeFileSync
|
|
89
89
|
} from "fs";
|
|
90
90
|
|
|
@@ -13729,7 +13729,7 @@ var BackgroundTaskConfigSchema = exports_external.object({
|
|
|
13729
13729
|
});
|
|
13730
13730
|
var FailoverConfigSchema = exports_external.object({
|
|
13731
13731
|
enabled: exports_external.boolean().default(true),
|
|
13732
|
-
timeoutMs: exports_external.number().min(
|
|
13732
|
+
timeoutMs: exports_external.number().min(0).default(15000),
|
|
13733
13733
|
chains: FallbackChainsSchema.default({})
|
|
13734
13734
|
});
|
|
13735
13735
|
var PluginConfigSchema = exports_external.object({
|
|
@@ -13756,6 +13756,67 @@ var DEFAULT_AGENT_MCPS = {
|
|
|
13756
13756
|
|
|
13757
13757
|
// src/cli/skills.ts
|
|
13758
13758
|
import { spawnSync } from "child_process";
|
|
13759
|
+
|
|
13760
|
+
// src/cli/custom-skills.ts
|
|
13761
|
+
import {
|
|
13762
|
+
copyFileSync,
|
|
13763
|
+
existsSync as existsSync2,
|
|
13764
|
+
mkdirSync as mkdirSync2,
|
|
13765
|
+
readdirSync,
|
|
13766
|
+
statSync
|
|
13767
|
+
} from "fs";
|
|
13768
|
+
import { homedir as homedir2 } from "os";
|
|
13769
|
+
import { dirname, join as join2 } from "path";
|
|
13770
|
+
import { fileURLToPath } from "url";
|
|
13771
|
+
var CUSTOM_SKILLS = [
|
|
13772
|
+
{
|
|
13773
|
+
name: "cartography",
|
|
13774
|
+
description: "Repository understanding and hierarchical codemap generation",
|
|
13775
|
+
allowedAgents: ["orchestrator", "explorer"],
|
|
13776
|
+
sourcePath: "src/skills/cartography"
|
|
13777
|
+
}
|
|
13778
|
+
];
|
|
13779
|
+
function getCustomSkillsDir() {
|
|
13780
|
+
return join2(homedir2(), ".config", "opencode", "skills");
|
|
13781
|
+
}
|
|
13782
|
+
function copyDirRecursive(src, dest) {
|
|
13783
|
+
if (!existsSync2(dest)) {
|
|
13784
|
+
mkdirSync2(dest, { recursive: true });
|
|
13785
|
+
}
|
|
13786
|
+
const entries = readdirSync(src);
|
|
13787
|
+
for (const entry of entries) {
|
|
13788
|
+
const srcPath = join2(src, entry);
|
|
13789
|
+
const destPath = join2(dest, entry);
|
|
13790
|
+
const stat = statSync(srcPath);
|
|
13791
|
+
if (stat.isDirectory()) {
|
|
13792
|
+
copyDirRecursive(srcPath, destPath);
|
|
13793
|
+
} else {
|
|
13794
|
+
const destDir = dirname(destPath);
|
|
13795
|
+
if (!existsSync2(destDir)) {
|
|
13796
|
+
mkdirSync2(destDir, { recursive: true });
|
|
13797
|
+
}
|
|
13798
|
+
copyFileSync(srcPath, destPath);
|
|
13799
|
+
}
|
|
13800
|
+
}
|
|
13801
|
+
}
|
|
13802
|
+
function installCustomSkill(skill) {
|
|
13803
|
+
try {
|
|
13804
|
+
const packageRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
13805
|
+
const sourcePath = join2(packageRoot, skill.sourcePath);
|
|
13806
|
+
const targetPath = join2(getCustomSkillsDir(), skill.name);
|
|
13807
|
+
if (!existsSync2(sourcePath)) {
|
|
13808
|
+
console.error(`Custom skill source not found: ${sourcePath}`);
|
|
13809
|
+
return false;
|
|
13810
|
+
}
|
|
13811
|
+
copyDirRecursive(sourcePath, targetPath);
|
|
13812
|
+
return true;
|
|
13813
|
+
} catch (error48) {
|
|
13814
|
+
console.error(`Failed to install custom skill: ${skill.name}`, error48);
|
|
13815
|
+
return false;
|
|
13816
|
+
}
|
|
13817
|
+
}
|
|
13818
|
+
|
|
13819
|
+
// src/cli/skills.ts
|
|
13759
13820
|
var RECOMMENDED_SKILLS = [
|
|
13760
13821
|
{
|
|
13761
13822
|
name: "simplify",
|
|
@@ -13863,7 +13924,7 @@ var MODEL_MAPPINGS = {
|
|
|
13863
13924
|
},
|
|
13864
13925
|
antigravity: {
|
|
13865
13926
|
orchestrator: { model: "google/antigravity-gemini-3-flash" },
|
|
13866
|
-
oracle: { model: "google/antigravity-gemini-3-pro" },
|
|
13927
|
+
oracle: { model: "google/antigravity-gemini-3.1-pro" },
|
|
13867
13928
|
librarian: {
|
|
13868
13929
|
model: "google/antigravity-gemini-3-flash",
|
|
13869
13930
|
variant: "low"
|
|
@@ -14203,9 +14264,9 @@ function stripJsonComments(json2) {
|
|
|
14203
14264
|
}
|
|
14204
14265
|
function parseConfigFile(path) {
|
|
14205
14266
|
try {
|
|
14206
|
-
if (!
|
|
14267
|
+
if (!existsSync3(path))
|
|
14207
14268
|
return { config: null };
|
|
14208
|
-
const stat =
|
|
14269
|
+
const stat = statSync2(path);
|
|
14209
14270
|
if (stat.size === 0)
|
|
14210
14271
|
return { config: null };
|
|
14211
14272
|
const content = readFileSync(path, "utf-8");
|
|
@@ -14234,8 +14295,8 @@ function writeConfig(configPath, config2) {
|
|
|
14234
14295
|
const bakPath = `${configPath}.bak`;
|
|
14235
14296
|
const content = `${JSON.stringify(config2, null, 2)}
|
|
14236
14297
|
`;
|
|
14237
|
-
if (
|
|
14238
|
-
|
|
14298
|
+
if (existsSync3(configPath)) {
|
|
14299
|
+
copyFileSync2(configPath, bakPath);
|
|
14239
14300
|
}
|
|
14240
14301
|
writeFileSync(tmpPath, content);
|
|
14241
14302
|
renameSync(tmpPath, configPath);
|
|
@@ -14284,8 +14345,8 @@ function writeLiteConfig(installConfig) {
|
|
|
14284
14345
|
const bakPath = `${configPath}.bak`;
|
|
14285
14346
|
const content = `${JSON.stringify(config2, null, 2)}
|
|
14286
14347
|
`;
|
|
14287
|
-
if (
|
|
14288
|
-
|
|
14348
|
+
if (existsSync3(configPath)) {
|
|
14349
|
+
copyFileSync2(configPath, bakPath);
|
|
14289
14350
|
}
|
|
14290
14351
|
writeFileSync(tmpPath, content);
|
|
14291
14352
|
renameSync(tmpPath, configPath);
|
|
@@ -14368,8 +14429,8 @@ function addGoogleProvider() {
|
|
|
14368
14429
|
const providers = config2.provider ?? {};
|
|
14369
14430
|
providers.google = {
|
|
14370
14431
|
models: {
|
|
14371
|
-
"antigravity-gemini-3-pro": {
|
|
14372
|
-
name: "Gemini 3 Pro (Antigravity)",
|
|
14432
|
+
"antigravity-gemini-3.1-pro": {
|
|
14433
|
+
name: "Gemini 3.1 Pro (Antigravity)",
|
|
14373
14434
|
limit: { context: 1048576, output: 65535 },
|
|
14374
14435
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] },
|
|
14375
14436
|
variants: {
|
|
@@ -14426,8 +14487,8 @@ function addGoogleProvider() {
|
|
|
14426
14487
|
limit: { context: 1048576, output: 65536 },
|
|
14427
14488
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
14428
14489
|
},
|
|
14429
|
-
"gemini-3-pro-preview": {
|
|
14430
|
-
name: "Gemini 3 Pro Preview (Gemini CLI)",
|
|
14490
|
+
"gemini-3.1-pro-preview": {
|
|
14491
|
+
name: "Gemini 3.1 Pro Preview (Gemini CLI)",
|
|
14431
14492
|
limit: { context: 1048576, output: 65535 },
|
|
14432
14493
|
modalities: { input: ["text", "image", "pdf"], output: ["text"] }
|
|
14433
14494
|
}
|
|
@@ -15751,7 +15812,7 @@ async function fetchExternalModelSignals(options) {
|
|
|
15751
15812
|
return { signals: aggregate, warnings };
|
|
15752
15813
|
}
|
|
15753
15814
|
// src/cli/system.ts
|
|
15754
|
-
import { statSync as
|
|
15815
|
+
import { statSync as statSync3 } from "fs";
|
|
15755
15816
|
var cachedOpenCodePath = null;
|
|
15756
15817
|
function getOpenCodePaths() {
|
|
15757
15818
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
@@ -15793,7 +15854,7 @@ function resolveOpenCodePath() {
|
|
|
15793
15854
|
if (opencodePath === "opencode")
|
|
15794
15855
|
continue;
|
|
15795
15856
|
try {
|
|
15796
|
-
const stat =
|
|
15857
|
+
const stat = statSync3(opencodePath);
|
|
15797
15858
|
if (stat.isFile()) {
|
|
15798
15859
|
cachedOpenCodePath = opencodePath;
|
|
15799
15860
|
return opencodePath;
|
|
@@ -16023,65 +16084,6 @@ function pickSupportOpenCodeModel(models, primaryModel) {
|
|
|
16023
16084
|
}, primaryModel);
|
|
16024
16085
|
return support;
|
|
16025
16086
|
}
|
|
16026
|
-
// src/cli/custom-skills.ts
|
|
16027
|
-
import {
|
|
16028
|
-
copyFileSync as copyFileSync2,
|
|
16029
|
-
existsSync as existsSync3,
|
|
16030
|
-
mkdirSync as mkdirSync2,
|
|
16031
|
-
readdirSync,
|
|
16032
|
-
statSync as statSync3
|
|
16033
|
-
} from "fs";
|
|
16034
|
-
import { homedir as homedir2 } from "os";
|
|
16035
|
-
import { dirname, join as join3 } from "path";
|
|
16036
|
-
import { fileURLToPath } from "url";
|
|
16037
|
-
var CUSTOM_SKILLS = [
|
|
16038
|
-
{
|
|
16039
|
-
name: "cartography",
|
|
16040
|
-
description: "Repository understanding and hierarchical codemap generation",
|
|
16041
|
-
allowedAgents: ["orchestrator"],
|
|
16042
|
-
sourcePath: "src/skills/cartography"
|
|
16043
|
-
}
|
|
16044
|
-
];
|
|
16045
|
-
function getCustomSkillsDir() {
|
|
16046
|
-
return join3(homedir2(), ".config", "opencode", "skills");
|
|
16047
|
-
}
|
|
16048
|
-
function copyDirRecursive(src, dest) {
|
|
16049
|
-
if (!existsSync3(dest)) {
|
|
16050
|
-
mkdirSync2(dest, { recursive: true });
|
|
16051
|
-
}
|
|
16052
|
-
const entries = readdirSync(src);
|
|
16053
|
-
for (const entry of entries) {
|
|
16054
|
-
const srcPath = join3(src, entry);
|
|
16055
|
-
const destPath = join3(dest, entry);
|
|
16056
|
-
const stat = statSync3(srcPath);
|
|
16057
|
-
if (stat.isDirectory()) {
|
|
16058
|
-
copyDirRecursive(srcPath, destPath);
|
|
16059
|
-
} else {
|
|
16060
|
-
const destDir = dirname(destPath);
|
|
16061
|
-
if (!existsSync3(destDir)) {
|
|
16062
|
-
mkdirSync2(destDir, { recursive: true });
|
|
16063
|
-
}
|
|
16064
|
-
copyFileSync2(srcPath, destPath);
|
|
16065
|
-
}
|
|
16066
|
-
}
|
|
16067
|
-
}
|
|
16068
|
-
function installCustomSkill(skill) {
|
|
16069
|
-
try {
|
|
16070
|
-
const packageRoot = fileURLToPath(new URL("../..", import.meta.url));
|
|
16071
|
-
const sourcePath = join3(packageRoot, skill.sourcePath);
|
|
16072
|
-
const targetPath = join3(getCustomSkillsDir(), skill.name);
|
|
16073
|
-
if (!existsSync3(sourcePath)) {
|
|
16074
|
-
console.error(`Custom skill source not found: ${sourcePath}`);
|
|
16075
|
-
return false;
|
|
16076
|
-
}
|
|
16077
|
-
copyDirRecursive(sourcePath, targetPath);
|
|
16078
|
-
return true;
|
|
16079
|
-
} catch (error48) {
|
|
16080
|
-
console.error(`Failed to install custom skill: ${skill.name}`, error48);
|
|
16081
|
-
return false;
|
|
16082
|
-
}
|
|
16083
|
-
}
|
|
16084
|
-
|
|
16085
16087
|
// src/cli/install.ts
|
|
16086
16088
|
var GREEN = "\x1B[32m";
|
|
16087
16089
|
var BLUE = "\x1B[34m";
|
|
@@ -16430,8 +16432,8 @@ async function runManualSetupMode(rl, detected, modelsOnly = false) {
|
|
|
16430
16432
|
}
|
|
16431
16433
|
if (antigravity === "yes") {
|
|
16432
16434
|
availableModels.push({
|
|
16433
|
-
model: "google/antigravity-gemini-3-pro",
|
|
16434
|
-
name: "Gemini 3 Pro"
|
|
16435
|
+
model: "google/antigravity-gemini-3.1-pro",
|
|
16436
|
+
name: "Gemini 3.1 Pro"
|
|
16435
16437
|
});
|
|
16436
16438
|
availableModels.push({
|
|
16437
16439
|
model: "google/antigravity-gemini-3-flash",
|
package/dist/cli/providers.d.ts
CHANGED
|
@@ -130,7 +130,7 @@ export declare const MODEL_MAPPINGS: {
|
|
|
130
130
|
readonly model: "google/antigravity-gemini-3-flash";
|
|
131
131
|
};
|
|
132
132
|
readonly oracle: {
|
|
133
|
-
readonly model: "google/antigravity-gemini-3-pro";
|
|
133
|
+
readonly model: "google/antigravity-gemini-3.1-pro";
|
|
134
134
|
};
|
|
135
135
|
readonly librarian: {
|
|
136
136
|
readonly model: "google/antigravity-gemini-3-flash";
|
package/dist/cli/skills.d.ts
CHANGED
|
@@ -15,11 +15,28 @@ export interface RecommendedSkill {
|
|
|
15
15
|
/** Optional commands to run after the skill is added */
|
|
16
16
|
postInstallCommands?: string[];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A skill that is managed externally (e.g. user-installed) and needs
|
|
20
|
+
* permission grants but is NOT installed by this plugin's CLI.
|
|
21
|
+
*/
|
|
22
|
+
export interface PermissionOnlySkill {
|
|
23
|
+
/** Skill name — must match the name OpenCode uses for permission checks */
|
|
24
|
+
name: string;
|
|
25
|
+
/** List of agents that should auto-allow this skill */
|
|
26
|
+
allowedAgents: string[];
|
|
27
|
+
/** Human-readable description (for documentation only) */
|
|
28
|
+
description: string;
|
|
29
|
+
}
|
|
18
30
|
/**
|
|
19
31
|
* List of recommended skills.
|
|
20
32
|
* Add new skills here to include them in the installation flow.
|
|
21
33
|
*/
|
|
22
34
|
export declare const RECOMMENDED_SKILLS: RecommendedSkill[];
|
|
35
|
+
/**
|
|
36
|
+
* Skills managed externally (not installed by this plugin's CLI).
|
|
37
|
+
* Entries here only affect agent permission grants — nothing is installed.
|
|
38
|
+
*/
|
|
39
|
+
export declare const PERMISSION_ONLY_SKILLS: PermissionOnlySkill[];
|
|
23
40
|
/**
|
|
24
41
|
* Install a skill using `npx skills add`.
|
|
25
42
|
* @param skill - The skill to install
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
import type { PluginConfig } from '../../config';
|
|
3
|
+
declare const AUTOPILOT_CONTINUE_PROMPT = "[AUTOPILOT] Continue executing work in this same session now. Do not acknowledge autopilot, do not ask for confirmation, and do not stop after a status message. Perform the next concrete action immediately (run a tool/command, edit files, or advance the active todo). Only stop when all todos are completed/cancelled or the user explicitly disables autopilot.";
|
|
4
|
+
interface MessagePart {
|
|
5
|
+
type: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
}
|
|
8
|
+
interface TodoEntry {
|
|
9
|
+
status?: string;
|
|
10
|
+
}
|
|
11
|
+
type AutopilotCommand = 'enable' | 'disable' | 'status' | null;
|
|
12
|
+
declare function parseAutopilotCommand(text: string, keyword: string, disableKeyword: string): AutopilotCommand;
|
|
13
|
+
declare function extractTodoList(data: unknown): TodoEntry[];
|
|
14
|
+
declare function isActiveTodo(todo: TodoEntry): boolean;
|
|
15
|
+
export declare function createAutopilotHook(ctx: PluginInput, config: PluginConfig): {
|
|
16
|
+
'chat.message': (input: {
|
|
17
|
+
sessionID: string;
|
|
18
|
+
agent?: string;
|
|
19
|
+
messageID?: string;
|
|
20
|
+
}, output: {
|
|
21
|
+
parts: MessagePart[];
|
|
22
|
+
}) => Promise<void>;
|
|
23
|
+
event: (input: {
|
|
24
|
+
event: {
|
|
25
|
+
type: string;
|
|
26
|
+
properties?: {
|
|
27
|
+
sessionID?: string;
|
|
28
|
+
status?: {
|
|
29
|
+
type?: string;
|
|
30
|
+
};
|
|
31
|
+
info?: {
|
|
32
|
+
id?: string;
|
|
33
|
+
role?: string;
|
|
34
|
+
sessionID?: string;
|
|
35
|
+
time?: {
|
|
36
|
+
completed?: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}) => Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
export { AUTOPILOT_CONTINUE_PROMPT, extractTodoList, isActiveTodo, parseAutopilotCommand, };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DelegateTaskErrorPattern {
|
|
2
|
+
pattern: string;
|
|
3
|
+
errorType: string;
|
|
4
|
+
fixHint: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const DELEGATE_TASK_ERROR_PATTERNS: DelegateTaskErrorPattern[];
|
|
7
|
+
export interface DetectedError {
|
|
8
|
+
errorType: string;
|
|
9
|
+
originalOutput: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function detectDelegateTaskError(output: string): DetectedError | null;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export type { AutoUpdateCheckerOptions } from './auto-update-checker';
|
|
2
2
|
export { createAutoUpdateCheckerHook } from './auto-update-checker';
|
|
3
|
+
export { createDelegateTaskRetryHook } from './delegate-task-retry';
|
|
4
|
+
export { createJsonErrorRecoveryHook } from './json-error-recovery';
|
|
3
5
|
export { createPhaseReminderHook } from './phase-reminder';
|
|
4
6
|
export { createPostReadNudgeHook } from './post-read-nudge';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PluginInput } from '@opencode-ai/plugin';
|
|
2
|
+
export declare const JSON_ERROR_TOOL_EXCLUDE_LIST: readonly ["bash", "read", "glob", "grep", "webfetch", "grep_app_searchgithub", "websearch_web_search_exa"];
|
|
3
|
+
export declare const JSON_ERROR_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp, RegExp];
|
|
4
|
+
export declare const JSON_ERROR_REMINDER = "\n[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]\n\nYou sent invalid JSON arguments. The system could not parse your tool call.\nSTOP and do this NOW:\n\n1. LOOK at the error message above to see what was expected vs what you sent.\n2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).\n3. RETRY the tool call with valid JSON.\n\nDO NOT repeat the exact same invalid call.\n";
|
|
5
|
+
interface ToolExecuteAfterInput {
|
|
6
|
+
tool: string;
|
|
7
|
+
sessionID: string;
|
|
8
|
+
callID: string;
|
|
9
|
+
}
|
|
10
|
+
interface ToolExecuteAfterOutput {
|
|
11
|
+
title: string;
|
|
12
|
+
output: unknown;
|
|
13
|
+
metadata: unknown;
|
|
14
|
+
}
|
|
15
|
+
export declare function createJsonErrorRecoveryHook(_ctx: PluginInput): {
|
|
16
|
+
'tool.execute.after': (input: ToolExecuteAfterInput, output: ToolExecuteAfterOutput) => Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createJsonErrorRecoveryHook, JSON_ERROR_PATTERNS, JSON_ERROR_REMINDER, JSON_ERROR_TOOL_EXCLUDE_LIST, } from './hook';
|
package/dist/index.js
CHANGED
|
@@ -3277,6 +3277,16 @@ var require_main = __commonJS((exports) => {
|
|
|
3277
3277
|
exports.createMessageConnection = createMessageConnection;
|
|
3278
3278
|
});
|
|
3279
3279
|
|
|
3280
|
+
// src/cli/custom-skills.ts
|
|
3281
|
+
var CUSTOM_SKILLS = [
|
|
3282
|
+
{
|
|
3283
|
+
name: "cartography",
|
|
3284
|
+
description: "Repository understanding and hierarchical codemap generation",
|
|
3285
|
+
allowedAgents: ["orchestrator", "explorer"],
|
|
3286
|
+
sourcePath: "src/skills/cartography"
|
|
3287
|
+
}
|
|
3288
|
+
];
|
|
3289
|
+
|
|
3280
3290
|
// src/cli/skills.ts
|
|
3281
3291
|
var RECOMMENDED_SKILLS = [
|
|
3282
3292
|
{
|
|
@@ -3298,6 +3308,13 @@ var RECOMMENDED_SKILLS = [
|
|
|
3298
3308
|
]
|
|
3299
3309
|
}
|
|
3300
3310
|
];
|
|
3311
|
+
var PERMISSION_ONLY_SKILLS = [
|
|
3312
|
+
{
|
|
3313
|
+
name: "requesting-code-review",
|
|
3314
|
+
allowedAgents: ["oracle"],
|
|
3315
|
+
description: "Code review template for reviewer subagents in multi-step workflows"
|
|
3316
|
+
}
|
|
3317
|
+
];
|
|
3301
3318
|
function getSkillPermissionsForAgent(agentName, skillList) {
|
|
3302
3319
|
const permissions = {
|
|
3303
3320
|
"*": agentName === "orchestrator" ? "allow" : "deny"
|
|
@@ -3321,6 +3338,18 @@ function getSkillPermissionsForAgent(agentName, skillList) {
|
|
|
3321
3338
|
permissions[skill.skillName] = "allow";
|
|
3322
3339
|
}
|
|
3323
3340
|
}
|
|
3341
|
+
for (const skill of CUSTOM_SKILLS) {
|
|
3342
|
+
const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
|
|
3343
|
+
if (isAllowed) {
|
|
3344
|
+
permissions[skill.name] = "allow";
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
for (const skill of PERMISSION_ONLY_SKILLS) {
|
|
3348
|
+
const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
|
|
3349
|
+
if (isAllowed) {
|
|
3350
|
+
permissions[skill.name] = "allow";
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3324
3353
|
return permissions;
|
|
3325
3354
|
}
|
|
3326
3355
|
|
|
@@ -3340,8 +3369,8 @@ var ORCHESTRATOR_NAME = "orchestrator";
|
|
|
3340
3369
|
var ALL_AGENT_NAMES = [ORCHESTRATOR_NAME, ...SUBAGENT_NAMES];
|
|
3341
3370
|
var SUBAGENT_DELEGATION_RULES = {
|
|
3342
3371
|
orchestrator: SUBAGENT_NAMES,
|
|
3343
|
-
fixer: [
|
|
3344
|
-
designer: [
|
|
3372
|
+
fixer: [],
|
|
3373
|
+
designer: [],
|
|
3345
3374
|
explorer: [],
|
|
3346
3375
|
librarian: [],
|
|
3347
3376
|
oracle: []
|
|
@@ -17010,7 +17039,7 @@ var BackgroundTaskConfigSchema = exports_external.object({
|
|
|
17010
17039
|
});
|
|
17011
17040
|
var FailoverConfigSchema = exports_external.object({
|
|
17012
17041
|
enabled: exports_external.boolean().default(true),
|
|
17013
|
-
timeoutMs: exports_external.number().min(
|
|
17042
|
+
timeoutMs: exports_external.number().min(0).default(15000),
|
|
17014
17043
|
chains: FallbackChainsSchema.default({})
|
|
17015
17044
|
});
|
|
17016
17045
|
var PluginConfigSchema = exports_external.object({
|
|
@@ -17280,9 +17309,10 @@ var FIXER_PROMPT = `You are Fixer - a fast, focused implementation specialist.
|
|
|
17280
17309
|
|
|
17281
17310
|
**Constraints**:
|
|
17282
17311
|
- NO external research (no websearch, context7, grep_app)
|
|
17283
|
-
- NO delegation (no background_task)
|
|
17312
|
+
- NO delegation (no background_task, no spawning subagents)
|
|
17284
17313
|
- No multi-step research/planning; minimal execution sequence ok
|
|
17285
|
-
- If context is insufficient
|
|
17314
|
+
- If context is insufficient: use grep/glob/lsp_diagnostics directly \u2014 do not delegate
|
|
17315
|
+
- Only ask for missing inputs you truly cannot retrieve yourself
|
|
17286
17316
|
|
|
17287
17317
|
**Output Format**:
|
|
17288
17318
|
<summary>
|
|
@@ -17504,6 +17534,10 @@ Balance: respect dependencies, avoid parallelizing what must be sequential.
|
|
|
17504
17534
|
- Confirm specialists completed successfully
|
|
17505
17535
|
- Verify solution meets requirements
|
|
17506
17536
|
|
|
17537
|
+
## Agent Role Mapping
|
|
17538
|
+
When a workflow calls for an **implementer** subagent: dispatch \`@fixer\`. Fixer has enforced constraints (no research, no delegation, structured output) that match the implementer role exactly.
|
|
17539
|
+
When a workflow calls for a **reviewer** subagent: dispatch \`@oracle\`. Oracle has the depth for architectural review and access to code review skills.
|
|
17540
|
+
|
|
17507
17541
|
</Workflow>
|
|
17508
17542
|
|
|
17509
17543
|
<Communication>
|
|
@@ -18094,6 +18128,10 @@ class BackgroundTaskManager {
|
|
|
18094
18128
|
return chain;
|
|
18095
18129
|
}
|
|
18096
18130
|
async promptWithTimeout(args, timeoutMs) {
|
|
18131
|
+
if (timeoutMs <= 0) {
|
|
18132
|
+
await this.client.session.prompt(args);
|
|
18133
|
+
return;
|
|
18134
|
+
}
|
|
18097
18135
|
await Promise.race([
|
|
18098
18136
|
this.client.session.prompt(args),
|
|
18099
18137
|
new Promise((_, reject) => {
|
|
@@ -18143,8 +18181,8 @@ class BackgroundTaskManager {
|
|
|
18143
18181
|
tools: toolPermissions,
|
|
18144
18182
|
parts: [{ type: "text", text: task.prompt }]
|
|
18145
18183
|
});
|
|
18146
|
-
const timeoutMs = this.config?.fallback?.timeoutMs ?? FALLBACK_FAILOVER_TIMEOUT_MS;
|
|
18147
18184
|
const fallbackEnabled = this.config?.fallback?.enabled ?? true;
|
|
18185
|
+
const timeoutMs = fallbackEnabled ? this.config?.fallback?.timeoutMs ?? FALLBACK_FAILOVER_TIMEOUT_MS : 0;
|
|
18148
18186
|
const chain = fallbackEnabled ? this.resolveFallbackChain(task.agent) : [];
|
|
18149
18187
|
const attemptModels = chain.length > 0 ? chain : [undefined];
|
|
18150
18188
|
const errors3 = [];
|
|
@@ -18933,10 +18971,169 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
|
18933
18971
|
body: { title, message, variant, duration: duration3 }
|
|
18934
18972
|
}).catch(() => {});
|
|
18935
18973
|
}
|
|
18974
|
+
// src/hooks/delegate-task-retry/patterns.ts
|
|
18975
|
+
var DELEGATE_TASK_ERROR_PATTERNS = [
|
|
18976
|
+
{
|
|
18977
|
+
pattern: "run_in_background",
|
|
18978
|
+
errorType: "missing_run_in_background",
|
|
18979
|
+
fixHint: "Add run_in_background=false (delegation) or run_in_background=true (parallel exploration)."
|
|
18980
|
+
},
|
|
18981
|
+
{
|
|
18982
|
+
pattern: "load_skills",
|
|
18983
|
+
errorType: "missing_load_skills",
|
|
18984
|
+
fixHint: "Add load_skills=[] (empty array when no skill is needed)."
|
|
18985
|
+
},
|
|
18986
|
+
{
|
|
18987
|
+
pattern: "category OR subagent_type",
|
|
18988
|
+
errorType: "mutual_exclusion",
|
|
18989
|
+
fixHint: 'Provide only one: category (e.g., "unspecified-low") OR subagent_type (e.g., "explorer").'
|
|
18990
|
+
},
|
|
18991
|
+
{
|
|
18992
|
+
pattern: "Must provide either category or subagent_type",
|
|
18993
|
+
errorType: "missing_category_or_agent",
|
|
18994
|
+
fixHint: 'Add either category="unspecified-low" or subagent_type="explorer".'
|
|
18995
|
+
},
|
|
18996
|
+
{
|
|
18997
|
+
pattern: "Unknown category",
|
|
18998
|
+
errorType: "unknown_category",
|
|
18999
|
+
fixHint: "Use a valid category listed in the error output."
|
|
19000
|
+
},
|
|
19001
|
+
{
|
|
19002
|
+
pattern: "Unknown agent",
|
|
19003
|
+
errorType: "unknown_agent",
|
|
19004
|
+
fixHint: "Use a valid agent name from the available list."
|
|
19005
|
+
},
|
|
19006
|
+
{
|
|
19007
|
+
pattern: "Skills not found",
|
|
19008
|
+
errorType: "unknown_skills",
|
|
19009
|
+
fixHint: "Use valid skill names listed in the error output."
|
|
19010
|
+
},
|
|
19011
|
+
{
|
|
19012
|
+
pattern: "is not allowed. Allowed agents:",
|
|
19013
|
+
errorType: "background_agent_not_allowed",
|
|
19014
|
+
fixHint: "Use one of the allowed agents shown in the error or delegate from a parent agent that can call this subagent."
|
|
19015
|
+
}
|
|
19016
|
+
];
|
|
19017
|
+
function detectDelegateTaskError(output) {
|
|
19018
|
+
if (!output || typeof output !== "string")
|
|
19019
|
+
return null;
|
|
19020
|
+
const hasErrorSignal = output.includes("[ERROR]") || output.includes("Invalid arguments") || output.includes("is not allowed. Allowed agents:");
|
|
19021
|
+
if (!hasErrorSignal)
|
|
19022
|
+
return null;
|
|
19023
|
+
for (const pattern of DELEGATE_TASK_ERROR_PATTERNS) {
|
|
19024
|
+
if (output.includes(pattern.pattern)) {
|
|
19025
|
+
return {
|
|
19026
|
+
errorType: pattern.errorType,
|
|
19027
|
+
originalOutput: output
|
|
19028
|
+
};
|
|
19029
|
+
}
|
|
19030
|
+
}
|
|
19031
|
+
return null;
|
|
19032
|
+
}
|
|
19033
|
+
// src/hooks/delegate-task-retry/guidance.ts
|
|
19034
|
+
function extractAvailableList(output) {
|
|
19035
|
+
const match = output.match(/Allowed agents:\s*(.+)$/m);
|
|
19036
|
+
if (match)
|
|
19037
|
+
return match[1].trim();
|
|
19038
|
+
const available = output.match(/Available[^:]*:\s*(.+)$/m);
|
|
19039
|
+
if (available)
|
|
19040
|
+
return available[1].trim();
|
|
19041
|
+
return null;
|
|
19042
|
+
}
|
|
19043
|
+
function buildRetryGuidance(errorInfo) {
|
|
19044
|
+
const pattern = DELEGATE_TASK_ERROR_PATTERNS.find((p) => p.errorType === errorInfo.errorType);
|
|
19045
|
+
if (!pattern) {
|
|
19046
|
+
return `
|
|
19047
|
+
[delegate-task retry] Fix parameters and retry with corrected arguments.`;
|
|
19048
|
+
}
|
|
19049
|
+
const available = extractAvailableList(errorInfo.originalOutput);
|
|
19050
|
+
const lines = [
|
|
19051
|
+
"",
|
|
19052
|
+
"[delegate-task retry suggestion]",
|
|
19053
|
+
`Error type: ${errorInfo.errorType}`,
|
|
19054
|
+
`Fix: ${pattern.fixHint}`
|
|
19055
|
+
];
|
|
19056
|
+
if (available) {
|
|
19057
|
+
lines.push(`Available: ${available}`);
|
|
19058
|
+
}
|
|
19059
|
+
lines.push("Retry now with corrected parameters. Example:", 'task(description="...", prompt="...", category="unspecified-low", run_in_background=false, load_skills=[])');
|
|
19060
|
+
return lines.join(`
|
|
19061
|
+
`);
|
|
19062
|
+
}
|
|
19063
|
+
// src/hooks/delegate-task-retry/hook.ts
|
|
19064
|
+
function createDelegateTaskRetryHook(_ctx) {
|
|
19065
|
+
return {
|
|
19066
|
+
"tool.execute.after": async (input, output) => {
|
|
19067
|
+
const toolName = input.tool.toLowerCase();
|
|
19068
|
+
const isDelegateTool = toolName === "task" || toolName === "background_task";
|
|
19069
|
+
if (!isDelegateTool)
|
|
19070
|
+
return;
|
|
19071
|
+
if (typeof output.output !== "string")
|
|
19072
|
+
return;
|
|
19073
|
+
const detected = detectDelegateTaskError(output.output);
|
|
19074
|
+
if (!detected)
|
|
19075
|
+
return;
|
|
19076
|
+
output.output += `
|
|
19077
|
+
${buildRetryGuidance(detected)}`;
|
|
19078
|
+
}
|
|
19079
|
+
};
|
|
19080
|
+
}
|
|
19081
|
+
// src/hooks/json-error-recovery/hook.ts
|
|
19082
|
+
var JSON_ERROR_TOOL_EXCLUDE_LIST = [
|
|
19083
|
+
"bash",
|
|
19084
|
+
"read",
|
|
19085
|
+
"glob",
|
|
19086
|
+
"grep",
|
|
19087
|
+
"webfetch",
|
|
19088
|
+
"grep_app_searchgithub",
|
|
19089
|
+
"websearch_web_search_exa"
|
|
19090
|
+
];
|
|
19091
|
+
var JSON_ERROR_PATTERNS = [
|
|
19092
|
+
/json parse error/i,
|
|
19093
|
+
/failed to parse json/i,
|
|
19094
|
+
/invalid json/i,
|
|
19095
|
+
/malformed json/i,
|
|
19096
|
+
/unexpected end of json input/i,
|
|
19097
|
+
/syntaxerror:\s*unexpected token.*json/i,
|
|
19098
|
+
/json[^\n]*expected '\}'/i,
|
|
19099
|
+
/json[^\n]*unexpected eof/i
|
|
19100
|
+
];
|
|
19101
|
+
var JSON_ERROR_REMINDER_MARKER = "[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]";
|
|
19102
|
+
var JSON_ERROR_EXCLUDED_TOOLS = new Set(JSON_ERROR_TOOL_EXCLUDE_LIST);
|
|
19103
|
+
var JSON_ERROR_REMINDER = `
|
|
19104
|
+
[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]
|
|
19105
|
+
|
|
19106
|
+
You sent invalid JSON arguments. The system could not parse your tool call.
|
|
19107
|
+
STOP and do this NOW:
|
|
19108
|
+
|
|
19109
|
+
1. LOOK at the error message above to see what was expected vs what you sent.
|
|
19110
|
+
2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).
|
|
19111
|
+
3. RETRY the tool call with valid JSON.
|
|
19112
|
+
|
|
19113
|
+
DO NOT repeat the exact same invalid call.
|
|
19114
|
+
`;
|
|
19115
|
+
function createJsonErrorRecoveryHook(_ctx) {
|
|
19116
|
+
return {
|
|
19117
|
+
"tool.execute.after": async (input, output) => {
|
|
19118
|
+
if (JSON_ERROR_EXCLUDED_TOOLS.has(input.tool.toLowerCase()))
|
|
19119
|
+
return;
|
|
19120
|
+
if (typeof output.output !== "string")
|
|
19121
|
+
return;
|
|
19122
|
+
if (output.output.includes(JSON_ERROR_REMINDER_MARKER))
|
|
19123
|
+
return;
|
|
19124
|
+
const outputText = output.output;
|
|
19125
|
+
const hasJsonError = JSON_ERROR_PATTERNS.some((pattern) => pattern.test(outputText));
|
|
19126
|
+
if (hasJsonError) {
|
|
19127
|
+
output.output += `
|
|
19128
|
+
${JSON_ERROR_REMINDER}`;
|
|
19129
|
+
}
|
|
19130
|
+
}
|
|
19131
|
+
};
|
|
19132
|
+
}
|
|
18936
19133
|
// src/hooks/phase-reminder/index.ts
|
|
18937
|
-
var PHASE_REMINDER = `<reminder
|
|
18938
|
-
|
|
18939
|
-
|
|
19134
|
+
var PHASE_REMINDER = `<reminder>Recall Workflow Rules:
|
|
19135
|
+
Understand \u2192 find the best path (delegate based on rules and parallelize independent work) \u2192 execute \u2192 verify.
|
|
19136
|
+
If delegating, launch the specialist in the same turn you mention it.</reminder>`;
|
|
18940
19137
|
function createPhaseReminderHook() {
|
|
18941
19138
|
return {
|
|
18942
19139
|
"experimental.chat.messages.transform": async (_input, output) => {
|
|
@@ -18976,7 +19173,7 @@ ${originalText}`;
|
|
|
18976
19173
|
var NUDGE = `
|
|
18977
19174
|
|
|
18978
19175
|
---
|
|
18979
|
-
Reminder
|
|
19176
|
+
Workflow Reminder: delegate based on rules; If mentioning a specialist, launch it in this same turn.`;
|
|
18980
19177
|
function createPostReadNudgeHook() {
|
|
18981
19178
|
return {
|
|
18982
19179
|
"tool.execute.after": async (input, output) => {
|
|
@@ -33242,6 +33439,8 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33242
33439
|
});
|
|
33243
33440
|
const phaseReminderHook = createPhaseReminderHook();
|
|
33244
33441
|
const postReadNudgeHook = createPostReadNudgeHook();
|
|
33442
|
+
const delegateTaskRetryHook = createDelegateTaskRetryHook(ctx);
|
|
33443
|
+
const jsonErrorRecoveryHook = createJsonErrorRecoveryHook(ctx);
|
|
33245
33444
|
return {
|
|
33246
33445
|
name: "oh-my-opencode-slim",
|
|
33247
33446
|
agent: agents,
|
|
@@ -33301,7 +33500,11 @@ var OhMyOpenCodeLite = async (ctx) => {
|
|
|
33301
33500
|
await tmuxSessionManager.onSessionDeleted(input.event);
|
|
33302
33501
|
},
|
|
33303
33502
|
"experimental.chat.messages.transform": phaseReminderHook["experimental.chat.messages.transform"],
|
|
33304
|
-
"tool.execute.after":
|
|
33503
|
+
"tool.execute.after": async (input, output) => {
|
|
33504
|
+
await delegateTaskRetryHook["tool.execute.after"](input, output);
|
|
33505
|
+
await jsonErrorRecoveryHook["tool.execute.after"](input, output);
|
|
33506
|
+
await postReadNudgeHook["tool.execute.after"](input, output);
|
|
33507
|
+
}
|
|
33305
33508
|
};
|
|
33306
33509
|
};
|
|
33307
33510
|
var src_default = OhMyOpenCodeLite;
|
package/package.json
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Account, AccountQuotaResult, AccountsConfig } from './types';
|
|
2
|
-
export declare const CONFIG_PATHS: string[];
|
|
3
|
-
export declare function loadAccountsConfig(): AccountsConfig | null;
|
|
4
|
-
export declare function fetchAccountQuota(account: Account): Promise<AccountQuotaResult>;
|
|
5
|
-
export declare function fetchAllQuotas(accounts: Account[]): Promise<AccountQuotaResult[]>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compact quota display tool - groups models by quota family
|
|
3
|
-
*
|
|
4
|
-
* Output format:
|
|
5
|
-
* ```
|
|
6
|
-
* tornikevault
|
|
7
|
-
* Claude [░░░░░░░░░░] 0% 3h23m
|
|
8
|
-
* G-Flash [██████████] 100% 4h59m
|
|
9
|
-
* G-Pro [██████████] 100% 4h59m
|
|
10
|
-
*
|
|
11
|
-
* tzedgin
|
|
12
|
-
* Claude [░░░░░░░░░░] 0% 1h41m
|
|
13
|
-
* G-Flash [██████████] 100% 4h59m
|
|
14
|
-
* G-Pro [██████████] 100% 4h59m
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export declare const antigravity_quota: {
|
|
18
|
-
description: string;
|
|
19
|
-
args: {};
|
|
20
|
-
execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
21
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export interface Account {
|
|
2
|
-
email: string;
|
|
3
|
-
refreshToken: string;
|
|
4
|
-
projectId?: string;
|
|
5
|
-
managedProjectId?: string;
|
|
6
|
-
rateLimitResetTimes: Record<string, number>;
|
|
7
|
-
}
|
|
8
|
-
export interface AccountsConfig {
|
|
9
|
-
accounts: Account[];
|
|
10
|
-
activeIndex: number;
|
|
11
|
-
}
|
|
12
|
-
export interface QuotaInfo {
|
|
13
|
-
remainingFraction?: number;
|
|
14
|
-
resetTime?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface ModelInfo {
|
|
17
|
-
displayName?: string;
|
|
18
|
-
model?: string;
|
|
19
|
-
quotaInfo?: QuotaInfo;
|
|
20
|
-
recommended?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export interface QuotaResponse {
|
|
23
|
-
models?: Record<string, ModelInfo>;
|
|
24
|
-
}
|
|
25
|
-
export interface TokenResponse {
|
|
26
|
-
access_token: string;
|
|
27
|
-
}
|
|
28
|
-
export interface LoadCodeAssistResponse {
|
|
29
|
-
cloudaicompanionProject?: unknown;
|
|
30
|
-
}
|
|
31
|
-
export interface ModelQuota {
|
|
32
|
-
name: string;
|
|
33
|
-
percent: number;
|
|
34
|
-
resetIn: string;
|
|
35
|
-
}
|
|
36
|
-
export interface AccountQuotaResult {
|
|
37
|
-
email: string;
|
|
38
|
-
success: boolean;
|
|
39
|
-
error?: string;
|
|
40
|
-
models: ModelQuota[];
|
|
41
|
-
}
|