mixdog 0.9.27 → 0.9.29
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/package.json +6 -2
- package/src/app.mjs +14 -0
- package/src/rules/lead/lead-tool.md +1 -2
- package/src/rules/shared/01-tool.md +13 -11
- package/src/runtime/channels/backends/discord-access.mjs +1 -3
- package/src/runtime/channels/backends/telegram.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +5 -29
- package/src/runtime/memory/tool-defs.mjs +1 -1
- package/src/runtime/shared/config.mjs +1 -6
- package/src/runtime/shared/schedules-db.mjs +2 -120
- package/src/runtime/shared/webhooks-db.mjs +3 -138
- package/src/session-runtime/runtime-core.mjs +32 -10
- package/src/standalone/agent-tool/tool-def.mjs +1 -1
- package/src/standalone/channel-admin.mjs +6 -27
- package/src/tui/App.jsx +2 -1
- package/src/tui/components/StatusLine.jsx +2 -2
- package/src/tui/components/ToolExecution.jsx +10 -1
- package/src/tui/display-width.mjs +4 -1
- package/src/tui/dist/index.mjs +173 -157
- package/src/tui/engine/notification-plan.mjs +5 -1
- package/src/tui/index.jsx +2 -1
- package/src/workflows/default/WORKFLOW.md +15 -11
- package/vendor/ink/build/display-width.js +3 -1
|
@@ -102,42 +102,22 @@ function seedBackendChannelIds(entry = {}, backend = 'discord') {
|
|
|
102
102
|
return next;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// Resolve the single-channel entry from the config
|
|
106
|
-
// object; fall back (read-side only, no on-disk migration) to the legacy
|
|
107
|
-
// channelsConfig[mainChannel ?? 'main'] entry, then the first entry with an id.
|
|
105
|
+
// Resolve the single-channel entry from the config's `channel` object.
|
|
108
106
|
function resolveChannelEntry(cfg = {}) {
|
|
109
107
|
if (cfg.channel && typeof cfg.channel === 'object'
|
|
110
108
|
&& (cfg.channel.channelId || cfg.channel.discordChannelId || cfg.channel.telegramChatId)) {
|
|
111
109
|
return cfg.channel;
|
|
112
110
|
}
|
|
113
|
-
const legacy = cfg.channelsConfig && typeof cfg.channelsConfig === 'object' ? cfg.channelsConfig : null;
|
|
114
|
-
if (legacy) {
|
|
115
|
-
const mainName = cfg.mainChannel ?? 'main';
|
|
116
|
-
const preferred = legacy[mainName];
|
|
117
|
-
if (preferred && typeof preferred === 'object'
|
|
118
|
-
&& (preferred.channelId || preferred.discordChannelId || preferred.telegramChatId)) {
|
|
119
|
-
return preferred;
|
|
120
|
-
}
|
|
121
|
-
for (const entry of Object.values(legacy)) {
|
|
122
|
-
if (entry && typeof entry === 'object'
|
|
123
|
-
&& (entry.channelId || entry.discordChannelId || entry.telegramChatId)) {
|
|
124
|
-
return entry;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
111
|
return cfg.channel && typeof cfg.channel === 'object' ? cfg.channel : {};
|
|
129
112
|
}
|
|
130
113
|
|
|
131
114
|
function updateChannelsSection(build) {
|
|
132
115
|
let next;
|
|
133
116
|
updateSection('channels', (current) => {
|
|
134
|
-
//
|
|
135
|
-
// for read-side compat, but never re-emit them from our writers: strip them
|
|
136
|
-
// out of the returned shape so writes converge on the single `channel`.
|
|
117
|
+
// Writes converge on the single `channel` object.
|
|
137
118
|
const normalized = normalizeChannelsConfig(current);
|
|
138
119
|
next = build(normalized);
|
|
139
|
-
|
|
140
|
-
return clean;
|
|
120
|
+
return normalizeChannelsConfig(next);
|
|
141
121
|
});
|
|
142
122
|
return next;
|
|
143
123
|
}
|
|
@@ -151,8 +131,7 @@ async function updateChannelsSectionAsync(build) {
|
|
|
151
131
|
await updateSectionAsync('channels', (current) => {
|
|
152
132
|
const normalized = normalizeChannelsConfig(current);
|
|
153
133
|
next = build(normalized);
|
|
154
|
-
|
|
155
|
-
return clean;
|
|
134
|
+
return normalizeChannelsConfig(next);
|
|
156
135
|
});
|
|
157
136
|
return next;
|
|
158
137
|
}
|
|
@@ -168,8 +147,8 @@ function listEntryDirs(dir) {
|
|
|
168
147
|
}
|
|
169
148
|
}
|
|
170
149
|
|
|
171
|
-
// Single-channel read: resolves `cfg.channel`
|
|
172
|
-
//
|
|
150
|
+
// Single-channel read: resolves `cfg.channel` into the flat shape the
|
|
151
|
+
// settings/TUI layer consumes.
|
|
173
152
|
export function getChannel(config = {}) {
|
|
174
153
|
const cfg = normalizeChannelsConfig(config);
|
|
175
154
|
const backend = cfg.backend === 'telegram' ? 'telegram' : 'discord';
|
package/src/tui/App.jsx
CHANGED
|
@@ -21,6 +21,7 @@ import { Box, Text, useApp, useInput, useStdin, useStdout } from 'ink';
|
|
|
21
21
|
import { theme, surfaceBackground } from './theme.mjs';
|
|
22
22
|
import { useEngine } from './hooks/useEngine.mjs';
|
|
23
23
|
import { classifyToolCategory } from '../runtime/shared/tool-surface.mjs';
|
|
24
|
+
import { localPackageVersion } from '../runtime/shared/update-checker.mjs';
|
|
24
25
|
import { Spinner } from './components/Spinner.jsx';
|
|
25
26
|
import { StatusLine } from './components/StatusLine.jsx';
|
|
26
27
|
import { PromptInput } from './components/PromptInput.jsx';
|
|
@@ -3058,7 +3059,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false })
|
|
|
3058
3059
|
<Text color={theme.logo ?? theme.claude} bold>{centerLine('██║╚██╔╝██║██║ ██╔██╗ ██║ ██║██║ ██║██║ ██║', frameColumns)}</Text>
|
|
3059
3060
|
<Text color={theme.logo ?? theme.claude} bold>{centerLine('██║ ╚═╝ ██║██║██╔╝ ██╗██████╔╝╚██████╔╝╚██████╔╝', frameColumns)}</Text>
|
|
3060
3061
|
<Box height={1} flexShrink={0} />
|
|
3061
|
-
<Text color={theme.inactive}>{centerLine(`mixdog coding agent · ${state.cwd}`, frameColumns, 4)}</Text>
|
|
3062
|
+
<Text color={theme.inactive}>{centerLine(`mixdog coding agent · v${localPackageVersion()} · ${state.cwd}`, frameColumns, 4)}</Text>
|
|
3062
3063
|
</Box>
|
|
3063
3064
|
) : null}
|
|
3064
3065
|
|
|
@@ -709,7 +709,7 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
709
709
|
return (
|
|
710
710
|
<Box flexDirection="column" width="100%" height={3} overflow="hidden" justifyContent="flex-start" paddingLeft={2} backgroundColor={surfaceBackground()}>
|
|
711
711
|
<Box flexDirection="row" width="100%" overflow="hidden">
|
|
712
|
-
<Box flexGrow={1} flexShrink={1} overflow="hidden">
|
|
712
|
+
<Box flexGrow={1} flexShrink={1} flexBasis={0} overflow="hidden">
|
|
713
713
|
<Text wrap="truncate">{lines[0] || ' '}</Text>
|
|
714
714
|
</Box>
|
|
715
715
|
<Box flexShrink={0} marginLeft={1} marginRight={1}>
|
|
@@ -717,7 +717,7 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
717
717
|
</Box>
|
|
718
718
|
</Box>
|
|
719
719
|
<Box flexDirection="row" width="100%" overflow="hidden">
|
|
720
|
-
<Box flexGrow={1} flexShrink={1} overflow="hidden">
|
|
720
|
+
<Box flexGrow={1} flexShrink={1} flexBasis={0} overflow="hidden">
|
|
721
721
|
<Text wrap="truncate">{lines[1] || ' '}</Text>
|
|
722
722
|
</Box>
|
|
723
723
|
</Box>
|
|
@@ -432,7 +432,16 @@ export function ToolExecution({ name, args, result, rawResult, isError, errorCou
|
|
|
432
432
|
const markerGlyph = isAgentResponse
|
|
433
433
|
? AGENT_RESPONSE_MARKER
|
|
434
434
|
: (isAgentSurfaceCard ? AGENT_CALL_MARKER : TURN_MARKER);
|
|
435
|
-
|
|
435
|
+
// Directional arrow markers (`←` spawn/send out, `→` response back) render 2
|
|
436
|
+
// cells wide in some terminals (Windows Terminal / Cascadia) while our width
|
|
437
|
+
// math counts them as 1, so the `Box minWidth={2}` gutter padding gets
|
|
438
|
+
// overdrawn and the label glues to the arrow ("←Spawn"). Carry an explicit
|
|
439
|
+
// trailing space in the marker string so the gap is a real character that
|
|
440
|
+
// survives regardless of how wide the terminal actually draws the glyph. The
|
|
441
|
+
// `●` turn marker is a true 1-cell glyph and keeps the padding-only gutter.
|
|
442
|
+
const isDirectionalMarker = isAgentResponse || isAgentSurfaceCard;
|
|
443
|
+
const markerText = isDirectionalMarker ? `${markerGlyph} ` : markerGlyph;
|
|
444
|
+
const dotText = pending && !blinkExpired && !blinkOn ? ' ' : markerText;
|
|
436
445
|
let labelText;
|
|
437
446
|
if (isAgentResponse) labelText = agentResponseTitle(parsedArgs);
|
|
438
447
|
else if (isBackgroundResponse) labelText = backgroundTaskResultTitle(normalizedName, backgroundMeta || parsedArgs);
|
|
@@ -38,9 +38,12 @@ const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme
|
|
|
38
38
|
* markers (agent card ←/→, history ↑/↓): WT draws them 1 cell in
|
|
39
39
|
* Cascadia, and widening them ate the marker's gutter padding space
|
|
40
40
|
* ("←Spawn" rendered glued / shifted vs the ● rows).
|
|
41
|
+
* Also excludes U+21BB (↻, the statusline quota-reset marker): WT/Cascadia
|
|
42
|
+
* draws it 1 cell, so widening it reserved a phantom cell that shifted the
|
|
43
|
+
* right-aligned workflow label one column left when the usage segment appeared.
|
|
41
44
|
*/
|
|
42
45
|
export function isProblemCodePoint(cp) {
|
|
43
|
-
return (cp >= 0x2460 && cp <= 0x24ff) || (cp >= 0x2194 && cp <= 0x21ff);
|
|
46
|
+
return (cp >= 0x2460 && cp <= 0x24ff) || (cp >= 0x2194 && cp <= 0x21ff && cp !== 0x21bb);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
// Fast precheck for the problem ranges above. Lets the hot path bail before
|