@agentuity/opencode 0.1.40 → 0.1.42

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.
Files changed (165) hide show
  1. package/README.md +324 -19
  2. package/dist/agents/architect.d.ts +4 -0
  3. package/dist/agents/architect.d.ts.map +1 -0
  4. package/dist/agents/architect.js +259 -0
  5. package/dist/agents/architect.js.map +1 -0
  6. package/dist/agents/builder.d.ts +1 -1
  7. package/dist/agents/builder.d.ts.map +1 -1
  8. package/dist/agents/builder.js +44 -1
  9. package/dist/agents/builder.js.map +1 -1
  10. package/dist/agents/index.d.ts.map +1 -1
  11. package/dist/agents/index.js +6 -0
  12. package/dist/agents/index.js.map +1 -1
  13. package/dist/agents/lead.d.ts +1 -1
  14. package/dist/agents/lead.d.ts.map +1 -1
  15. package/dist/agents/lead.js +185 -22
  16. package/dist/agents/lead.js.map +1 -1
  17. package/dist/agents/planner.d.ts +4 -0
  18. package/dist/agents/planner.d.ts.map +1 -0
  19. package/dist/agents/planner.js +158 -0
  20. package/dist/agents/planner.js.map +1 -0
  21. package/dist/agents/runner.d.ts +4 -0
  22. package/dist/agents/runner.d.ts.map +1 -0
  23. package/dist/agents/runner.js +364 -0
  24. package/dist/agents/runner.js.map +1 -0
  25. package/dist/agents/types.d.ts +5 -1
  26. package/dist/agents/types.d.ts.map +1 -1
  27. package/dist/background/concurrency.d.ts +36 -0
  28. package/dist/background/concurrency.d.ts.map +1 -0
  29. package/dist/background/concurrency.js +92 -0
  30. package/dist/background/concurrency.js.map +1 -0
  31. package/dist/background/index.d.ts +5 -0
  32. package/dist/background/index.d.ts.map +1 -0
  33. package/dist/background/index.js +4 -0
  34. package/dist/background/index.js.map +1 -0
  35. package/dist/background/manager.d.ts +54 -0
  36. package/dist/background/manager.d.ts.map +1 -0
  37. package/dist/background/manager.js +409 -0
  38. package/dist/background/manager.js.map +1 -0
  39. package/dist/background/types.d.ts +47 -0
  40. package/dist/background/types.d.ts.map +1 -0
  41. package/dist/background/types.js +2 -0
  42. package/dist/background/types.js.map +1 -0
  43. package/dist/config/index.d.ts +2 -0
  44. package/dist/config/index.d.ts.map +1 -1
  45. package/dist/config/index.js +2 -0
  46. package/dist/config/index.js.map +1 -1
  47. package/dist/config/loader.d.ts +24 -0
  48. package/dist/config/loader.d.ts.map +1 -1
  49. package/dist/config/loader.js +102 -23
  50. package/dist/config/loader.js.map +1 -1
  51. package/dist/config/presets.d.ts +16 -0
  52. package/dist/config/presets.d.ts.map +1 -0
  53. package/dist/config/presets.js +20 -0
  54. package/dist/config/presets.js.map +1 -0
  55. package/dist/config/validation.d.ts +26 -0
  56. package/dist/config/validation.d.ts.map +1 -0
  57. package/dist/config/validation.js +48 -0
  58. package/dist/config/validation.js.map +1 -0
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/plugin/hooks/cadence.d.ts.map +1 -1
  63. package/dist/plugin/hooks/cadence.js +3 -1
  64. package/dist/plugin/hooks/cadence.js.map +1 -1
  65. package/dist/plugin/hooks/keyword.d.ts.map +1 -1
  66. package/dist/plugin/hooks/keyword.js +3 -0
  67. package/dist/plugin/hooks/keyword.js.map +1 -1
  68. package/dist/plugin/plugin.d.ts.map +1 -1
  69. package/dist/plugin/plugin.js +335 -36
  70. package/dist/plugin/plugin.js.map +1 -1
  71. package/dist/skills/frontmatter.d.ts +7 -0
  72. package/dist/skills/frontmatter.d.ts.map +1 -0
  73. package/dist/skills/frontmatter.js +17 -0
  74. package/dist/skills/frontmatter.js.map +1 -0
  75. package/dist/skills/index.d.ts +4 -0
  76. package/dist/skills/index.d.ts.map +1 -0
  77. package/dist/skills/index.js +4 -0
  78. package/dist/skills/index.js.map +1 -0
  79. package/dist/skills/loader.d.ts +20 -0
  80. package/dist/skills/loader.d.ts.map +1 -0
  81. package/dist/skills/loader.js +152 -0
  82. package/dist/skills/loader.js.map +1 -0
  83. package/dist/skills/types.d.ts +41 -0
  84. package/dist/skills/types.d.ts.map +1 -0
  85. package/dist/skills/types.js +2 -0
  86. package/dist/skills/types.js.map +1 -0
  87. package/dist/tmux/decision-engine.d.ts +24 -0
  88. package/dist/tmux/decision-engine.d.ts.map +1 -0
  89. package/dist/tmux/decision-engine.js +193 -0
  90. package/dist/tmux/decision-engine.js.map +1 -0
  91. package/dist/tmux/executor.d.ts +84 -0
  92. package/dist/tmux/executor.d.ts.map +1 -0
  93. package/dist/tmux/executor.js +546 -0
  94. package/dist/tmux/executor.js.map +1 -0
  95. package/dist/tmux/index.d.ts +7 -0
  96. package/dist/tmux/index.d.ts.map +1 -0
  97. package/dist/tmux/index.js +7 -0
  98. package/dist/tmux/index.js.map +1 -0
  99. package/dist/tmux/manager.d.ts +116 -0
  100. package/dist/tmux/manager.d.ts.map +1 -0
  101. package/dist/tmux/manager.js +488 -0
  102. package/dist/tmux/manager.js.map +1 -0
  103. package/dist/tmux/state-query.d.ts +7 -0
  104. package/dist/tmux/state-query.d.ts.map +1 -0
  105. package/dist/tmux/state-query.js +70 -0
  106. package/dist/tmux/state-query.js.map +1 -0
  107. package/dist/tmux/types.d.ts +97 -0
  108. package/dist/tmux/types.d.ts.map +1 -0
  109. package/dist/tmux/types.js +8 -0
  110. package/dist/tmux/types.js.map +1 -0
  111. package/dist/tmux/utils.d.ts +32 -0
  112. package/dist/tmux/utils.d.ts.map +1 -0
  113. package/dist/tmux/utils.js +80 -0
  114. package/dist/tmux/utils.js.map +1 -0
  115. package/dist/tools/background.d.ts +61 -0
  116. package/dist/tools/background.d.ts.map +1 -0
  117. package/dist/tools/background.js +78 -0
  118. package/dist/tools/background.js.map +1 -0
  119. package/dist/tools/delegate.d.ts +6 -0
  120. package/dist/tools/delegate.d.ts.map +1 -1
  121. package/dist/tools/delegate.js +8 -2
  122. package/dist/tools/delegate.js.map +1 -1
  123. package/dist/tools/index.d.ts +1 -0
  124. package/dist/tools/index.d.ts.map +1 -1
  125. package/dist/tools/index.js +1 -0
  126. package/dist/tools/index.js.map +1 -1
  127. package/dist/types.d.ts +118 -18
  128. package/dist/types.d.ts.map +1 -1
  129. package/dist/types.js +49 -7
  130. package/dist/types.js.map +1 -1
  131. package/package.json +4 -3
  132. package/src/agents/architect.ts +262 -0
  133. package/src/agents/builder.ts +44 -1
  134. package/src/agents/index.ts +6 -0
  135. package/src/agents/lead.ts +185 -22
  136. package/src/agents/planner.ts +161 -0
  137. package/src/agents/runner.ts +367 -0
  138. package/src/agents/types.ts +5 -1
  139. package/src/background/concurrency.ts +116 -0
  140. package/src/background/index.ts +4 -0
  141. package/src/background/manager.ts +478 -0
  142. package/src/background/types.ts +52 -0
  143. package/src/config/index.ts +2 -0
  144. package/src/config/loader.ts +128 -31
  145. package/src/config/presets.ts +21 -0
  146. package/src/config/validation.ts +70 -0
  147. package/src/index.ts +1 -0
  148. package/src/plugin/hooks/cadence.ts +2 -1
  149. package/src/plugin/hooks/keyword.ts +3 -0
  150. package/src/plugin/plugin.ts +374 -42
  151. package/src/skills/frontmatter.ts +25 -0
  152. package/src/skills/index.ts +3 -0
  153. package/src/skills/loader.ts +185 -0
  154. package/src/skills/types.ts +43 -0
  155. package/src/tmux/decision-engine.ts +246 -0
  156. package/src/tmux/executor.ts +618 -0
  157. package/src/tmux/index.ts +14 -0
  158. package/src/tmux/manager.ts +577 -0
  159. package/src/tmux/state-query.ts +77 -0
  160. package/src/tmux/types.ts +107 -0
  161. package/src/tmux/utils.ts +85 -0
  162. package/src/tools/background.ts +145 -0
  163. package/src/tools/delegate.ts +8 -2
  164. package/src/tools/index.ts +9 -0
  165. package/src/types.ts +88 -15
@@ -0,0 +1,152 @@
1
+ import { homedir } from 'node:os';
2
+ import { basename, join, resolve, sep } from 'node:path';
3
+ import { readdir, realpath } from 'node:fs/promises';
4
+ import { parseFrontmatter } from './frontmatter';
5
+ const SKILL_FILENAME = 'SKILL.md';
6
+ /**
7
+ * Load skills from standard directories.
8
+ * Priority order (later overrides earlier):
9
+ * 1. User OpenCode: ~/.config/opencode/skills/
10
+ * 2. User Agentuity: ~/.config/agentuity/opencode/skills/
11
+ * 3. User Claude Code compat: ~/.claude/skills/
12
+ * 4. Project OpenCode: ./.opencode/skills/
13
+ * 5. Project Claude Code compat: ./.claude/skills/
14
+ */
15
+ export async function loadAllSkills(config) {
16
+ if (config?.enabled === false) {
17
+ return [];
18
+ }
19
+ const skillDirs = [
20
+ { dir: join(homedir(), '.config', 'opencode', 'skills'), scope: 'user' },
21
+ { dir: join(homedir(), '.config', 'agentuity', 'opencode', 'skills'), scope: 'user' },
22
+ { dir: join(homedir(), '.claude', 'skills'), scope: 'user' },
23
+ { dir: join(process.cwd(), '.opencode', 'skills'), scope: 'project' },
24
+ { dir: join(process.cwd(), '.claude', 'skills'), scope: 'project' },
25
+ ];
26
+ if (config?.paths?.length) {
27
+ for (const skillPath of config.paths) {
28
+ const resolvedPath = resolve(skillPath);
29
+ skillDirs.push({ dir: resolvedPath, scope: inferScope(resolvedPath) });
30
+ }
31
+ }
32
+ const disabled = new Set(config?.disabled ?? []);
33
+ const skillsByName = new Map();
34
+ for (const { dir, scope } of skillDirs) {
35
+ const skills = await loadSkillsFromDir(dir, scope);
36
+ for (const skill of skills) {
37
+ if (disabled.has(skill.name)) {
38
+ continue;
39
+ }
40
+ skillsByName.set(skill.name, skill);
41
+ }
42
+ }
43
+ return Array.from(skillsByName.values());
44
+ }
45
+ /**
46
+ * Load skills from a single directory
47
+ */
48
+ export async function loadSkillsFromDir(dir, scope) {
49
+ const results = [];
50
+ const resolvedDir = await safeRealpath(dir);
51
+ let entries;
52
+ try {
53
+ entries = await readdir(resolvedDir, { withFileTypes: true });
54
+ }
55
+ catch {
56
+ return results;
57
+ }
58
+ for (const entry of entries) {
59
+ if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
60
+ const skillPath = join(dir, entry.name);
61
+ const skill = await loadSkillFromPath(skillPath, resolvedDir, basename(entry.name, '.md'), scope);
62
+ if (skill) {
63
+ results.push(skill);
64
+ }
65
+ continue;
66
+ }
67
+ if (entry.isDirectory()) {
68
+ const subdirPath = join(dir, entry.name);
69
+ const resolvedSubdir = await safeRealpath(subdirPath);
70
+ const candidates = [
71
+ join(subdirPath, SKILL_FILENAME),
72
+ join(subdirPath, `${entry.name}.md`),
73
+ ];
74
+ for (const candidate of candidates) {
75
+ const skill = await loadSkillFromPath(candidate, resolvedSubdir, entry.name, scope);
76
+ if (skill) {
77
+ results.push(skill);
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return results;
84
+ }
85
+ /**
86
+ * Load a single skill file (supports both .md files and SKILL.md in directories)
87
+ */
88
+ async function loadSkillFromPath(skillPath, resolvedPath, defaultName, scope) {
89
+ const file = Bun.file(skillPath);
90
+ if (!(await file.exists())) {
91
+ return null;
92
+ }
93
+ const content = await file.text();
94
+ const parsed = parseFrontmatter(content);
95
+ const metadata = parsed.data ?? {};
96
+ const name = metadata.name?.trim() || defaultName;
97
+ if (!name) {
98
+ return null;
99
+ }
100
+ const allowedTools = normalizeAllowedTools(metadata['allowed-tools']);
101
+ return {
102
+ name,
103
+ path: skillPath,
104
+ resolvedPath,
105
+ content: parsed.body,
106
+ metadata,
107
+ scope,
108
+ ...(allowedTools ? { allowedTools } : {}),
109
+ };
110
+ }
111
+ /**
112
+ * Get skill by name from loaded skills
113
+ */
114
+ export function getSkillByName(skills, name) {
115
+ return skills.find((skill) => skill.name === name);
116
+ }
117
+ function normalizeAllowedTools(value) {
118
+ if (!value)
119
+ return undefined;
120
+ if (Array.isArray(value)) {
121
+ const tools = value.filter((tool) => typeof tool === 'string');
122
+ return tools.length > 0 ? tools : undefined;
123
+ }
124
+ if (typeof value === 'string') {
125
+ const tool = value.trim();
126
+ return tool ? [tool] : undefined;
127
+ }
128
+ return undefined;
129
+ }
130
+ function inferScope(skillPath) {
131
+ const resolved = resolve(skillPath);
132
+ const cwd = resolve(process.cwd());
133
+ const home = resolve(homedir());
134
+ if (isWithin(cwd, resolved))
135
+ return 'project';
136
+ if (isWithin(home, resolved))
137
+ return 'user';
138
+ return 'opencode';
139
+ }
140
+ function isWithin(base, target) {
141
+ const baseWithSep = base.endsWith(sep) ? base : `${base}${sep}`;
142
+ return target === base || target.startsWith(baseWithSep);
143
+ }
144
+ async function safeRealpath(path) {
145
+ try {
146
+ return await realpath(path);
147
+ }
148
+ catch {
149
+ return path;
150
+ }
151
+ }
152
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/skills/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Skill scope determines where the skill was loaded from
3
+ * Priority order: project > user > opencode
4
+ */
5
+ export type SkillScope = 'project' | 'user' | 'opencode';
6
+ /**
7
+ * Frontmatter metadata parsed from skill files
8
+ */
9
+ export interface SkillMetadata {
10
+ name?: string;
11
+ description?: string;
12
+ model?: string;
13
+ agent?: string;
14
+ subtask?: boolean;
15
+ 'argument-hint'?: string;
16
+ 'allowed-tools'?: string | string[];
17
+ license?: string;
18
+ compatibility?: string;
19
+ metadata?: Record<string, string>;
20
+ }
21
+ /**
22
+ * A loaded skill ready for use
23
+ */
24
+ export interface LoadedSkill {
25
+ name: string;
26
+ path: string;
27
+ resolvedPath: string;
28
+ content: string;
29
+ metadata: SkillMetadata;
30
+ scope: SkillScope;
31
+ allowedTools?: string[];
32
+ }
33
+ /**
34
+ * Configuration for skills loading
35
+ */
36
+ export interface SkillsConfig {
37
+ enabled: boolean;
38
+ paths?: string[];
39
+ disabled?: string[];
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import type { CapacityConfig, SessionMapping, SpawnDecision, WindowState } from './types';
2
+ /**
3
+ * Extended capacity config that includes maxPanes limit
4
+ */
5
+ export interface ExtendedCapacityConfig extends CapacityConfig {
6
+ maxPanes?: number;
7
+ }
8
+ /**
9
+ * Decide what actions to take to spawn a new agent pane
10
+ *
11
+ * Respects maxPanes limit with LRU rotation:
12
+ * - If current agent panes >= maxPanes, close oldest pane before spawning new one
13
+ * - This implements LRU (Least Recently Used) rotation
14
+ */
15
+ export declare function decideSpawnActions(state: WindowState, sessionId: string, description: string, config: ExtendedCapacityConfig, sessionMappings: SessionMapping[]): SpawnDecision;
16
+ /**
17
+ * Calculate grid capacity based on window size
18
+ */
19
+ export declare function calculateCapacity(windowWidth: number, windowHeight: number): {
20
+ cols: number;
21
+ rows: number;
22
+ total: number;
23
+ };
24
+ //# sourceMappingURL=decision-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-engine.d.ts","sourceRoot":"","sources":["../../src/tmux/decision-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,cAAc,EAEd,cAAc,EACd,aAAa,EACb,WAAW,EACX,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,sBAAsB,EAC9B,eAAe,EAAE,cAAc,EAAE,GAC/B,aAAa,CAkIf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAU/C"}
@@ -0,0 +1,193 @@
1
+ import { MIN_PANE_HEIGHT, MIN_PANE_WIDTH } from './types';
2
+ /**
3
+ * Decide what actions to take to spawn a new agent pane
4
+ *
5
+ * Respects maxPanes limit with LRU rotation:
6
+ * - If current agent panes >= maxPanes, close oldest pane before spawning new one
7
+ * - This implements LRU (Least Recently Used) rotation
8
+ */
9
+ export function decideSpawnActions(state, sessionId, description, config, sessionMappings) {
10
+ if (!state.mainPane) {
11
+ return { canSpawn: false, actions: [], reason: 'Main pane not found.' };
12
+ }
13
+ if (state.windowWidth < config.mainPaneMinWidth + config.agentPaneMinWidth) {
14
+ return { canSpawn: false, actions: [], reason: 'Window too small for split.' };
15
+ }
16
+ const capacity = calculateCapacity(state.windowWidth, state.windowHeight);
17
+ if (capacity.total <= 0) {
18
+ return { canSpawn: false, actions: [], reason: 'Window too small for agent panes.' };
19
+ }
20
+ // Determine effective max panes (user config or calculated capacity)
21
+ const effectiveMaxPanes = config.maxPanes ?? capacity.total;
22
+ const currentPaneCount = state.agentPanes.length;
23
+ // Check if we need LRU rotation (at or over maxPanes limit)
24
+ if (currentPaneCount >= effectiveMaxPanes) {
25
+ // Find oldest pane to close (LRU rotation)
26
+ const oldestMapping = pickOldestPane(sessionMappings);
27
+ if (!oldestMapping) {
28
+ // No tracked sessions, try replacement instead
29
+ const replacement = pickReplacementPane(state, sessionMappings);
30
+ if (!replacement) {
31
+ return { canSpawn: false, actions: [], reason: 'No pane available to replace.' };
32
+ }
33
+ return {
34
+ canSpawn: true,
35
+ actions: [
36
+ {
37
+ type: 'replace',
38
+ paneId: replacement.paneId,
39
+ oldSessionId: replacement.sessionId,
40
+ newSessionId: sessionId,
41
+ description,
42
+ },
43
+ ],
44
+ };
45
+ }
46
+ // Close oldest pane, then spawn new one
47
+ const actions = [
48
+ {
49
+ type: 'close',
50
+ paneId: oldestMapping.paneId,
51
+ sessionId: oldestMapping.sessionId,
52
+ },
53
+ ];
54
+ // After closing, we'll have room to spawn
55
+ // Determine where to spawn the new pane
56
+ if (currentPaneCount === 1) {
57
+ // After closing the only agent pane, split from main
58
+ actions.push({
59
+ type: 'spawn',
60
+ sessionId,
61
+ description,
62
+ targetPaneId: state.mainPane.paneId,
63
+ splitDirection: '-h',
64
+ });
65
+ }
66
+ else {
67
+ // Find a remaining pane to split (not the one being closed)
68
+ const remainingPanes = state.agentPanes.filter((p) => p.paneId !== oldestMapping.paneId);
69
+ const targetPane = pickBestSplitPane(remainingPanes);
70
+ if (targetPane) {
71
+ const splitDirection = chooseSplitDirection(targetPane, config.agentPaneMinWidth);
72
+ actions.push({
73
+ type: 'spawn',
74
+ sessionId,
75
+ description,
76
+ targetPaneId: targetPane.paneId,
77
+ splitDirection,
78
+ });
79
+ }
80
+ else {
81
+ // Fallback: split from main pane
82
+ actions.push({
83
+ type: 'spawn',
84
+ sessionId,
85
+ description,
86
+ targetPaneId: state.mainPane.paneId,
87
+ splitDirection: '-h',
88
+ });
89
+ }
90
+ }
91
+ return { canSpawn: true, actions };
92
+ }
93
+ // Under maxPanes limit - normal spawn logic
94
+ if (state.agentPanes.length === 0) {
95
+ if (!canSplitHorizontally(state.mainPane, config.agentPaneMinWidth)) {
96
+ return { canSpawn: false, actions: [], reason: 'Main pane too narrow to split.' };
97
+ }
98
+ return {
99
+ canSpawn: true,
100
+ actions: [
101
+ {
102
+ type: 'spawn',
103
+ sessionId,
104
+ description,
105
+ targetPaneId: state.mainPane.paneId,
106
+ splitDirection: '-h',
107
+ },
108
+ ],
109
+ };
110
+ }
111
+ const targetPane = pickBestSplitPane(state.agentPanes);
112
+ if (!targetPane) {
113
+ return { canSpawn: false, actions: [], reason: 'No suitable pane to split.' };
114
+ }
115
+ const splitDirection = chooseSplitDirection(targetPane, config.agentPaneMinWidth);
116
+ if (!canSplitPane(targetPane, splitDirection, config.agentPaneMinWidth)) {
117
+ return { canSpawn: false, actions: [], reason: 'No suitable pane to split.' };
118
+ }
119
+ return {
120
+ canSpawn: true,
121
+ actions: [
122
+ {
123
+ type: 'spawn',
124
+ sessionId,
125
+ description,
126
+ targetPaneId: targetPane.paneId,
127
+ splitDirection,
128
+ },
129
+ ],
130
+ };
131
+ }
132
+ /**
133
+ * Calculate grid capacity based on window size
134
+ */
135
+ export function calculateCapacity(windowWidth, windowHeight) {
136
+ const reservedWidth = Math.floor(windowWidth * 0.5);
137
+ const agentWidth = Math.max(0, windowWidth - reservedWidth);
138
+ const cols = Math.floor(agentWidth / MIN_PANE_WIDTH);
139
+ const rows = Math.floor(windowHeight / MIN_PANE_HEIGHT);
140
+ return {
141
+ cols: Math.max(0, cols),
142
+ rows: Math.max(0, rows),
143
+ total: Math.max(0, cols * rows),
144
+ };
145
+ }
146
+ function pickBestSplitPane(panes) {
147
+ if (panes.length === 0) {
148
+ return undefined;
149
+ }
150
+ return panes.reduce((best, pane) => {
151
+ const bestArea = best.width * best.height;
152
+ const area = pane.width * pane.height;
153
+ return area > bestArea ? pane : best;
154
+ });
155
+ }
156
+ function chooseSplitDirection(pane, minAgentWidth) {
157
+ const canSplitHorizontally = pane.width >= minAgentWidth * 2;
158
+ const canSplitVertically = pane.height >= MIN_PANE_HEIGHT * 2;
159
+ if (canSplitHorizontally && canSplitVertically) {
160
+ return pane.width >= pane.height ? '-h' : '-v';
161
+ }
162
+ if (canSplitHorizontally)
163
+ return '-h';
164
+ if (canSplitVertically)
165
+ return '-v';
166
+ return '-h';
167
+ }
168
+ function canSplitPane(pane, direction, minAgentWidth) {
169
+ if (direction === '-h') {
170
+ return canSplitHorizontally(pane, minAgentWidth);
171
+ }
172
+ return pane.height >= MIN_PANE_HEIGHT * 2;
173
+ }
174
+ function canSplitHorizontally(pane, minAgentWidth) {
175
+ return pane.width >= minAgentWidth * 2;
176
+ }
177
+ function pickReplacementPane(state, sessionMappings) {
178
+ const panesById = new Set(state.agentPanes.map((pane) => pane.paneId));
179
+ const candidates = sessionMappings.filter((mapping) => panesById.has(mapping.paneId));
180
+ if (candidates.length === 0)
181
+ return null;
182
+ return candidates.reduce((oldest, entry) => entry.createdAt.getTime() < oldest.createdAt.getTime() ? entry : oldest);
183
+ }
184
+ /**
185
+ * Pick the oldest pane from session mappings (LRU - Least Recently Used)
186
+ * Used for rotation when maxPanes limit is reached
187
+ */
188
+ function pickOldestPane(sessionMappings) {
189
+ if (sessionMappings.length === 0)
190
+ return null;
191
+ return sessionMappings.reduce((oldest, entry) => entry.createdAt.getTime() < oldest.createdAt.getTime() ? entry : oldest);
192
+ }
193
+ //# sourceMappingURL=decision-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-engine.js","sourceRoot":"","sources":["../../src/tmux/decision-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import type { PaneAction, WindowState, TmuxConfig } from './types';
2
+ export interface ActionResult {
3
+ success: boolean;
4
+ paneId?: string;
5
+ windowId?: string;
6
+ pid?: number;
7
+ error?: string;
8
+ }
9
+ /**
10
+ * Kill a process and all its children (the entire process tree).
11
+ *
12
+ * This is necessary because we spawn `bash -c "opencode attach ...; tmux kill-pane"`
13
+ * and #{pane_pid} returns the bash PID, not the opencode attach PID.
14
+ * We need to kill the children (opencode attach) not just the parent (bash).
15
+ */
16
+ export declare function killProcessByPid(pid: number): Promise<boolean>;
17
+ /**
18
+ * Execute a single pane action
19
+ *
20
+ * All agents spawn in a dedicated "Agents" window with tiled grid layout.
21
+ */
22
+ export declare function executeAction(action: PaneAction, ctx: {
23
+ config: TmuxConfig;
24
+ serverUrl: string;
25
+ windowState: WindowState;
26
+ }): Promise<ActionResult>;
27
+ /**
28
+ * Execute multiple actions in sequence
29
+ */
30
+ export declare function executeActions(actions: PaneAction[], ctx: {
31
+ config: TmuxConfig;
32
+ serverUrl: string;
33
+ windowState: WindowState;
34
+ }): Promise<{
35
+ success: boolean;
36
+ spawnedPaneId?: string;
37
+ results: Array<{
38
+ action: PaneAction;
39
+ result: ActionResult;
40
+ }>;
41
+ }>;
42
+ /**
43
+ * Close a pane by its ID
44
+ * Exported for use by TmuxSessionManager when sessions complete
45
+ */
46
+ export declare function closePaneById(paneId: string, pid?: number): Promise<ActionResult>;
47
+ /**
48
+ * Reset the agents window state (for cleanup)
49
+ */
50
+ export declare function resetAgentsWindow(): void;
51
+ /**
52
+ * Close the agents window if it exists
53
+ * This kills the entire window, which closes all panes within it
54
+ */
55
+ export declare function closeAgentsWindow(): Promise<void>;
56
+ /**
57
+ * Synchronously close the agents window (for shutdown)
58
+ * Uses spawnSync to ensure it completes before process exit
59
+ */
60
+ export declare function closeAgentsWindowSync(): void;
61
+ /**
62
+ * Get the current agents window ID (for testing/debugging)
63
+ * Also checks persisted file for crash recovery
64
+ */
65
+ export declare function getAgentsWindowId(): string | undefined;
66
+ /**
67
+ * Kill all orphaned opencode attach processes for a given server URL.
68
+ * This is a fallback cleanup method when PID-based cleanup fails.
69
+ *
70
+ * @param serverUrl - The server URL to match (optional, kills all if not provided)
71
+ * @param logger - Optional logging function for debug output
72
+ * @returns Number of processes killed
73
+ */
74
+ export declare function killOrphanedAttachProcesses(serverUrl?: string, logger?: (msg: string) => void): Promise<number>;
75
+ /**
76
+ * Synchronous version of killOrphanedAttachProcesses for shutdown handlers.
77
+ * Uses spawnSync to ensure completion before process exit.
78
+ *
79
+ * @param serverUrl - The server URL to match (optional, kills all if not provided)
80
+ * @param logger - Optional logging function for debug output
81
+ * @returns Number of processes killed
82
+ */
83
+ export declare function killOrphanedAttachProcessesSync(serverUrl?: string, logger?: (msg: string) => void): number;
84
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/tmux/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA2BnE,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAuBD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiDpE;AAsDD;;;;GAIG;AACH,wBAAsB,aAAa,CAClC,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GACtE,OAAO,CAAC,YAAY,CAAC,CASvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,OAAO,EAAE,UAAU,EAAE,EACrB,GAAG,EAAE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,GACtE,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CAC7D,CAAC,CAgBD;AAUD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAevF;AAkKD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CASvD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAS5C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAEtD;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAChD,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAqEjB;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAC9C,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,MAAM,CA4ER"}