newmark-agent 0.5.10 → 0.5.11
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.
|
@@ -8383,7 +8383,7 @@ var require_createWorker = __commonJS({
|
|
|
8383
8383
|
...defaultOptions,
|
|
8384
8384
|
..._options
|
|
8385
8385
|
});
|
|
8386
|
-
const
|
|
8386
|
+
const promises3 = {};
|
|
8387
8387
|
const currentLangs = typeof langs === "string" ? langs.split("+") : langs;
|
|
8388
8388
|
let currentOem = oem;
|
|
8389
8389
|
let currentConfig = config;
|
|
@@ -8403,7 +8403,7 @@ var require_createWorker = __commonJS({
|
|
|
8403
8403
|
const startJob = ({ id: jobId, action, payload }) => new Promise((resolve16, reject) => {
|
|
8404
8404
|
log2(`[${id}]: Start ${jobId}, action=${action}`);
|
|
8405
8405
|
const promiseId = `${action}-${jobId}`;
|
|
8406
|
-
|
|
8406
|
+
promises3[promiseId] = { resolve: resolve16, reject };
|
|
8407
8407
|
send(worker, {
|
|
8408
8408
|
workerId: id,
|
|
8409
8409
|
jobId,
|
|
@@ -8508,11 +8508,11 @@ var require_createWorker = __commonJS({
|
|
|
8508
8508
|
const promiseId = `${action}-${jobId}`;
|
|
8509
8509
|
if (status === "resolve") {
|
|
8510
8510
|
log2(`[${workerId}]: Complete ${jobId}`);
|
|
8511
|
-
|
|
8512
|
-
delete
|
|
8511
|
+
promises3[promiseId].resolve({ jobId, data });
|
|
8512
|
+
delete promises3[promiseId];
|
|
8513
8513
|
} else if (status === "reject") {
|
|
8514
|
-
|
|
8515
|
-
delete
|
|
8514
|
+
promises3[promiseId].reject(data);
|
|
8515
|
+
delete promises3[promiseId];
|
|
8516
8516
|
if (action === "load") workerResReject(data);
|
|
8517
8517
|
if (errorHandler) {
|
|
8518
8518
|
errorHandler(data);
|
|
@@ -54006,18 +54006,18 @@ var require_proxy_agent = __commonJS({
|
|
|
54006
54006
|
}
|
|
54007
54007
|
}
|
|
54008
54008
|
[kClose]() {
|
|
54009
|
-
const
|
|
54009
|
+
const promises3 = [this[kAgent].close()];
|
|
54010
54010
|
if (this[kClient]) {
|
|
54011
|
-
|
|
54011
|
+
promises3.push(this[kClient].close());
|
|
54012
54012
|
}
|
|
54013
|
-
return Promise.all(
|
|
54013
|
+
return Promise.all(promises3);
|
|
54014
54014
|
}
|
|
54015
54015
|
[kDestroy]() {
|
|
54016
|
-
const
|
|
54016
|
+
const promises3 = [this[kAgent].destroy()];
|
|
54017
54017
|
if (this[kClient]) {
|
|
54018
|
-
|
|
54018
|
+
promises3.push(this[kClient].destroy());
|
|
54019
54019
|
}
|
|
54020
|
-
return Promise.all(
|
|
54020
|
+
return Promise.all(promises3);
|
|
54021
54021
|
}
|
|
54022
54022
|
};
|
|
54023
54023
|
function buildHeaders(headers) {
|
|
@@ -344923,6 +344923,7 @@ var fs24 = __toESM(require("fs"));
|
|
|
344923
344923
|
var path27 = __toESM(require("path"));
|
|
344924
344924
|
var import_crypto14 = require("crypto");
|
|
344925
344925
|
var processStates = /* @__PURE__ */ new Map();
|
|
344926
|
+
var preparedPreviousStates = /* @__PURE__ */ new Map();
|
|
344926
344927
|
function stateKey(root2, role) {
|
|
344927
344928
|
return `${path27.resolve(root2)}\0${role}`;
|
|
344928
344929
|
}
|
|
@@ -344968,7 +344969,8 @@ function beginRuntimeLifecycle(root2, role = "main") {
|
|
|
344968
344969
|
const key3 = stateKey(root2, role);
|
|
344969
344970
|
const existingProcessState = processStates.get(key3);
|
|
344970
344971
|
if (existingProcessState) return existingProcessState;
|
|
344971
|
-
const previousStates = readActiveStates(root2, role);
|
|
344972
|
+
const previousStates = preparedPreviousStates.get(key3) || readActiveStates(root2, role);
|
|
344973
|
+
preparedPreviousStates.delete(key3);
|
|
344972
344974
|
const previousOwnerAlive = previousStates.some((previous) => isRuntimeProcessAlive(Number(previous.pid)));
|
|
344973
344975
|
const state = {
|
|
344974
344976
|
role,
|
|
@@ -344991,12 +344993,12 @@ function markRuntimeLifecycleClean(root2, role = "main") {
|
|
|
344991
344993
|
const current = processStates.get(key3);
|
|
344992
344994
|
if (!current) return;
|
|
344993
344995
|
try {
|
|
344994
|
-
|
|
344995
|
-
...current,
|
|
344996
|
-
active: false,
|
|
344997
|
-
cleanExitAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
344998
|
-
});
|
|
344996
|
+
fs24.unlinkSync(statePath(root2, role, current.ownerId));
|
|
344999
344997
|
} catch {
|
|
344998
|
+
try {
|
|
344999
|
+
writeState(root2, role, { ...current, active: false, cleanExitAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
345000
|
+
} catch {
|
|
345001
|
+
}
|
|
345000
345002
|
}
|
|
345001
345003
|
}
|
|
345002
345004
|
|
|
@@ -9,6 +9,8 @@ export interface RuntimeLifecycleState {
|
|
|
9
9
|
active: true;
|
|
10
10
|
}
|
|
11
11
|
export declare function isRuntimeProcessAlive(pid: number): boolean;
|
|
12
|
+
/** Prepare crash-recovery markers asynchronously after the startup shell is visible. */
|
|
13
|
+
export declare function prepareRuntimeLifecycle(root: string, role?: RuntimeLifecycleRole): Promise<void>;
|
|
12
14
|
/**
|
|
13
15
|
* Claim this process/role as the current runtime owner.
|
|
14
16
|
*
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.isRuntimeProcessAlive = isRuntimeProcessAlive;
|
|
37
|
+
exports.prepareRuntimeLifecycle = prepareRuntimeLifecycle;
|
|
37
38
|
exports.beginRuntimeLifecycle = beginRuntimeLifecycle;
|
|
38
39
|
exports.markRuntimeLifecycleClean = markRuntimeLifecycleClean;
|
|
39
40
|
exports.runtimeLifecycleState = runtimeLifecycleState;
|
|
@@ -41,6 +42,8 @@ const fs = __importStar(require("fs"));
|
|
|
41
42
|
const path = __importStar(require("path"));
|
|
42
43
|
const crypto_1 = require("crypto");
|
|
43
44
|
const processStates = new Map();
|
|
45
|
+
const preparedPreviousStates = new Map();
|
|
46
|
+
const lifecyclePreparations = new Map();
|
|
44
47
|
function stateKey(root, role) {
|
|
45
48
|
return `${path.resolve(root)}\u0000${role}`;
|
|
46
49
|
}
|
|
@@ -89,6 +92,50 @@ function readActiveStates(root, role) {
|
|
|
89
92
|
return [];
|
|
90
93
|
}
|
|
91
94
|
}
|
|
95
|
+
/** Prepare crash-recovery markers asynchronously after the startup shell is visible. */
|
|
96
|
+
function prepareRuntimeLifecycle(root, role = 'main') {
|
|
97
|
+
const key = stateKey(root, role);
|
|
98
|
+
if (processStates.has(key) || preparedPreviousStates.has(key))
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
const current = lifecyclePreparations.get(key);
|
|
101
|
+
if (current)
|
|
102
|
+
return current.then(() => undefined);
|
|
103
|
+
const preparation = (async () => {
|
|
104
|
+
const directory = path.join(root, '.newmark-runtime');
|
|
105
|
+
let files;
|
|
106
|
+
try {
|
|
107
|
+
files = (await fs.promises.readdir(directory))
|
|
108
|
+
.filter(file => file.startsWith(`lifecycle-${role}`) && file.endsWith('.json'));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
const active = [];
|
|
114
|
+
for (let offset = 0; offset < files.length; offset += 24) {
|
|
115
|
+
const states = await Promise.all(files.slice(offset, offset + 24).map(async (file) => {
|
|
116
|
+
const filePath = path.join(directory, file);
|
|
117
|
+
try {
|
|
118
|
+
const state = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));
|
|
119
|
+
if (state?.active === true)
|
|
120
|
+
return state;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// A corrupt marker cannot establish a live owner.
|
|
124
|
+
}
|
|
125
|
+
await fs.promises.unlink(filePath).catch(() => undefined);
|
|
126
|
+
return null;
|
|
127
|
+
}));
|
|
128
|
+
for (const state of states)
|
|
129
|
+
if (state)
|
|
130
|
+
active.push(state);
|
|
131
|
+
}
|
|
132
|
+
return active;
|
|
133
|
+
})();
|
|
134
|
+
lifecyclePreparations.set(key, preparation);
|
|
135
|
+
return preparation.then(states => {
|
|
136
|
+
preparedPreviousStates.set(key, states);
|
|
137
|
+
}).finally(() => lifecyclePreparations.delete(key));
|
|
138
|
+
}
|
|
92
139
|
/**
|
|
93
140
|
* Claim this process/role as the current runtime owner.
|
|
94
141
|
*
|
|
@@ -101,7 +148,8 @@ function beginRuntimeLifecycle(root, role = 'main') {
|
|
|
101
148
|
const existingProcessState = processStates.get(key);
|
|
102
149
|
if (existingProcessState)
|
|
103
150
|
return existingProcessState;
|
|
104
|
-
const previousStates = readActiveStates(root, role);
|
|
151
|
+
const previousStates = preparedPreviousStates.get(key) || readActiveStates(root, role);
|
|
152
|
+
preparedPreviousStates.delete(key);
|
|
105
153
|
const previousOwnerAlive = previousStates.some(previous => isRuntimeProcessAlive(Number(previous.pid)));
|
|
106
154
|
const state = {
|
|
107
155
|
role,
|
|
@@ -129,15 +177,16 @@ function markRuntimeLifecycleClean(root, role = 'main') {
|
|
|
129
177
|
if (!current)
|
|
130
178
|
return;
|
|
131
179
|
try {
|
|
132
|
-
|
|
133
|
-
...current,
|
|
134
|
-
active: false,
|
|
135
|
-
cleanExitAt: new Date().toISOString(),
|
|
136
|
-
});
|
|
180
|
+
fs.unlinkSync(statePath(root, role, current.ownerId));
|
|
137
181
|
}
|
|
138
182
|
catch {
|
|
139
|
-
|
|
140
|
-
|
|
183
|
+
try {
|
|
184
|
+
writeState(root, role, { ...current, active: false, cleanExitAt: new Date().toISOString() });
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Leaving the marker active is safer than claiming a clean exit after a
|
|
188
|
+
// failed durable write.
|
|
189
|
+
}
|
|
141
190
|
}
|
|
142
191
|
}
|
|
143
192
|
function runtimeLifecycleState(root, role = 'main') {
|
package/dist/main.js
CHANGED
|
@@ -1803,12 +1803,10 @@ else {
|
|
|
1803
1803
|
};
|
|
1804
1804
|
let firstRunInitialized = false;
|
|
1805
1805
|
if (!automationWakeMode) {
|
|
1806
|
-
//
|
|
1807
|
-
// startup
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
startupShellLoadedAt = Date.now();
|
|
1811
|
-
startupWindow = createDesktopWindow(true, true, startupAttempt);
|
|
1806
|
+
// Keep Chromium's heavy index renderer off the event loop until the
|
|
1807
|
+
// lightweight startup shell is painted and durable recovery is ready.
|
|
1808
|
+
startupAttempt = 0;
|
|
1809
|
+
startupWindow = createDesktopWindow(false, true);
|
|
1812
1810
|
mainWindow = startupWindow;
|
|
1813
1811
|
createTray();
|
|
1814
1812
|
}
|
|
@@ -1901,6 +1899,8 @@ else {
|
|
|
1901
1899
|
recordStartup('first-run-init');
|
|
1902
1900
|
}
|
|
1903
1901
|
if (!agent) {
|
|
1902
|
+
await (0, runtimeLifecycle_1.prepareRuntimeLifecycle)(root, 'main');
|
|
1903
|
+
recordStartup('runtime-lifecycle-prepared');
|
|
1904
1904
|
agent = new agent_1.Agent(root);
|
|
1905
1905
|
mcpManager = new mcpManager_1.McpManager(root);
|
|
1906
1906
|
activeAgentBackendMode = process.platform === 'win32' && agent.config.getBool('agent', 'run_in_wsl') ? 'wsl' : 'windows';
|
|
@@ -8383,7 +8383,7 @@ var require_createWorker = __commonJS({
|
|
|
8383
8383
|
...defaultOptions,
|
|
8384
8384
|
..._options
|
|
8385
8385
|
});
|
|
8386
|
-
const
|
|
8386
|
+
const promises3 = {};
|
|
8387
8387
|
const currentLangs = typeof langs === "string" ? langs.split("+") : langs;
|
|
8388
8388
|
let currentOem = oem;
|
|
8389
8389
|
let currentConfig = config;
|
|
@@ -8403,7 +8403,7 @@ var require_createWorker = __commonJS({
|
|
|
8403
8403
|
const startJob = ({ id: jobId, action, payload }) => new Promise((resolve16, reject) => {
|
|
8404
8404
|
log2(`[${id}]: Start ${jobId}, action=${action}`);
|
|
8405
8405
|
const promiseId = `${action}-${jobId}`;
|
|
8406
|
-
|
|
8406
|
+
promises3[promiseId] = { resolve: resolve16, reject };
|
|
8407
8407
|
send(worker, {
|
|
8408
8408
|
workerId: id,
|
|
8409
8409
|
jobId,
|
|
@@ -8508,11 +8508,11 @@ var require_createWorker = __commonJS({
|
|
|
8508
8508
|
const promiseId = `${action}-${jobId}`;
|
|
8509
8509
|
if (status === "resolve") {
|
|
8510
8510
|
log2(`[${workerId}]: Complete ${jobId}`);
|
|
8511
|
-
|
|
8512
|
-
delete
|
|
8511
|
+
promises3[promiseId].resolve({ jobId, data });
|
|
8512
|
+
delete promises3[promiseId];
|
|
8513
8513
|
} else if (status === "reject") {
|
|
8514
|
-
|
|
8515
|
-
delete
|
|
8514
|
+
promises3[promiseId].reject(data);
|
|
8515
|
+
delete promises3[promiseId];
|
|
8516
8516
|
if (action === "load") workerResReject(data);
|
|
8517
8517
|
if (errorHandler) {
|
|
8518
8518
|
errorHandler(data);
|
|
@@ -54006,18 +54006,18 @@ var require_proxy_agent = __commonJS({
|
|
|
54006
54006
|
}
|
|
54007
54007
|
}
|
|
54008
54008
|
[kClose]() {
|
|
54009
|
-
const
|
|
54009
|
+
const promises3 = [this[kAgent].close()];
|
|
54010
54010
|
if (this[kClient]) {
|
|
54011
|
-
|
|
54011
|
+
promises3.push(this[kClient].close());
|
|
54012
54012
|
}
|
|
54013
|
-
return Promise.all(
|
|
54013
|
+
return Promise.all(promises3);
|
|
54014
54014
|
}
|
|
54015
54015
|
[kDestroy]() {
|
|
54016
|
-
const
|
|
54016
|
+
const promises3 = [this[kAgent].destroy()];
|
|
54017
54017
|
if (this[kClient]) {
|
|
54018
|
-
|
|
54018
|
+
promises3.push(this[kClient].destroy());
|
|
54019
54019
|
}
|
|
54020
|
-
return Promise.all(
|
|
54020
|
+
return Promise.all(promises3);
|
|
54021
54021
|
}
|
|
54022
54022
|
};
|
|
54023
54023
|
function buildHeaders(headers) {
|
|
@@ -344927,6 +344927,7 @@ var fs24 = __toESM(require("fs"));
|
|
|
344927
344927
|
var path27 = __toESM(require("path"));
|
|
344928
344928
|
var import_crypto14 = require("crypto");
|
|
344929
344929
|
var processStates = /* @__PURE__ */ new Map();
|
|
344930
|
+
var preparedPreviousStates = /* @__PURE__ */ new Map();
|
|
344930
344931
|
function stateKey(root2, role) {
|
|
344931
344932
|
return `${path27.resolve(root2)}\0${role}`;
|
|
344932
344933
|
}
|
|
@@ -344972,7 +344973,8 @@ function beginRuntimeLifecycle(root2, role = "main") {
|
|
|
344972
344973
|
const key3 = stateKey(root2, role);
|
|
344973
344974
|
const existingProcessState = processStates.get(key3);
|
|
344974
344975
|
if (existingProcessState) return existingProcessState;
|
|
344975
|
-
const previousStates = readActiveStates(root2, role);
|
|
344976
|
+
const previousStates = preparedPreviousStates.get(key3) || readActiveStates(root2, role);
|
|
344977
|
+
preparedPreviousStates.delete(key3);
|
|
344976
344978
|
const previousOwnerAlive = previousStates.some((previous) => isRuntimeProcessAlive(Number(previous.pid)));
|
|
344977
344979
|
const state = {
|
|
344978
344980
|
role,
|
|
@@ -344995,12 +344997,12 @@ function markRuntimeLifecycleClean(root2, role = "main") {
|
|
|
344995
344997
|
const current = processStates.get(key3);
|
|
344996
344998
|
if (!current) return;
|
|
344997
344999
|
try {
|
|
344998
|
-
|
|
344999
|
-
...current,
|
|
345000
|
-
active: false,
|
|
345001
|
-
cleanExitAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
345002
|
-
});
|
|
345000
|
+
fs24.unlinkSync(statePath(root2, role, current.ownerId));
|
|
345003
345001
|
} catch {
|
|
345002
|
+
try {
|
|
345003
|
+
writeState(root2, role, { ...current, active: false, cleanExitAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
345004
|
+
} catch {
|
|
345005
|
+
}
|
|
345004
345006
|
}
|
|
345005
345007
|
}
|
|
345006
345008
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newmark-agent",
|
|
3
3
|
"productName": "Newmark Agent",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.11",
|
|
5
5
|
"description": "Newmark Agent — Portable AI coding agent with rich GUI and CLI (TypeScript)",
|
|
6
6
|
"homepage": "https://github.com/positer/Newmark-Agent",
|
|
7
7
|
"repository": {
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
"test:tool-process": "npm run build && node dist/tests/toolProcessVerify.js",
|
|
83
83
|
"test:real-tool-concurrency": "npm run build && node dist/tests/realProviderToolConcurrencyStress.js",
|
|
84
84
|
"test:startup-prewarm": "npm run build && node dist/tests/startupPrewarmVerify.js",
|
|
85
|
+
"test:startup-responsiveness": "npm run build && node dist/tests/runtimeLifecycleStartupVerify.js && node dist/tests/startupPrewarmVerify.js && node scripts/measure-startup-responsiveness.cjs",
|
|
85
86
|
"test:browser-use-electron": "npm run build && electron dist/tests/browserUseElectronVerify.js",
|
|
86
87
|
"test:dev009": "npm run build && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/guideUiReconcileVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/computerUsePerformanceVerify.js && electron dist/tests/browserUseElectronVerify.js",
|
|
87
88
|
"test:dev008": "npm run build && node dist/tests/dev008-subagent.js",
|