@nathapp/nax 0.79.1 → 0.79.2
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 +240 -172
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -18733,6 +18733,181 @@ var init_json_file = __esm(() => {
|
|
|
18733
18733
|
init_logger2();
|
|
18734
18734
|
});
|
|
18735
18735
|
|
|
18736
|
+
// src/config/migrations.ts
|
|
18737
|
+
function migrateLegacyTestPattern(raw, logger) {
|
|
18738
|
+
const context = raw.context;
|
|
18739
|
+
const legacyPattern = context?.testCoverage?.testPattern;
|
|
18740
|
+
if (legacyPattern === undefined)
|
|
18741
|
+
return raw;
|
|
18742
|
+
logger?.warn("config", "context.testCoverage.testPattern is deprecated \u2014 migrate to " + "execution.smartTestRunner.testFilePatterns (array). Migration shim applied.", { legacyPattern });
|
|
18743
|
+
const safeContext = context ?? {};
|
|
18744
|
+
const { testPattern: _drop, ...testCoverageRest } = safeContext.testCoverage ?? {};
|
|
18745
|
+
const migratedContext = { ...safeContext, testCoverage: testCoverageRest };
|
|
18746
|
+
const execution = raw.execution;
|
|
18747
|
+
const smartRunnerPatterns = execution?.smartTestRunner?.testFilePatterns;
|
|
18748
|
+
if (smartRunnerPatterns !== undefined) {
|
|
18749
|
+
return { ...raw, context: migratedContext };
|
|
18750
|
+
}
|
|
18751
|
+
const aliasedSmartRunner = {
|
|
18752
|
+
...execution?.smartTestRunner,
|
|
18753
|
+
testFilePatterns: [legacyPattern]
|
|
18754
|
+
};
|
|
18755
|
+
const migratedExecution = {
|
|
18756
|
+
...execution,
|
|
18757
|
+
smartTestRunner: aliasedSmartRunner
|
|
18758
|
+
};
|
|
18759
|
+
return { ...raw, execution: migratedExecution, context: migratedContext };
|
|
18760
|
+
}
|
|
18761
|
+
function migrateLegacyReviewModelKey(raw, logger) {
|
|
18762
|
+
const review = raw.review;
|
|
18763
|
+
if (!review)
|
|
18764
|
+
return raw;
|
|
18765
|
+
const semantic = migrateBlock(review.semantic, "review.semantic", logger);
|
|
18766
|
+
const adversarial = migrateBlock(review.adversarial, "review.adversarial", logger);
|
|
18767
|
+
if (semantic === review.semantic && adversarial === review.adversarial)
|
|
18768
|
+
return raw;
|
|
18769
|
+
return {
|
|
18770
|
+
...raw,
|
|
18771
|
+
review: {
|
|
18772
|
+
...review,
|
|
18773
|
+
...semantic !== undefined ? { semantic } : {},
|
|
18774
|
+
...adversarial !== undefined ? { adversarial } : {}
|
|
18775
|
+
}
|
|
18776
|
+
};
|
|
18777
|
+
function migrateBlock(block, path, log) {
|
|
18778
|
+
if (!block || block.modelTier === undefined)
|
|
18779
|
+
return block;
|
|
18780
|
+
const { modelTier, ...rest } = block;
|
|
18781
|
+
if (block.model !== undefined) {
|
|
18782
|
+
log?.warn("config", `${path}.modelTier is deprecated and ignored \u2014 ${path}.model is set and wins. Remove ${path}.modelTier.`, { legacyKey: `${path}.modelTier`, canonicalKey: `${path}.model` });
|
|
18783
|
+
return rest;
|
|
18784
|
+
}
|
|
18785
|
+
log?.warn("config", `${path}.modelTier is deprecated \u2014 migrate to ${path}.model (accepts the same tier string or a { agent, model } pin). Migration shim applied.`, { legacyKey: `${path}.modelTier`, canonicalKey: `${path}.model`, value: modelTier });
|
|
18786
|
+
return { ...rest, model: modelTier };
|
|
18787
|
+
}
|
|
18788
|
+
}
|
|
18789
|
+
|
|
18790
|
+
// src/config/compat-shims.ts
|
|
18791
|
+
function defaultConfigWarn(msg) {
|
|
18792
|
+
try {
|
|
18793
|
+
getLogger().warn("config", msg);
|
|
18794
|
+
} catch {}
|
|
18795
|
+
}
|
|
18796
|
+
function createConfigWarnDedupe(sink = defaultConfigWarn) {
|
|
18797
|
+
const seen = new Set;
|
|
18798
|
+
const admit = (msg, data) => {
|
|
18799
|
+
const key = data === undefined ? msg : `${msg}\x00${JSON.stringify(data)}`;
|
|
18800
|
+
if (seen.has(key))
|
|
18801
|
+
return false;
|
|
18802
|
+
seen.add(key);
|
|
18803
|
+
return true;
|
|
18804
|
+
};
|
|
18805
|
+
return {
|
|
18806
|
+
warn: (msg) => {
|
|
18807
|
+
if (admit(msg))
|
|
18808
|
+
sink(msg);
|
|
18809
|
+
},
|
|
18810
|
+
wrapLogger: (logger) => logger && {
|
|
18811
|
+
warn: (stage, message, data) => {
|
|
18812
|
+
if (admit(message, data))
|
|
18813
|
+
logger.warn(stage, message, data);
|
|
18814
|
+
}
|
|
18815
|
+
}
|
|
18816
|
+
};
|
|
18817
|
+
}
|
|
18818
|
+
function applyRemovedStrategyCompat(conf, warn = defaultConfigWarn) {
|
|
18819
|
+
const routing = conf.routing;
|
|
18820
|
+
const strategy = routing?.strategy;
|
|
18821
|
+
const REMOVED_STRATEGIES = ["manual", "adaptive", "custom"];
|
|
18822
|
+
if (typeof strategy === "string" && REMOVED_STRATEGIES.includes(strategy)) {
|
|
18823
|
+
warn(`routing.strategy="${strategy}" was removed in ROUTE-001 and is no longer supported. Falling back to "keyword". Update your config to use "keyword" or "llm".`);
|
|
18824
|
+
return { ...conf, routing: { ...routing, strategy: "keyword" } };
|
|
18825
|
+
}
|
|
18826
|
+
return conf;
|
|
18827
|
+
}
|
|
18828
|
+
function _applyRemovedRoutingKeysShim(conf, warn = defaultConfigWarn) {
|
|
18829
|
+
const routing = conf.routing;
|
|
18830
|
+
if (!routing || typeof routing !== "object")
|
|
18831
|
+
return conf;
|
|
18832
|
+
const REMOVED_ROUTING_KEYS = ["customStrategyPath", "adaptive"];
|
|
18833
|
+
let newRouting = routing;
|
|
18834
|
+
for (const key of REMOVED_ROUTING_KEYS) {
|
|
18835
|
+
if (key in newRouting) {
|
|
18836
|
+
warn(`routing.${key} was removed in ROUTE-001 along with the "custom"/"adaptive" strategies and has no effect. Remove it from your config.`);
|
|
18837
|
+
const { [key]: _removed, ...rest } = newRouting;
|
|
18838
|
+
newRouting = rest;
|
|
18839
|
+
}
|
|
18840
|
+
}
|
|
18841
|
+
return newRouting === routing ? conf : { ...conf, routing: newRouting };
|
|
18842
|
+
}
|
|
18843
|
+
function applyBatchModeCompat(conf, warn = defaultConfigWarn) {
|
|
18844
|
+
const routing = conf.routing;
|
|
18845
|
+
const llm = routing?.llm;
|
|
18846
|
+
if (llm && "batchMode" in llm && !("mode" in llm)) {
|
|
18847
|
+
const batchMode = llm.batchMode;
|
|
18848
|
+
if (typeof batchMode === "boolean") {
|
|
18849
|
+
const mappedMode = batchMode ? "one-shot" : "per-story";
|
|
18850
|
+
warn(`routing.llm.batchMode is deprecated and will be removed in v1.0. Mapped to mode="${mappedMode}". Update your config to use routing.llm.mode instead.`);
|
|
18851
|
+
return {
|
|
18852
|
+
...conf,
|
|
18853
|
+
routing: {
|
|
18854
|
+
...routing,
|
|
18855
|
+
llm: { ...llm, mode: mappedMode }
|
|
18856
|
+
}
|
|
18857
|
+
};
|
|
18858
|
+
}
|
|
18859
|
+
}
|
|
18860
|
+
return conf;
|
|
18861
|
+
}
|
|
18862
|
+
function _applyLegacyReviewExecutionShim(conf, warn = defaultConfigWarn) {
|
|
18863
|
+
let result = conf;
|
|
18864
|
+
const execution = conf.execution;
|
|
18865
|
+
if (execution && typeof execution === "object" && "inlineReview" in execution) {
|
|
18866
|
+
warn("execution.inlineReview is a legacy field that has been removed. Remove it from your config.");
|
|
18867
|
+
const { inlineReview: _ir, ...restExecution } = execution;
|
|
18868
|
+
result = { ...result, execution: restExecution };
|
|
18869
|
+
}
|
|
18870
|
+
const review = result.review ?? conf.review;
|
|
18871
|
+
if (review && typeof review === "object") {
|
|
18872
|
+
let newReview = review;
|
|
18873
|
+
const LEGACY_PLUGIN_MODE_VALUE = "per-story";
|
|
18874
|
+
if ("pluginMode" in review && review.pluginMode === LEGACY_PLUGIN_MODE_VALUE) {
|
|
18875
|
+
warn('review.pluginMode: "per-story" is a legacy value that has been removed. Remove it from your config (or set to "observational"/"gating").');
|
|
18876
|
+
const { pluginMode: _pm, ...rest } = review;
|
|
18877
|
+
newReview = rest;
|
|
18878
|
+
}
|
|
18879
|
+
const dialogue = newReview.dialogue;
|
|
18880
|
+
if (dialogue && typeof dialogue === "object" && dialogue.enabled === true) {
|
|
18881
|
+
warn("review.dialogue.enabled is a legacy field that has been removed. Remove it from your config.");
|
|
18882
|
+
const { dialogue: _d, ...rest } = newReview;
|
|
18883
|
+
newReview = rest;
|
|
18884
|
+
}
|
|
18885
|
+
result = { ...result, review: newReview };
|
|
18886
|
+
}
|
|
18887
|
+
return result;
|
|
18888
|
+
}
|
|
18889
|
+
function applyRoutingRetryDeprecationWarning(conf, warn = defaultConfigWarn) {
|
|
18890
|
+
const routing = conf.routing;
|
|
18891
|
+
const llm = routing?.llm;
|
|
18892
|
+
if (!llm)
|
|
18893
|
+
return conf;
|
|
18894
|
+
if ("retries" in llm) {
|
|
18895
|
+
warn("routing.llm.retries is deprecated (issue #856). " + "This value is still applied but will be removed in v1.0. " + "Retry policy is now declared on each operation \u2014 remove this key from your config.");
|
|
18896
|
+
}
|
|
18897
|
+
if ("retryDelayMs" in llm) {
|
|
18898
|
+
warn("routing.llm.retryDelayMs is deprecated (issue #856). " + "This value is still applied but will be removed in v1.0. " + "Retry policy is now declared on each operation \u2014 remove this key from your config.");
|
|
18899
|
+
}
|
|
18900
|
+
return conf;
|
|
18901
|
+
}
|
|
18902
|
+
function applyConfigCompatShims(conf, logger, dedupe) {
|
|
18903
|
+
const log = dedupe.wrapLogger(logger);
|
|
18904
|
+
const warn = dedupe.warn;
|
|
18905
|
+
return _applyLegacyReviewExecutionShim(_applyRemovedRoutingKeysShim(applyRoutingRetryDeprecationWarning(applyBatchModeCompat(applyRemovedStrategyCompat(migrateLegacyReviewModelKey(migrateLegacyTestPattern(conf, log), log), warn), warn), warn), warn), warn);
|
|
18906
|
+
}
|
|
18907
|
+
var init_compat_shims = __esm(() => {
|
|
18908
|
+
init_logger2();
|
|
18909
|
+
});
|
|
18910
|
+
|
|
18736
18911
|
// src/config/config-guards.ts
|
|
18737
18912
|
function rejectLegacyAgentKeys(conf) {
|
|
18738
18913
|
const legacyKeys = [];
|
|
@@ -19140,60 +19315,6 @@ function isPlainObject2(value) {
|
|
|
19140
19315
|
return typeof value === "object" && value !== null && !Array.isArray(value) && value.constructor === Object;
|
|
19141
19316
|
}
|
|
19142
19317
|
|
|
19143
|
-
// src/config/migrations.ts
|
|
19144
|
-
function migrateLegacyTestPattern(raw, logger) {
|
|
19145
|
-
const context = raw.context;
|
|
19146
|
-
const legacyPattern = context?.testCoverage?.testPattern;
|
|
19147
|
-
if (legacyPattern === undefined)
|
|
19148
|
-
return raw;
|
|
19149
|
-
logger?.warn("config", "context.testCoverage.testPattern is deprecated \u2014 migrate to " + "execution.smartTestRunner.testFilePatterns (array). Migration shim applied.", { legacyPattern });
|
|
19150
|
-
const safeContext = context ?? {};
|
|
19151
|
-
const { testPattern: _drop, ...testCoverageRest } = safeContext.testCoverage ?? {};
|
|
19152
|
-
const migratedContext = { ...safeContext, testCoverage: testCoverageRest };
|
|
19153
|
-
const execution = raw.execution;
|
|
19154
|
-
const smartRunnerPatterns = execution?.smartTestRunner?.testFilePatterns;
|
|
19155
|
-
if (smartRunnerPatterns !== undefined) {
|
|
19156
|
-
return { ...raw, context: migratedContext };
|
|
19157
|
-
}
|
|
19158
|
-
const aliasedSmartRunner = {
|
|
19159
|
-
...execution?.smartTestRunner,
|
|
19160
|
-
testFilePatterns: [legacyPattern]
|
|
19161
|
-
};
|
|
19162
|
-
const migratedExecution = {
|
|
19163
|
-
...execution,
|
|
19164
|
-
smartTestRunner: aliasedSmartRunner
|
|
19165
|
-
};
|
|
19166
|
-
return { ...raw, execution: migratedExecution, context: migratedContext };
|
|
19167
|
-
}
|
|
19168
|
-
function migrateLegacyReviewModelKey(raw, logger) {
|
|
19169
|
-
const review = raw.review;
|
|
19170
|
-
if (!review)
|
|
19171
|
-
return raw;
|
|
19172
|
-
const semantic = migrateBlock(review.semantic, "review.semantic", logger);
|
|
19173
|
-
const adversarial = migrateBlock(review.adversarial, "review.adversarial", logger);
|
|
19174
|
-
if (semantic === review.semantic && adversarial === review.adversarial)
|
|
19175
|
-
return raw;
|
|
19176
|
-
return {
|
|
19177
|
-
...raw,
|
|
19178
|
-
review: {
|
|
19179
|
-
...review,
|
|
19180
|
-
...semantic !== undefined ? { semantic } : {},
|
|
19181
|
-
...adversarial !== undefined ? { adversarial } : {}
|
|
19182
|
-
}
|
|
19183
|
-
};
|
|
19184
|
-
function migrateBlock(block, path, log) {
|
|
19185
|
-
if (!block || block.modelTier === undefined)
|
|
19186
|
-
return block;
|
|
19187
|
-
const { modelTier, ...rest } = block;
|
|
19188
|
-
if (block.model !== undefined) {
|
|
19189
|
-
log?.warn("config", `${path}.modelTier is deprecated and ignored \u2014 ${path}.model is set and wins. Remove ${path}.modelTier.`, { legacyKey: `${path}.modelTier`, canonicalKey: `${path}.model` });
|
|
19190
|
-
return rest;
|
|
19191
|
-
}
|
|
19192
|
-
log?.warn("config", `${path}.modelTier is deprecated \u2014 migrate to ${path}.model (accepts the same tier string or a { agent, model } pin). Migration shim applied.`, { legacyKey: `${path}.modelTier`, canonicalKey: `${path}.model`, value: modelTier });
|
|
19193
|
-
return { ...rest, model: modelTier };
|
|
19194
|
-
}
|
|
19195
|
-
}
|
|
19196
|
-
|
|
19197
19318
|
// src/config/path-security.ts
|
|
19198
19319
|
import { existsSync as existsSync2, lstatSync, realpathSync } from "fs";
|
|
19199
19320
|
import { basename, isAbsolute, normalize, resolve } from "path";
|
|
@@ -19432,100 +19553,9 @@ function findProjectDir(startDir = process.cwd()) {
|
|
|
19432
19553
|
}
|
|
19433
19554
|
return null;
|
|
19434
19555
|
}
|
|
19435
|
-
function defaultConfigWarn(msg) {
|
|
19436
|
-
try {
|
|
19437
|
-
getLogger().warn("config", msg);
|
|
19438
|
-
} catch {}
|
|
19439
|
-
}
|
|
19440
|
-
function applyRemovedStrategyCompat(conf) {
|
|
19441
|
-
const routing = conf.routing;
|
|
19442
|
-
const strategy = routing?.strategy;
|
|
19443
|
-
const REMOVED_STRATEGIES = ["manual", "adaptive", "custom"];
|
|
19444
|
-
if (typeof strategy === "string" && REMOVED_STRATEGIES.includes(strategy)) {
|
|
19445
|
-
defaultConfigWarn(`routing.strategy="${strategy}" was removed in ROUTE-001 and is no longer supported. Falling back to "keyword". Update your config to use "keyword" or "llm".`);
|
|
19446
|
-
return { ...conf, routing: { ...routing, strategy: "keyword" } };
|
|
19447
|
-
}
|
|
19448
|
-
return conf;
|
|
19449
|
-
}
|
|
19450
|
-
function _applyRemovedRoutingKeysShim(conf, warn = defaultConfigWarn) {
|
|
19451
|
-
const routing = conf.routing;
|
|
19452
|
-
if (!routing || typeof routing !== "object")
|
|
19453
|
-
return conf;
|
|
19454
|
-
const REMOVED_ROUTING_KEYS = ["customStrategyPath", "adaptive"];
|
|
19455
|
-
let newRouting = routing;
|
|
19456
|
-
for (const key of REMOVED_ROUTING_KEYS) {
|
|
19457
|
-
if (key in newRouting) {
|
|
19458
|
-
warn(`routing.${key} was removed in ROUTE-001 along with the "custom"/"adaptive" strategies and has no effect. Remove it from your config.`);
|
|
19459
|
-
const { [key]: _removed, ...rest } = newRouting;
|
|
19460
|
-
newRouting = rest;
|
|
19461
|
-
}
|
|
19462
|
-
}
|
|
19463
|
-
return newRouting === routing ? conf : { ...conf, routing: newRouting };
|
|
19464
|
-
}
|
|
19465
|
-
function applyBatchModeCompat(conf) {
|
|
19466
|
-
const routing = conf.routing;
|
|
19467
|
-
const llm = routing?.llm;
|
|
19468
|
-
if (llm && "batchMode" in llm && !("mode" in llm)) {
|
|
19469
|
-
const batchMode = llm.batchMode;
|
|
19470
|
-
if (typeof batchMode === "boolean") {
|
|
19471
|
-
const mappedMode = batchMode ? "one-shot" : "per-story";
|
|
19472
|
-
defaultConfigWarn(`routing.llm.batchMode is deprecated and will be removed in v1.0. Mapped to mode="${mappedMode}". Update your config to use routing.llm.mode instead.`);
|
|
19473
|
-
return {
|
|
19474
|
-
...conf,
|
|
19475
|
-
routing: {
|
|
19476
|
-
...routing,
|
|
19477
|
-
llm: { ...llm, mode: mappedMode }
|
|
19478
|
-
}
|
|
19479
|
-
};
|
|
19480
|
-
}
|
|
19481
|
-
}
|
|
19482
|
-
return conf;
|
|
19483
|
-
}
|
|
19484
|
-
function _applyLegacyReviewExecutionShim(conf, warn = defaultConfigWarn) {
|
|
19485
|
-
let result = conf;
|
|
19486
|
-
const execution = conf.execution;
|
|
19487
|
-
if (execution && typeof execution === "object" && "inlineReview" in execution) {
|
|
19488
|
-
warn("execution.inlineReview is a legacy field that has been removed. Remove it from your config.");
|
|
19489
|
-
const { inlineReview: _ir, ...restExecution } = execution;
|
|
19490
|
-
result = { ...result, execution: restExecution };
|
|
19491
|
-
}
|
|
19492
|
-
const review = result.review ?? conf.review;
|
|
19493
|
-
if (review && typeof review === "object") {
|
|
19494
|
-
let newReview = review;
|
|
19495
|
-
const LEGACY_PLUGIN_MODE_VALUE = "per-story";
|
|
19496
|
-
if ("pluginMode" in review && review.pluginMode === LEGACY_PLUGIN_MODE_VALUE) {
|
|
19497
|
-
warn('review.pluginMode: "per-story" is a legacy value that has been removed. Remove it from your config (or set to "observational"/"gating").');
|
|
19498
|
-
const { pluginMode: _pm, ...rest } = review;
|
|
19499
|
-
newReview = rest;
|
|
19500
|
-
}
|
|
19501
|
-
const dialogue = newReview.dialogue;
|
|
19502
|
-
if (dialogue && typeof dialogue === "object" && dialogue.enabled === true) {
|
|
19503
|
-
warn("review.dialogue.enabled is a legacy field that has been removed. Remove it from your config.");
|
|
19504
|
-
const { dialogue: _d, ...rest } = newReview;
|
|
19505
|
-
newReview = rest;
|
|
19506
|
-
}
|
|
19507
|
-
result = { ...result, review: newReview };
|
|
19508
|
-
}
|
|
19509
|
-
return result;
|
|
19510
|
-
}
|
|
19511
|
-
function applyRoutingRetryDeprecationWarning(conf, warn = defaultConfigWarn) {
|
|
19512
|
-
const routing = conf.routing;
|
|
19513
|
-
const llm = routing?.llm;
|
|
19514
|
-
if (!llm)
|
|
19515
|
-
return conf;
|
|
19516
|
-
if ("retries" in llm) {
|
|
19517
|
-
warn("routing.llm.retries is deprecated (issue #856). " + "This value is still applied but will be removed in v1.0. " + "Retry policy is now declared on each operation \u2014 remove this key from your config.");
|
|
19518
|
-
}
|
|
19519
|
-
if ("retryDelayMs" in llm) {
|
|
19520
|
-
warn("routing.llm.retryDelayMs is deprecated (issue #856). " + "This value is still applied but will be removed in v1.0. " + "Retry policy is now declared on each operation \u2014 remove this key from your config.");
|
|
19521
|
-
}
|
|
19522
|
-
return conf;
|
|
19523
|
-
}
|
|
19524
|
-
function applyConfigCompatShims(conf, logger) {
|
|
19525
|
-
return _applyLegacyReviewExecutionShim(_applyRemovedRoutingKeysShim(applyRoutingRetryDeprecationWarning(applyBatchModeCompat(applyRemovedStrategyCompat(migrateLegacyReviewModelKey(migrateLegacyTestPattern(conf, logger), logger))))));
|
|
19526
|
-
}
|
|
19527
19556
|
async function loadConfig(startDir, cliOverrides) {
|
|
19528
19557
|
let rawConfig = structuredClone(DEFAULT_CONFIG);
|
|
19558
|
+
const warnDedupe = createConfigWarnDedupe();
|
|
19529
19559
|
const projDir = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? startDir : findProjectDir(startDir) : findProjectDir();
|
|
19530
19560
|
const projectRoot = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? dirname(startDir) : startDir : process.cwd();
|
|
19531
19561
|
const profileChain = await resolveProfileNames(cliOverrides ?? {}, process.env, projectRoot);
|
|
@@ -19537,14 +19567,14 @@ async function loadConfig(startDir, cliOverrides) {
|
|
|
19537
19567
|
} catch {}
|
|
19538
19568
|
if (globalConfRaw) {
|
|
19539
19569
|
const { profile: _gProfile, ...globalConfStripped } = globalConfRaw;
|
|
19540
|
-
const globalConf = applyConfigCompatShims(globalConfStripped, logger);
|
|
19570
|
+
const globalConf = applyConfigCompatShims(globalConfStripped, logger, warnDedupe);
|
|
19541
19571
|
rawConfig = deepMergeConfig(rawConfig, globalConf);
|
|
19542
19572
|
}
|
|
19543
19573
|
if (projDir) {
|
|
19544
19574
|
const projConf = await loadJsonFile(join3(projDir, "config.json"), "config");
|
|
19545
19575
|
if (projConf) {
|
|
19546
19576
|
const { profile: _pProfile, ...projConfStripped } = projConf;
|
|
19547
|
-
const resolvedProjConf = applyConfigCompatShims(projConfStripped, logger);
|
|
19577
|
+
const resolvedProjConf = applyConfigCompatShims(projConfStripped, logger, warnDedupe);
|
|
19548
19578
|
rawConfig = deepMergeConfig(rawConfig, resolvedProjConf);
|
|
19549
19579
|
}
|
|
19550
19580
|
}
|
|
@@ -19552,11 +19582,11 @@ async function loadConfig(startDir, cliOverrides) {
|
|
|
19552
19582
|
const profileData = await loadProfile(name, projectRoot);
|
|
19553
19583
|
const profileEnv = await loadProfileEnv(name, projectRoot);
|
|
19554
19584
|
const resolvedProfileData = Object.keys(profileEnv).length > 0 ? resolveEnvVars(profileData, profileEnv) : profileData;
|
|
19555
|
-
const shimmedProfileData = applyConfigCompatShims(resolvedProfileData, logger);
|
|
19585
|
+
const shimmedProfileData = applyConfigCompatShims(resolvedProfileData, logger, warnDedupe);
|
|
19556
19586
|
rawConfig = deepMergeConfig(rawConfig, shimmedProfileData);
|
|
19557
19587
|
}
|
|
19558
19588
|
if (cliOverrides) {
|
|
19559
|
-
const shimmedCliOverrides = applyConfigCompatShims(cliOverrides, logger);
|
|
19589
|
+
const shimmedCliOverrides = applyConfigCompatShims(cliOverrides, logger, warnDedupe);
|
|
19560
19590
|
rawConfig = deepMergeConfig(rawConfig, shimmedCliOverrides);
|
|
19561
19591
|
}
|
|
19562
19592
|
rawConfig.profile = overlayChain.length > 0 ? overlayChain.join("+") : "default";
|
|
@@ -19662,6 +19692,7 @@ var init_loader = __esm(() => {
|
|
|
19662
19692
|
init_errors();
|
|
19663
19693
|
init_logger2();
|
|
19664
19694
|
init_json_file();
|
|
19695
|
+
init_compat_shims();
|
|
19665
19696
|
init_config_guards();
|
|
19666
19697
|
init_path_security();
|
|
19667
19698
|
init_paths();
|
|
@@ -21966,7 +21997,7 @@ function parseAcpxJsonLine(line, state) {
|
|
|
21966
21997
|
state.text = "";
|
|
21967
21998
|
state.sawJsonLine = true;
|
|
21968
21999
|
}
|
|
21969
|
-
const looksLikeJsonRpcShape = typeof event.method === "string" && event.params !== undefined || event.id !== undefined &&
|
|
22000
|
+
const looksLikeJsonRpcShape = typeof event.method === "string" && event.params !== undefined || event.id !== undefined && event.result && typeof event.result === "object";
|
|
21970
22001
|
if (event.jsonrpc !== "2.0" && looksLikeJsonRpcShape) {
|
|
21971
22002
|
getSafeLogger()?.error("acp-adapter", "Unsupported or missing JSON-RPC protocol version in acpx output", {
|
|
21972
22003
|
jsonrpc: event.jsonrpc,
|
|
@@ -22086,7 +22117,20 @@ function parseAcpxJsonLine(line, state) {
|
|
|
22086
22117
|
if (event.stop_reason)
|
|
22087
22118
|
state.stopReason = event.stop_reason;
|
|
22088
22119
|
if (event.error) {
|
|
22089
|
-
|
|
22120
|
+
if (typeof event.error === "string") {
|
|
22121
|
+
state.error ??= event.error;
|
|
22122
|
+
} else {
|
|
22123
|
+
let errorMsg = typeof event.error.message === "string" ? event.error.message : JSON.stringify(event.error);
|
|
22124
|
+
const data = event.error.data;
|
|
22125
|
+
if (data && typeof data === "object") {
|
|
22126
|
+
const suffix = [data.acpxCode, data.detailCode].filter(Boolean).join("/");
|
|
22127
|
+
if (suffix)
|
|
22128
|
+
errorMsg = `${errorMsg} [${suffix}]`;
|
|
22129
|
+
if (!state.error && data.retryable === true)
|
|
22130
|
+
state.retryable = true;
|
|
22131
|
+
}
|
|
22132
|
+
state.error ??= errorMsg;
|
|
22133
|
+
}
|
|
22090
22134
|
}
|
|
22091
22135
|
} catch {
|
|
22092
22136
|
if (!state.text && !state.sawJsonLine)
|
|
@@ -45525,7 +45569,7 @@ var package_default;
|
|
|
45525
45569
|
var init_package = __esm(() => {
|
|
45526
45570
|
package_default = {
|
|
45527
45571
|
name: "@nathapp/nax",
|
|
45528
|
-
version: "0.79.
|
|
45572
|
+
version: "0.79.2",
|
|
45529
45573
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
45530
45574
|
type: "module",
|
|
45531
45575
|
bin: {
|
|
@@ -45638,8 +45682,8 @@ var init_version = __esm(() => {
|
|
|
45638
45682
|
NAX_VERSION = package_default.version;
|
|
45639
45683
|
NAX_COMMIT = (() => {
|
|
45640
45684
|
try {
|
|
45641
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
45642
|
-
return "
|
|
45685
|
+
if (/^[0-9a-f]{6,10}$/.test("840b1200"))
|
|
45686
|
+
return "840b1200";
|
|
45643
45687
|
} catch {}
|
|
45644
45688
|
try {
|
|
45645
45689
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -55547,17 +55591,33 @@ var init_cli = __esm(() => {
|
|
|
55547
55591
|
CLIConfigSchema = exports_external.object({}).passthrough();
|
|
55548
55592
|
});
|
|
55549
55593
|
|
|
55594
|
+
// src/interaction/plugins/telegram-config.ts
|
|
55595
|
+
function normalizeChatId(raw) {
|
|
55596
|
+
const chatId = raw.trim();
|
|
55597
|
+
return { chatId, unmatchable: !NUMERIC_CHAT_ID.test(chatId) };
|
|
55598
|
+
}
|
|
55599
|
+
var NUMERIC_CHAT_ID, TelegramConfigSchema;
|
|
55600
|
+
var init_telegram_config = __esm(() => {
|
|
55601
|
+
init_zod();
|
|
55602
|
+
NUMERIC_CHAT_ID = /^-?\d+$/;
|
|
55603
|
+
TelegramConfigSchema = exports_external.object({
|
|
55604
|
+
botToken: exports_external.string().optional(),
|
|
55605
|
+
chatId: exports_external.string().optional()
|
|
55606
|
+
});
|
|
55607
|
+
});
|
|
55608
|
+
|
|
55550
55609
|
// src/interaction/plugins/telegram-format.ts
|
|
55551
55610
|
function truncateUtf8Bytes(text, maxBytes) {
|
|
55552
55611
|
if (maxBytes <= 0)
|
|
55553
55612
|
return "";
|
|
55554
|
-
|
|
55613
|
+
const encoded = Buffer.from(text, "utf8");
|
|
55614
|
+
if (encoded.length <= maxBytes)
|
|
55555
55615
|
return text;
|
|
55556
|
-
let end =
|
|
55557
|
-
while (end > 0 &&
|
|
55616
|
+
let end = maxBytes;
|
|
55617
|
+
while (end > 0 && (encoded[end] & 192) === 128) {
|
|
55558
55618
|
end--;
|
|
55559
55619
|
}
|
|
55560
|
-
return
|
|
55620
|
+
return encoded.toString("utf8", 0, end);
|
|
55561
55621
|
}
|
|
55562
55622
|
function truncateIdForCallbackData(id, suffix) {
|
|
55563
55623
|
const suffixBytes = Buffer.byteLength(suffix, "utf8");
|
|
@@ -55568,6 +55628,9 @@ function truncateIdForCallbackData(id, suffix) {
|
|
|
55568
55628
|
return truncateUtf8Bytes(`h${digest}`, maxIdBytes);
|
|
55569
55629
|
}
|
|
55570
55630
|
function buildCallbackData(id, suffix) {
|
|
55631
|
+
if (id.includes(":")) {
|
|
55632
|
+
throw new NaxError(`Interaction request id must not contain ":" \u2014 it is the callback_data field separator, and an id containing it can never be matched back to its prompt (id: ${id})`, "INTERACTION_INVALID_REQUEST_ID", { stage: "interaction", requestId: id });
|
|
55633
|
+
}
|
|
55571
55634
|
return `${truncateIdForCallbackData(id, suffix)}${suffix}`;
|
|
55572
55635
|
}
|
|
55573
55636
|
function buildHeader(request) {
|
|
@@ -55691,26 +55754,21 @@ function getStageEmoji(stage) {
|
|
|
55691
55754
|
}
|
|
55692
55755
|
}
|
|
55693
55756
|
var MAX_MESSAGE_CHARS = 4000, TELEGRAM_CALLBACK_DATA_MAX_BYTES = 64;
|
|
55757
|
+
var init_telegram_format = __esm(() => {
|
|
55758
|
+
init_errors();
|
|
55759
|
+
});
|
|
55694
55760
|
|
|
55695
55761
|
// src/interaction/plugins/telegram.ts
|
|
55696
|
-
|
|
55697
|
-
const chatId = raw.trim();
|
|
55698
|
-
return { chatId, unmatchable: !NUMERIC_CHAT_ID.test(chatId) };
|
|
55699
|
-
}
|
|
55700
|
-
var _telegramPluginDeps, CALLBACK_API_TIMEOUT_MS = 4000, NUMERIC_CHAT_ID, TelegramConfigSchema, TelegramInteractionPlugin;
|
|
55762
|
+
var _telegramPluginDeps, CALLBACK_API_TIMEOUT_MS = 4000, TelegramInteractionPlugin;
|
|
55701
55763
|
var init_telegram = __esm(() => {
|
|
55702
|
-
init_zod();
|
|
55703
55764
|
init_logger2();
|
|
55765
|
+
init_telegram_config();
|
|
55766
|
+
init_telegram_format();
|
|
55704
55767
|
_telegramPluginDeps = {
|
|
55705
55768
|
fetch: globalThis.fetch.bind(globalThis),
|
|
55706
55769
|
basePollBackoffMs: 1000,
|
|
55707
55770
|
sleep: (ms) => new Promise((resolve14) => setTimeout(resolve14, ms))
|
|
55708
55771
|
};
|
|
55709
|
-
NUMERIC_CHAT_ID = /^-?\d+$/;
|
|
55710
|
-
TelegramConfigSchema = exports_external.object({
|
|
55711
|
-
botToken: exports_external.string().optional(),
|
|
55712
|
-
chatId: exports_external.string().optional()
|
|
55713
|
-
});
|
|
55714
55772
|
TelegramInteractionPlugin = class TelegramInteractionPlugin {
|
|
55715
55773
|
name = "telegram";
|
|
55716
55774
|
logger = getSafeLogger();
|
|
@@ -55771,7 +55829,15 @@ var init_telegram = __esm(() => {
|
|
|
55771
55829
|
await this.drainBacklog();
|
|
55772
55830
|
}
|
|
55773
55831
|
const header = buildHeader(request);
|
|
55774
|
-
|
|
55832
|
+
let keyboard = null;
|
|
55833
|
+
try {
|
|
55834
|
+
keyboard = buildKeyboard(request);
|
|
55835
|
+
} catch (err) {
|
|
55836
|
+
this.logger?.error("interaction", "Cannot build Telegram keyboard \u2014 sending prompt without buttons", {
|
|
55837
|
+
requestId: request.id,
|
|
55838
|
+
error: errorMessage(err)
|
|
55839
|
+
});
|
|
55840
|
+
}
|
|
55775
55841
|
const body = buildBody(request);
|
|
55776
55842
|
const chunks = splitText(body, MAX_MESSAGE_CHARS - header.length - 10);
|
|
55777
55843
|
try {
|
|
@@ -55968,7 +56034,7 @@ ${partLabel}${chunks[i]}`;
|
|
|
55968
56034
|
if (parts.length < 2)
|
|
55969
56035
|
return null;
|
|
55970
56036
|
const action = parts[1];
|
|
55971
|
-
const value = parts.length > 2 ? parts
|
|
56037
|
+
const value = parts.length > 2 ? parts.slice(2).join(":") : undefined;
|
|
55972
56038
|
const suffix = value !== undefined ? `:${action}:${value}` : `:${action}`;
|
|
55973
56039
|
const expectedIdPart = truncateIdForCallbackData(requestId, suffix);
|
|
55974
56040
|
if (parts[0] !== expectedIdPart)
|
|
@@ -56612,6 +56678,8 @@ var init_interaction = __esm(() => {
|
|
|
56612
56678
|
init_chain();
|
|
56613
56679
|
init_cli();
|
|
56614
56680
|
init_telegram();
|
|
56681
|
+
init_telegram_config();
|
|
56682
|
+
init_telegram_format();
|
|
56615
56683
|
init_webhook();
|
|
56616
56684
|
init_triggers();
|
|
56617
56685
|
init_init();
|