mixdog 0.9.85 → 0.9.87

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 (102) hide show
  1. package/README.md +7 -1
  2. package/package.json +4 -3
  3. package/src/defaults/agents.json +12 -0
  4. package/src/defaults/skills/setup/SKILL.md +44 -12
  5. package/src/help.mjs +40 -9
  6. package/src/lib/keychain-cjs.cjs +11 -1
  7. package/src/rules/agent/43-title-agent.md +22 -0
  8. package/src/rules/shared/01-tool.md +3 -3
  9. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +4 -2
  10. package/src/runtime/agent/orchestrator/mcp/client.mjs +24 -0
  11. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +84 -3
  12. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +125 -16
  13. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -2
  14. package/src/runtime/agent/orchestrator/session/context-utils.mjs +73 -45
  15. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +15 -18
  16. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  17. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -0
  18. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +135 -9
  19. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +31 -12
  20. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +4 -0
  21. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +14 -0
  22. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +170 -0
  23. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +45 -6
  24. package/src/runtime/agent/orchestrator/session/manager.mjs +3 -0
  25. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +26 -0
  26. package/src/runtime/agent/orchestrator/session/token-bpe.mjs +42 -0
  27. package/src/runtime/agent/orchestrator/session/token-native.mjs +186 -0
  28. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +15 -5
  29. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +20 -0
  30. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +9 -2
  31. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +24 -0
  32. package/src/runtime/agent/orchestrator/tools/env-scrub.mjs +8 -0
  33. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +11 -11
  34. package/src/runtime/agent/orchestrator/tools/lib/pwsh-standby-pool.mjs +286 -0
  35. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
  36. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -3
  37. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +152 -18
  38. package/src/runtime/agent/orchestrator/tools/token-binary-fetcher.mjs +201 -0
  39. package/src/runtime/agent/orchestrator/tools/token-manifest.json +26 -0
  40. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +3 -3
  41. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  42. package/src/runtime/media/renditions.mjs +1 -1
  43. package/src/runtime/media/store.mjs +1 -1
  44. package/src/runtime/memory/lib/memory-action-handlers.mjs +4 -1
  45. package/src/runtime/memory/tool-defs.mjs +19 -3
  46. package/src/runtime/shared/atomic-file.mjs +25 -14
  47. package/src/runtime/shared/automation-attachments.mjs +3 -3
  48. package/src/runtime/shared/child-guardian.mjs +15 -5
  49. package/src/runtime/shared/child-spawn-gate.mjs +6 -12
  50. package/src/runtime/shared/resource-admission.mjs +7 -3
  51. package/src/runtime/shared/turn-snapshot.mjs +0 -3
  52. package/src/session-runtime/lifecycle-api.mjs +49 -9
  53. package/src/session-runtime/prewarm.mjs +35 -0
  54. package/src/session-runtime/provider-auth-api.mjs +8 -0
  55. package/src/session-runtime/provider-usage.mjs +30 -5
  56. package/src/session-runtime/remote-control.mjs +8 -47
  57. package/src/session-runtime/remote-transcript.mjs +3 -7
  58. package/src/session-runtime/route-preparation.mjs +24 -0
  59. package/src/session-runtime/runtime-core.mjs +286 -548
  60. package/src/session-runtime/session-lifecycle.mjs +378 -0
  61. package/src/session-runtime/session-turn-api.mjs +9 -2
  62. package/src/session-runtime/workflow-agents-api.mjs +3 -0
  63. package/src/standalone/agent-shard/shard-child.mjs +300 -0
  64. package/src/standalone/agent-shard/shard-pool.mjs +443 -0
  65. package/src/standalone/agent-tool/job-views.mjs +329 -0
  66. package/src/standalone/agent-tool/spawn-flow.mjs +629 -0
  67. package/src/standalone/agent-tool/tag-registry.mjs +340 -0
  68. package/src/standalone/agent-tool.mjs +112 -941
  69. package/src/standalone/channel-daemon-transport.mjs +126 -185
  70. package/src/standalone/channel-daemon.mjs +9 -10
  71. package/src/standalone/usage-dashboard.mjs +23 -1
  72. package/src/tui/App.jsx +362 -2569
  73. package/src/tui/app/app-view.jsx +504 -0
  74. package/src/tui/app/channel-pickers.mjs +3 -8
  75. package/src/tui/app/create-app-pickers.mjs +313 -0
  76. package/src/tui/app/prompt-submit.mjs +501 -0
  77. package/src/tui/app/route-pickers.mjs +117 -152
  78. package/src/tui/app/settings-picker.mjs +90 -89
  79. package/src/tui/app/shell-layout.mjs +563 -0
  80. package/src/tui/app/slash-commands.mjs +7 -7
  81. package/src/tui/app/slash-dispatch.mjs +0 -45
  82. package/src/tui/app/usage-context-panels.mjs +288 -0
  83. package/src/tui/app/use-copy-selection.mjs +56 -0
  84. package/src/tui/app/use-global-key-input.mjs +151 -0
  85. package/src/tui/app/use-pasted-buffers.mjs +115 -0
  86. package/src/tui/app/use-prompt-draft-flow.mjs +167 -0
  87. package/src/tui/app/use-prompt-hint.mjs +58 -0
  88. package/src/tui/app/use-prompt-queue-history.mjs +100 -0
  89. package/src/tui/app/use-terminal-chrome.mjs +72 -0
  90. package/src/tui/app/use-transcript-activity.mjs +131 -0
  91. package/src/tui/app/use-welcome-prompt-hint.mjs +96 -0
  92. package/src/tui/components/StatusLine.jsx +1 -1
  93. package/src/tui/components/tool-execution/ResultBody.jsx +1 -1
  94. package/src/tui/dist/index.mjs +9857 -9159
  95. package/src/tui/engine/session-api-ext.mjs +47 -9
  96. package/src/tui/engine.mjs +7 -1
  97. package/src/tui/figures.mjs +0 -1
  98. package/src/ui/statusline-format.mjs +0 -1
  99. package/src/hooks/lib/permission-evaluator.cjs +0 -24
  100. package/src/lib/config-cjs.cjs +0 -61
  101. package/src/runtime/shared/launcher-control.mjs +0 -258
  102. package/src/runtime/shared/workspace-router.mjs +0 -259
@@ -1,259 +0,0 @@
1
- import { existsSync, readdirSync, statSync } from 'node:fs';
2
- import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
3
-
4
- const PROJECT_MARKER_FILES = [
5
- '.git',
6
- 'package.json',
7
- 'pyproject.toml',
8
- 'setup.py',
9
- 'go.mod',
10
- 'Cargo.toml',
11
- 'pom.xml',
12
- 'build.gradle',
13
- 'build.gradle.kts',
14
- 'build.sbt',
15
- 'Package.swift',
16
- 'composer.json',
17
- ];
18
-
19
- const IGNORE_DIRS = new Set([
20
- '.git',
21
- '.hg',
22
- '.svn',
23
- '.idea',
24
- '.vscode',
25
- '.cache',
26
- '.next',
27
- '.nuxt',
28
- '.turbo',
29
- 'node_modules',
30
- '_backup',
31
- '_backups',
32
- 'backup',
33
- 'backups',
34
- '.backup',
35
- '.backups',
36
- 'dist',
37
- 'build',
38
- 'out',
39
- 'target',
40
- 'bin',
41
- 'obj',
42
- 'coverage',
43
- 'Library',
44
- 'Temp',
45
- 'Logs',
46
- 'UserSettings',
47
- ]);
48
-
49
- const DEFAULT_MAX_DEPTH = 3;
50
- const DEFAULT_MAX_DIRS = 700;
51
- const DEFAULT_MAX_CANDIDATES = 80;
52
-
53
- function safeResolve(path) {
54
- try { return resolve(path); } catch { return null; }
55
- }
56
-
57
- function safeIsDirectory(path) {
58
- try { return statSync(path).isDirectory(); } catch { return false; }
59
- }
60
-
61
- function samePath(left, right) {
62
- const a = safeResolve(left);
63
- const b = safeResolve(right);
64
- if (!a || !b) return false;
65
- return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
66
- }
67
-
68
- function markerForDir(dir) {
69
- for (const marker of PROJECT_MARKER_FILES) {
70
- if (existsSync(join(dir, marker))) return marker === '.git' ? 'git' : marker;
71
- }
72
- if (existsSync(join(dir, 'ProjectSettings')) && existsSync(join(dir, 'Packages', 'manifest.json'))) {
73
- return 'unity';
74
- }
75
- try {
76
- const entries = readdirSync(dir, { withFileTypes: true });
77
- if (entries.some((entry) => entry.isFile() && entry.name.toLowerCase().endsWith('.sln'))) {
78
- return 'solution';
79
- }
80
- } catch { /* unreadable */ }
81
- return null;
82
- }
83
-
84
- function projectFromRoot(root, marker) {
85
- const resolved = safeResolve(root);
86
- if (!resolved) return null;
87
- return {
88
- root: resolved,
89
- name: basename(resolved),
90
- marker: marker || markerForDir(resolved) || 'project',
91
- };
92
- }
93
-
94
- function findNearestProjectRoot(start) {
95
- const initial = safeResolve(start);
96
- if (!initial || !safeIsDirectory(initial)) return null;
97
- let cur = initial;
98
- while (true) {
99
- const marker = markerForDir(cur);
100
- if (marker) return projectFromRoot(cur, marker);
101
- const parent = dirname(cur);
102
- if (parent === cur) return null;
103
- cur = parent;
104
- }
105
- }
106
-
107
- function shouldIgnoreDir(name) {
108
- return IGNORE_DIRS.has(name) || name.startsWith('$') || name.endsWith('.tmp');
109
- }
110
-
111
- function discoverProjectCandidates(base, {
112
- maxDepth = DEFAULT_MAX_DEPTH,
113
- maxDirs = DEFAULT_MAX_DIRS,
114
- maxCandidates = DEFAULT_MAX_CANDIDATES,
115
- } = {}) {
116
- const root = safeResolve(base);
117
- if (!root || !safeIsDirectory(root)) return [];
118
-
119
- const found = new Map();
120
- const queue = [{ dir: root, depth: 0 }];
121
- let visited = 0;
122
-
123
- while (queue.length && visited < maxDirs && found.size < maxCandidates) {
124
- const { dir, depth } = queue.shift();
125
- visited += 1;
126
-
127
- const marker = markerForDir(dir);
128
- if (marker) {
129
- const project = projectFromRoot(dir, marker);
130
- if (project) {
131
- const key = process.platform === 'win32' ? project.root.toLowerCase() : project.root;
132
- found.set(key, project);
133
- }
134
- continue;
135
- }
136
-
137
- if (depth >= maxDepth) continue;
138
- let entries = [];
139
- try { entries = readdirSync(dir, { withFileTypes: true }); } catch { continue; }
140
- for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
141
- if (!entry.isDirectory() || entry.isSymbolicLink?.() || shouldIgnoreDir(entry.name)) continue;
142
- queue.push({ dir: join(dir, entry.name), depth: depth + 1 });
143
- }
144
- }
145
-
146
- return [...found.values()].sort((a, b) => a.root.localeCompare(b.root));
147
- }
148
-
149
- function uniqueProjects(projects) {
150
- const out = new Map();
151
- for (const project of projects || []) {
152
- if (!project?.root) continue;
153
- const key = process.platform === 'win32' ? resolve(project.root).toLowerCase() : resolve(project.root);
154
- if (!out.has(key)) out.set(key, project);
155
- }
156
- return [...out.values()].sort((a, b) => a.root.localeCompare(b.root));
157
- }
158
-
159
- function orderProjects(projects, activeProject) {
160
- const values = [...(projects || [])];
161
- values.sort((a, b) => {
162
- const aActive = activeProject?.root && samePath(a.root, activeProject.root);
163
- const bActive = activeProject?.root && samePath(b.root, activeProject.root);
164
- if (aActive !== bActive) return aActive ? -1 : 1;
165
- return a.root.localeCompare(b.root);
166
- });
167
- return values;
168
- }
169
-
170
- function preferGitProjects(projects, activeProject) {
171
- const values = [...(projects || [])];
172
- if (!values.some((project) => project.marker === 'git')) return values;
173
- return values.filter((project) => project.marker === 'git'
174
- || (activeProject?.root && samePath(project.root, activeProject.root)));
175
- }
176
-
177
- function scanBaseFor(currentCwd, activeProject) {
178
- if (activeProject?.root) return dirname(activeProject.root);
179
- return currentCwd;
180
- }
181
-
182
- function createWorkspaceRouter({
183
- entryCwd = process.cwd(),
184
- maxDepth = DEFAULT_MAX_DEPTH,
185
- maxDirs = DEFAULT_MAX_DIRS,
186
- maxCandidates = DEFAULT_MAX_CANDIDATES,
187
- } = {}) {
188
- let cached = null;
189
-
190
- function snapshot(currentCwd) {
191
- const resolvedCwd = resolve(currentCwd || entryCwd || process.cwd());
192
- const activeProject = findNearestProjectRoot(resolvedCwd);
193
- const entryProject = findNearestProjectRoot(entryCwd);
194
- const scanBase = scanBaseFor(resolvedCwd, activeProject);
195
- const key = [
196
- process.platform === 'win32' ? scanBase.toLowerCase() : scanBase,
197
- maxDepth,
198
- maxDirs,
199
- maxCandidates,
200
- ].join('|');
201
-
202
- if (!cached || cached.key !== key) {
203
- cached = {
204
- key,
205
- projects: uniqueProjects([
206
- ...(entryProject ? [entryProject] : []),
207
- ...(activeProject ? [activeProject] : []),
208
- ...discoverProjectCandidates(scanBase, { maxDepth, maxDirs, maxCandidates }),
209
- ]),
210
- };
211
- }
212
-
213
- const candidates = orderProjects(
214
- preferGitProjects(cached.projects, activeProject),
215
- activeProject,
216
- );
217
-
218
- return {
219
- currentCwd: resolvedCwd,
220
- activeProject,
221
- scanBase,
222
- candidates,
223
- isProjectRoot: activeProject ? samePath(resolvedCwd, activeProject.root) : false,
224
- };
225
- }
226
-
227
- return { snapshot };
228
- }
229
-
230
- function formatWorkspaceSessionContext(snapshot) {
231
- if (!snapshot) return '';
232
- const candidates = (snapshot.candidates || []).slice(0, 20);
233
- const lines = ['# Workspace'];
234
- lines.push(`current cwd: ${snapshot.currentCwd}`);
235
- if (snapshot.activeProject) {
236
- lines.push(`detected project: ${snapshot.activeProject.name} (${snapshot.activeProject.root})`);
237
- if (!snapshot.isProjectRoot) {
238
- lines.push('current cwd is inside a project but is not the project root; set cwd to the project root before repo-wide work.');
239
- }
240
- } else {
241
- lines.push('detected project: none');
242
- }
243
- if (candidates.length) {
244
- lines.push('project candidates:');
245
- candidates.forEach((project, index) => {
246
- lines.push(`${index + 1}. ${project.name} [${project.marker}] ${project.root}`);
247
- });
248
- } else {
249
- lines.push('project candidates: none');
250
- lines.push('If the user asks for repo-scoped work, summarize that no project was detected and ask for the working directory.');
251
- }
252
- return lines.join('\n');
253
- }
254
-
255
- function resolveWorkspaceCwd(baseCwd, value) {
256
- const raw = String(value || '').trim();
257
- if (!raw) return resolve(baseCwd || process.cwd());
258
- return isAbsolute(raw) ? resolve(raw) : resolve(baseCwd || process.cwd(), raw);
259
- }