newmark-agent 0.3.11 → 0.4.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.
- package/config.example.json +6 -0
- package/dist/cli-commands.d.ts +8 -0
- package/dist/cli-commands.js +216 -16
- package/dist/cli-discovery.d.ts +15 -0
- package/dist/cli-discovery.js +182 -0
- package/dist/cli-help.d.ts +2 -0
- package/dist/cli-help.js +25 -1
- package/dist/context/domain/types.d.ts +37 -0
- package/dist/context/services/context-orchestrator.js +2 -0
- package/dist/conversation-utility-host.bundle.cjs +1503 -214
- package/dist/conversation-utility-host.js +3 -0
- package/dist/core/agent.d.ts +157 -8
- package/dist/core/agent.js +1176 -112
- package/dist/core/agentKernel/agent-loop.js +29 -3
- package/dist/core/agentKernel/types.d.ts +7 -0
- package/dist/core/agentKernelRunner.d.ts +2 -0
- package/dist/core/agentKernelRunner.js +174 -27
- package/dist/core/config.d.ts +7 -2
- package/dist/core/config.js +24 -6
- package/dist/core/conversationKernel.d.ts +5 -0
- package/dist/core/conversationKernel.js +30 -1
- package/dist/core/dshCompatibility.d.ts +198 -0
- package/dist/core/dshCompatibility.js +600 -0
- package/dist/core/electronUtilityAgentClient.d.ts +4 -0
- package/dist/core/electronUtilityAgentClient.js +4 -0
- package/dist/core/electronUtilityRuntimePool.d.ts +19 -0
- package/dist/core/electronUtilityRuntimePool.js +76 -0
- package/dist/core/flow-runner.js +1 -1
- package/dist/core/mcpManager.d.ts +1 -0
- package/dist/core/mcpManager.js +100 -10
- package/dist/core/modelValidationStore.d.ts +4 -1
- package/dist/core/modelValidationStore.js +7 -1
- package/dist/core/subagent.d.ts +6 -0
- package/dist/core/subagent.js +22 -1
- package/dist/core/toolPolicy.d.ts +6 -0
- package/dist/core/toolPolicy.js +49 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/utilityAgentProtocol.d.ts +8 -1
- package/dist/core/workspace.d.ts +15 -0
- package/dist/core/workspace.js +62 -1
- package/dist/core/wslAgentClient.d.ts +4 -0
- package/dist/core/wslAgentClient.js +4 -0
- package/dist/core/wslAgentProtocol.d.ts +8 -1
- package/dist/core/wslAgentRuntimePool.d.ts +12 -0
- package/dist/core/wslAgentRuntimePool.js +71 -0
- package/dist/launcher.js +48 -11
- package/dist/llm/provider.d.ts +9 -6
- package/dist/llm/provider.js +89 -36
- package/dist/main.js +326 -52
- package/dist/preload.js +17 -0
- package/dist/providers/chat-completions.adapter.js +42 -20
- package/dist/providers/provider-adapter.d.ts +3 -0
- package/dist/providers/provider-events.d.ts +7 -0
- package/dist/providers/provider-events.js +44 -0
- package/dist/providers/responses.adapter.js +1 -3
- package/dist/toolchain/registry/tool-registry.d.ts +13 -1
- package/dist/toolchain/registry/tool-registry.js +8 -0
- package/dist/toolchain/registry-seeder.js +51 -5
- package/dist/tools/index.js +11 -2
- package/dist/tools/nativeTools.js +5 -1
- package/dist/tui/src/adapters/core-runtime-adapter.js +40 -3
- package/dist/tui/src/app.js +47 -13
- package/dist/tui/src/render.js +23 -7
- package/dist/tui/src/state.js +61 -9
- package/dist/ui/index.html +2775 -284
- package/dist/ui/lucide-sprite.svg +26 -0
- package/dist/wsl-agent-host.bundle.cjs +1503 -214
- package/dist/wsl-agent-host.js +3 -0
- package/package.json +16 -5
package/dist/tui/src/app.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const readline = require("node:readline");
|
|
4
4
|
const path = require("node:path");
|
|
5
5
|
const { render } = require("./render");
|
|
6
|
+
const { targetKey } = require("./adapters/newmark-contract");
|
|
6
7
|
const {
|
|
7
8
|
activateMenu,
|
|
8
9
|
activateMemorySelection,
|
|
@@ -89,6 +90,20 @@ function executeAction(state, action) {
|
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
function argumentValue(args, name) {
|
|
94
|
+
const inline = args.find((arg) => String(arg).startsWith(`${name}=`));
|
|
95
|
+
if (inline) return String(inline).slice(name.length + 1);
|
|
96
|
+
const index = args.indexOf(name);
|
|
97
|
+
return index >= 0 ? args[index + 1] || "" : "";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function resolveTuiWorkspacePath(args, options = {}) {
|
|
101
|
+
const explicitWorkspace = options.workspacePath || argumentValue(args, "--workspace");
|
|
102
|
+
if (explicitWorkspace) return explicitWorkspace;
|
|
103
|
+
const explicitRoot = options.root || argumentValue(args, "--root");
|
|
104
|
+
return explicitRoot || process.cwd();
|
|
105
|
+
}
|
|
106
|
+
|
|
92
107
|
function start(options = {}) {
|
|
93
108
|
const forcedTerminal = process.env.NEWMARK_FORCE_TTY === "1";
|
|
94
109
|
if ((!process.stdin.isTTY || !process.stdout.isTTY) && !forcedTerminal) {
|
|
@@ -98,20 +113,16 @@ function start(options = {}) {
|
|
|
98
113
|
}
|
|
99
114
|
|
|
100
115
|
const args = process.argv.slice(2);
|
|
101
|
-
const optionValue = (name) => {
|
|
102
|
-
const index = args.indexOf(name);
|
|
103
|
-
return index >= 0 ? args[index + 1] : "";
|
|
104
|
-
};
|
|
105
116
|
let adapter;
|
|
106
117
|
try {
|
|
107
118
|
if (args.includes("--demo") || process.env.NEWMARK_TUI_DEMO === "1") {
|
|
108
119
|
adapter = require("./adapters/mock-newmark-adapter").createMockNewmarkAdapter();
|
|
109
120
|
} else {
|
|
110
|
-
const root = options.root ||
|
|
111
|
-
const workspacePath = options.workspacePath
|
|
121
|
+
const root = options.root || argumentValue(args, "--root");
|
|
122
|
+
const workspacePath = resolveTuiWorkspacePath(args, { root, workspacePath: options.workspacePath });
|
|
112
123
|
adapter = require("./adapters/core-runtime-adapter").createCoreRuntimeAdapter({
|
|
113
124
|
root: root ? path.resolve(root) : undefined,
|
|
114
|
-
workspacePath:
|
|
125
|
+
workspacePath: path.resolve(workspacePath),
|
|
115
126
|
desktopDist: options.desktopDist
|
|
116
127
|
});
|
|
117
128
|
}
|
|
@@ -185,6 +196,7 @@ function start(options = {}) {
|
|
|
185
196
|
|
|
186
197
|
async function sendRealMessage(text) {
|
|
187
198
|
const target = { ...state.target };
|
|
199
|
+
const key = targetKey(target);
|
|
188
200
|
state.input = "";
|
|
189
201
|
state.inputCursor = 0;
|
|
190
202
|
state.inputMode = false;
|
|
@@ -201,13 +213,26 @@ function start(options = {}) {
|
|
|
201
213
|
}, 250);
|
|
202
214
|
}
|
|
203
215
|
paint();
|
|
216
|
+
const previous = state.sendQueueByConversation?.get(key) || Promise.resolve();
|
|
217
|
+
const current = previous
|
|
218
|
+
.catch(() => {})
|
|
219
|
+
.then(() => state.adapter.sendMessage(text, target));
|
|
220
|
+
state.sendQueueByConversation?.set(key, current);
|
|
204
221
|
try {
|
|
205
|
-
const snapshot = await
|
|
206
|
-
|
|
222
|
+
const snapshot = await current;
|
|
223
|
+
if (state.sendQueueByConversation?.get(key) === current) {
|
|
224
|
+
applyConversationResult(state, target, snapshot);
|
|
225
|
+
}
|
|
207
226
|
} catch (error) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
227
|
+
if (state.sendQueueByConversation?.get(key) === current) {
|
|
228
|
+
markConversationRunning(state, target, false);
|
|
229
|
+
state.notice = `Agent error: ${error.message}`;
|
|
230
|
+
paint();
|
|
231
|
+
}
|
|
232
|
+
} finally {
|
|
233
|
+
if (state.sendQueueByConversation?.get(key) === current) {
|
|
234
|
+
state.sendQueueByConversation.delete(key);
|
|
235
|
+
}
|
|
211
236
|
}
|
|
212
237
|
}
|
|
213
238
|
|
|
@@ -439,6 +464,15 @@ function start(options = {}) {
|
|
|
439
464
|
|
|
440
465
|
function handleKey(str, key) {
|
|
441
466
|
if (key.ctrl && key.name === "c") return quit();
|
|
467
|
+
// A real run leaves input mode immediately after Enter. Keep Esc target-bound
|
|
468
|
+
// at the app boundary so users can stop that run from the content view too.
|
|
469
|
+
if (key.name === "escape"
|
|
470
|
+
&& !state.overlay
|
|
471
|
+
&& !state.memorySearchActive
|
|
472
|
+
&& state.runningConversationKeys?.size) {
|
|
473
|
+
Promise.resolve(requestConversationStop(state)).finally(paint);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
442
476
|
if (state.overlay === "palette") handlePalette(str, key);
|
|
443
477
|
else if (state.overlay === "flow-select") handleFlowSelection(key);
|
|
444
478
|
else if (state.overlay === "settings-choice") handleSettingChoice(key);
|
|
@@ -501,4 +535,4 @@ function start(options = {}) {
|
|
|
501
535
|
paint();
|
|
502
536
|
}
|
|
503
537
|
|
|
504
|
-
module.exports = { createPaintScheduler, executeAction, start };
|
|
538
|
+
module.exports = { createPaintScheduler, executeAction, resolveTuiWorkspacePath, start };
|
package/dist/tui/src/render.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const data = require("./data");
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
activeConversationModelLabel,
|
|
6
|
+
filteredCommands,
|
|
7
|
+
memoryTagOptions,
|
|
8
|
+
resolveThemeAppearance,
|
|
9
|
+
selectedMemoryDetail
|
|
10
|
+
} = require("./state");
|
|
5
11
|
const { SETTINGS_CATEGORIES, displaySettingValue, settingsRows } = require("./settings-schema");
|
|
6
12
|
|
|
7
13
|
const ESC = "\u001b[";
|
|
@@ -94,11 +100,16 @@ function palette(state) {
|
|
|
94
100
|
};
|
|
95
101
|
const colors = state.theme === "light" ? light : dark;
|
|
96
102
|
const appearance = state.settings?.personalization;
|
|
97
|
-
if (!appearance
|
|
103
|
+
if (!appearance) {
|
|
98
104
|
return { ...colors, paint: "", final: `${ESC}0m` };
|
|
99
105
|
}
|
|
100
|
-
const
|
|
101
|
-
|
|
106
|
+
const resolvedAppearance = resolveThemeAppearance(
|
|
107
|
+
state.theme,
|
|
108
|
+
appearance.fontColor,
|
|
109
|
+
appearance.backgroundColor
|
|
110
|
+
);
|
|
111
|
+
const [fr, fg, fb] = hexRgb(resolvedAppearance.fontColor);
|
|
112
|
+
const [br, bg, bb] = hexRgb(resolvedAppearance.backgroundColor);
|
|
102
113
|
const paint = `${ESC}38;2;${fr};${fg};${fb}m${ESC}48;2;${br};${bg};${bb}m`;
|
|
103
114
|
return {
|
|
104
115
|
...colors,
|
|
@@ -951,10 +962,15 @@ function contrastRatio(foreground, background) {
|
|
|
951
962
|
|
|
952
963
|
function personalizationPreview(state, p) {
|
|
953
964
|
const appearance = state.settings.personalization;
|
|
954
|
-
const
|
|
955
|
-
|
|
965
|
+
const resolvedAppearance = resolveThemeAppearance(
|
|
966
|
+
state.theme,
|
|
967
|
+
appearance.fontColor,
|
|
968
|
+
appearance.backgroundColor
|
|
969
|
+
);
|
|
970
|
+
const [fr, fg, fb] = hexRgb(resolvedAppearance.fontColor);
|
|
971
|
+
const [br, bg, bb] = hexRgb(resolvedAppearance.backgroundColor);
|
|
956
972
|
const sample = `${ESC}38;2;${fr};${fg};${fb}m${ESC}48;2;${br};${bg};${bb}m Newmark Aa 中 123 ${p.reset}`;
|
|
957
|
-
const contrast = contrastRatio(
|
|
973
|
+
const contrast = contrastRatio(resolvedAppearance.fontColor, resolvedAppearance.backgroundColor);
|
|
958
974
|
return [
|
|
959
975
|
`${p.bold}Live color preview${p.reset} ${sample}`,
|
|
960
976
|
`${p.muted}Font request: ${appearance.fontFamily} · contrast ${contrast.toFixed(2)}:1 ${contrast >= 4.5 ? "PASS" : "LOW"}${p.reset}`,
|
package/dist/tui/src/state.js
CHANGED
|
@@ -5,6 +5,55 @@ const { createMockNewmarkAdapter } = require("./adapters/mock-newmark-adapter");
|
|
|
5
5
|
const { targetKey, validateSnapshot } = require("./adapters/newmark-contract");
|
|
6
6
|
const { SETTINGS_CATEGORIES, settingsRows } = require("./settings-schema");
|
|
7
7
|
const INTELLIGENCE_TIERS = Object.freeze(["low", "medium", "high", "xhigh", "max", "ultra"]);
|
|
8
|
+
const HEX_COLOR_PATTERN = /^#[0-9a-f]{6}$/i;
|
|
9
|
+
const THEME_APPEARANCE_DEFAULTS = Object.freeze({
|
|
10
|
+
dark: Object.freeze({ fontColor: "#E6EAF2", backgroundColor: "#0A0A1A" }),
|
|
11
|
+
light: Object.freeze({ fontColor: "#1F2937", backgroundColor: "#F0F2F8" })
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
function normalizedTheme(value) {
|
|
15
|
+
return String(value || "dark").trim().toLowerCase() === "light" ? "light" : "dark";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function normalizedHexColor(value) {
|
|
19
|
+
const candidate = String(value || "").trim();
|
|
20
|
+
return HEX_COLOR_PATTERN.test(candidate) ? candidate.toUpperCase() : "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function contrastRatio(foreground, background) {
|
|
24
|
+
const luminance = (value) => {
|
|
25
|
+
const channels = [0, 2, 4].map((offset) => Number.parseInt(value.slice(offset, offset + 2), 16) / 255)
|
|
26
|
+
.map((channel) => channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4);
|
|
27
|
+
return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2];
|
|
28
|
+
};
|
|
29
|
+
const foregroundLuminance = luminance(foreground.slice(1));
|
|
30
|
+
const backgroundLuminance = luminance(background.slice(1));
|
|
31
|
+
return (Math.max(foregroundLuminance, backgroundLuminance) + 0.05)
|
|
32
|
+
/ (Math.min(foregroundLuminance, backgroundLuminance) + 0.05);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolve persisted appearance without allowing a legacy/mismatched color
|
|
37
|
+
* pair to disable the whole terminal canvas. Explicit colors are retained
|
|
38
|
+
* when readable; otherwise the closest theme-safe pair is used for rendering.
|
|
39
|
+
*/
|
|
40
|
+
function resolveThemeAppearance(theme, fontColor, backgroundColor) {
|
|
41
|
+
const resolvedTheme = normalizedTheme(theme);
|
|
42
|
+
const defaults = THEME_APPEARANCE_DEFAULTS[resolvedTheme];
|
|
43
|
+
let foreground = normalizedHexColor(fontColor) || defaults.fontColor;
|
|
44
|
+
let background = normalizedHexColor(backgroundColor) || defaults.backgroundColor;
|
|
45
|
+
if (contrastRatio(foreground, background) < 4.5) {
|
|
46
|
+
if (contrastRatio(defaults.fontColor, background) >= 4.5) {
|
|
47
|
+
foreground = defaults.fontColor;
|
|
48
|
+
} else if (contrastRatio(foreground, defaults.backgroundColor) >= 4.5) {
|
|
49
|
+
background = defaults.backgroundColor;
|
|
50
|
+
} else {
|
|
51
|
+
foreground = defaults.fontColor;
|
|
52
|
+
background = defaults.backgroundColor;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { theme: resolvedTheme, fontColor: foreground, backgroundColor: background };
|
|
56
|
+
}
|
|
8
57
|
|
|
9
58
|
function applySnapshot(state, snapshot) {
|
|
10
59
|
const valid = validateSnapshot(snapshot);
|
|
@@ -53,15 +102,15 @@ function applyThemeAppearance(state, selection) {
|
|
|
53
102
|
: String(selection || "Dark").toLowerCase() === "system"
|
|
54
103
|
? "System"
|
|
55
104
|
: "Dark";
|
|
56
|
-
const
|
|
57
|
-
state.theme =
|
|
105
|
+
const appearance = resolveThemeAppearance(label, "", "");
|
|
106
|
+
state.theme = appearance.theme;
|
|
58
107
|
state.settings.personalization.theme = label;
|
|
59
|
-
state.settings.personalization.fontColor =
|
|
60
|
-
state.settings.personalization.backgroundColor =
|
|
108
|
+
state.settings.personalization.fontColor = appearance.fontColor;
|
|
109
|
+
state.settings.personalization.backgroundColor = appearance.backgroundColor;
|
|
61
110
|
return {
|
|
62
111
|
theme: label.toLowerCase(),
|
|
63
|
-
fontColor:
|
|
64
|
-
backgroundColor:
|
|
112
|
+
fontColor: appearance.fontColor,
|
|
113
|
+
backgroundColor: appearance.backgroundColor
|
|
65
114
|
};
|
|
66
115
|
}
|
|
67
116
|
|
|
@@ -101,6 +150,7 @@ function createState(options = {}) {
|
|
|
101
150
|
}
|
|
102
151
|
return [name, workflow || { name, components: [] }];
|
|
103
152
|
}));
|
|
153
|
+
const appearance = resolveThemeAppearance(snapshot.darkMode, snapshot.fontColor, snapshot.backgroundColor);
|
|
104
154
|
return {
|
|
105
155
|
adapter,
|
|
106
156
|
adapterKind: adapter.kind,
|
|
@@ -135,7 +185,7 @@ function createState(options = {}) {
|
|
|
135
185
|
flowSelectionIndex: 0,
|
|
136
186
|
flowByConversation: initialFlow ? { [`${target.workspaceId}::${target.conversationId}`]: initialFlow } : {},
|
|
137
187
|
currentFlow: initialFlow,
|
|
138
|
-
theme:
|
|
188
|
+
theme: appearance.theme,
|
|
139
189
|
overlay: null,
|
|
140
190
|
settingChoiceTab: "",
|
|
141
191
|
settingChoiceKey: "",
|
|
@@ -161,6 +211,7 @@ function createState(options = {}) {
|
|
|
161
211
|
: `Newmark core connected · ${workspaces.find((item) => item.id === target.workspaceId)?.path || target.workspaceId}`,
|
|
162
212
|
busy: false,
|
|
163
213
|
runningConversationKeys: new Set(),
|
|
214
|
+
sendQueueByConversation: new Map(),
|
|
164
215
|
stopStageByConversation: new Map(),
|
|
165
216
|
tick: 0,
|
|
166
217
|
messages: snapshot.chatMessages.map((item) => ({ ...item })),
|
|
@@ -199,8 +250,8 @@ function createState(options = {}) {
|
|
|
199
250
|
personalization: {
|
|
200
251
|
theme: { light: "Light", system: "System", dark: "Dark" }[String(snapshot.darkMode || "dark").toLowerCase()] || "Dark",
|
|
201
252
|
fontFamily: snapshot.fontFamily || "Terminal default",
|
|
202
|
-
fontColor:
|
|
203
|
-
backgroundColor:
|
|
253
|
+
fontColor: appearance.fontColor,
|
|
254
|
+
backgroundColor: appearance.backgroundColor,
|
|
204
255
|
glassAlpha: Number(snapshot.glassAlpha || 0.85)
|
|
205
256
|
},
|
|
206
257
|
runtime: {
|
|
@@ -1285,6 +1336,7 @@ module.exports = {
|
|
|
1285
1336
|
activateMenu,
|
|
1286
1337
|
activateMemorySelection,
|
|
1287
1338
|
applyThemeAppearance,
|
|
1339
|
+
resolveThemeAppearance,
|
|
1288
1340
|
applySnapshot,
|
|
1289
1341
|
applyConversationResult,
|
|
1290
1342
|
beginAutomationCreate,
|