@nathapp/nax 0.54.3 → 0.54.4
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/dist/nax.js +93 -42
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -22348,7 +22348,7 @@ var package_default;
|
|
|
22348
22348
|
var init_package = __esm(() => {
|
|
22349
22349
|
package_default = {
|
|
22350
22350
|
name: "@nathapp/nax",
|
|
22351
|
-
version: "0.54.
|
|
22351
|
+
version: "0.54.4",
|
|
22352
22352
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
22353
22353
|
type: "module",
|
|
22354
22354
|
bin: {
|
|
@@ -22425,8 +22425,8 @@ var init_version = __esm(() => {
|
|
|
22425
22425
|
NAX_VERSION = package_default.version;
|
|
22426
22426
|
NAX_COMMIT = (() => {
|
|
22427
22427
|
try {
|
|
22428
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
22429
|
-
return "
|
|
22428
|
+
if (/^[0-9a-f]{6,10}$/.test("d0da600"))
|
|
22429
|
+
return "d0da600";
|
|
22430
22430
|
} catch {}
|
|
22431
22431
|
try {
|
|
22432
22432
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -23144,28 +23144,38 @@ class TelegramInteractionPlugin {
|
|
|
23144
23144
|
if (!this.botToken || !this.chatId) {
|
|
23145
23145
|
throw new Error("Telegram plugin not initialized");
|
|
23146
23146
|
}
|
|
23147
|
-
const
|
|
23147
|
+
const header = this.buildHeader(request);
|
|
23148
23148
|
const keyboard = this.buildKeyboard(request);
|
|
23149
|
+
const body = this.buildBody(request);
|
|
23150
|
+
const chunks = this.splitText(body, MAX_MESSAGE_CHARS - header.length - 10);
|
|
23149
23151
|
try {
|
|
23150
|
-
const
|
|
23151
|
-
|
|
23152
|
-
|
|
23153
|
-
|
|
23154
|
-
|
|
23155
|
-
|
|
23156
|
-
|
|
23157
|
-
|
|
23158
|
-
|
|
23159
|
-
|
|
23160
|
-
|
|
23161
|
-
|
|
23162
|
-
|
|
23163
|
-
|
|
23164
|
-
|
|
23165
|
-
|
|
23166
|
-
|
|
23152
|
+
const sentIds = [];
|
|
23153
|
+
for (let i = 0;i < chunks.length; i++) {
|
|
23154
|
+
const isLast = i === chunks.length - 1;
|
|
23155
|
+
const partLabel = chunks.length > 1 ? `[${i + 1}/${chunks.length}] ` : "";
|
|
23156
|
+
const text = `${header}
|
|
23157
|
+
${partLabel}${chunks[i]}`;
|
|
23158
|
+
const response = await fetch(`https://api.telegram.org/bot${this.botToken}/sendMessage`, {
|
|
23159
|
+
method: "POST",
|
|
23160
|
+
headers: { "Content-Type": "application/json" },
|
|
23161
|
+
body: JSON.stringify({
|
|
23162
|
+
chat_id: this.chatId,
|
|
23163
|
+
text,
|
|
23164
|
+
reply_markup: isLast && keyboard ? { inline_keyboard: keyboard } : undefined,
|
|
23165
|
+
parse_mode: "Markdown"
|
|
23166
|
+
})
|
|
23167
|
+
});
|
|
23168
|
+
if (!response.ok) {
|
|
23169
|
+
const errorBody = await response.text().catch(() => "");
|
|
23170
|
+
throw new Error(`Telegram API error (${response.status}): ${errorBody || response.statusText}`);
|
|
23171
|
+
}
|
|
23172
|
+
const data = await response.json();
|
|
23173
|
+
if (!data.ok) {
|
|
23174
|
+
throw new Error(`Telegram API returned ok=false: ${JSON.stringify(data)}`);
|
|
23175
|
+
}
|
|
23176
|
+
sentIds.push(data.result.message_id);
|
|
23167
23177
|
}
|
|
23168
|
-
this.pendingMessages.set(request.id,
|
|
23178
|
+
this.pendingMessages.set(request.id, sentIds);
|
|
23169
23179
|
} catch (err) {
|
|
23170
23180
|
const msg = err instanceof Error ? err.message : String(err);
|
|
23171
23181
|
throw new Error(`Failed to send Telegram message: ${msg}`);
|
|
@@ -23202,10 +23212,9 @@ class TelegramInteractionPlugin {
|
|
|
23202
23212
|
await this.sendTimeoutMessage(requestId);
|
|
23203
23213
|
this.pendingMessages.delete(requestId);
|
|
23204
23214
|
}
|
|
23205
|
-
|
|
23215
|
+
buildHeader(request) {
|
|
23206
23216
|
const emoji3 = this.getStageEmoji(request.stage);
|
|
23207
23217
|
let text = `${emoji3} *${request.stage.toUpperCase()}*
|
|
23208
|
-
|
|
23209
23218
|
`;
|
|
23210
23219
|
text += `*Feature:* ${request.featureName}
|
|
23211
23220
|
`;
|
|
@@ -23214,11 +23223,15 @@ class TelegramInteractionPlugin {
|
|
|
23214
23223
|
`;
|
|
23215
23224
|
}
|
|
23216
23225
|
text += `
|
|
23217
|
-
|
|
23226
|
+
`;
|
|
23227
|
+
return text;
|
|
23228
|
+
}
|
|
23229
|
+
buildBody(request) {
|
|
23230
|
+
let text = `${this.sanitizeMarkdown(request.summary)}
|
|
23218
23231
|
`;
|
|
23219
23232
|
if (request.detail) {
|
|
23220
23233
|
text += `
|
|
23221
|
-
${request.detail}
|
|
23234
|
+
${this.sanitizeMarkdown(request.detail)}
|
|
23222
23235
|
`;
|
|
23223
23236
|
}
|
|
23224
23237
|
if (request.options && request.options.length > 0) {
|
|
@@ -23226,8 +23239,8 @@ ${request.detail}
|
|
|
23226
23239
|
*Options:*
|
|
23227
23240
|
`;
|
|
23228
23241
|
for (const opt of request.options) {
|
|
23229
|
-
const desc = opt.description ? `
|
|
23230
|
-
text += `
|
|
23242
|
+
const desc = opt.description ? ` - ${this.sanitizeMarkdown(opt.description)}` : "";
|
|
23243
|
+
text += ` - ${opt.label}${desc}
|
|
23231
23244
|
`;
|
|
23232
23245
|
}
|
|
23233
23246
|
}
|
|
@@ -23238,6 +23251,30 @@ ${request.detail}
|
|
|
23238
23251
|
}
|
|
23239
23252
|
return text;
|
|
23240
23253
|
}
|
|
23254
|
+
sanitizeMarkdown(text) {
|
|
23255
|
+
return text.replace(/\\(?=[_*`\[])/g, "\\\\").replace(/_/g, "\\_").replace(/`/g, "\\`").replace(/\*/g, "\\*").replace(/\[/g, "\\[");
|
|
23256
|
+
}
|
|
23257
|
+
splitText(text, maxChars) {
|
|
23258
|
+
if (text.length <= maxChars)
|
|
23259
|
+
return [text];
|
|
23260
|
+
const chunks = [];
|
|
23261
|
+
let remaining = text;
|
|
23262
|
+
while (remaining.length > maxChars) {
|
|
23263
|
+
const slice = remaining.slice(0, maxChars);
|
|
23264
|
+
const lastNewline = slice.lastIndexOf(`
|
|
23265
|
+
`);
|
|
23266
|
+
if (lastNewline > maxChars * 0.5) {
|
|
23267
|
+
chunks.push(remaining.slice(0, lastNewline));
|
|
23268
|
+
remaining = remaining.slice(lastNewline + 1);
|
|
23269
|
+
} else {
|
|
23270
|
+
chunks.push(slice);
|
|
23271
|
+
remaining = remaining.slice(maxChars);
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23274
|
+
if (remaining.length > 0)
|
|
23275
|
+
chunks.push(remaining);
|
|
23276
|
+
return chunks;
|
|
23277
|
+
}
|
|
23241
23278
|
buildKeyboard(request) {
|
|
23242
23279
|
switch (request.type) {
|
|
23243
23280
|
case "confirm":
|
|
@@ -23345,8 +23382,11 @@ ${request.detail}
|
|
|
23345
23382
|
};
|
|
23346
23383
|
}
|
|
23347
23384
|
if (update.message?.text) {
|
|
23348
|
-
const
|
|
23349
|
-
if (!
|
|
23385
|
+
const messageIds = this.pendingMessages.get(requestId);
|
|
23386
|
+
if (!messageIds)
|
|
23387
|
+
return null;
|
|
23388
|
+
const replyToId = update.message.reply_to_message?.message_id;
|
|
23389
|
+
if (replyToId !== undefined && !messageIds.includes(replyToId))
|
|
23350
23390
|
return null;
|
|
23351
23391
|
return {
|
|
23352
23392
|
requestId,
|
|
@@ -23372,20 +23412,20 @@ ${request.detail}
|
|
|
23372
23412
|
} catch {}
|
|
23373
23413
|
}
|
|
23374
23414
|
async sendTimeoutMessage(requestId) {
|
|
23375
|
-
const
|
|
23376
|
-
if (!
|
|
23415
|
+
const messageIds = this.pendingMessages.get(requestId);
|
|
23416
|
+
if (!messageIds || !this.botToken || !this.chatId) {
|
|
23377
23417
|
this.pendingMessages.delete(requestId);
|
|
23378
23418
|
return;
|
|
23379
23419
|
}
|
|
23420
|
+
const lastId = messageIds[messageIds.length - 1];
|
|
23380
23421
|
try {
|
|
23381
23422
|
await fetch(`https://api.telegram.org/bot${this.botToken}/editMessageText`, {
|
|
23382
23423
|
method: "POST",
|
|
23383
23424
|
headers: { "Content-Type": "application/json" },
|
|
23384
23425
|
body: JSON.stringify({
|
|
23385
23426
|
chat_id: this.chatId,
|
|
23386
|
-
message_id:
|
|
23387
|
-
text: "\u23F1
|
|
23388
|
-
parse_mode: "Markdown"
|
|
23427
|
+
message_id: lastId,
|
|
23428
|
+
text: "\u23F1 EXPIRED \u2014 Interaction timed out"
|
|
23389
23429
|
})
|
|
23390
23430
|
});
|
|
23391
23431
|
} catch {} finally {
|
|
@@ -23393,7 +23433,7 @@ ${request.detail}
|
|
|
23393
23433
|
}
|
|
23394
23434
|
}
|
|
23395
23435
|
}
|
|
23396
|
-
var TelegramConfigSchema;
|
|
23436
|
+
var MAX_MESSAGE_CHARS = 4000, TelegramConfigSchema;
|
|
23397
23437
|
var init_telegram = __esm(() => {
|
|
23398
23438
|
init_zod();
|
|
23399
23439
|
TelegramConfigSchema = exports_external.object({
|
|
@@ -34481,7 +34521,7 @@ __export(exports_parallel_executor_rectify, {
|
|
|
34481
34521
|
});
|
|
34482
34522
|
import path15 from "path";
|
|
34483
34523
|
async function rectifyConflictedStory(options) {
|
|
34484
|
-
const { storyId, workdir, config: config2, hooks, pluginRegistry, prd, eventEmitter } = options;
|
|
34524
|
+
const { storyId, workdir, config: config2, hooks, pluginRegistry, prd, eventEmitter, agentGetFn } = options;
|
|
34485
34525
|
const logger = getSafeLogger();
|
|
34486
34526
|
logger?.info("parallel", "Rectifying story on updated base", { storyId, attempt: "rectification" });
|
|
34487
34527
|
try {
|
|
@@ -34513,7 +34553,8 @@ async function rectifyConflictedStory(options) {
|
|
|
34513
34553
|
hooks,
|
|
34514
34554
|
plugins: pluginRegistry,
|
|
34515
34555
|
storyStartTime: new Date().toISOString(),
|
|
34516
|
-
routing
|
|
34556
|
+
routing,
|
|
34557
|
+
agentGetFn
|
|
34517
34558
|
};
|
|
34518
34559
|
const pipelineResult = await runPipeline2(defaultPipeline2, pipelineContext, eventEmitter);
|
|
34519
34560
|
const cost = pipelineResult.context.agentResult?.estimatedCost ?? 0;
|
|
@@ -34549,7 +34590,7 @@ var init_parallel_executor_rectify = __esm(() => {
|
|
|
34549
34590
|
// src/execution/parallel-executor-rectification-pass.ts
|
|
34550
34591
|
async function runRectificationPass(conflictedStories, options, prd, rectifyConflictedStory2) {
|
|
34551
34592
|
const logger = getSafeLogger();
|
|
34552
|
-
const { workdir, config: config2, hooks, pluginRegistry, eventEmitter } = options;
|
|
34593
|
+
const { workdir, config: config2, hooks, pluginRegistry, eventEmitter, agentGetFn } = options;
|
|
34553
34594
|
const rectify = rectifyConflictedStory2 || (async (opts) => {
|
|
34554
34595
|
const { rectifyConflictedStory: importedRectify } = await Promise.resolve().then(() => (init_parallel_executor_rectify(), exports_parallel_executor_rectify));
|
|
34555
34596
|
return importedRectify(opts);
|
|
@@ -34570,7 +34611,8 @@ async function runRectificationPass(conflictedStories, options, prd, rectifyConf
|
|
|
34570
34611
|
hooks,
|
|
34571
34612
|
pluginRegistry,
|
|
34572
34613
|
prd,
|
|
34573
|
-
eventEmitter
|
|
34614
|
+
eventEmitter,
|
|
34615
|
+
agentGetFn
|
|
34574
34616
|
});
|
|
34575
34617
|
additionalCost += result.cost;
|
|
34576
34618
|
if (result.success) {
|
|
@@ -68907,11 +68949,19 @@ function validateStory(raw, index, allIds) {
|
|
|
68907
68949
|
...contextFiles.length > 0 ? { contextFiles } : {}
|
|
68908
68950
|
};
|
|
68909
68951
|
}
|
|
68952
|
+
function sanitizeInvalidEscapes(text) {
|
|
68953
|
+
let result = text.replace(/\\x([0-9a-fA-F]{1,2})/g, (_, hex3) => `\\u00${hex3.padStart(2, "0")}`);
|
|
68954
|
+
result = result.replace(/\\u([0-9a-fA-F]{1,3})(?![0-9a-fA-F])/g, (_, digits) => `\\u${digits.padStart(4, "0")}`);
|
|
68955
|
+
result = result.replace(/\\u(?![0-9a-fA-F])/g, "\\");
|
|
68956
|
+
result = result.replace(/\\([^"\\\/bfnrtu])/g, "$1");
|
|
68957
|
+
return result;
|
|
68958
|
+
}
|
|
68910
68959
|
function parseRawString(text) {
|
|
68911
68960
|
const extracted = extractJsonFromMarkdown(text);
|
|
68912
68961
|
const cleaned = stripTrailingCommas(extracted);
|
|
68962
|
+
const sanitized = sanitizeInvalidEscapes(cleaned);
|
|
68913
68963
|
try {
|
|
68914
|
-
return JSON.parse(
|
|
68964
|
+
return JSON.parse(sanitized);
|
|
68915
68965
|
} catch (err) {
|
|
68916
68966
|
const parseErr = err;
|
|
68917
68967
|
throw new Error(`[schema] Failed to parse JSON: ${parseErr.message}`, { cause: parseErr });
|
|
@@ -72036,7 +72086,8 @@ async function runExecutionPhase(options, prd, pluginRegistry) {
|
|
|
72036
72086
|
allStoryMetrics,
|
|
72037
72087
|
pluginRegistry,
|
|
72038
72088
|
formatterMode: options.formatterMode,
|
|
72039
|
-
headless: options.headless
|
|
72089
|
+
headless: options.headless,
|
|
72090
|
+
agentGetFn: options.agentGetFn
|
|
72040
72091
|
}, prd);
|
|
72041
72092
|
prd = parallelResult.prd;
|
|
72042
72093
|
totalCost = parallelResult.totalCost;
|