oh-my-opencode-slim 0.7.0 → 0.8.0

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 @@
1
+ export declare function buildModelKeyAliases(input: string): string[];
@@ -12,3 +12,7 @@ export declare function discoverProviderFreeModels(providerID: string): Promise<
12
12
  models: OpenCodeFreeModel[];
13
13
  error?: string;
14
14
  }>;
15
+ export declare function discoverProviderModels(providerID: string): Promise<{
16
+ models: DiscoveredModel[];
17
+ error?: string;
18
+ }>;
@@ -3,5 +3,7 @@ export declare function getOpenCodeConfigPaths(): string[];
3
3
  export declare function getConfigJson(): string;
4
4
  export declare function getConfigJsonc(): string;
5
5
  export declare function getLiteConfig(): string;
6
+ export declare function getLiteConfigJsonc(): string;
7
+ export declare function getExistingLiteConfigPath(): string;
6
8
  export declare function getExistingConfigPath(): string;
7
9
  export declare function ensureConfigDir(): void;
@@ -0,0 +1,16 @@
1
+ import type { AgentResolutionProvenance } from './types';
2
+ export interface AgentLayerInput {
3
+ agentName: string;
4
+ openCodeDirectOverride?: string;
5
+ manualUserPlan?: string[];
6
+ pinnedModel?: string;
7
+ dynamicRecommendation?: string[];
8
+ providerFallbackPolicy?: string[];
9
+ systemDefault: string[];
10
+ }
11
+ export interface ResolvedAgentLayerResult {
12
+ model: string;
13
+ chain: string[];
14
+ provenance: AgentResolutionProvenance;
15
+ }
16
+ export declare function resolveAgentWithPrecedence(input: AgentLayerInput): ResolvedAgentLayerResult;
@@ -0,0 +1,4 @@
1
+ import type { DiscoveredModel, ExternalSignalMap } from '../types';
2
+ import type { ScoredCandidate, ScoringAgentName } from './types';
3
+ export declare function scoreCandidateV2(model: DiscoveredModel, agent: ScoringAgentName, externalSignals?: ExternalSignalMap): ScoredCandidate;
4
+ export declare function rankModelsV2(models: DiscoveredModel[], agent: ScoringAgentName, externalSignals?: ExternalSignalMap): ScoredCandidate[];
@@ -0,0 +1,3 @@
1
+ import type { DiscoveredModel, ExternalSignalMap } from '../types';
2
+ import type { FeatureVector, ScoringAgentName } from './types';
3
+ export declare function extractFeatureVector(model: DiscoveredModel, agent: ScoringAgentName, externalSignals?: ExternalSignalMap): FeatureVector;
@@ -0,0 +1,4 @@
1
+ export { rankModelsV2, scoreCandidateV2 } from './engine';
2
+ export { extractFeatureVector } from './features';
3
+ export type { FeatureVector, ScoredCandidate, ScoringAgentName, } from './types';
4
+ export { getFeatureWeights } from './weights';
@@ -0,0 +1,17 @@
1
+ import type { DiscoveredModel, ExternalSignalMap } from '../types';
2
+ export type ScoreFeatureName = 'status' | 'context' | 'output' | 'versionBonus' | 'reasoning' | 'toolcall' | 'attachment' | 'quality' | 'coding' | 'latencyPenalty' | 'pricePenalty';
3
+ export type FeatureVector = Record<ScoreFeatureName, number>;
4
+ export type FeatureWeights = Record<ScoreFeatureName, number>;
5
+ export type ScoringAgentName = 'orchestrator' | 'oracle' | 'designer' | 'explorer' | 'librarian' | 'fixer';
6
+ export interface ScoringContext {
7
+ agent: ScoringAgentName;
8
+ externalSignals?: ExternalSignalMap;
9
+ }
10
+ export interface ScoredCandidate {
11
+ model: DiscoveredModel;
12
+ totalScore: number;
13
+ scoreBreakdown: {
14
+ features: FeatureVector;
15
+ weighted: FeatureVector;
16
+ };
17
+ }
@@ -0,0 +1,2 @@
1
+ import type { FeatureWeights, ScoringAgentName } from './types';
2
+ export declare function getFeatureWeights(agent: ScoringAgentName): FeatureWeights;
@@ -1,4 +1,6 @@
1
+ export declare function resolveOpenCodePath(): string;
1
2
  export declare function isOpenCodeInstalled(): Promise<boolean>;
2
3
  export declare function isTmuxInstalled(): Promise<boolean>;
3
4
  export declare function getOpenCodeVersion(): Promise<string | null>;
5
+ export declare function getOpenCodePath(): string | null;
4
6
  export declare function fetchLatestVersion(packageName: string): Promise<string | null>;
@@ -11,7 +11,12 @@ export interface InstallArgs {
11
11
  tmux?: BooleanArg;
12
12
  skills?: BooleanArg;
13
13
  opencodeFree?: BooleanArg;
14
+ balancedSpend?: BooleanArg;
14
15
  opencodeFreeModel?: string;
16
+ aaKey?: string;
17
+ openrouterKey?: string;
18
+ dryRun?: boolean;
19
+ modelsOnly?: boolean;
15
20
  }
16
21
  export interface OpenCodeFreeModel {
17
22
  providerID: string;
@@ -43,10 +48,41 @@ export interface DynamicAgentAssignment {
43
48
  model: string;
44
49
  variant?: string;
45
50
  }
51
+ export type ScoringEngineVersion = 'v1' | 'v2-shadow' | 'v2';
52
+ export type ResolutionLayerName = 'opencode-direct-override' | 'manual-user-plan' | 'pinned-model' | 'dynamic-recommendation' | 'provider-fallback-policy' | 'system-default';
53
+ export interface AgentResolutionProvenance {
54
+ winnerLayer: ResolutionLayerName;
55
+ winnerModel: string;
56
+ }
57
+ export interface DynamicPlanScoringMeta {
58
+ engineVersionApplied: 'v1' | 'v2';
59
+ shadowCompared: boolean;
60
+ diffs?: Record<string, {
61
+ v1TopModel?: string;
62
+ v2TopModel?: string;
63
+ }>;
64
+ }
46
65
  export interface DynamicModelPlan {
47
66
  agents: Record<string, DynamicAgentAssignment>;
48
67
  chains: Record<string, string[]>;
68
+ provenance?: Record<string, AgentResolutionProvenance>;
69
+ scoring?: DynamicPlanScoringMeta;
70
+ }
71
+ export interface ExternalModelSignal {
72
+ qualityScore?: number;
73
+ codingScore?: number;
74
+ latencySeconds?: number;
75
+ inputPricePer1M?: number;
76
+ outputPricePer1M?: number;
77
+ source: 'artificial-analysis' | 'openrouter' | 'merged';
49
78
  }
79
+ export type ExternalSignalMap = Record<string, ExternalModelSignal>;
80
+ export type ManualAgentConfig = {
81
+ primary: string;
82
+ fallback1: string;
83
+ fallback2: string;
84
+ fallback3: string;
85
+ };
50
86
  export interface OpenCodeConfig {
51
87
  plugin?: string[];
52
88
  provider?: Record<string, unknown>;
@@ -69,11 +105,19 @@ export interface InstallConfig {
69
105
  availableOpenCodeFreeModels?: OpenCodeFreeModel[];
70
106
  selectedChutesPrimaryModel?: string;
71
107
  selectedChutesSecondaryModel?: string;
72
- availableChutesFreeModels?: OpenCodeFreeModel[];
108
+ availableChutesModels?: DiscoveredModel[];
73
109
  dynamicModelPlan?: DynamicModelPlan;
110
+ scoringEngineVersion?: ScoringEngineVersion;
111
+ artificialAnalysisApiKey?: string;
112
+ openRouterApiKey?: string;
113
+ balanceProviderUsage?: boolean;
74
114
  hasTmux: boolean;
75
115
  installSkills: boolean;
76
116
  installCustomSkills: boolean;
117
+ setupMode: 'quick' | 'manual';
118
+ manualAgentConfigs?: Record<string, ManualAgentConfig>;
119
+ dryRun?: boolean;
120
+ modelsOnly?: boolean;
77
121
  }
78
122
  export interface ConfigMergeResult {
79
123
  success: boolean;
@@ -3,6 +3,7 @@ export declare const SUBAGENT_NAMES: readonly ["explorer", "librarian", "oracle"
3
3
  export declare const ORCHESTRATOR_NAME: "orchestrator";
4
4
  export declare const ALL_AGENT_NAMES: readonly ["orchestrator", "explorer", "librarian", "oracle", "designer", "fixer"];
5
5
  export type AgentName = (typeof ALL_AGENT_NAMES)[number];
6
+ export declare const SUBAGENT_DELEGATION_RULES: Record<AgentName, readonly string[]>;
6
7
  export declare const DEFAULT_MODELS: Record<AgentName, string>;
7
8
  export declare const POLL_INTERVAL_MS = 500;
8
9
  export declare const POLL_INTERVAL_SLOW_MS = 1000;
@@ -1,5 +1,53 @@
1
1
  import { z } from 'zod';
2
2
  declare const FALLBACK_AGENT_NAMES: readonly ["orchestrator", "oracle", "designer", "explorer", "librarian", "fixer"];
3
+ declare const MANUAL_AGENT_NAMES: readonly ["orchestrator", "oracle", "designer", "explorer", "librarian", "fixer"];
4
+ export declare const ManualAgentPlanSchema: z.ZodObject<{
5
+ primary: z.ZodString;
6
+ fallback1: z.ZodString;
7
+ fallback2: z.ZodString;
8
+ fallback3: z.ZodString;
9
+ }, z.core.$strip>;
10
+ export declare const ManualPlanSchema: z.ZodObject<{
11
+ orchestrator: z.ZodObject<{
12
+ primary: z.ZodString;
13
+ fallback1: z.ZodString;
14
+ fallback2: z.ZodString;
15
+ fallback3: z.ZodString;
16
+ }, z.core.$strip>;
17
+ oracle: z.ZodObject<{
18
+ primary: z.ZodString;
19
+ fallback1: z.ZodString;
20
+ fallback2: z.ZodString;
21
+ fallback3: z.ZodString;
22
+ }, z.core.$strip>;
23
+ designer: z.ZodObject<{
24
+ primary: z.ZodString;
25
+ fallback1: z.ZodString;
26
+ fallback2: z.ZodString;
27
+ fallback3: z.ZodString;
28
+ }, z.core.$strip>;
29
+ explorer: z.ZodObject<{
30
+ primary: z.ZodString;
31
+ fallback1: z.ZodString;
32
+ fallback2: z.ZodString;
33
+ fallback3: z.ZodString;
34
+ }, z.core.$strip>;
35
+ librarian: z.ZodObject<{
36
+ primary: z.ZodString;
37
+ fallback1: z.ZodString;
38
+ fallback2: z.ZodString;
39
+ fallback3: z.ZodString;
40
+ }, z.core.$strip>;
41
+ fixer: z.ZodObject<{
42
+ primary: z.ZodString;
43
+ fallback1: z.ZodString;
44
+ fallback2: z.ZodString;
45
+ fallback3: z.ZodString;
46
+ }, z.core.$strip>;
47
+ }, z.core.$strict>;
48
+ export type ManualAgentName = (typeof MANUAL_AGENT_NAMES)[number];
49
+ export type ManualAgentPlan = z.infer<typeof ManualAgentPlanSchema>;
50
+ export type ManualPlan = z.infer<typeof ManualPlanSchema>;
3
51
  export type FallbackAgentName = (typeof FALLBACK_AGENT_NAMES)[number];
4
52
  export declare const AgentOverrideConfigSchema: z.ZodObject<{
5
53
  model: z.ZodOptional<z.ZodString>;
@@ -57,11 +105,55 @@ export declare const FailoverConfigSchema: z.ZodObject<{
57
105
  explorer: z.ZodOptional<z.ZodArray<z.ZodString>>;
58
106
  librarian: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
107
  fixer: z.ZodOptional<z.ZodArray<z.ZodString>>;
60
- }, z.core.$strict>>;
108
+ }, z.core.$catchall<z.ZodArray<z.ZodString>>>>;
61
109
  }, z.core.$strip>;
62
110
  export type FailoverConfig = z.infer<typeof FailoverConfigSchema>;
63
111
  export declare const PluginConfigSchema: z.ZodObject<{
64
112
  preset: z.ZodOptional<z.ZodString>;
113
+ scoringEngineVersion: z.ZodOptional<z.ZodEnum<{
114
+ v1: "v1";
115
+ "v2-shadow": "v2-shadow";
116
+ v2: "v2";
117
+ }>>;
118
+ balanceProviderUsage: z.ZodOptional<z.ZodBoolean>;
119
+ manualPlan: z.ZodOptional<z.ZodObject<{
120
+ orchestrator: z.ZodObject<{
121
+ primary: z.ZodString;
122
+ fallback1: z.ZodString;
123
+ fallback2: z.ZodString;
124
+ fallback3: z.ZodString;
125
+ }, z.core.$strip>;
126
+ oracle: z.ZodObject<{
127
+ primary: z.ZodString;
128
+ fallback1: z.ZodString;
129
+ fallback2: z.ZodString;
130
+ fallback3: z.ZodString;
131
+ }, z.core.$strip>;
132
+ designer: z.ZodObject<{
133
+ primary: z.ZodString;
134
+ fallback1: z.ZodString;
135
+ fallback2: z.ZodString;
136
+ fallback3: z.ZodString;
137
+ }, z.core.$strip>;
138
+ explorer: z.ZodObject<{
139
+ primary: z.ZodString;
140
+ fallback1: z.ZodString;
141
+ fallback2: z.ZodString;
142
+ fallback3: z.ZodString;
143
+ }, z.core.$strip>;
144
+ librarian: z.ZodObject<{
145
+ primary: z.ZodString;
146
+ fallback1: z.ZodString;
147
+ fallback2: z.ZodString;
148
+ fallback3: z.ZodString;
149
+ }, z.core.$strip>;
150
+ fixer: z.ZodObject<{
151
+ primary: z.ZodString;
152
+ fallback1: z.ZodString;
153
+ fallback2: z.ZodString;
154
+ fallback3: z.ZodString;
155
+ }, z.core.$strip>;
156
+ }, z.core.$strict>>;
65
157
  presets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
66
158
  model: z.ZodOptional<z.ZodString>;
67
159
  temperature: z.ZodOptional<z.ZodNumber>;
@@ -101,7 +193,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
101
193
  explorer: z.ZodOptional<z.ZodArray<z.ZodString>>;
102
194
  librarian: z.ZodOptional<z.ZodArray<z.ZodString>>;
103
195
  fixer: z.ZodOptional<z.ZodArray<z.ZodString>>;
104
- }, z.core.$strict>>;
196
+ }, z.core.$catchall<z.ZodArray<z.ZodString>>>>;
105
197
  }, z.core.$strip>>;
106
198
  }, z.core.$strip>;
107
199
  export type PluginConfig = z.infer<typeof PluginConfigSchema>;
package/dist/index.js CHANGED
@@ -3338,6 +3338,14 @@ var SUBAGENT_NAMES = [
3338
3338
  ];
3339
3339
  var ORCHESTRATOR_NAME = "orchestrator";
3340
3340
  var ALL_AGENT_NAMES = [ORCHESTRATOR_NAME, ...SUBAGENT_NAMES];
3341
+ var SUBAGENT_DELEGATION_RULES = {
3342
+ orchestrator: SUBAGENT_NAMES,
3343
+ fixer: ["explorer"],
3344
+ designer: ["explorer"],
3345
+ explorer: [],
3346
+ librarian: [],
3347
+ oracle: []
3348
+ };
3341
3349
  var DEFAULT_MODELS = {
3342
3350
  orchestrator: "kimi-for-coding/k2p5",
3343
3351
  oracle: "openai/gpt-5.2-codex",
@@ -16939,6 +16947,34 @@ function date4(params) {
16939
16947
  // node_modules/zod/v4/classic/external.js
16940
16948
  config(en_default());
16941
16949
  // src/config/schema.ts
16950
+ var ProviderModelIdSchema = exports_external.string().regex(/^[^/\s]+\/[^\s]+$/, "Expected provider/model format (provider/.../model)");
16951
+ var ManualAgentPlanSchema = exports_external.object({
16952
+ primary: ProviderModelIdSchema,
16953
+ fallback1: ProviderModelIdSchema,
16954
+ fallback2: ProviderModelIdSchema,
16955
+ fallback3: ProviderModelIdSchema
16956
+ }).superRefine((value, ctx) => {
16957
+ const unique = new Set([
16958
+ value.primary,
16959
+ value.fallback1,
16960
+ value.fallback2,
16961
+ value.fallback3
16962
+ ]);
16963
+ if (unique.size !== 4) {
16964
+ ctx.addIssue({
16965
+ code: exports_external.ZodIssueCode.custom,
16966
+ message: "primary and fallbacks must be unique per agent"
16967
+ });
16968
+ }
16969
+ });
16970
+ var ManualPlanSchema = exports_external.object({
16971
+ orchestrator: ManualAgentPlanSchema,
16972
+ oracle: ManualAgentPlanSchema,
16973
+ designer: ManualAgentPlanSchema,
16974
+ explorer: ManualAgentPlanSchema,
16975
+ librarian: ManualAgentPlanSchema,
16976
+ fixer: ManualAgentPlanSchema
16977
+ }).strict();
16942
16978
  var AgentModelChainSchema = exports_external.array(exports_external.string()).min(1);
16943
16979
  var FallbackChainsSchema = exports_external.object({
16944
16980
  orchestrator: AgentModelChainSchema.optional(),
@@ -16947,7 +16983,7 @@ var FallbackChainsSchema = exports_external.object({
16947
16983
  explorer: AgentModelChainSchema.optional(),
16948
16984
  librarian: AgentModelChainSchema.optional(),
16949
16985
  fixer: AgentModelChainSchema.optional()
16950
- }).strict();
16986
+ }).catchall(AgentModelChainSchema);
16951
16987
  var AgentOverrideConfigSchema = exports_external.object({
16952
16988
  model: exports_external.string().optional(),
16953
16989
  temperature: exports_external.number().min(0).max(2).optional(),
@@ -16979,6 +17015,9 @@ var FailoverConfigSchema = exports_external.object({
16979
17015
  });
16980
17016
  var PluginConfigSchema = exports_external.object({
16981
17017
  preset: exports_external.string().optional(),
17018
+ scoringEngineVersion: exports_external.enum(["v1", "v2-shadow", "v2"]).optional(),
17019
+ balanceProviderUsage: exports_external.boolean().optional(),
17020
+ manualPlan: ManualPlanSchema.optional(),
16982
17021
  presets: exports_external.record(exports_external.string(), PresetSchema).optional(),
16983
17022
  agents: exports_external.record(exports_external.string(), AgentOverrideConfigSchema).optional(),
16984
17023
  disabled_mcps: exports_external.array(exports_external.string()).optional(),
@@ -17430,7 +17469,7 @@ Each specialist delivers 10x results in their domain:
17430
17469
  - @explorer \u2192 Parallel discovery when you need to find unknowns, not read knowns
17431
17470
  - @librarian \u2192 Complex/evolving APIs where docs prevent errors, not basic usage
17432
17471
  - @oracle \u2192 High-stakes decisions where wrong choice is costly, not routine calls
17433
- - @designer \u2192 User-facing experiences where polish matters, not internal logic
17472
+ - @designer \u2192 User-facing experiences where polish matters, not internal logic
17434
17473
  - @fixer \u2192 Parallel execution of clear specs, not explaining trivial changes
17435
17474
 
17436
17475
  **Delegation efficiency:**
@@ -17522,6 +17561,8 @@ ${customAppendPrompt}`;
17522
17561
  function applyOverrides(agent, override) {
17523
17562
  if (override.model)
17524
17563
  agent.config.model = override.model;
17564
+ if (override.variant)
17565
+ agent.config.variant = override.variant;
17525
17566
  if (override.temperature !== undefined)
17526
17567
  agent.config.temperature = override.temperature;
17527
17568
  }
@@ -17829,6 +17870,16 @@ async function closeTmuxPane(paneId) {
17829
17870
  return false;
17830
17871
  }
17831
17872
  try {
17873
+ log("[tmux] closeTmuxPane: sending Ctrl+C for graceful shutdown", {
17874
+ paneId
17875
+ });
17876
+ const ctrlCProc = spawn([tmux, "send-keys", "-t", paneId, "C-c"], {
17877
+ stdout: "pipe",
17878
+ stderr: "pipe"
17879
+ });
17880
+ await ctrlCProc.exited;
17881
+ await new Promise((r) => setTimeout(r, 250));
17882
+ log("[tmux] closeTmuxPane: killing pane", { paneId });
17832
17883
  const proc = spawn([tmux, "kill-pane", "-t", paneId], {
17833
17884
  stdout: "pipe",
17834
17885
  stderr: "pipe"
@@ -17959,6 +18010,7 @@ function generateTaskId() {
17959
18010
  class BackgroundTaskManager {
17960
18011
  tasks = new Map;
17961
18012
  tasksBySessionId = new Map;
18013
+ agentBySessionId = new Map;
17962
18014
  client;
17963
18015
  directory;
17964
18016
  tmuxEnabled;
@@ -17978,6 +18030,20 @@ class BackgroundTaskManager {
17978
18030
  };
17979
18031
  this.maxConcurrentStarts = this.backgroundConfig.maxConcurrentStarts;
17980
18032
  }
18033
+ getSubagentRules(agentName) {
18034
+ return SUBAGENT_DELEGATION_RULES[agentName] ?? ["explorer"];
18035
+ }
18036
+ isAgentAllowed(parentSessionId, requestedAgent) {
18037
+ const parentAgentName = this.agentBySessionId.get(parentSessionId) ?? "orchestrator";
18038
+ const allowedSubagents = this.getSubagentRules(parentAgentName);
18039
+ if (allowedSubagents.length === 0)
18040
+ return false;
18041
+ return allowedSubagents.includes(requestedAgent);
18042
+ }
18043
+ getAllowedSubagents(parentSessionId) {
18044
+ const parentAgentName = this.agentBySessionId.get(parentSessionId) ?? "orchestrator";
18045
+ return this.getSubagentRules(parentAgentName);
18046
+ }
17981
18047
  launch(opts) {
17982
18048
  const task = {
17983
18049
  id: generateTaskId(),
@@ -18037,6 +18103,13 @@ class BackgroundTaskManager {
18037
18103
  })
18038
18104
  ]);
18039
18105
  }
18106
+ calculateToolPermissions(agentName) {
18107
+ const allowedSubagents = this.getSubagentRules(agentName);
18108
+ if (allowedSubagents.length === 0) {
18109
+ return { background_task: false, task: false };
18110
+ }
18111
+ return { background_task: true, task: true };
18112
+ }
18040
18113
  async startTask(task) {
18041
18114
  task.status = "starting";
18042
18115
  this.activeStarts++;
@@ -18057,15 +18130,17 @@ class BackgroundTaskManager {
18057
18130
  }
18058
18131
  task.sessionId = session.data.id;
18059
18132
  this.tasksBySessionId.set(session.data.id, task.id);
18133
+ this.agentBySessionId.set(session.data.id, task.agent);
18060
18134
  task.status = "running";
18061
18135
  if (this.tmuxEnabled) {
18062
18136
  await new Promise((r) => setTimeout(r, 500));
18063
18137
  }
18138
+ const toolPermissions = this.calculateToolPermissions(task.agent);
18064
18139
  const promptQuery = { directory: this.directory };
18065
18140
  const resolvedVariant = resolveAgentVariant(this.config, task.agent);
18066
18141
  const basePromptBody = applyAgentVariant(resolvedVariant, {
18067
18142
  agent: task.agent,
18068
- tools: { background_task: false, task: false },
18143
+ tools: toolPermissions,
18069
18144
  parts: [{ type: "text", text: task.prompt }]
18070
18145
  });
18071
18146
  const timeoutMs = this.config?.fallback?.timeoutMs ?? FALLBACK_FAILOVER_TIMEOUT_MS;
@@ -18133,6 +18208,33 @@ class BackgroundTaskManager {
18133
18208
  await this.extractAndCompleteTask(task);
18134
18209
  }
18135
18210
  }
18211
+ async handleSessionDeleted(event) {
18212
+ if (event.type !== "session.deleted")
18213
+ return;
18214
+ const sessionId = event.properties?.info?.id ?? event.properties?.sessionID;
18215
+ if (!sessionId)
18216
+ return;
18217
+ const taskId = this.tasksBySessionId.get(sessionId);
18218
+ if (!taskId)
18219
+ return;
18220
+ const task = this.tasks.get(taskId);
18221
+ if (!task)
18222
+ return;
18223
+ if (task.status === "running" || task.status === "pending") {
18224
+ log(`[background-manager] Session deleted, cancelling task: ${task.id}`);
18225
+ task.status = "cancelled";
18226
+ task.completedAt = new Date;
18227
+ task.error = "Session deleted";
18228
+ this.tasksBySessionId.delete(sessionId);
18229
+ this.agentBySessionId.delete(sessionId);
18230
+ const resolver = this.completionResolvers.get(taskId);
18231
+ if (resolver) {
18232
+ resolver(task);
18233
+ this.completionResolvers.delete(taskId);
18234
+ }
18235
+ log(`[background-manager] Task cancelled due to session deletion: ${task.id}`);
18236
+ }
18237
+ }
18136
18238
  async extractAndCompleteTask(task) {
18137
18239
  if (!task.sessionId)
18138
18240
  return;
@@ -18175,6 +18277,12 @@ class BackgroundTaskManager {
18175
18277
  }
18176
18278
  if (task.sessionId) {
18177
18279
  this.tasksBySessionId.delete(task.sessionId);
18280
+ this.agentBySessionId.delete(task.sessionId);
18281
+ }
18282
+ if (task.sessionId) {
18283
+ this.client.session.abort({
18284
+ path: { id: task.sessionId }
18285
+ }).catch(() => {});
18178
18286
  }
18179
18287
  if (task.parentSessionId) {
18180
18288
  this.sendCompletionNotification(task).catch((err) => {
@@ -18261,6 +18369,7 @@ class BackgroundTaskManager {
18261
18369
  this.completionResolvers.clear();
18262
18370
  this.tasks.clear();
18263
18371
  this.tasksBySessionId.clear();
18372
+ this.agentBySessionId.clear();
18264
18373
  }
18265
18374
  }
18266
18375
  // src/background/tmux-session-manager.ts
@@ -18342,6 +18451,19 @@ class TmuxSessionManager {
18342
18451
  await this.closeSession(sessionId);
18343
18452
  }
18344
18453
  }
18454
+ async onSessionDeleted(event) {
18455
+ if (!this.enabled)
18456
+ return;
18457
+ if (event.type !== "session.deleted")
18458
+ return;
18459
+ const sessionId = event.properties?.sessionID;
18460
+ if (!sessionId)
18461
+ return;
18462
+ log("[tmux-session-manager] session deleted, closing pane", {
18463
+ sessionId
18464
+ });
18465
+ await this.closeSession(sessionId);
18466
+ }
18345
18467
  startPolling() {
18346
18468
  if (this.pollInterval)
18347
18469
  return;
@@ -18420,6 +18542,8 @@ class TmuxSessionManager {
18420
18542
  // src/hooks/auto-update-checker/cache.ts
18421
18543
  import * as fs3 from "fs";
18422
18544
  import * as path4 from "path";
18545
+ // src/cli/dynamic-model-selection.ts
18546
+ var FREE_BIASED_PROVIDERS = new Set(["opencode"]);
18423
18547
  // src/hooks/auto-update-checker/constants.ts
18424
18548
  import * as os3 from "os";
18425
18549
  import * as path3 from "path";
@@ -31789,11 +31913,16 @@ Key behaviors:
31789
31913
  const agent = String(args.agent);
31790
31914
  const prompt = String(args.prompt);
31791
31915
  const description = String(args.description);
31916
+ const parentSessionId = toolContext.sessionID;
31917
+ if (!manager.isAgentAllowed(parentSessionId, agent)) {
31918
+ const allowed = manager.getAllowedSubagents(parentSessionId);
31919
+ return `Agent '${agent}' is not allowed. Allowed agents: ${allowed.join(", ")}`;
31920
+ }
31792
31921
  const task = manager.launch({
31793
31922
  agent,
31794
31923
  prompt,
31795
31924
  description,
31796
- parentSessionId: toolContext.sessionID
31925
+ parentSessionId
31797
31926
  });
31798
31927
  return `Background task launched.
31799
31928
 
@@ -32164,11 +32293,14 @@ ${summary}`);
32164
32293
 
32165
32294
  // src/tools/grep/tools.ts
32166
32295
  var grep = tool({
32167
- description: "Fast content search tool with safety limits (60s timeout, 10MB output). " + "Searches file contents using regular expressions. " + 'Supports full regex syntax (eg. "log.*Error", "function\\s+\\w+", etc.). ' + 'Filter files by pattern with the include parameter (eg. "*.js", "*.{ts,tsx}"). ' + "Returns file paths with matches sorted by modification time.",
32296
+ description: "Fast content search tool with safety limits (60s timeout, 10MB output). " + "Searches file contents using regular expressions. " + 'Supports full regex syntax (eg. "log.*Error", "function\\s+\\w+", etc.). ' + 'Filter files by pattern with the include parameter (e.g. "*.js", "*.{ts,tsx}"). ' + "Returns file paths with matches sorted by modification time.",
32168
32297
  args: {
32169
32298
  pattern: tool.schema.string().describe("The regex pattern to search for in file contents"),
32170
32299
  include: tool.schema.string().optional().describe('File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")'),
32171
- path: tool.schema.string().optional().describe("The directory to search in. Defaults to the current working directory.")
32300
+ path: tool.schema.string().optional().describe("The directory to search in. Defaults to the current working directory."),
32301
+ caseSensitive: tool.schema.boolean().optional().default(false).describe("Perform case-sensitive search (default: false)"),
32302
+ wholeWord: tool.schema.boolean().optional().default(false).describe("Match whole words only (default: false)"),
32303
+ fixedStrings: tool.schema.boolean().optional().default(false).describe("Treat pattern as literal string (default: false)")
32172
32304
  },
32173
32305
  execute: async (args) => {
32174
32306
  try {
@@ -32178,7 +32310,10 @@ var grep = tool({
32178
32310
  pattern: args.pattern,
32179
32311
  paths: paths2,
32180
32312
  globs,
32181
- context: 0
32313
+ context: 0,
32314
+ caseSensitive: args.caseSensitive ?? false,
32315
+ wholeWord: args.wholeWord ?? false,
32316
+ fixedStrings: args.fixedStrings ?? false
32182
32317
  });
32183
32318
  return formatGrepResult(result);
32184
32319
  } catch (e) {
@@ -33162,6 +33297,8 @@ var OhMyOpenCodeLite = async (ctx) => {
33162
33297
  await tmuxSessionManager.onSessionCreated(input.event);
33163
33298
  await backgroundManager.handleSessionStatus(input.event);
33164
33299
  await tmuxSessionManager.onSessionStatus(input.event);
33300
+ await backgroundManager.handleSessionDeleted(input.event);
33301
+ await tmuxSessionManager.onSessionDeleted(input.event);
33165
33302
  },
33166
33303
  "experimental.chat.messages.transform": phaseReminderHook["experimental.chat.messages.transform"],
33167
33304
  "tool.execute.after": postReadNudgeHook["tool.execute.after"]
@@ -0,0 +1,5 @@
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[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
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
+ };
@@ -0,0 +1,41 @@
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
+ }
@@ -0,0 +1 @@
1
+ export declare function getEnv(name: string): string | undefined;
@@ -1,4 +1,5 @@
1
1
  export * from './agent-variant';
2
+ export * from './env';
2
3
  export { log } from './logger';
3
4
  export * from './polling';
4
5
  export * from './tmux';