atomix-cli 1.0.0 → 1.2.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/README.md +38 -0
- package/dist/cli.js +3442 -1618
- package/dist/session.d.ts +377 -0
- package/dist/session.js +126512 -0
- package/dist/session.mjs +126489 -0
- package/dist/tui.mjs +2100 -962
- package/package.json +14 -2
package/dist/tui.mjs
CHANGED
|
@@ -27277,13 +27277,33 @@ var require_stack_utils = __commonJS({
|
|
|
27277
27277
|
}
|
|
27278
27278
|
});
|
|
27279
27279
|
|
|
27280
|
+
// src/paths.ts
|
|
27281
|
+
import * as os3 from "os";
|
|
27282
|
+
import * as path from "path";
|
|
27283
|
+
function getAtomixRoot() {
|
|
27284
|
+
const custom = process.env.ATOMIX_ROOT;
|
|
27285
|
+
if (custom) return path.resolve(custom);
|
|
27286
|
+
return path.join(os3.homedir(), ".atomix");
|
|
27287
|
+
}
|
|
27288
|
+
var init_paths = __esm({
|
|
27289
|
+
"src/paths.ts"() {
|
|
27290
|
+
"use strict";
|
|
27291
|
+
}
|
|
27292
|
+
});
|
|
27293
|
+
|
|
27280
27294
|
// ../atomix-core/dist/util/adapter.js
|
|
27281
27295
|
var require_adapter = __commonJS({
|
|
27282
27296
|
"../atomix-core/dist/util/adapter.js"(exports2) {
|
|
27283
27297
|
"use strict";
|
|
27284
27298
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
27285
|
-
exports2.TEMPERATURE_ONE_MODELS = void 0;
|
|
27299
|
+
exports2.TEMPERATURE_MAX = exports2.TEMPERATURE_MIN = exports2.DEFAULT_ANTHROPIC_TEMPERATURE = exports2.TEMPERATURE_ONE_MODELS = void 0;
|
|
27286
27300
|
exports2.resolveAdapter = resolveAdapter;
|
|
27301
|
+
exports2.openaiTemperatureCapability = openaiTemperatureCapability;
|
|
27302
|
+
exports2.modelForcesTemperatureOne = modelForcesTemperatureOne3;
|
|
27303
|
+
exports2.modelRejectsTemperature = modelRejectsTemperature3;
|
|
27304
|
+
exports2.modelTemperatureGatedByThinking = modelTemperatureGatedByThinking3;
|
|
27305
|
+
exports2.isValidTemperature = isValidTemperature3;
|
|
27306
|
+
exports2.assertTemperature = assertTemperature;
|
|
27287
27307
|
exports2.useMaxCompletionTokens = useMaxCompletionTokens;
|
|
27288
27308
|
exports2.modelForcesThinking = modelForcesThinking;
|
|
27289
27309
|
exports2.forcedThinkingEffort = forcedThinkingEffort;
|
|
@@ -27332,6 +27352,60 @@ var require_adapter = __commonJS({
|
|
|
27332
27352
|
"kimi-k2.5",
|
|
27333
27353
|
"moonshotai/kimi-k2.5"
|
|
27334
27354
|
];
|
|
27355
|
+
var OPENAI_TEMPERATURE_NORMAL_PREFIXES = ["gpt-5-chat", "gpt-5.1-chat", "gpt-5.2-chat"];
|
|
27356
|
+
var OPENAI_TEMPERATURE_REJECT_EXACT = ["gpt-5"];
|
|
27357
|
+
var OPENAI_TEMPERATURE_REJECT_PREFIXES = [
|
|
27358
|
+
"o1",
|
|
27359
|
+
"o3",
|
|
27360
|
+
"o4",
|
|
27361
|
+
"gpt-5-mini",
|
|
27362
|
+
"gpt-5-nano",
|
|
27363
|
+
"gpt-5-20",
|
|
27364
|
+
// 初代及其日期快照(gpt-5-2025-08-07)
|
|
27365
|
+
"gpt-5-pro",
|
|
27366
|
+
"gpt-5.1-pro",
|
|
27367
|
+
"gpt-5.2-pro",
|
|
27368
|
+
"gpt-5-codex",
|
|
27369
|
+
"gpt-5.1-codex",
|
|
27370
|
+
"gpt-5.2-codex"
|
|
27371
|
+
];
|
|
27372
|
+
var OPENAI_TEMPERATURE_GATED_PREFIXES = ["gpt-5.1", "gpt-5.2"];
|
|
27373
|
+
function bareModelName(modelName) {
|
|
27374
|
+
const lower = modelName.toLowerCase();
|
|
27375
|
+
return lower.split("/").pop() ?? lower;
|
|
27376
|
+
}
|
|
27377
|
+
function openaiTemperatureCapability(modelName) {
|
|
27378
|
+
const bare = bareModelName(modelName);
|
|
27379
|
+
if (OPENAI_TEMPERATURE_NORMAL_PREFIXES.some((p) => bare.startsWith(p)))
|
|
27380
|
+
return "normal";
|
|
27381
|
+
if (OPENAI_TEMPERATURE_REJECT_EXACT.includes(bare) || OPENAI_TEMPERATURE_REJECT_PREFIXES.some((p) => bare.startsWith(p)))
|
|
27382
|
+
return "reject";
|
|
27383
|
+
if (OPENAI_TEMPERATURE_GATED_PREFIXES.some((p) => bare.startsWith(p)))
|
|
27384
|
+
return "gated";
|
|
27385
|
+
if (bare.startsWith("gpt-5"))
|
|
27386
|
+
return "reject";
|
|
27387
|
+
return null;
|
|
27388
|
+
}
|
|
27389
|
+
function modelForcesTemperatureOne3(modelName) {
|
|
27390
|
+
return exports2.TEMPERATURE_ONE_MODELS.includes(modelName);
|
|
27391
|
+
}
|
|
27392
|
+
function modelRejectsTemperature3(modelName) {
|
|
27393
|
+
return openaiTemperatureCapability(modelName) === "reject";
|
|
27394
|
+
}
|
|
27395
|
+
function modelTemperatureGatedByThinking3(modelName) {
|
|
27396
|
+
return openaiTemperatureCapability(modelName) === "gated";
|
|
27397
|
+
}
|
|
27398
|
+
function isValidTemperature3(t) {
|
|
27399
|
+
return typeof t === "number" && Number.isFinite(t) && t >= exports2.TEMPERATURE_MIN && t <= exports2.TEMPERATURE_MAX;
|
|
27400
|
+
}
|
|
27401
|
+
exports2.DEFAULT_ANTHROPIC_TEMPERATURE = 0.7;
|
|
27402
|
+
exports2.TEMPERATURE_MIN = 0;
|
|
27403
|
+
exports2.TEMPERATURE_MAX = 2;
|
|
27404
|
+
function assertTemperature(t) {
|
|
27405
|
+
if (!isValidTemperature3(t)) {
|
|
27406
|
+
throw new Error(`temperature \u987B\u4E3A ${exports2.TEMPERATURE_MIN}\u2013${exports2.TEMPERATURE_MAX} \u7684\u6570\u5B57,\u6536\u5230 ${JSON.stringify(t)}`);
|
|
27407
|
+
}
|
|
27408
|
+
}
|
|
27335
27409
|
var MAX_COMPLETION_TOKENS_PREFIXES = [
|
|
27336
27410
|
"o1",
|
|
27337
27411
|
"o3",
|
|
@@ -27525,7 +27599,8 @@ var require_apiUtil = __commonJS({
|
|
|
27525
27599
|
model: modelName,
|
|
27526
27600
|
messages: [{ role: "user", content: 'Please respond with exactly "YES" (in capital letters) to confirm this connection is working.' }],
|
|
27527
27601
|
...(0, adapter_1.useMaxCompletionTokens)(modelName) ? { max_completion_tokens: 200 } : { max_tokens: 200 },
|
|
27528
|
-
temperature
|
|
27602
|
+
// 不发 temperature:与正式请求(adapt/openai.ts)一致,交给服务端默认。之前固定发 0.0,
|
|
27603
|
+
// gpt-5 / o 系列等只接受默认值 1 的模型直接 400("does not support 0.0 with this model"),把可用模型挡在添加阶段
|
|
27529
27604
|
stream: false
|
|
27530
27605
|
}),
|
|
27531
27606
|
extractContent: (response) => response.choices?.[0]?.message?.content || "",
|
|
@@ -34969,7 +35044,7 @@ var require_combineLatest = __commonJS({
|
|
|
34969
35044
|
maybeSchedule(scheduler, function() {
|
|
34970
35045
|
var length = observables.length;
|
|
34971
35046
|
var values2 = new Array(length);
|
|
34972
|
-
var
|
|
35047
|
+
var active = length;
|
|
34973
35048
|
var remainingFirstValues = length;
|
|
34974
35049
|
var _loop_1 = function(i2) {
|
|
34975
35050
|
maybeSchedule(scheduler, function() {
|
|
@@ -34985,7 +35060,7 @@ var require_combineLatest = __commonJS({
|
|
|
34985
35060
|
subscriber.next(valueTransform(values2.slice()));
|
|
34986
35061
|
}
|
|
34987
35062
|
}, function() {
|
|
34988
|
-
if (!--
|
|
35063
|
+
if (!--active) {
|
|
34989
35064
|
subscriber.complete();
|
|
34990
35065
|
}
|
|
34991
35066
|
}));
|
|
@@ -35019,20 +35094,20 @@ var require_mergeInternals = __commonJS({
|
|
|
35019
35094
|
var OperatorSubscriber_1 = require_OperatorSubscriber();
|
|
35020
35095
|
function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) {
|
|
35021
35096
|
var buffer = [];
|
|
35022
|
-
var
|
|
35097
|
+
var active = 0;
|
|
35023
35098
|
var index = 0;
|
|
35024
35099
|
var isComplete = false;
|
|
35025
35100
|
var checkComplete = function() {
|
|
35026
|
-
if (isComplete && !buffer.length && !
|
|
35101
|
+
if (isComplete && !buffer.length && !active) {
|
|
35027
35102
|
subscriber.complete();
|
|
35028
35103
|
}
|
|
35029
35104
|
};
|
|
35030
35105
|
var outerNext = function(value) {
|
|
35031
|
-
return
|
|
35106
|
+
return active < concurrent ? doInnerSub(value) : buffer.push(value);
|
|
35032
35107
|
};
|
|
35033
35108
|
var doInnerSub = function(value) {
|
|
35034
35109
|
expand && subscriber.next(value);
|
|
35035
|
-
|
|
35110
|
+
active++;
|
|
35036
35111
|
var innerComplete = false;
|
|
35037
35112
|
innerFrom_1.innerFrom(project(value, index++)).subscribe(OperatorSubscriber_1.createOperatorSubscriber(subscriber, function(innerValue) {
|
|
35038
35113
|
onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);
|
|
@@ -35046,7 +35121,7 @@ var require_mergeInternals = __commonJS({
|
|
|
35046
35121
|
}, void 0, function() {
|
|
35047
35122
|
if (innerComplete) {
|
|
35048
35123
|
try {
|
|
35049
|
-
|
|
35124
|
+
active--;
|
|
35050
35125
|
var _loop_1 = function() {
|
|
35051
35126
|
var bufferedValue = buffer.shift();
|
|
35052
35127
|
if (innerSubScheduler) {
|
|
@@ -35057,7 +35132,7 @@ var require_mergeInternals = __commonJS({
|
|
|
35057
35132
|
doInnerSub(bufferedValue);
|
|
35058
35133
|
}
|
|
35059
35134
|
};
|
|
35060
|
-
while (buffer.length &&
|
|
35135
|
+
while (buffer.length && active < concurrent) {
|
|
35061
35136
|
_loop_1();
|
|
35062
35137
|
}
|
|
35063
35138
|
checkComplete();
|
|
@@ -42241,7 +42316,7 @@ var require_shell = __commonJS({
|
|
|
42241
42316
|
var os9 = __importStar(__require("os"));
|
|
42242
42317
|
var crypto3 = __importStar(__require("crypto"));
|
|
42243
42318
|
var log_1 = require_log();
|
|
42244
|
-
var TEMPFILE_PREFIX = os9.tmpdir()
|
|
42319
|
+
var TEMPFILE_PREFIX = (0, path_1.join)(os9.tmpdir(), "sema-");
|
|
42245
42320
|
var DEFAULT_TIMEOUT = 30 * 60 * 1e3;
|
|
42246
42321
|
var SIGTERM_CODE = 143;
|
|
42247
42322
|
var FILE_SUFFIXES = {
|
|
@@ -44610,7 +44685,8 @@ var require_model = __commonJS({
|
|
|
44610
44685
|
apiKey: config.apiKey,
|
|
44611
44686
|
maxTokens: config.maxTokens || fallback.maxTokens,
|
|
44612
44687
|
contextLength: config.contextLength || fallback.contextLength,
|
|
44613
|
-
adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName)
|
|
44688
|
+
adapt: config.adapt ?? (0, adapter_1.resolveAdapter)(config.provider, config.modelName),
|
|
44689
|
+
...config.temperature !== void 0 ? { temperature: config.temperature } : {}
|
|
44614
44690
|
};
|
|
44615
44691
|
}
|
|
44616
44692
|
}
|
|
@@ -44661,10 +44737,12 @@ var require_ModelManager = __commonJS({
|
|
|
44661
44737
|
exports2.getModelManager = exports2.ModelManager = void 0;
|
|
44662
44738
|
var fs14 = __importStar(__require("fs"));
|
|
44663
44739
|
var path15 = __importStar(__require("path"));
|
|
44740
|
+
var adapter_1 = require_adapter();
|
|
44664
44741
|
var apiUtil_1 = require_apiUtil();
|
|
44665
44742
|
var savePath_1 = require_savePath();
|
|
44666
44743
|
var model_1 = require_model();
|
|
44667
44744
|
var log_1 = require_log();
|
|
44745
|
+
var EngineContext_1 = require_EngineContext();
|
|
44668
44746
|
var ModelManager = class {
|
|
44669
44747
|
constructor(initialConfig) {
|
|
44670
44748
|
this.configPath = (0, savePath_1.getModelConfigFilePath)();
|
|
@@ -44692,6 +44770,8 @@ var require_ModelManager = __commonJS({
|
|
|
44692
44770
|
* @param skipValidation 是否跳过API校验,默认为false
|
|
44693
44771
|
*/
|
|
44694
44772
|
async addNewModel(config, skipValidation = false) {
|
|
44773
|
+
if (config.temperature !== void 0)
|
|
44774
|
+
this.assertProfileTemperature(config.modelName, config.temperature);
|
|
44695
44775
|
const profile = (0, model_1.convertToModelProfile)(config);
|
|
44696
44776
|
const existingModelIndex = this.config.modelProfiles.findIndex((p) => p.name === profile.name);
|
|
44697
44777
|
if (!skipValidation) {
|
|
@@ -44720,7 +44800,7 @@ ${testResult.curlCommand}` : testResult.message;
|
|
|
44720
44800
|
}
|
|
44721
44801
|
}
|
|
44722
44802
|
if (existingModelIndex !== -1) {
|
|
44723
|
-
this.config.modelProfiles[existingModelIndex] = profile;
|
|
44803
|
+
this.config.modelProfiles[existingModelIndex] = { ...this.config.modelProfiles[existingModelIndex], ...profile };
|
|
44724
44804
|
} else {
|
|
44725
44805
|
this.config.modelProfiles.push(profile);
|
|
44726
44806
|
if (this.config.modelProfiles.length === 1) {
|
|
@@ -44819,16 +44899,36 @@ ${testResult.curlCommand}` : testResult.message;
|
|
|
44819
44899
|
};
|
|
44820
44900
|
}
|
|
44821
44901
|
/**
|
|
44822
|
-
*
|
|
44902
|
+
* 解析指针槽位实际指向的模型标识(harness-model-v1 §2):
|
|
44903
|
+
* 当前会话(EngineStore.coreConfig.modelOverrides)有覆盖则用覆盖,否则用 model.conf 指针。
|
|
44904
|
+
* ALS 之外(无 EngineStore)读不到覆盖 = base。
|
|
44905
|
+
*/
|
|
44906
|
+
resolvePointer(pointer) {
|
|
44907
|
+
const override = (0, EngineContext_1.getEngineStore)()?.coreConfig?.modelOverrides?.[pointer];
|
|
44908
|
+
if (typeof override === "string" && override)
|
|
44909
|
+
return { id: override, overridden: true };
|
|
44910
|
+
return { id: this.config.modelPointers?.[pointer] || null, overridden: false };
|
|
44911
|
+
}
|
|
44912
|
+
/**
|
|
44913
|
+
* 获取指定类型的模型配置(会话覆盖优先)。
|
|
44914
|
+
* 覆盖指向的 profile 已不存在(会话中被删)时返回 null,由调用方报错——不静默回落 base。
|
|
44823
44915
|
*/
|
|
44824
44916
|
getModel(pointer) {
|
|
44825
|
-
const
|
|
44826
|
-
if (!
|
|
44917
|
+
const { id } = this.resolvePointer(pointer);
|
|
44918
|
+
if (!id) {
|
|
44827
44919
|
return null;
|
|
44828
44920
|
}
|
|
44829
|
-
const profile = (0, model_1.findModelProfile)(
|
|
44921
|
+
const profile = (0, model_1.findModelProfile)(id, this.config.modelProfiles);
|
|
44830
44922
|
return profile || null;
|
|
44831
44923
|
}
|
|
44924
|
+
/** 已配置的模型标识列表(同步;harness 解析是同步纯函数,不能等异步 getModelData)。 */
|
|
44925
|
+
getModelNames() {
|
|
44926
|
+
return this.config.modelProfiles.map((p) => p.name);
|
|
44927
|
+
}
|
|
44928
|
+
/** model.conf 的指针值(base,不含会话覆盖;同步)。 */
|
|
44929
|
+
getModelPointers() {
|
|
44930
|
+
return { main: this.config.modelPointers?.main ?? "", quick: this.config.modelPointers?.quick ?? "" };
|
|
44931
|
+
}
|
|
44832
44932
|
/**
|
|
44833
44933
|
* 获取指定类型的模型名称
|
|
44834
44934
|
*/
|
|
@@ -44836,6 +44936,89 @@ ${testResult.curlCommand}` : testResult.message;
|
|
|
44836
44936
|
const profile = this.getModel(pointer);
|
|
44837
44937
|
return profile ? profile.modelName : null;
|
|
44838
44938
|
}
|
|
44939
|
+
// ===================== 温度 / profile 字段编辑(model-temperature-v1) =====================
|
|
44940
|
+
/** 去 apiKey 的只读视图;adapt 补齐(缺省按 provider/modelName 推断),cli 展示"协议默认"时不必再算 */
|
|
44941
|
+
getModelProfiles() {
|
|
44942
|
+
return this.config.modelProfiles.map((p) => {
|
|
44943
|
+
const { apiKey: _k, ...rest2 } = p;
|
|
44944
|
+
return { ...rest2, adapt: p.adapt ?? (0, adapter_1.resolveAdapter)(p.provider, p.modelName) };
|
|
44945
|
+
});
|
|
44946
|
+
}
|
|
44947
|
+
/**
|
|
44948
|
+
* 改单个 profile 的字段,不重跑连通性测试。`'temperature' in patch && patch.temperature === undefined` = 清除。
|
|
44949
|
+
* 硬约束模型(TEMPERATURE_ONE_MODELS)拒绝设温度:覆盖只会换来 4xx。
|
|
44950
|
+
*/
|
|
44951
|
+
async updateModelProfile(name, patch) {
|
|
44952
|
+
const idx = this.config.modelProfiles.findIndex((p) => p.name === name);
|
|
44953
|
+
if (idx === -1)
|
|
44954
|
+
throw new Error(`\u6A21\u578B\u4E0D\u5B58\u5728: ${name}`);
|
|
44955
|
+
const next = { ...this.config.modelProfiles[idx] };
|
|
44956
|
+
if ("temperature" in patch) {
|
|
44957
|
+
if (patch.temperature === void 0)
|
|
44958
|
+
delete next.temperature;
|
|
44959
|
+
else {
|
|
44960
|
+
this.assertProfileTemperature(next.modelName, patch.temperature);
|
|
44961
|
+
next.temperature = patch.temperature;
|
|
44962
|
+
}
|
|
44963
|
+
}
|
|
44964
|
+
for (const k of ["maxTokens", "contextLength"]) {
|
|
44965
|
+
if (k in patch) {
|
|
44966
|
+
const v = patch[k];
|
|
44967
|
+
if (!Number.isInteger(v) || v <= 0)
|
|
44968
|
+
throw new Error(`${k} \u987B\u4E3A\u6B63\u6574\u6570,\u6536\u5230 ${JSON.stringify(v)}`);
|
|
44969
|
+
next[k] = v;
|
|
44970
|
+
}
|
|
44971
|
+
}
|
|
44972
|
+
if ("vision" in patch) {
|
|
44973
|
+
if (patch.vision === void 0)
|
|
44974
|
+
delete next.vision;
|
|
44975
|
+
else if (typeof patch.vision !== "boolean")
|
|
44976
|
+
throw new Error(`vision \u987B\u4E3A\u5E03\u5C14\u503C`);
|
|
44977
|
+
else
|
|
44978
|
+
next.vision = patch.vision;
|
|
44979
|
+
}
|
|
44980
|
+
this.config.modelProfiles[idx] = next;
|
|
44981
|
+
await this.saveConfig();
|
|
44982
|
+
const { apiKey: _k, ...rest2 } = next;
|
|
44983
|
+
return { ...rest2, adapt: next.adapt ?? (0, adapter_1.resolveAdapter)(next.provider, next.modelName) };
|
|
44984
|
+
}
|
|
44985
|
+
/** 范围校验 + 模型侧约束拒绝;addNewModel / updateModelProfile 共用。gpt-5 系列允许配置(thinking 关时生效),这里不挡 */
|
|
44986
|
+
assertProfileTemperature(modelName, t) {
|
|
44987
|
+
(0, adapter_1.assertTemperature)(t);
|
|
44988
|
+
if ((0, adapter_1.modelForcesTemperatureOne)(modelName))
|
|
44989
|
+
throw new Error(`\u6A21\u578B ${modelName} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1,\u4E0D\u80FD\u8BBE\u7F6E temperature`);
|
|
44990
|
+
if ((0, adapter_1.modelRejectsTemperature)(modelName))
|
|
44991
|
+
throw new Error(`\u6A21\u578B ${modelName} \u4E0D\u652F\u6301 temperature \u53C2\u6570(\u63A8\u7406\u6A21\u578B),\u4E0D\u80FD\u8BBE\u7F6E`);
|
|
44992
|
+
}
|
|
44993
|
+
/**
|
|
44994
|
+
* 请求时的温度解析(model-temperature-v1 §1.1),高者胜:
|
|
44995
|
+
* 1 模型侧约束:kimi 恒 1;o 系列永不发;gpt-5 系列 thinking 开(发 reasoning_effort)时不发;anthropic 协议开 thinking 不发;
|
|
44996
|
+
* 2 会话级覆盖(harness,经 EngineStore);3 profile.temperature;4 协议默认(anthropic 0.7,openai 不发)。
|
|
44997
|
+
* 返回 undefined = 请求体不带该字段。
|
|
44998
|
+
*/
|
|
44999
|
+
resolveTemperature(pointer, profile, opts) {
|
|
45000
|
+
if ((0, adapter_1.modelForcesTemperatureOne)(profile.modelName))
|
|
45001
|
+
return 1;
|
|
45002
|
+
if ((0, adapter_1.modelRejectsTemperature)(profile.modelName))
|
|
45003
|
+
return void 0;
|
|
45004
|
+
if (opts.enableThinking && (0, adapter_1.modelTemperatureGatedByThinking)(profile.modelName))
|
|
45005
|
+
return void 0;
|
|
45006
|
+
if (opts.adapter === "anthropic" && opts.enableThinking)
|
|
45007
|
+
return void 0;
|
|
45008
|
+
const over2 = (0, EngineContext_1.getEngineStore)()?.coreConfig?.temperatureOverrides?.[pointer];
|
|
45009
|
+
if (over2 !== void 0 && !(0, adapter_1.isValidTemperature)(over2))
|
|
45010
|
+
(0, log_1.logWarn)(`temperatureOverrides.${pointer} \u975E\u6CD5(${JSON.stringify(over2)}),\u5FFD\u7565,\u6539\u7528 profile / \u9ED8\u8BA4`);
|
|
45011
|
+
if (profile.temperature !== void 0 && !(0, adapter_1.isValidTemperature)(profile.temperature))
|
|
45012
|
+
(0, log_1.logWarn)(`\u6A21\u578B ${profile.name} \u7684 temperature \u975E\u6CD5(${JSON.stringify(profile.temperature)}),\u5FFD\u7565,\u6539\u7528\u534F\u8BAE\u9ED8\u8BA4`);
|
|
45013
|
+
let t = (0, adapter_1.isValidTemperature)(over2) ? over2 : (0, adapter_1.isValidTemperature)(profile.temperature) ? profile.temperature : void 0;
|
|
45014
|
+
if (t === void 0)
|
|
45015
|
+
return opts.adapter === "anthropic" ? adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE : void 0;
|
|
45016
|
+
if (opts.adapter === "anthropic" && t > 1) {
|
|
45017
|
+
(0, log_1.logWarn)(`temperature ${t} \u8D85\u51FA anthropic \u534F\u8BAE\u4E0A\u9650,\u6309 1 \u53D1\u9001(${profile.name})`);
|
|
45018
|
+
t = 1;
|
|
45019
|
+
}
|
|
45020
|
+
return t;
|
|
45021
|
+
}
|
|
44839
45022
|
/**
|
|
44840
45023
|
* 获取当前模型数据
|
|
44841
45024
|
* @param showModelProfiles 是否包含详细的模型配置信息,默认为false
|
|
@@ -51127,9 +51310,9 @@ var require_agentsManager = __commonJS({
|
|
|
51127
51310
|
}
|
|
51128
51311
|
const userNext = /* @__PURE__ */ new Map();
|
|
51129
51312
|
await this.loadAgentsFromDir(userNext, this.userAgentsDir, "user");
|
|
51130
|
-
const
|
|
51313
|
+
const projectDir = opts?.projectAgentsDir !== void 0 ? path15.resolve(opts.projectAgentsDir) : this.resolveProjectAgentsDir();
|
|
51131
51314
|
const projectNext = /* @__PURE__ */ new Map();
|
|
51132
|
-
await this.loadAgentsFromDir(projectNext,
|
|
51315
|
+
await this.loadAgentsFromDir(projectNext, projectDir, "project");
|
|
51133
51316
|
for (const name of userNext.keys()) {
|
|
51134
51317
|
if (managedNext.has(name) || builtinNext.has(name))
|
|
51135
51318
|
(0, log_1.logWarn)(`Agent [${name}] \u88AB user \u7EA7\u914D\u7F6E\u8986\u76D6`);
|
|
@@ -51142,11 +51325,11 @@ var require_agentsManager = __commonJS({
|
|
|
51142
51325
|
this.builtinLayer = builtinNext;
|
|
51143
51326
|
this.managedLayers.set(key, managedNext);
|
|
51144
51327
|
this.userLayer = userNext;
|
|
51145
|
-
this.projectLayers.set(
|
|
51328
|
+
this.projectLayers.set(projectDir, projectNext);
|
|
51146
51329
|
this.lastInitKey = key;
|
|
51147
|
-
this.lastInitProjectKey =
|
|
51330
|
+
this.lastInitProjectKey = projectDir;
|
|
51148
51331
|
this.invalidateCache();
|
|
51149
|
-
const agentNames = Array.from(this.mergedFor(key,
|
|
51332
|
+
const agentNames = Array.from(this.mergedFor(key, projectDir).keys()).join(", ");
|
|
51150
51333
|
(0, log_1.logInfo)(`\u52A0\u8F7D Agents \u914D\u7F6E: ${agentNames}`);
|
|
51151
51334
|
}
|
|
51152
51335
|
/** 按 managed 键 + project 键合并四层(带缓存);spread 顺序即覆盖顺序 */
|
|
@@ -51385,20 +51568,20 @@ var require_agentsManager = __commonJS({
|
|
|
51385
51568
|
if (this.currentMerged(view).has(agentConf.name)) {
|
|
51386
51569
|
(0, log_1.logWarn)(`Agent [${agentConf.name}] \u88AB\u8986\u76D6`);
|
|
51387
51570
|
}
|
|
51388
|
-
const
|
|
51571
|
+
const projectDir = view?.projectAgentsDir !== void 0 ? path15.resolve(view.projectAgentsDir) : this.resolveProjectAgentsDir();
|
|
51389
51572
|
if (agentConf.locate === "user") {
|
|
51390
51573
|
this.userLayer.set(agentConf.name, { ...agentConf });
|
|
51391
51574
|
} else {
|
|
51392
|
-
let layer = this.projectLayers.get(
|
|
51575
|
+
let layer = this.projectLayers.get(projectDir);
|
|
51393
51576
|
if (!layer) {
|
|
51394
51577
|
layer = /* @__PURE__ */ new Map();
|
|
51395
|
-
this.projectLayers.set(
|
|
51578
|
+
this.projectLayers.set(projectDir, layer);
|
|
51396
51579
|
}
|
|
51397
51580
|
layer.set(agentConf.name, { ...agentConf });
|
|
51398
51581
|
}
|
|
51399
51582
|
this.invalidateCache();
|
|
51400
51583
|
(0, log_1.logInfo)(`\u6DFB\u52A0 Agent \u914D\u7F6E: ${agentConf.name}`);
|
|
51401
|
-
const saved = await this.saveAgentToFile(agentConf,
|
|
51584
|
+
const saved = await this.saveAgentToFile(agentConf, projectDir);
|
|
51402
51585
|
if (!saved) {
|
|
51403
51586
|
(0, log_1.logWarn)(`Agent \u914D\u7F6E\u5DF2\u6DFB\u52A0\u5230\u5185\u5B58\uFF0C\u4F46\u4FDD\u5B58\u5230\u6587\u4EF6\u5931\u8D25: ${agentConf.name}`);
|
|
51404
51587
|
}
|
|
@@ -51870,9 +52053,15 @@ var require_Bash = __commonJS({
|
|
|
51870
52053
|
"--eof",
|
|
51871
52054
|
"-a",
|
|
51872
52055
|
"--arg-file"
|
|
51873
|
-
])
|
|
51874
|
-
|
|
51875
|
-
|
|
52056
|
+
]),
|
|
52057
|
+
// zsh precommand modifier(macOS 默认 $SHELL 是 zsh,PersistentShell 直接用它):
|
|
52058
|
+
// `repeat N cmd`、`noglob cmd`、`nocorrect cmd`、`- cmd`(argv[0] 加 `-`)都会执行后面的命令
|
|
52059
|
+
repeat: W([], [], 1),
|
|
52060
|
+
noglob: W([], []),
|
|
52061
|
+
nocorrect: W([], []),
|
|
52062
|
+
"-": W([], [])
|
|
52063
|
+
};
|
|
52064
|
+
var CMD_KEYWORDS = /* @__PURE__ */ new Set([
|
|
51876
52065
|
"!",
|
|
51877
52066
|
"{",
|
|
51878
52067
|
"}",
|
|
@@ -51885,13 +52074,9 @@ var require_Bash = __commonJS({
|
|
|
51885
52074
|
"until",
|
|
51886
52075
|
"do",
|
|
51887
52076
|
"done",
|
|
51888
|
-
"case",
|
|
51889
52077
|
"esac",
|
|
51890
|
-
"
|
|
51891
|
-
"
|
|
51892
|
-
"select",
|
|
51893
|
-
"function",
|
|
51894
|
-
"coproc"
|
|
52078
|
+
"always",
|
|
52079
|
+
"end"
|
|
51895
52080
|
]);
|
|
51896
52081
|
var REDIRECT_OPS = /* @__PURE__ */ new Set([">", ">>", "<", ">&", "<&", "<<<", ">|"]);
|
|
51897
52082
|
var LIST_SEPARATORS = /* @__PURE__ */ new Set(["&&", "||", ";", ";;", "|", "|&", "&"]);
|
|
@@ -51901,6 +52086,8 @@ var require_Bash = __commonJS({
|
|
|
51901
52086
|
var isClobberPipe = (entries, k) => isOp(entries[k], "|") && isOp(entries[k - 1], ">");
|
|
51902
52087
|
function analyzeCommandSegments(command) {
|
|
51903
52088
|
const out = [];
|
|
52089
|
+
let state = "cmd";
|
|
52090
|
+
let caseDepth = 0;
|
|
51904
52091
|
for (const line of command.split(/\r\n|\n|\r/)) {
|
|
51905
52092
|
if (!line.trim())
|
|
51906
52093
|
continue;
|
|
@@ -51911,32 +52098,226 @@ var require_Bash = __commonJS({
|
|
|
51911
52098
|
out.push({ error: `command could not be parsed: ${line}` });
|
|
51912
52099
|
continue;
|
|
51913
52100
|
}
|
|
51914
|
-
|
|
52101
|
+
if (state !== "patterns")
|
|
52102
|
+
state = "cmd";
|
|
52103
|
+
let pending = null;
|
|
52104
|
+
let parenList = false;
|
|
52105
|
+
let patternWord = false;
|
|
51915
52106
|
let cur = [];
|
|
51916
|
-
|
|
52107
|
+
let failed = false;
|
|
52108
|
+
const flush = () => {
|
|
52109
|
+
if (cur.length) {
|
|
52110
|
+
const r = unwrapEntries(cur, line);
|
|
52111
|
+
if (r !== null)
|
|
52112
|
+
out.push(r);
|
|
52113
|
+
}
|
|
52114
|
+
cur = [];
|
|
52115
|
+
};
|
|
52116
|
+
const fail = (msg) => {
|
|
52117
|
+
out.push({ error: msg });
|
|
52118
|
+
failed = true;
|
|
52119
|
+
};
|
|
52120
|
+
for (let k = 0; k < entries.length && !failed; k++) {
|
|
51917
52121
|
const e = entries[k];
|
|
51918
|
-
|
|
51919
|
-
|
|
51920
|
-
|
|
51921
|
-
|
|
51922
|
-
|
|
51923
|
-
|
|
51924
|
-
|
|
51925
|
-
|
|
51926
|
-
|
|
51927
|
-
|
|
51928
|
-
|
|
52122
|
+
if (typeof e === "object" && "comment" in e)
|
|
52123
|
+
break;
|
|
52124
|
+
const kw = typeof e === "string" ? e : null;
|
|
52125
|
+
const isWord = kw !== null || isOp(e, "glob");
|
|
52126
|
+
if (isWord) {
|
|
52127
|
+
switch (state) {
|
|
52128
|
+
case "cmd":
|
|
52129
|
+
if (kw !== null && CMD_KEYWORDS.has(kw)) {
|
|
52130
|
+
flush();
|
|
52131
|
+
if (kw === "esac")
|
|
52132
|
+
caseDepth = Math.max(0, caseDepth - 1);
|
|
52133
|
+
continue;
|
|
52134
|
+
}
|
|
52135
|
+
if (kw === "for" || kw === "select" || kw === "foreach") {
|
|
52136
|
+
flush();
|
|
52137
|
+
pending = "for";
|
|
52138
|
+
state = "name";
|
|
52139
|
+
continue;
|
|
52140
|
+
}
|
|
52141
|
+
if (kw === "case") {
|
|
52142
|
+
flush();
|
|
52143
|
+
pending = "case";
|
|
52144
|
+
state = "name";
|
|
52145
|
+
continue;
|
|
52146
|
+
}
|
|
52147
|
+
if (kw === "function") {
|
|
52148
|
+
flush();
|
|
52149
|
+
pending = "function";
|
|
52150
|
+
state = "name";
|
|
52151
|
+
continue;
|
|
52152
|
+
}
|
|
52153
|
+
if (kw === "coproc") {
|
|
52154
|
+
flush();
|
|
52155
|
+
if (typeof entries[k + 1] === "string" && (entries[k + 2] === "{" || isOp(entries[k + 2], "(")))
|
|
52156
|
+
k++;
|
|
52157
|
+
continue;
|
|
52158
|
+
}
|
|
52159
|
+
if (kw === "[[") {
|
|
52160
|
+
flush();
|
|
52161
|
+
state = "cond";
|
|
52162
|
+
continue;
|
|
52163
|
+
}
|
|
52164
|
+
cur.push(e);
|
|
52165
|
+
if (kw !== null && (ENV_ASSIGN_RE.test(kw) || kw.startsWith("-") || /^\d+$/.test(kw) && isRedirectOp(entries[k + 1])))
|
|
52166
|
+
continue;
|
|
52167
|
+
if (kw !== null && WRAPPERS[kw]) {
|
|
52168
|
+
const words2 = [kw];
|
|
52169
|
+
for (let j = k + 1; j < entries.length; j++) {
|
|
52170
|
+
const w = entries[j];
|
|
52171
|
+
if (typeof w === "string")
|
|
52172
|
+
words2.push(w);
|
|
52173
|
+
else if (isOp(w, "glob"))
|
|
52174
|
+
words2.push(w.pattern);
|
|
52175
|
+
else
|
|
52176
|
+
break;
|
|
52177
|
+
}
|
|
52178
|
+
const r = consumeWrapper(words2, 0);
|
|
52179
|
+
if ("error" in r) {
|
|
52180
|
+
fail(r.error);
|
|
52181
|
+
continue;
|
|
52182
|
+
}
|
|
52183
|
+
const n = Math.min(r.next, words2.length);
|
|
52184
|
+
for (let m = 1; m < n; m++)
|
|
52185
|
+
cur.push(entries[k + m]);
|
|
52186
|
+
k += n - 1;
|
|
52187
|
+
if (r.query)
|
|
52188
|
+
state = "args";
|
|
52189
|
+
continue;
|
|
52190
|
+
}
|
|
52191
|
+
state = "args";
|
|
52192
|
+
continue;
|
|
52193
|
+
case "args":
|
|
52194
|
+
if (kw === "}") {
|
|
52195
|
+
flush();
|
|
52196
|
+
state = "cmd";
|
|
52197
|
+
continue;
|
|
52198
|
+
}
|
|
52199
|
+
cur.push(e);
|
|
52200
|
+
continue;
|
|
52201
|
+
case "name":
|
|
52202
|
+
state = pending === "function" ? "cmd" : "afterName";
|
|
52203
|
+
continue;
|
|
52204
|
+
case "afterName":
|
|
52205
|
+
if (kw === "in") {
|
|
52206
|
+
if (pending === "case") {
|
|
52207
|
+
caseDepth++;
|
|
52208
|
+
state = "patterns";
|
|
52209
|
+
patternWord = false;
|
|
52210
|
+
} else
|
|
52211
|
+
state = "wordList";
|
|
52212
|
+
continue;
|
|
52213
|
+
}
|
|
52214
|
+
if (kw === "do" && pending === "for") {
|
|
52215
|
+
state = "cmd";
|
|
52216
|
+
continue;
|
|
52217
|
+
}
|
|
52218
|
+
state = "cmd";
|
|
52219
|
+
k--;
|
|
52220
|
+
continue;
|
|
52221
|
+
case "wordList":
|
|
52222
|
+
continue;
|
|
52223
|
+
// 字面量列表,不是命令
|
|
52224
|
+
case "patterns":
|
|
52225
|
+
if (kw === "esac") {
|
|
52226
|
+
caseDepth = Math.max(0, caseDepth - 1);
|
|
52227
|
+
state = "cmd";
|
|
52228
|
+
continue;
|
|
52229
|
+
}
|
|
52230
|
+
if (patternWord) {
|
|
52231
|
+
fail(`case pattern cannot be analyzed statically in: ${line}`);
|
|
52232
|
+
continue;
|
|
52233
|
+
}
|
|
52234
|
+
patternWord = true;
|
|
52235
|
+
continue;
|
|
52236
|
+
case "cond":
|
|
52237
|
+
if (kw === "]]")
|
|
52238
|
+
state = "cmd";
|
|
52239
|
+
continue;
|
|
52240
|
+
}
|
|
52241
|
+
}
|
|
52242
|
+
const op = e.op;
|
|
52243
|
+
if (state === "cond") {
|
|
52244
|
+
if (LIST_SEPARATORS.has(op) && op !== "&&" && op !== "||")
|
|
52245
|
+
state = "cmd";
|
|
51929
52246
|
continue;
|
|
51930
52247
|
}
|
|
52248
|
+
if ((state === "name" || state === "afterName") && !(state === "afterName" && op === "(")) {
|
|
52249
|
+
state = "cmd";
|
|
52250
|
+
k--;
|
|
52251
|
+
continue;
|
|
52252
|
+
}
|
|
52253
|
+
if (REDIRECT_OPS.has(op) || isAmpRedirect(entries, k)) {
|
|
52254
|
+
const skip = state === "wordList" || state === "patterns";
|
|
52255
|
+
const take2 = (idx) => {
|
|
52256
|
+
if (!skip)
|
|
52257
|
+
cur.push(entries[idx]);
|
|
52258
|
+
};
|
|
52259
|
+
take2(k);
|
|
52260
|
+
if (op === "&")
|
|
52261
|
+
take2(++k);
|
|
52262
|
+
while (k + 1 < entries.length && (isRedirectOp(entries[k + 1]) || isClobberPipe(entries, k + 1)))
|
|
52263
|
+
take2(++k);
|
|
52264
|
+
if (k + 1 < entries.length && typeof entries[k + 1] === "string")
|
|
52265
|
+
take2(++k);
|
|
52266
|
+
continue;
|
|
52267
|
+
}
|
|
52268
|
+
if (op === "(") {
|
|
52269
|
+
if (state === "afterName") {
|
|
52270
|
+
state = "wordList";
|
|
52271
|
+
parenList = true;
|
|
52272
|
+
continue;
|
|
52273
|
+
}
|
|
52274
|
+
if (state === "patterns") {
|
|
52275
|
+
patternWord = false;
|
|
52276
|
+
continue;
|
|
52277
|
+
}
|
|
52278
|
+
flush();
|
|
52279
|
+
state = "cmd";
|
|
52280
|
+
continue;
|
|
52281
|
+
}
|
|
52282
|
+
if (op === ")") {
|
|
52283
|
+
if (state === "wordList" && parenList) {
|
|
52284
|
+
parenList = false;
|
|
52285
|
+
state = "cmd";
|
|
52286
|
+
continue;
|
|
52287
|
+
}
|
|
52288
|
+
if (state === "patterns") {
|
|
52289
|
+
state = "cmd";
|
|
52290
|
+
continue;
|
|
52291
|
+
}
|
|
52292
|
+
flush();
|
|
52293
|
+
state = "cmd";
|
|
52294
|
+
continue;
|
|
52295
|
+
}
|
|
52296
|
+
if (op === "|" && state === "patterns") {
|
|
52297
|
+
patternWord = false;
|
|
52298
|
+
continue;
|
|
52299
|
+
}
|
|
52300
|
+
if (LIST_SEPARATORS.has(op) && !isClobberPipe(entries, k)) {
|
|
52301
|
+
flush();
|
|
52302
|
+
if (op === ";;" && caseDepth > 0) {
|
|
52303
|
+
state = "patterns";
|
|
52304
|
+
patternWord = false;
|
|
52305
|
+
} else
|
|
52306
|
+
state = "cmd";
|
|
52307
|
+
parenList = false;
|
|
52308
|
+
continue;
|
|
52309
|
+
}
|
|
52310
|
+
if (state === "wordList" || state === "patterns")
|
|
52311
|
+
continue;
|
|
51931
52312
|
cur.push(e);
|
|
51932
52313
|
}
|
|
51933
|
-
if (
|
|
51934
|
-
|
|
51935
|
-
|
|
51936
|
-
|
|
51937
|
-
|
|
51938
|
-
out.push(r);
|
|
52314
|
+
if (failed)
|
|
52315
|
+
continue;
|
|
52316
|
+
if (state === "cond") {
|
|
52317
|
+
fail(`unterminated [[ in: ${line}`);
|
|
52318
|
+
continue;
|
|
51939
52319
|
}
|
|
52320
|
+
flush();
|
|
51940
52321
|
}
|
|
51941
52322
|
return out;
|
|
51942
52323
|
}
|
|
@@ -51977,53 +52358,62 @@ var require_Bash = __commonJS({
|
|
|
51977
52358
|
i++;
|
|
51978
52359
|
continue;
|
|
51979
52360
|
}
|
|
51980
|
-
|
|
51981
|
-
if (!spec)
|
|
52361
|
+
if (!WRAPPERS[t])
|
|
51982
52362
|
break;
|
|
51983
|
-
|
|
51984
|
-
|
|
51985
|
-
|
|
51986
|
-
|
|
51987
|
-
|
|
51988
|
-
|
|
51989
|
-
}
|
|
51990
|
-
i++;
|
|
51991
|
-
while (i < tokens.length && tokens[i].startsWith("-")) {
|
|
51992
|
-
const opt = tokens[i];
|
|
51993
|
-
if (opt === "--") {
|
|
51994
|
-
i++;
|
|
51995
|
-
break;
|
|
51996
|
-
}
|
|
51997
|
-
const eq2 = opt.startsWith("--") ? opt.indexOf("=") : -1;
|
|
51998
|
-
const name = eq2 > 0 ? opt.slice(0, eq2) : opt;
|
|
51999
|
-
if (eq2 > 0 && (spec.flags.has(name) || spec.valueFlags.has(name))) {
|
|
52000
|
-
i++;
|
|
52001
|
-
continue;
|
|
52002
|
-
}
|
|
52003
|
-
if (spec.flags.has(opt)) {
|
|
52004
|
-
i++;
|
|
52005
|
-
continue;
|
|
52006
|
-
}
|
|
52007
|
-
if (spec.valueFlags.has(opt)) {
|
|
52008
|
-
i += 2;
|
|
52009
|
-
continue;
|
|
52010
|
-
}
|
|
52011
|
-
if (/^-[A-Za-z]/.test(opt) && opt.length > 2 && spec.valueFlags.has(opt.slice(0, 2))) {
|
|
52012
|
-
i++;
|
|
52013
|
-
continue;
|
|
52014
|
-
}
|
|
52015
|
-
if (t === "nice" && /^-\d+$/.test(opt)) {
|
|
52016
|
-
i++;
|
|
52017
|
-
continue;
|
|
52018
|
-
}
|
|
52019
|
-
return { error: `option '${opt}' of wrapper '${t}' cannot be analyzed statically` };
|
|
52020
|
-
}
|
|
52021
|
-
i += spec.positional ?? 0;
|
|
52363
|
+
const r = consumeWrapper(tokens, i);
|
|
52364
|
+
if ("error" in r)
|
|
52365
|
+
return r;
|
|
52366
|
+
if (r.query)
|
|
52367
|
+
return { baseCmd: "command", args: tokens.slice(i + 1) };
|
|
52368
|
+
i = r.next;
|
|
52022
52369
|
}
|
|
52023
52370
|
if (i >= tokens.length)
|
|
52024
52371
|
return { baseCmd: tokens[tokens.length - 1], args: [] };
|
|
52025
52372
|
return { baseCmd: tokens[i], args: tokens.slice(i + 1) };
|
|
52026
52373
|
}
|
|
52374
|
+
function consumeWrapper(tokens, i) {
|
|
52375
|
+
const t = tokens[i];
|
|
52376
|
+
const spec = WRAPPERS[t];
|
|
52377
|
+
if (t === "command") {
|
|
52378
|
+
const rest2 = tokens.slice(i + 1);
|
|
52379
|
+
const optEnd = rest2.findIndex((x) => !x.startsWith("-") || x === "--");
|
|
52380
|
+
const opts = optEnd < 0 ? rest2 : rest2.slice(0, optEnd);
|
|
52381
|
+
if (opts.some((o) => /^-[pvV]*[vV][pvV]*$/.test(o)))
|
|
52382
|
+
return { next: tokens.length, query: true };
|
|
52383
|
+
}
|
|
52384
|
+
i++;
|
|
52385
|
+
while (i < tokens.length && tokens[i].startsWith("-")) {
|
|
52386
|
+
const opt = tokens[i];
|
|
52387
|
+
if (opt === "--") {
|
|
52388
|
+
i++;
|
|
52389
|
+
break;
|
|
52390
|
+
}
|
|
52391
|
+
const eq2 = opt.startsWith("--") ? opt.indexOf("=") : -1;
|
|
52392
|
+
const name = eq2 > 0 ? opt.slice(0, eq2) : opt;
|
|
52393
|
+
if (eq2 > 0 && (spec.flags.has(name) || spec.valueFlags.has(name))) {
|
|
52394
|
+
i++;
|
|
52395
|
+
continue;
|
|
52396
|
+
}
|
|
52397
|
+
if (spec.flags.has(opt)) {
|
|
52398
|
+
i++;
|
|
52399
|
+
continue;
|
|
52400
|
+
}
|
|
52401
|
+
if (spec.valueFlags.has(opt)) {
|
|
52402
|
+
i += 2;
|
|
52403
|
+
continue;
|
|
52404
|
+
}
|
|
52405
|
+
if (/^-[A-Za-z]/.test(opt) && opt.length > 2 && spec.valueFlags.has(opt.slice(0, 2))) {
|
|
52406
|
+
i++;
|
|
52407
|
+
continue;
|
|
52408
|
+
}
|
|
52409
|
+
if (t === "nice" && /^-\d+$/.test(opt)) {
|
|
52410
|
+
i++;
|
|
52411
|
+
continue;
|
|
52412
|
+
}
|
|
52413
|
+
return { error: `option '${opt}' of wrapper '${t}' cannot be analyzed statically` };
|
|
52414
|
+
}
|
|
52415
|
+
return { next: i + (spec.positional ?? 0) };
|
|
52416
|
+
}
|
|
52027
52417
|
function resolveCdTarget(args) {
|
|
52028
52418
|
const positional = [];
|
|
52029
52419
|
let optionsDone = false;
|
|
@@ -64769,7 +65159,7 @@ var init_iteratee = __esm({
|
|
|
64769
65159
|
});
|
|
64770
65160
|
|
|
64771
65161
|
// ../atomix-core/node_modules/lodash-es/join.js
|
|
64772
|
-
function
|
|
65162
|
+
function join2(array, separator) {
|
|
64773
65163
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
64774
65164
|
}
|
|
64775
65165
|
var arrayProto2, nativeJoin, join_default;
|
|
@@ -64777,7 +65167,7 @@ var init_join = __esm({
|
|
|
64777
65167
|
"../atomix-core/node_modules/lodash-es/join.js"() {
|
|
64778
65168
|
arrayProto2 = Array.prototype;
|
|
64779
65169
|
nativeJoin = arrayProto2.join;
|
|
64780
|
-
join_default =
|
|
65170
|
+
join_default = join2;
|
|
64781
65171
|
}
|
|
64782
65172
|
});
|
|
64783
65173
|
|
|
@@ -74274,15 +74664,30 @@ var require_skillRegistry = __commonJS({
|
|
|
74274
74664
|
"../atomix-core/dist/services/skill/skillRegistry.js"(exports2) {
|
|
74275
74665
|
"use strict";
|
|
74276
74666
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
74667
|
+
exports2.skillRegistryKey = skillRegistryKey;
|
|
74277
74668
|
exports2.initializeSkillRegistry = initializeSkillRegistry;
|
|
74278
74669
|
exports2.getSkillRegistry = getSkillRegistry;
|
|
74279
74670
|
exports2.findSkill = findSkill;
|
|
74280
74671
|
exports2.getSkillsInfo = getSkillsInfo;
|
|
74281
74672
|
exports2.getSkillsSummary = getSkillsSummary;
|
|
74673
|
+
exports2.invalidateSkillCache = invalidateSkillCache;
|
|
74282
74674
|
exports2.clearSkillRegistry = clearSkillRegistry;
|
|
74283
74675
|
var skillLoader_1 = require_skillLoader();
|
|
74284
74676
|
var log_1 = require_log();
|
|
74285
|
-
var
|
|
74677
|
+
var EngineContext_1 = require_EngineContext();
|
|
74678
|
+
var registries = /* @__PURE__ */ new Map();
|
|
74679
|
+
var lastKey = null;
|
|
74680
|
+
function skillRegistryKey(workingDir, extraDirs) {
|
|
74681
|
+
return workingDir + "\0" + (extraDirs ?? []).map((e) => `${e.locate}:${e.dir}`).join("\0");
|
|
74682
|
+
}
|
|
74683
|
+
function viewFromContext() {
|
|
74684
|
+
const store = (0, EngineContext_1.getEngineStore)();
|
|
74685
|
+
const cfg = store?.coreConfig;
|
|
74686
|
+
if (!store || !cfg)
|
|
74687
|
+
return null;
|
|
74688
|
+
const workingDir = cfg.agentDataDir || cfg.workingDir || store.agentDataDir || store.workingDir || process.cwd();
|
|
74689
|
+
return { workingDir, extraDirs: cfg.skillsExtraDirs, disabledNames: cfg.skillsDisabledNames };
|
|
74690
|
+
}
|
|
74286
74691
|
function initializeSkillRegistry(workingDir, extraDirs) {
|
|
74287
74692
|
const registry = /* @__PURE__ */ new Map();
|
|
74288
74693
|
const skills = (0, skillLoader_1.loadAllSkills)(workingDir, extraDirs);
|
|
@@ -74294,21 +74699,44 @@ var require_skillRegistry = __commonJS({
|
|
|
74294
74699
|
}
|
|
74295
74700
|
registry.set(name, skill);
|
|
74296
74701
|
}
|
|
74297
|
-
|
|
74702
|
+
const key = skillRegistryKey(workingDir, extraDirs);
|
|
74703
|
+
registries.set(key, registry);
|
|
74704
|
+
lastKey = key;
|
|
74298
74705
|
return registry;
|
|
74299
74706
|
}
|
|
74300
|
-
function
|
|
74301
|
-
|
|
74707
|
+
function resolve9(view) {
|
|
74708
|
+
const v = view ?? viewFromContext();
|
|
74709
|
+
if (v) {
|
|
74710
|
+
const key = skillRegistryKey(v.workingDir, v.extraDirs);
|
|
74711
|
+
let registry = registries.get(key);
|
|
74712
|
+
if (!registry) {
|
|
74713
|
+
registry = initializeSkillRegistry(v.workingDir, v.extraDirs);
|
|
74714
|
+
}
|
|
74715
|
+
return { registry, disabled: new Set(v.disabledNames ?? []) };
|
|
74716
|
+
}
|
|
74717
|
+
if (!lastKey) {
|
|
74302
74718
|
throw new Error("Skill registry not initialized. Call initializeSkillRegistry() first.");
|
|
74303
74719
|
}
|
|
74304
|
-
return
|
|
74305
|
-
}
|
|
74306
|
-
function
|
|
74307
|
-
const registry =
|
|
74720
|
+
return { registry: registries.get(lastKey), disabled: /* @__PURE__ */ new Set() };
|
|
74721
|
+
}
|
|
74722
|
+
function getSkillRegistry(view) {
|
|
74723
|
+
const { registry, disabled } = resolve9(view);
|
|
74724
|
+
if (disabled.size === 0)
|
|
74725
|
+
return registry;
|
|
74726
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
74727
|
+
for (const [name, skill] of registry)
|
|
74728
|
+
if (!disabled.has(name))
|
|
74729
|
+
filtered.set(name, skill);
|
|
74730
|
+
return filtered;
|
|
74731
|
+
}
|
|
74732
|
+
function findSkill(name, view) {
|
|
74733
|
+
const { registry, disabled } = resolve9(view);
|
|
74734
|
+
if (disabled.has(name))
|
|
74735
|
+
return void 0;
|
|
74308
74736
|
return registry.get(name);
|
|
74309
74737
|
}
|
|
74310
|
-
function getSkillsInfo() {
|
|
74311
|
-
const registry = getSkillRegistry();
|
|
74738
|
+
function getSkillsInfo(view, opts) {
|
|
74739
|
+
const registry = opts?.includeDisabled ? resolve9(view).registry : getSkillRegistry(view);
|
|
74312
74740
|
const skillsInfo = [];
|
|
74313
74741
|
for (const [name, skill] of registry.entries()) {
|
|
74314
74742
|
skillsInfo.push({
|
|
@@ -74320,8 +74748,8 @@ var require_skillRegistry = __commonJS({
|
|
|
74320
74748
|
}
|
|
74321
74749
|
return skillsInfo;
|
|
74322
74750
|
}
|
|
74323
|
-
function getSkillsSummary() {
|
|
74324
|
-
const registry = getSkillRegistry();
|
|
74751
|
+
function getSkillsSummary(view) {
|
|
74752
|
+
const registry = getSkillRegistry(view);
|
|
74325
74753
|
if (registry.size === 0) {
|
|
74326
74754
|
return "";
|
|
74327
74755
|
}
|
|
@@ -74335,10 +74763,14 @@ var require_skillRegistry = __commonJS({
|
|
|
74335
74763
|
lines.push("When a task requires specific domain knowledge or workflow, use the Skill tool to activate the relevant skill.");
|
|
74336
74764
|
return lines.join("\n");
|
|
74337
74765
|
}
|
|
74338
|
-
function
|
|
74339
|
-
globalRegistry = null;
|
|
74766
|
+
function invalidateSkillCache() {
|
|
74340
74767
|
skillLoader_1.loadAllSkills.cache.clear?.();
|
|
74341
74768
|
}
|
|
74769
|
+
function clearSkillRegistry() {
|
|
74770
|
+
registries.clear();
|
|
74771
|
+
lastKey = null;
|
|
74772
|
+
invalidateSkillCache();
|
|
74773
|
+
}
|
|
74342
74774
|
}
|
|
74343
74775
|
});
|
|
74344
74776
|
|
|
@@ -74710,13 +75142,15 @@ var require_cacheLLM = __commonJS({
|
|
|
74710
75142
|
/**
|
|
74711
75143
|
* 生成缓存键 - 基于消息内容生成简单hash
|
|
74712
75144
|
*/
|
|
74713
|
-
generateKey(messages, systemPrompt, modelName, enableThinking = false) {
|
|
75145
|
+
generateKey(messages, systemPrompt, modelName, enableThinking = false, temperature) {
|
|
74714
75146
|
const normalizedSystemPrompt = Array.isArray(systemPrompt) && systemPrompt.length > 0 && typeof systemPrompt[0] === "object" && "type" in systemPrompt[0] ? systemPrompt.map((item) => item.text) : systemPrompt;
|
|
74715
75147
|
const content = JSON.stringify({
|
|
74716
75148
|
messages: messages.map((msg) => msg.message.content),
|
|
74717
75149
|
systemPrompt: normalizedSystemPrompt,
|
|
74718
75150
|
modelName,
|
|
74719
|
-
enableThinking
|
|
75151
|
+
enableThinking,
|
|
75152
|
+
temperature: temperature ?? null
|
|
75153
|
+
// 不同温度不共享缓存(model-temperature-v1)
|
|
74720
75154
|
});
|
|
74721
75155
|
return crypto_1.default.createHash("md5").update(content).digest("hex");
|
|
74722
75156
|
}
|
|
@@ -74746,8 +75180,8 @@ var require_cacheLLM = __commonJS({
|
|
|
74746
75180
|
/**
|
|
74747
75181
|
* 获取缓存
|
|
74748
75182
|
*/
|
|
74749
|
-
get(messages, systemPrompt, modelName, enableThinking = false) {
|
|
74750
|
-
const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
|
|
75183
|
+
get(messages, systemPrompt, modelName, enableThinking = false, temperature) {
|
|
75184
|
+
const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
|
|
74751
75185
|
const entries = this.readCacheFile();
|
|
74752
75186
|
const entry = entries.find((e) => e.key === key);
|
|
74753
75187
|
return entry ? entry.response : null;
|
|
@@ -74755,8 +75189,8 @@ var require_cacheLLM = __commonJS({
|
|
|
74755
75189
|
/**
|
|
74756
75190
|
* 设置缓存
|
|
74757
75191
|
*/
|
|
74758
|
-
set(messages, systemPrompt, modelName, response, enableThinking = false) {
|
|
74759
|
-
const key = this.generateKey(messages, systemPrompt, modelName, enableThinking);
|
|
75192
|
+
set(messages, systemPrompt, modelName, response, enableThinking = false, temperature) {
|
|
75193
|
+
const key = this.generateKey(messages, systemPrompt, modelName, enableThinking, temperature);
|
|
74760
75194
|
let entries = this.readCacheFile();
|
|
74761
75195
|
entries = entries.filter((e) => e.key !== key);
|
|
74762
75196
|
entries.unshift({
|
|
@@ -74805,8 +75239,8 @@ var require_cache = __commonJS({
|
|
|
74805
75239
|
var log_1 = require_log();
|
|
74806
75240
|
var CACHE_STREAM_CHUNK_SIZE = 20;
|
|
74807
75241
|
var CACHE_STREAM_DELAY = 100;
|
|
74808
|
-
async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal) {
|
|
74809
|
-
const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking);
|
|
75242
|
+
async function tryGetCachedResponse(messages, systemPromptContent, modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature) {
|
|
75243
|
+
const cachedResponse = cacheLLM_1.llmCache.get(messages, systemPromptContent, modelName, enableThinking, temperature);
|
|
74810
75244
|
if (!cachedResponse) {
|
|
74811
75245
|
return null;
|
|
74812
75246
|
}
|
|
@@ -74879,8 +75313,8 @@ var require_cache = __commonJS({
|
|
|
74879
75313
|
function calcSimulatedDelay(contentLength, maxDelay) {
|
|
74880
75314
|
return Math.min(Math.ceil(contentLength / CACHE_STREAM_CHUNK_SIZE) * CACHE_STREAM_DELAY, maxDelay);
|
|
74881
75315
|
}
|
|
74882
|
-
function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false) {
|
|
74883
|
-
cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking);
|
|
75316
|
+
function setCachedResponse(messages, systemPromptContent, modelName, response, enableThinking = false, temperature) {
|
|
75317
|
+
cacheLLM_1.llmCache.set(messages, systemPromptContent, modelName, response, enableThinking, temperature);
|
|
74884
75318
|
}
|
|
74885
75319
|
function getCacheSize() {
|
|
74886
75320
|
return cacheLLM_1.llmCache.size();
|
|
@@ -88147,7 +88581,7 @@ var require_openai2 = __commonJS({
|
|
|
88147
88581
|
}
|
|
88148
88582
|
};
|
|
88149
88583
|
}
|
|
88150
|
-
async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
|
|
88584
|
+
async function queryOpenAI(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
|
|
88151
88585
|
const start = Date.now();
|
|
88152
88586
|
let baseURL = modelProfile.baseURL || "https://api.openai.com/v1";
|
|
88153
88587
|
const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, baseURL);
|
|
@@ -88172,6 +88606,7 @@ var require_openai2 = __commonJS({
|
|
|
88172
88606
|
stream: true,
|
|
88173
88607
|
...openaiTools && { tools: openaiTools },
|
|
88174
88608
|
...(0, adapter_1.useMaxCompletionTokens)(modelProfile.modelName) ? { max_completion_tokens: modelProfile.maxTokens || 8e3 } : { max_tokens: modelProfile.maxTokens || 8e3 },
|
|
88609
|
+
...temperature !== void 0 && { temperature },
|
|
88175
88610
|
// thinking 参数按 provider profile 统一构造(openai/openrouter/qwen/compat 等)
|
|
88176
88611
|
...(0, providerProfile_1.buildThinkingParams)(modelProfile, enableThinking)
|
|
88177
88612
|
};
|
|
@@ -99381,7 +99816,7 @@ var require_anthropic = __commonJS({
|
|
|
99381
99816
|
usage: usage2
|
|
99382
99817
|
};
|
|
99383
99818
|
}
|
|
99384
|
-
async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents) {
|
|
99819
|
+
async function queryAnthropic(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents) {
|
|
99385
99820
|
const start = Date.now();
|
|
99386
99821
|
const rawBaseURL = modelProfile.baseURL || "https://api.anthropic.com";
|
|
99387
99822
|
const providerEndpoints = (0, providerEndpoint_1.getProviderEndpoints)(modelProfile.provider, rawBaseURL);
|
|
@@ -99402,7 +99837,7 @@ var require_anthropic = __commonJS({
|
|
|
99402
99837
|
messages: anthropicMessages,
|
|
99403
99838
|
system: systemPromptContent,
|
|
99404
99839
|
max_tokens: modelProfile.maxTokens,
|
|
99405
|
-
temperature
|
|
99840
|
+
...temperature !== void 0 && { temperature },
|
|
99406
99841
|
stream: true,
|
|
99407
99842
|
...anthropicTools && { tools: anthropicTools }
|
|
99408
99843
|
};
|
|
@@ -99483,7 +99918,8 @@ var require_queryLLM = __commonJS({
|
|
|
99483
99918
|
async function queryLLM(messages, systemPromptContent, signal, tools, modelPointer = "main", disableChunkEvents = false, suppressErrorEvent = false) {
|
|
99484
99919
|
const modelProfile = (0, ModelManager_1.getModelManager)().getModel(modelPointer);
|
|
99485
99920
|
if (!modelProfile) {
|
|
99486
|
-
|
|
99921
|
+
const { id, overridden } = (0, ModelManager_1.getModelManager)().resolvePointer(modelPointer);
|
|
99922
|
+
throw new Error(id ? `\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer} \u2192 ${id} \u4E0D\u5728\u6A21\u578B\u914D\u7F6E\u4E2D${overridden ? "(\u4F1A\u8BDD\u7EA7\u8986\u76D6,\u6765\u81EA harness)" : ""}` : `\u89E3\u6790\u6A21\u578B\u5931\u8D25: ${modelPointer}`);
|
|
99487
99923
|
}
|
|
99488
99924
|
try {
|
|
99489
99925
|
const coreConfig = (0, ConfManager_1.getConfManager)().getCoreConfig();
|
|
@@ -99491,30 +99927,31 @@ var require_queryLLM = __commonJS({
|
|
|
99491
99927
|
const shouldStream = coreConfig?.stream !== false;
|
|
99492
99928
|
const enableThinking = modelPointer !== "quick" && coreConfig?.thinking === true;
|
|
99493
99929
|
const emitChunkEvents = !disableChunkEvents && shouldStream !== false;
|
|
99930
|
+
const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
|
|
99931
|
+
const temperature = (0, ModelManager_1.getModelManager)().resolveTemperature(modelPointer, modelProfile, { adapter: adapt, enableThinking });
|
|
99494
99932
|
if (shouldUseCache) {
|
|
99495
|
-
const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal);
|
|
99933
|
+
const cachedResponse = await (0, cache_1.tryGetCachedResponse)(messages, systemPromptContent, modelProfile.modelName, shouldStream, enableThinking, emitChunkEvents, signal, temperature);
|
|
99496
99934
|
if (cachedResponse) {
|
|
99497
99935
|
(0, logLLM_1.logLLMRequest)({ cached: true, model: modelProfile.modelName, messages });
|
|
99498
99936
|
(0, logLLM_1.logLLMResponse)(cachedResponse);
|
|
99499
99937
|
return cachedResponse;
|
|
99500
99938
|
}
|
|
99501
99939
|
}
|
|
99502
|
-
const adapt = modelProfile.adapt || (0, adapter_1.resolveAdapter)(modelProfile.provider, modelProfile.modelName);
|
|
99503
99940
|
let result2;
|
|
99504
99941
|
switch (adapt) {
|
|
99505
99942
|
case "anthropic":
|
|
99506
|
-
result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
|
|
99943
|
+
result2 = await (0, anthropic_1.queryAnthropic)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
|
|
99507
99944
|
break;
|
|
99508
99945
|
case "openai":
|
|
99509
99946
|
default:
|
|
99510
|
-
result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, emitChunkEvents);
|
|
99947
|
+
result2 = await (0, openai_1.queryOpenAI)(messages, systemPromptContent, tools, signal, modelProfile, enableThinking, temperature, emitChunkEvents);
|
|
99511
99948
|
break;
|
|
99512
99949
|
}
|
|
99513
99950
|
(0, logLLM_1.logLLMResponse)(result2);
|
|
99514
99951
|
if (shouldUseCache && !signal.aborted) {
|
|
99515
99952
|
const hasContent = result2.message.content.some((block) => block.type === "text" && block.text.trim().length > 0 || block.type === "tool_use");
|
|
99516
99953
|
if (hasContent) {
|
|
99517
|
-
(0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking);
|
|
99954
|
+
(0, cache_1.setCachedResponse)(messages, systemPromptContent, modelProfile.modelName, result2, enableThinking, temperature);
|
|
99518
99955
|
(0, log_1.logDebug)(`LLM\u54CD\u5E94\u5DF2\u7F13\u5B58\uFF0C\u5F53\u524D\u7F13\u5B58\u6761\u76EE\u6570: ${(0, cache_1.getCacheSize)()}`);
|
|
99519
99956
|
}
|
|
99520
99957
|
}
|
|
@@ -135411,7 +135848,7 @@ var require_session = __commonJS({
|
|
|
135411
135848
|
exports2.parseSessionIdFromHistoryPath = parseSessionIdFromHistoryPath;
|
|
135412
135849
|
exports2.generateSessionId = generateSessionId;
|
|
135413
135850
|
exports2.initializeSessionId = initializeSessionId;
|
|
135414
|
-
exports2.validateSessionId =
|
|
135851
|
+
exports2.validateSessionId = validateSessionId2;
|
|
135415
135852
|
exports2.generateHistoryPath = generateHistoryPath;
|
|
135416
135853
|
var crypto3 = __importStar(__require("crypto"));
|
|
135417
135854
|
var path15 = __importStar(__require("path"));
|
|
@@ -135446,7 +135883,7 @@ var require_session = __commonJS({
|
|
|
135446
135883
|
}
|
|
135447
135884
|
return generateSessionId();
|
|
135448
135885
|
}
|
|
135449
|
-
function
|
|
135886
|
+
function validateSessionId2(sessionId) {
|
|
135450
135887
|
const shortIdRegex = /^[0-9a-f]{8}$/i;
|
|
135451
135888
|
return shortIdRegex.test(sessionId);
|
|
135452
135889
|
}
|
|
@@ -136392,6 +136829,12 @@ var require_SemaEngine = __commonJS({
|
|
|
136392
136829
|
cfg.memoryFiles = partial2.memoryFiles ?? null;
|
|
136393
136830
|
if ("personaFile" in partial2)
|
|
136394
136831
|
cfg.personaFile = partial2.personaFile ?? null;
|
|
136832
|
+
if ("modelOverrides" in partial2)
|
|
136833
|
+
cfg.modelOverrides = partial2.modelOverrides ?? null;
|
|
136834
|
+
if ("temperatureOverrides" in partial2)
|
|
136835
|
+
cfg.temperatureOverrides = partial2.temperatureOverrides ?? null;
|
|
136836
|
+
if ("thinking" in partial2)
|
|
136837
|
+
cfg.thinking = partial2.thinking === true;
|
|
136395
136838
|
}
|
|
136396
136839
|
/**
|
|
136397
136840
|
* 当前 session 的 coreConfig 只读快照(= initialConfig,含运行时 mutation 结果)。
|
|
@@ -136429,7 +136872,7 @@ var require_SemaEngine = __commonJS({
|
|
|
136429
136872
|
*/
|
|
136430
136873
|
async initializePlugins(workingDir, extraDirs) {
|
|
136431
136874
|
try {
|
|
136432
|
-
(0, skillRegistry_1.
|
|
136875
|
+
(0, skillRegistry_1.invalidateSkillCache)();
|
|
136433
136876
|
(0, skillRegistry_1.initializeSkillRegistry)(workingDir || process.cwd(), extraDirs);
|
|
136434
136877
|
(0, log_1.logDebug)("Skill registry initialized successfully");
|
|
136435
136878
|
} catch (error) {
|
|
@@ -136609,6 +137052,11 @@ var require_SemaSession = __commonJS({
|
|
|
136609
137052
|
this.engine = new SemaEngine_1.SemaEngine(instanceId, resolvedConfig, this.instanceMCPManager, kernel);
|
|
136610
137053
|
if (resolvedConfig.skipMCPInit) {
|
|
136611
137054
|
this.configPromise = (0, ConfManager_1.getConfManager)().registerProjectConfig(resolvedConfig);
|
|
137055
|
+
} else if (resolvedConfig.multiSession) {
|
|
137056
|
+
(0, log_1.setLogLevel)(resolvedConfig.logLevel || "info");
|
|
137057
|
+
this.configPromise = (0, ConfManager_1.getConfManager)().registerProjectConfig(resolvedConfig).then(async () => {
|
|
137058
|
+
await this.instanceMCPManager.init();
|
|
137059
|
+
});
|
|
136612
137060
|
} else {
|
|
136613
137061
|
this.configPromise = (0, ConfManager_1.getConfManager)().setCoreConfig(resolvedConfig);
|
|
136614
137062
|
this.configPromise = this.configPromise.then(async () => {
|
|
@@ -136675,26 +137123,34 @@ var require_SemaSession = __commonJS({
|
|
|
136675
137123
|
return this.engine.coreConfig;
|
|
136676
137124
|
}
|
|
136677
137125
|
// ==================== Skill 热重载(session 触发)====================
|
|
137126
|
+
/** 本 session 的 skill 视图(同 agentsView:显式上下文,ALS 外可读)。 */
|
|
137127
|
+
skillsView() {
|
|
137128
|
+
const config = this.engine["initialConfig"];
|
|
137129
|
+
return {
|
|
137130
|
+
workingDir: config.agentDataDir || config.workingDir || (0, cwd_1.getCwd)(),
|
|
137131
|
+
extraDirs: config.skillsExtraDirs,
|
|
137132
|
+
disabledNames: config.skillsDisabledNames ?? []
|
|
137133
|
+
};
|
|
137134
|
+
}
|
|
136678
137135
|
/**
|
|
136679
137136
|
* 热重载 Skill 注册表(不重建 session/历史)。
|
|
136680
137137
|
*
|
|
136681
|
-
*
|
|
136682
|
-
*
|
|
136683
|
-
* session。这是 D6「project 层 vs 全局 registry」矛盾的具象,Stage A 保持现状行为
|
|
136684
|
-
* (全局重扫),Stage D 做 global/project 分层 + mtime 缓存时彻底解决。
|
|
137138
|
+
* 注册表按供给键(workingDir + skillsExtraDirs)隔离,只重建本 session 键;屏蔽名单写入
|
|
137139
|
+
* initialConfig.skillsDisabledNames 由读取端过滤(session-api-v1 §3.1,语义同 reloadAgents)。
|
|
136685
137140
|
*
|
|
136686
|
-
* @param disabledNames
|
|
137141
|
+
* @param disabledNames 按名屏蔽的 skill 集合;undefined = 只重扫,屏蔽名单不变。
|
|
136687
137142
|
*/
|
|
136688
137143
|
reloadSkills(disabledNames) {
|
|
136689
137144
|
const config = this.engine["initialConfig"];
|
|
136690
|
-
|
|
136691
|
-
|
|
136692
|
-
const
|
|
136693
|
-
|
|
136694
|
-
|
|
136695
|
-
|
|
136696
|
-
|
|
136697
|
-
|
|
137145
|
+
if (disabledNames !== void 0)
|
|
137146
|
+
config.skillsDisabledNames = [...disabledNames];
|
|
137147
|
+
const view = this.skillsView();
|
|
137148
|
+
(0, skillRegistry_1.invalidateSkillCache)();
|
|
137149
|
+
(0, skillRegistry_1.initializeSkillRegistry)(view.workingDir, view.extraDirs);
|
|
137150
|
+
}
|
|
137151
|
+
/** 本 session 视角的 skills 列表;includeDisabled 取供给全集(harness whitelist 求补用)。 */
|
|
137152
|
+
getSkillsInfo(opts) {
|
|
137153
|
+
return (0, skillRegistry_1.getSkillsInfo)(this.skillsView(), opts);
|
|
136698
137154
|
}
|
|
136699
137155
|
// ==================== Agents(session 视角,显式上下文)====================
|
|
136700
137156
|
/**
|
|
@@ -137237,7 +137693,7 @@ var require_AtomixCore = __commonJS({
|
|
|
137237
137693
|
exports2.AtomixCore = void 0;
|
|
137238
137694
|
var SemaKernel_1 = require_SemaKernel();
|
|
137239
137695
|
var ConfManager_1 = require_ConfManager();
|
|
137240
|
-
var
|
|
137696
|
+
var AtomixCore4 = class {
|
|
137241
137697
|
constructor(config) {
|
|
137242
137698
|
this.setWorkingDir = (newDir) => this.session.setWorkingDir(newDir);
|
|
137243
137699
|
this.clearWorkingDir = () => this.session.clearWorkingDir();
|
|
@@ -137263,6 +137719,10 @@ var require_AtomixCore = __commonJS({
|
|
|
137263
137719
|
this.switchModel = (ModelName) => this.kernel.models.switchCurrentModel(ModelName);
|
|
137264
137720
|
this.applyTaskModel = (config2) => this.kernel.models.applyTaskModelConfig(config2);
|
|
137265
137721
|
this.getModelData = () => this.kernel.models.getModelData();
|
|
137722
|
+
this.getModelNames = () => this.kernel.models.getModelNames();
|
|
137723
|
+
this.getModelPointers = () => this.kernel.models.getModelPointers();
|
|
137724
|
+
this.getModelProfiles = () => this.kernel.models.getModelProfiles();
|
|
137725
|
+
this.updateModel = (name, patch) => this.kernel.models.updateModelProfile(name, patch);
|
|
137266
137726
|
this.updateCoreConfByKey = (key, value) => {
|
|
137267
137727
|
if (key === "customRules") {
|
|
137268
137728
|
this.session.updateAssemblyConfig({ customRules: value ?? "" });
|
|
@@ -137287,7 +137747,7 @@ var require_AtomixCore = __commonJS({
|
|
|
137287
137747
|
this.getMCPServerConfigs = () => this.session.getMCPServerConfigs();
|
|
137288
137748
|
this.connectMCPServer = (name) => this.session.connectMCPServer(name);
|
|
137289
137749
|
this.updateMCPUseTools = (name, toolNames) => this.session.updateMCPUseTools(name, toolNames);
|
|
137290
|
-
this.getSkillsInfo = () => this.
|
|
137750
|
+
this.getSkillsInfo = (opts) => this.session.getSkillsInfo(opts);
|
|
137291
137751
|
this.getAgentsInfo = () => this.session.getAgentsInfo();
|
|
137292
137752
|
this.addAgentConf = (agentConf) => this.session.addAgentConf(agentConf);
|
|
137293
137753
|
this.getCustomCommands = () => this.session.getCustomCommands();
|
|
@@ -137311,7 +137771,7 @@ var require_AtomixCore = __commonJS({
|
|
|
137311
137771
|
return this.session.workbenchService;
|
|
137312
137772
|
}
|
|
137313
137773
|
};
|
|
137314
|
-
exports2.AtomixCore =
|
|
137774
|
+
exports2.AtomixCore = AtomixCore4;
|
|
137315
137775
|
}
|
|
137316
137776
|
});
|
|
137317
137777
|
|
|
@@ -143886,7 +144346,7 @@ var require_dist4 = __commonJS({
|
|
|
143886
144346
|
"../atomix-core/dist/index.js"(exports2) {
|
|
143887
144347
|
"use strict";
|
|
143888
144348
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
143889
|
-
exports2.fetchModels = exports2.testApiConnection = exports2.inferVision = exports2.modelHasVision = exports2.ImageLoadError = exports2.preprocessImage = exports2.imageBlockToPlaceholder = exports2.loadImagesAsBlocks = exports2.loadImageAsBlock = exports2.HOOK_EVENTS = exports2.executeHooks = exports2.HookManager = exports2.projectPathToDirName = exports2.getHistoryFilePath = exports2.getProjectHistoryDir = exports2.getHistoryDir = exports2.setModelConfigPathOverride = exports2.setLogLevel = exports2.getModelManager = exports2.SemaSession = exports2.SemaKernel = exports2.getAgentOwnedFilePaths = exports2.renderContextReminder = exports2.readContextSections = exports2.normalizeMemoryFiles = exports2.resolveContextFiles = exports2.isReadOnlyBashCommand = exports2.DEFAULT_PERMISSION_MODE = exports2.PERMISSION_MODES = exports2.assemblePromptSections = exports2.PROMPT_SECTION_CATALOG = exports2.AtomixCore = void 0;
|
|
144349
|
+
exports2.fetchModels = exports2.testApiConnection = exports2.inferVision = exports2.modelHasVision = exports2.ImageLoadError = exports2.preprocessImage = exports2.imageBlockToPlaceholder = exports2.loadImagesAsBlocks = exports2.loadImageAsBlock = exports2.HOOK_EVENTS = exports2.executeHooks = exports2.HookManager = exports2.projectPathToDirName = exports2.getHistoryFilePath = exports2.getProjectHistoryDir = exports2.getHistoryDir = exports2.setModelConfigPathOverride = exports2.setLogLevel = exports2.TEMPERATURE_MAX = exports2.TEMPERATURE_MIN = exports2.DEFAULT_ANTHROPIC_TEMPERATURE = exports2.isValidTemperature = exports2.openaiTemperatureCapability = exports2.modelTemperatureGatedByThinking = exports2.modelRejectsTemperature = exports2.modelForcesTemperatureOne = exports2.getModelManager = exports2.SemaSession = exports2.SemaKernel = exports2.getAgentOwnedFilePaths = exports2.renderContextReminder = exports2.readContextSections = exports2.normalizeMemoryFiles = exports2.resolveContextFiles = exports2.isReadOnlyBashCommand = exports2.DEFAULT_PERMISSION_MODE = exports2.PERMISSION_MODES = exports2.assemblePromptSections = exports2.PROMPT_SECTION_CATALOG = exports2.AtomixCore = void 0;
|
|
143890
144350
|
var AtomixCore_1 = require_AtomixCore();
|
|
143891
144351
|
Object.defineProperty(exports2, "AtomixCore", { enumerable: true, get: function() {
|
|
143892
144352
|
return AtomixCore_1.AtomixCore;
|
|
@@ -143937,6 +144397,31 @@ var require_dist4 = __commonJS({
|
|
|
143937
144397
|
Object.defineProperty(exports2, "getModelManager", { enumerable: true, get: function() {
|
|
143938
144398
|
return ModelManager_1.getModelManager;
|
|
143939
144399
|
} });
|
|
144400
|
+
var adapter_1 = require_adapter();
|
|
144401
|
+
Object.defineProperty(exports2, "modelForcesTemperatureOne", { enumerable: true, get: function() {
|
|
144402
|
+
return adapter_1.modelForcesTemperatureOne;
|
|
144403
|
+
} });
|
|
144404
|
+
Object.defineProperty(exports2, "modelRejectsTemperature", { enumerable: true, get: function() {
|
|
144405
|
+
return adapter_1.modelRejectsTemperature;
|
|
144406
|
+
} });
|
|
144407
|
+
Object.defineProperty(exports2, "modelTemperatureGatedByThinking", { enumerable: true, get: function() {
|
|
144408
|
+
return adapter_1.modelTemperatureGatedByThinking;
|
|
144409
|
+
} });
|
|
144410
|
+
Object.defineProperty(exports2, "openaiTemperatureCapability", { enumerable: true, get: function() {
|
|
144411
|
+
return adapter_1.openaiTemperatureCapability;
|
|
144412
|
+
} });
|
|
144413
|
+
Object.defineProperty(exports2, "isValidTemperature", { enumerable: true, get: function() {
|
|
144414
|
+
return adapter_1.isValidTemperature;
|
|
144415
|
+
} });
|
|
144416
|
+
Object.defineProperty(exports2, "DEFAULT_ANTHROPIC_TEMPERATURE", { enumerable: true, get: function() {
|
|
144417
|
+
return adapter_1.DEFAULT_ANTHROPIC_TEMPERATURE;
|
|
144418
|
+
} });
|
|
144419
|
+
Object.defineProperty(exports2, "TEMPERATURE_MIN", { enumerable: true, get: function() {
|
|
144420
|
+
return adapter_1.TEMPERATURE_MIN;
|
|
144421
|
+
} });
|
|
144422
|
+
Object.defineProperty(exports2, "TEMPERATURE_MAX", { enumerable: true, get: function() {
|
|
144423
|
+
return adapter_1.TEMPERATURE_MAX;
|
|
144424
|
+
} });
|
|
143940
144425
|
var log_1 = require_log();
|
|
143941
144426
|
Object.defineProperty(exports2, "setLogLevel", { enumerable: true, get: function() {
|
|
143942
144427
|
return log_1.setLogLevel;
|
|
@@ -144002,20 +144487,6 @@ var require_dist4 = __commonJS({
|
|
|
144002
144487
|
}
|
|
144003
144488
|
});
|
|
144004
144489
|
|
|
144005
|
-
// src/paths.ts
|
|
144006
|
-
import * as os3 from "os";
|
|
144007
|
-
import * as path from "path";
|
|
144008
|
-
function getAtomixRoot() {
|
|
144009
|
-
const custom = process.env.ATOMIX_ROOT;
|
|
144010
|
-
if (custom) return path.resolve(custom);
|
|
144011
|
-
return path.join(os3.homedir(), ".atomix");
|
|
144012
|
-
}
|
|
144013
|
-
var init_paths = __esm({
|
|
144014
|
-
"src/paths.ts"() {
|
|
144015
|
-
"use strict";
|
|
144016
|
-
}
|
|
144017
|
-
});
|
|
144018
|
-
|
|
144019
144490
|
// src/theme.ts
|
|
144020
144491
|
function getThemeName() {
|
|
144021
144492
|
return activeThemeName;
|
|
@@ -151445,616 +151916,50 @@ var require_dist5 = __commonJS({
|
|
|
151445
151916
|
}
|
|
151446
151917
|
});
|
|
151447
151918
|
|
|
151448
|
-
// src/
|
|
151449
|
-
var agents_exports = {};
|
|
151450
|
-
__export(agents_exports, {
|
|
151451
|
-
agentsCommand: () => agentsCommand,
|
|
151452
|
-
applyDisabledAgents: () => applyDisabledAgents,
|
|
151453
|
-
disableAgent: () => disableAgent,
|
|
151454
|
-
enableAgent: () => enableAgent,
|
|
151455
|
-
readDisabledAgents: () => readDisabledAgents
|
|
151456
|
-
});
|
|
151919
|
+
// src/memoryPaths.ts
|
|
151457
151920
|
import * as fs2 from "fs";
|
|
151458
151921
|
import * as path2 from "path";
|
|
151459
|
-
function disabledFile() {
|
|
151460
|
-
return path2.join(getAtomixRoot(), "disabled-agents.json");
|
|
151461
|
-
}
|
|
151462
|
-
function readDisabledAgents() {
|
|
151463
|
-
try {
|
|
151464
|
-
const parsed = JSON.parse(fs2.readFileSync(disabledFile(), "utf8"));
|
|
151465
|
-
if (Array.isArray(parsed.disabled)) return new Set(parsed.disabled);
|
|
151466
|
-
} catch {
|
|
151467
|
-
}
|
|
151468
|
-
return /* @__PURE__ */ new Set();
|
|
151469
|
-
}
|
|
151470
|
-
function writeDisabledAgents(disabled) {
|
|
151471
|
-
fs2.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
151472
|
-
fs2.writeFileSync(disabledFile(), JSON.stringify({ disabled: [...disabled].sort() }, null, 2) + "\n");
|
|
151473
|
-
}
|
|
151474
|
-
function disableAgent(name) {
|
|
151475
|
-
const s = readDisabledAgents();
|
|
151476
|
-
s.add(name);
|
|
151477
|
-
writeDisabledAgents(s);
|
|
151478
|
-
}
|
|
151479
|
-
function enableAgent(name) {
|
|
151480
|
-
const s = readDisabledAgents();
|
|
151481
|
-
if (!s.delete(name)) return false;
|
|
151482
|
-
writeDisabledAgents(s);
|
|
151483
|
-
return true;
|
|
151484
|
-
}
|
|
151485
|
-
async function applyDisabledAgents(core) {
|
|
151486
|
-
await core.reloadAgents(/* @__PURE__ */ new Set());
|
|
151487
|
-
const allNames = core.getAgentsInfo().map((a) => a.name);
|
|
151488
|
-
recordAgentUniverse(allNames);
|
|
151489
|
-
const disabled = /* @__PURE__ */ new Set([...readDisabledAgents(), ...harnessDisabledAgents(allNames)]);
|
|
151490
|
-
await core.reloadAgents(disabled);
|
|
151491
|
-
}
|
|
151492
|
-
async function agentsCommand(core, args) {
|
|
151493
|
-
const [sub, ...rest2] = args;
|
|
151494
|
-
const name = rest2.join(" ").trim();
|
|
151495
|
-
switch (sub) {
|
|
151496
|
-
case void 0:
|
|
151497
|
-
case "list": {
|
|
151498
|
-
const infos = [...core.getAgentsInfo()].sort(
|
|
151499
|
-
(a, b) => a.locate.localeCompare(b.locate) || a.name.localeCompare(b.name)
|
|
151500
|
-
);
|
|
151501
|
-
const disabledSet = readDisabledAgents();
|
|
151502
|
-
const lines = infos.filter((a) => !disabledSet.has(a.name)).map((a) => {
|
|
151503
|
-
const desc = a.description ? ` \u2014 ${a.description.length > 60 ? a.description.slice(0, 60) + "\u2026" : a.description}` : "";
|
|
151504
|
-
return `\u25CF ${a.name} [${a.locate}]${desc}`;
|
|
151505
|
-
});
|
|
151506
|
-
for (const n of [...disabledSet].sort()) lines.push(`\u25CB ${n} \uFF08\u5DF2\u7981\u7528\uFF09`);
|
|
151507
|
-
if (!lines.length) lines.push("\uFF08\u65E0\u53EF\u7528\u4EBA\u8BBE\uFF09");
|
|
151508
|
-
lines.push(`\u25CF \u542F\u7528\u4E2D \u25CB \u5DF2\u7981\u7528${disabledSet.size === 0 ? "\uFF08\u5F53\u524D\u65E0\u7981\u7528\u9879\uFF09" : ""} \xB7 \u7528\u6CD5\uFF1A/agents list | enable <\u540D\u79F0> | disable <\u540D\u79F0>`);
|
|
151509
|
-
return lines.join("\n ");
|
|
151510
|
-
}
|
|
151511
|
-
case "disable": {
|
|
151512
|
-
if (!name) return "\u7528\u6CD5\uFF1A/agents disable <\u540D\u79F0>";
|
|
151513
|
-
disableAgent(name);
|
|
151514
|
-
await applyDisabledAgents(core);
|
|
151515
|
-
return `\u5DF2\u7981\u7528\u4EBA\u8BBE\uFF1A${name}`;
|
|
151516
|
-
}
|
|
151517
|
-
case "enable": {
|
|
151518
|
-
if (!name) return "\u7528\u6CD5\uFF1A/agents enable <\u540D\u79F0>";
|
|
151519
|
-
if (!enableAgent(name)) return `${name} \u672A\u88AB\u7981\u7528`;
|
|
151520
|
-
await applyDisabledAgents(core);
|
|
151521
|
-
return `\u5DF2\u542F\u7528\u4EBA\u8BBE\uFF1A${name}`;
|
|
151522
|
-
}
|
|
151523
|
-
default:
|
|
151524
|
-
return `\u672A\u77E5\u5B50\u547D\u4EE4\uFF1A${sub}\uFF08\u7528\u6CD5\uFF1A/agents list | enable <\u540D\u79F0> | disable <\u540D\u79F0>\uFF09`;
|
|
151525
|
-
}
|
|
151526
|
-
}
|
|
151527
|
-
var init_agents = __esm({
|
|
151528
|
-
"src/agents.ts"() {
|
|
151529
|
-
"use strict";
|
|
151530
|
-
init_paths();
|
|
151531
|
-
init_harness();
|
|
151532
|
-
}
|
|
151533
|
-
});
|
|
151534
|
-
|
|
151535
|
-
// src/harness.ts
|
|
151536
|
-
import * as fs3 from "fs";
|
|
151537
|
-
import * as path3 from "path";
|
|
151538
|
-
function overrideOf(activeValue, baseValue) {
|
|
151539
|
-
if (baseValue === void 0 || activeValue === void 0) return null;
|
|
151540
|
-
const baseOn = baseValue !== null;
|
|
151541
|
-
const activeOn = activeValue !== null;
|
|
151542
|
-
return activeOn === baseOn ? null : activeOn ? "on" : "off";
|
|
151543
|
-
}
|
|
151544
|
-
function personaOverrideOf(activeValue, baseValue) {
|
|
151545
|
-
const basic = overrideOf(activeValue, baseValue);
|
|
151546
|
-
if (basic !== null) return basic;
|
|
151547
|
-
if (activeValue && baseValue && activeValue !== baseValue) return "swap";
|
|
151548
|
-
return null;
|
|
151549
|
-
}
|
|
151550
|
-
function harnessMemoryOverride() {
|
|
151551
|
-
return overrideOf(activeMemoryFiles, baseline.memoryFiles);
|
|
151552
|
-
}
|
|
151553
|
-
function harnessPersonaOverride() {
|
|
151554
|
-
return personaOverrideOf(activePersonaFile, baseline.personaFile);
|
|
151555
|
-
}
|
|
151556
|
-
function getActivePersonaFile() {
|
|
151557
|
-
return activePersonaFile;
|
|
151558
|
-
}
|
|
151559
|
-
function getActiveHarnessName() {
|
|
151560
|
-
return active?.name ?? BASE_HARNESS;
|
|
151561
|
-
}
|
|
151562
|
-
function recordSkillUniverse(names) {
|
|
151563
|
-
fullSkillNames = names.slice();
|
|
151564
|
-
}
|
|
151565
|
-
function recordAgentUniverse(names) {
|
|
151566
|
-
fullAgentNames = names.slice();
|
|
151567
|
-
}
|
|
151568
|
-
function computeDisabledFrom(spec, allNames) {
|
|
151569
|
-
if (!spec) return /* @__PURE__ */ new Set();
|
|
151570
|
-
return spec.mode === "whitelist" ? new Set(allNames.filter((n) => !spec.enable.includes(n))) : new Set(spec.disable);
|
|
151571
|
-
}
|
|
151572
|
-
function harnessDisabledSkills(allNames) {
|
|
151573
|
-
return computeDisabledFrom(active?.skillsSpec ?? null, allNames);
|
|
151574
|
-
}
|
|
151575
|
-
function harnessDisabledAgents(allNames) {
|
|
151576
|
-
return computeDisabledFrom(active?.agentsSpec ?? null, allNames);
|
|
151577
|
-
}
|
|
151578
|
-
function libraryDir() {
|
|
151579
|
-
return path3.join(getAtomixRoot(), "harness");
|
|
151580
|
-
}
|
|
151581
|
-
function statePath(cwd2) {
|
|
151582
|
-
return path3.join(cwd2, ".atomix", "harness-state.json");
|
|
151583
|
-
}
|
|
151584
|
-
function readState(cwd2) {
|
|
151585
|
-
try {
|
|
151586
|
-
const parsed = JSON.parse(fs3.readFileSync(statePath(cwd2), "utf8"));
|
|
151587
|
-
return typeof parsed.active === "string" && parsed.active ? parsed.active : BASE_HARNESS;
|
|
151588
|
-
} catch {
|
|
151589
|
-
return BASE_HARNESS;
|
|
151590
|
-
}
|
|
151591
|
-
}
|
|
151592
|
-
function writeState(cwd2, name) {
|
|
151593
|
-
const p = statePath(cwd2);
|
|
151594
|
-
if (name === BASE_HARNESS) {
|
|
151595
|
-
try {
|
|
151596
|
-
fs3.unlinkSync(p);
|
|
151597
|
-
} catch {
|
|
151598
|
-
}
|
|
151599
|
-
return;
|
|
151600
|
-
}
|
|
151601
|
-
fs3.mkdirSync(path3.dirname(p), { recursive: true });
|
|
151602
|
-
fs3.writeFileSync(p, JSON.stringify({ active: name }, null, 2) + "\n");
|
|
151603
|
-
}
|
|
151604
|
-
function listHarnesses() {
|
|
151605
|
-
let names = [];
|
|
151606
|
-
try {
|
|
151607
|
-
names = fs3.readdirSync(libraryDir(), { withFileTypes: true }).filter((e) => e.isDirectory() && fs3.existsSync(path3.join(libraryDir(), e.name, "harness.yaml"))).map((e) => e.name).sort();
|
|
151608
|
-
} catch {
|
|
151609
|
-
}
|
|
151610
|
-
return [BASE_HARNESS, ...names.filter((n) => n !== BASE_HARNESS)];
|
|
151611
|
-
}
|
|
151612
|
-
function asStrArr(v) {
|
|
151613
|
-
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
151614
|
-
}
|
|
151615
|
-
function asMode(v) {
|
|
151616
|
-
return v === "whitelist" ? "whitelist" : "blacklist";
|
|
151617
|
-
}
|
|
151618
|
-
function normalizePromptGroup(raw) {
|
|
151619
|
-
const warnings = [];
|
|
151620
|
-
if (!raw || typeof raw !== "object") return { overrides: null, warnings };
|
|
151621
|
-
const g = raw;
|
|
151622
|
-
const meta = new Map(import_atomix_core2.PROMPT_SECTION_CATALOG.map((m) => [m.name, m]));
|
|
151623
|
-
const replace2 = {};
|
|
151624
|
-
if (g.replace && typeof g.replace === "object") {
|
|
151625
|
-
for (const [name, text] of Object.entries(g.replace)) {
|
|
151626
|
-
const m = meta.get(name);
|
|
151627
|
-
if (!m) {
|
|
151628
|
-
warnings.push(`prompt.replace \u672A\u77E5\u6BB5\u540D ${name}(\u53EF\u7528:${[...meta.keys()].join(" / ")})`);
|
|
151629
|
-
continue;
|
|
151630
|
-
}
|
|
151631
|
-
if (m.locked) {
|
|
151632
|
-
warnings.push(`prompt.replace \u5FFD\u7565 ${name}:\u5B89\u5168\u6761\u6B3E\u6BB5\u4EE3\u7801\u7EA7\u9501\u5B9A`);
|
|
151633
|
-
continue;
|
|
151634
|
-
}
|
|
151635
|
-
if (m.dynamic) {
|
|
151636
|
-
warnings.push(`prompt.replace \u5FFD\u7565 ${name}:\u52A8\u6001\u6BB5(\u6BCF\u8F6E\u91CD\u7B97)\u53EA\u53EF disable`);
|
|
151637
|
-
continue;
|
|
151638
|
-
}
|
|
151639
|
-
if (typeof text !== "string") {
|
|
151640
|
-
warnings.push(`prompt.replace.${name} \u975E\u5B57\u7B26\u4E32,\u5FFD\u7565`);
|
|
151641
|
-
continue;
|
|
151642
|
-
}
|
|
151643
|
-
replace2[name] = text;
|
|
151644
|
-
}
|
|
151645
|
-
}
|
|
151646
|
-
const disable = [];
|
|
151647
|
-
for (const name of asStrArr(g.disable)) {
|
|
151648
|
-
const m = meta.get(name);
|
|
151649
|
-
if (!m) {
|
|
151650
|
-
warnings.push(`prompt.disable \u672A\u77E5\u6BB5\u540D ${name}`);
|
|
151651
|
-
continue;
|
|
151652
|
-
}
|
|
151653
|
-
if (m.locked) {
|
|
151654
|
-
warnings.push(`prompt.disable \u5FFD\u7565 ${name}:\u5B89\u5168\u6761\u6B3E\u6BB5\u4EE3\u7801\u7EA7\u9501\u5B9A`);
|
|
151655
|
-
continue;
|
|
151656
|
-
}
|
|
151657
|
-
disable.push(name);
|
|
151658
|
-
}
|
|
151659
|
-
const insert = [];
|
|
151660
|
-
if (Array.isArray(g.insert)) {
|
|
151661
|
-
for (const item of g.insert) {
|
|
151662
|
-
if (!item || typeof item !== "object") continue;
|
|
151663
|
-
const it = item;
|
|
151664
|
-
const name = typeof it.name === "string" ? it.name : "";
|
|
151665
|
-
const text = typeof it.text === "string" ? it.text : "";
|
|
151666
|
-
if (!name || !text.trim()) {
|
|
151667
|
-
warnings.push("prompt.insert \u5FFD\u7565\u7F3A name/text \u7684\u6761\u76EE");
|
|
151668
|
-
continue;
|
|
151669
|
-
}
|
|
151670
|
-
if (meta.has(name)) {
|
|
151671
|
-
warnings.push(`prompt.insert \u5FFD\u7565 ${name}:\u4E0E\u5185\u7F6E\u6BB5\u91CD\u540D(\u6539\u5185\u7F6E\u6BB5\u7528 replace)`);
|
|
151672
|
-
continue;
|
|
151673
|
-
}
|
|
151674
|
-
const order = typeof it.order === "number" && Number.isFinite(it.order) ? it.order : 999;
|
|
151675
|
-
insert.push({ name, order, text });
|
|
151676
|
-
}
|
|
151677
|
-
}
|
|
151678
|
-
const overrides = {};
|
|
151679
|
-
if (Object.keys(replace2).length) overrides.replace = replace2;
|
|
151680
|
-
if (disable.length) overrides.disable = disable;
|
|
151681
|
-
if (insert.length) overrides.insert = insert;
|
|
151682
|
-
return { overrides: Object.keys(overrides).length ? overrides : null, warnings };
|
|
151683
|
-
}
|
|
151684
|
-
function assertSafeHarnessName(name) {
|
|
151685
|
-
if (!name || name === "." || name === ".." || name.includes("/") || name.includes("\\") || path3.basename(name) !== name) {
|
|
151686
|
-
throw new Error(`\u975E\u6CD5 harness \u540D\u79F0:${JSON.stringify(name)}`);
|
|
151687
|
-
}
|
|
151688
|
-
}
|
|
151689
|
-
function assertInsideDir(dir, target, what) {
|
|
151690
|
-
const rel = path3.relative(dir, target);
|
|
151691
|
-
if (rel === ".." || rel.startsWith(`..${path3.sep}`) || path3.isAbsolute(rel)) {
|
|
151692
|
-
throw new Error(`${what}\u5FC5\u987B\u4F4D\u4E8E harness \u76EE\u5F55\u5185:${target}`);
|
|
151693
|
-
}
|
|
151694
|
-
}
|
|
151695
|
-
function loadHarnessDoc(name) {
|
|
151696
|
-
assertSafeHarnessName(name);
|
|
151697
|
-
const dir = path3.join(libraryDir(), name);
|
|
151698
|
-
const yamlPath = path3.join(dir, "harness.yaml");
|
|
151699
|
-
const raw = import_yaml.default.parse(fs3.readFileSync(yamlPath, "utf8"));
|
|
151700
|
-
if (!raw || typeof raw !== "object") throw new Error(`harness.yaml \u4E3A\u7A7A\u6216\u975E\u5BF9\u8C61:${yamlPath}`);
|
|
151701
|
-
const t = raw.tools ?? {};
|
|
151702
|
-
const sk = raw.skills ?? {};
|
|
151703
|
-
const ag = raw.agents ?? {};
|
|
151704
|
-
let rulesText = "";
|
|
151705
|
-
const rulesFile = typeof raw.rules === "string" ? raw.rules : "rules.md";
|
|
151706
|
-
const rulesPath = path3.resolve(dir, rulesFile);
|
|
151707
|
-
assertInsideDir(path3.resolve(dir), rulesPath, "rules \u6587\u4EF6");
|
|
151708
|
-
let rulesReal = null;
|
|
151709
|
-
try {
|
|
151710
|
-
rulesReal = fs3.realpathSync(rulesPath);
|
|
151711
|
-
} catch {
|
|
151712
|
-
}
|
|
151713
|
-
if (rulesReal !== null) {
|
|
151714
|
-
assertInsideDir(fs3.realpathSync(dir), rulesReal, "rules \u6587\u4EF6(symlink \u89E3\u6790\u540E)");
|
|
151715
|
-
rulesText = fs3.readFileSync(rulesReal, "utf8").trim();
|
|
151716
|
-
}
|
|
151717
|
-
let soulPath = null;
|
|
151718
|
-
let soulReal = null;
|
|
151719
|
-
try {
|
|
151720
|
-
soulReal = fs3.realpathSync(path3.resolve(dir, "SOUL.md"));
|
|
151721
|
-
} catch (e) {
|
|
151722
|
-
if (e.code !== "ENOENT") throw e;
|
|
151723
|
-
}
|
|
151724
|
-
if (soulReal !== null) {
|
|
151725
|
-
assertInsideDir(fs3.realpathSync(dir), soulReal, "SOUL \u6587\u4EF6(symlink \u89E3\u6790\u540E)");
|
|
151726
|
-
const soulStat = fs3.statSync(soulReal);
|
|
151727
|
-
if (!soulStat.isFile()) throw new Error(`SOUL.md \u4E0D\u662F\u666E\u901A\u6587\u4EF6:${soulReal}`);
|
|
151728
|
-
if (soulStat.nlink > 1) throw new Error(`SOUL.md \u662F\u591A\u786C\u94FE\u63A5\u6587\u4EF6,\u62D2\u7EDD\u52A0\u8F7D:${soulReal}`);
|
|
151729
|
-
soulPath = soulReal;
|
|
151730
|
-
}
|
|
151731
|
-
const promptGroup = normalizePromptGroup(raw.prompt);
|
|
151732
|
-
const toggleWarnings = [];
|
|
151733
|
-
const parseToggle = (v, key) => {
|
|
151734
|
-
if (v === void 0 || v === null) return null;
|
|
151735
|
-
if (v === "off" || v === false) return "off";
|
|
151736
|
-
if (v === "on" || v === true) return "on";
|
|
151737
|
-
toggleWarnings.push(`${key} \u53EA\u8BA4 on/off,\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
|
|
151738
|
-
return null;
|
|
151739
|
-
};
|
|
151740
|
-
const memory = parseToggle(raw.memory, "memory");
|
|
151741
|
-
const persona = parseToggle(raw.persona, "persona");
|
|
151742
|
-
return {
|
|
151743
|
-
name: typeof raw.name === "string" && raw.name ? raw.name : name,
|
|
151744
|
-
description: typeof raw.description === "string" ? raw.description : void 0,
|
|
151745
|
-
version: typeof raw.version === "string" ? raw.version : void 0,
|
|
151746
|
-
rulesText,
|
|
151747
|
-
tools: {
|
|
151748
|
-
mode: asMode(t.mode),
|
|
151749
|
-
useTools: Array.isArray(t.useTools) ? asStrArr(t.useTools) : null,
|
|
151750
|
-
disable: asStrArr(t.disable),
|
|
151751
|
-
enable: asStrArr(t.enable),
|
|
151752
|
-
defer: asStrArr(t.defer),
|
|
151753
|
-
pin: asStrArr(t.pin)
|
|
151754
|
-
},
|
|
151755
|
-
skills: { mode: asMode(sk.mode), disable: asStrArr(sk.disable), enable: asStrArr(sk.enable) },
|
|
151756
|
-
agents: { mode: asMode(ag.mode), disable: asStrArr(ag.disable), enable: asStrArr(ag.enable) },
|
|
151757
|
-
prompt: promptGroup.overrides,
|
|
151758
|
-
promptWarnings: promptGroup.warnings,
|
|
151759
|
-
memory,
|
|
151760
|
-
persona,
|
|
151761
|
-
soulPath,
|
|
151762
|
-
toggleWarnings,
|
|
151763
|
-
dir
|
|
151764
|
-
};
|
|
151765
|
-
}
|
|
151766
|
-
function resolveBase(ctx) {
|
|
151767
|
-
return {
|
|
151768
|
-
name: BASE_HARNESS,
|
|
151769
|
-
useTools: ctx.baseline.useTools,
|
|
151770
|
-
deferBuiltinTools: ctx.baseline.deferBuiltinTools ?? [],
|
|
151771
|
-
pinnedTools: [],
|
|
151772
|
-
customRules: "",
|
|
151773
|
-
promptOverrides: null,
|
|
151774
|
-
memoryFiles: ctx.baseline.memoryFiles,
|
|
151775
|
-
personaFile: ctx.baseline.personaFile,
|
|
151776
|
-
warnings: [],
|
|
151777
|
-
skillsSpec: null,
|
|
151778
|
-
agentsSpec: null,
|
|
151779
|
-
skillsDisabled: /* @__PURE__ */ new Set(),
|
|
151780
|
-
agentsDisabled: /* @__PURE__ */ new Set()
|
|
151781
|
-
};
|
|
151782
|
-
}
|
|
151783
|
-
function resolveHarness(doc, ctx) {
|
|
151784
|
-
if (!doc) return resolveBase(ctx);
|
|
151785
|
-
let useTools;
|
|
151786
|
-
if (doc.tools.mode === "whitelist") {
|
|
151787
|
-
useTools = doc.tools.enable.slice();
|
|
151788
|
-
} else {
|
|
151789
|
-
useTools = doc.tools.useTools ?? ctx.baseline.useTools;
|
|
151790
|
-
if (doc.tools.disable.length) {
|
|
151791
|
-
const src = useTools ?? ctx.allToolNames;
|
|
151792
|
-
const drop2 = new Set(doc.tools.disable);
|
|
151793
|
-
useTools = src.filter((n) => !drop2.has(n));
|
|
151794
|
-
}
|
|
151795
|
-
}
|
|
151796
|
-
const warnings = [...doc.promptWarnings, ...doc.toggleWarnings];
|
|
151797
|
-
const resolveToggle = (toggle, base, potential, emptyWarning) => {
|
|
151798
|
-
if (base === void 0) return void 0;
|
|
151799
|
-
if (toggle === "off") return null;
|
|
151800
|
-
if (toggle === "on") {
|
|
151801
|
-
const p = potential === void 0 ? base : potential;
|
|
151802
|
-
if (p === null) {
|
|
151803
|
-
warnings.push(emptyWarning);
|
|
151804
|
-
return null;
|
|
151805
|
-
}
|
|
151806
|
-
return p;
|
|
151807
|
-
}
|
|
151808
|
-
return base;
|
|
151809
|
-
};
|
|
151810
|
-
const memoryFiles = resolveToggle(
|
|
151811
|
-
doc.memory,
|
|
151812
|
-
ctx.baseline.memoryFiles,
|
|
151813
|
-
ctx.baseline.potentialMemoryFiles,
|
|
151814
|
-
"memory: on \u65E0\u8D27\u53EF\u5F00:config.json \u5DF2\u628A global/project \u90FD\u663E\u5F0F\u5173\u6B7B"
|
|
151815
|
-
);
|
|
151816
|
-
let personaFile;
|
|
151817
|
-
if (ctx.baseline.personaFile === void 0) {
|
|
151818
|
-
personaFile = void 0;
|
|
151819
|
-
} else if (doc.persona === "off") {
|
|
151820
|
-
personaFile = null;
|
|
151821
|
-
} else if (doc.soulPath) {
|
|
151822
|
-
personaFile = doc.soulPath;
|
|
151823
|
-
} else {
|
|
151824
|
-
if (doc.persona === "on") warnings.push("persona: on \u65E0\u6548:\u672C harness \u672A\u5E26\u4E13\u5C5E SOUL.md(\u4E25\u683C\u9694\u79BB,\u4E0D\u501F base \u4EBA\u8BBE;\u653E\u4E00\u4EFD SOUL.md \u8FDB harness \u76EE\u5F55\u5373\u751F\u6548)");
|
|
151825
|
-
personaFile = null;
|
|
151826
|
-
}
|
|
151827
|
-
return {
|
|
151828
|
-
name: doc.name,
|
|
151829
|
-
useTools,
|
|
151830
|
-
deferBuiltinTools: doc.tools.defer.length ? doc.tools.defer : ctx.baseline.deferBuiltinTools ?? [],
|
|
151831
|
-
pinnedTools: doc.tools.pin,
|
|
151832
|
-
customRules: doc.rulesText,
|
|
151833
|
-
promptOverrides: doc.prompt,
|
|
151834
|
-
memoryFiles,
|
|
151835
|
-
personaFile,
|
|
151836
|
-
warnings,
|
|
151837
|
-
skillsSpec: doc.skills,
|
|
151838
|
-
agentsSpec: doc.agents,
|
|
151839
|
-
skillsDisabled: computeDisabledFrom(doc.skills, ctx.allSkillNames),
|
|
151840
|
-
agentsDisabled: computeDisabledFrom(doc.agents, ctx.allAgentNames)
|
|
151841
|
-
};
|
|
151842
|
-
}
|
|
151843
|
-
function buildContext(core) {
|
|
151844
|
-
return {
|
|
151845
|
-
baseline,
|
|
151846
|
-
// 工具:getToolInfos 恒返回内置全集(禁用项带 status),可直读;
|
|
151847
|
-
// skill/agent:注册表是已过滤视图,优先用 applyDisabled* 回写的全集缓存,
|
|
151848
|
-
// 缓存为空只在启动初始化时(此刻注册表尚未过滤,直读即全集)
|
|
151849
|
-
allToolNames: core.getToolInfos().map((t) => t.name),
|
|
151850
|
-
allSkillNames: fullSkillNames ?? core.getSkillsInfo().map((s) => s.name),
|
|
151851
|
-
allAgentNames: fullAgentNames ?? core.getAgentsInfo().map((a) => a.name)
|
|
151852
|
-
};
|
|
151853
|
-
}
|
|
151854
|
-
function applyAssembly(core, r) {
|
|
151855
|
-
core.updateAssemblyConfig({
|
|
151856
|
-
useTools: r.useTools,
|
|
151857
|
-
deferBuiltinTools: r.deferBuiltinTools,
|
|
151858
|
-
pinnedTools: r.pinnedTools,
|
|
151859
|
-
customRules: r.customRules,
|
|
151860
|
-
promptOverrides: r.promptOverrides,
|
|
151861
|
-
// null = 回默认组装(base 清场)
|
|
151862
|
-
// 基线未知(宿主没给快照)时不下发该键:传 undefined 会被 core 当 null 落,把供给层开着的注入误关
|
|
151863
|
-
...r.memoryFiles !== void 0 ? { memoryFiles: r.memoryFiles } : {},
|
|
151864
|
-
...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {}
|
|
151865
|
-
});
|
|
151866
|
-
activeMemoryFiles = r.memoryFiles;
|
|
151867
|
-
activePersonaFile = r.personaFile;
|
|
151868
|
-
active = r.name === BASE_HARNESS ? null : r;
|
|
151869
|
-
}
|
|
151870
|
-
function initHarness(core, cwd2, base) {
|
|
151871
|
-
baseline = {
|
|
151872
|
-
useTools: base.useTools ? [...base.useTools] : null,
|
|
151873
|
-
deferBuiltinTools: base.deferBuiltinTools?.slice(),
|
|
151874
|
-
memoryFiles: base.memoryFiles,
|
|
151875
|
-
personaFile: base.personaFile,
|
|
151876
|
-
potentialMemoryFiles: base.potentialMemoryFiles
|
|
151877
|
-
};
|
|
151878
|
-
activeMemoryFiles = base.memoryFiles;
|
|
151879
|
-
activePersonaFile = base.personaFile;
|
|
151880
|
-
projectDir = cwd2;
|
|
151881
|
-
const name = readState(cwd2);
|
|
151882
|
-
if (name === BASE_HARNESS) return null;
|
|
151883
|
-
try {
|
|
151884
|
-
const doc = loadHarnessDoc(name);
|
|
151885
|
-
const r = resolveHarness(doc, buildContext(core));
|
|
151886
|
-
applyAssembly(core, r);
|
|
151887
|
-
return r.warnings.length ? `harness "${r.name}"(\u6765\u81EA .atomix/harness-state.json)\u5DF2\u52A0\u8F7D:
|
|
151888
|
-
\u26A0 ${r.warnings.join("\n \u26A0 ")}` : null;
|
|
151889
|
-
} catch (e) {
|
|
151890
|
-
return `harness "${name}"(\u6765\u81EA .atomix/harness-state.json)\u52A0\u8F7D\u5931\u8D25,\u5DF2\u56DE\u843D base:${e instanceof Error ? e.message : e}`;
|
|
151891
|
-
}
|
|
151892
|
-
}
|
|
151893
|
-
async function switchTo(core, name) {
|
|
151894
|
-
if (!projectDir) throw new Error("harness \u672A\u521D\u59CB\u5316(initHarness \u672A\u8C03\u7528)");
|
|
151895
|
-
const ctx = buildContext(core);
|
|
151896
|
-
const r = name === BASE_HARNESS ? resolveBase(ctx) : resolveHarness(loadHarnessDoc(name), ctx);
|
|
151897
|
-
const wasOn = (v) => v !== null && v !== void 0;
|
|
151898
|
-
const memWasOn = wasOn(activeMemoryFiles);
|
|
151899
|
-
const personaWas = activePersonaFile;
|
|
151900
|
-
applyAssembly(core, r);
|
|
151901
|
-
const memNowOn = wasOn(activeMemoryFiles);
|
|
151902
|
-
const personaNow = activePersonaFile;
|
|
151903
|
-
writeState(projectDir, name);
|
|
151904
|
-
const { applyDisabledSkills: applyDisabledSkills2 } = await Promise.resolve().then(() => (init_skills(), skills_exports));
|
|
151905
|
-
const { applyDisabledAgents: applyDisabledAgents2 } = await Promise.resolve().then(() => (init_agents(), agents_exports));
|
|
151906
|
-
applyDisabledSkills2(core);
|
|
151907
|
-
await applyDisabledAgents2(core);
|
|
151908
|
-
const warn = r.warnings.length ? "\n \u26A0 " + r.warnings.join("\n \u26A0 ") : "";
|
|
151909
|
-
const hints = [];
|
|
151910
|
-
if (memWasOn !== memNowOn) hints.push(memNowOn ? "\u8BB0\u5FC6\u6CE8\u5165\u5DF2\u5F00;\u9700 /compact\u3001/clear \u6216\u65B0\u4F1A\u8BDD\u540E\u91CD\u65B0\u6CE8\u5165" : "\u8BB0\u5FC6\u6CE8\u5165\u5DF2\u5173;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u8BB0\u5FC6\u9700 /compact \u6216 /clear \u624D\u64A4\u51FA");
|
|
151911
|
-
const pWasOn = wasOn(personaWas);
|
|
151912
|
-
const pNowOn = wasOn(personaNow);
|
|
151913
|
-
if (pWasOn !== pNowOn) hints.push(pNowOn ? "\u4EBA\u8BBE\u6CE8\u5165\u5DF2\u5F00;\u9700 /compact\u3001/clear \u6216\u65B0\u4F1A\u8BDD\u540E\u91CD\u65B0\u6CE8\u5165" : "\u4EBA\u8BBE\u6CE8\u5165\u5DF2\u5173;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u4EBA\u8BBE\u9700 /compact \u6216 /clear \u624D\u64A4\u51FA");
|
|
151914
|
-
else if (pWasOn && pNowOn && personaWas !== personaNow) hints.push("\u4EBA\u8BBE\u6765\u6E90\u5DF2\u5207\u6362;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u4EBA\u8BBE\u9700 /compact \u6216 /clear \u624D\u66F4\u65B0");
|
|
151915
|
-
const hintText = hints.map((h) => `
|
|
151916
|
-
${h}`).join("");
|
|
151917
|
-
return (name === BASE_HARNESS ? "\u5DF2\u56DE\u5230 base(\u9ED8\u8BA4\u88C5\u914D)" : `\u5DF2\u5207\u6362 harness:${r.name}(\u4EC5\u5F53\u524D\u9879\u76EE\u751F\u6548)`) + hintText + warn;
|
|
151918
|
-
}
|
|
151919
|
-
function summarize(r, ctx) {
|
|
151920
|
-
const lines = [];
|
|
151921
|
-
const base = resolveBase(ctx);
|
|
151922
|
-
const baseSet2 = new Set(base.useTools ?? ctx.allToolNames);
|
|
151923
|
-
const curSet = new Set(r.useTools ?? ctx.allToolNames);
|
|
151924
|
-
const removed = [...baseSet2].filter((n) => !curSet.has(n));
|
|
151925
|
-
const added = [...curSet].filter((n) => !baseSet2.has(n));
|
|
151926
|
-
lines.push(`\u5DE5\u5177 ${r.useTools ? `${curSet.size} \u4E2A` : "\u5168\u90E8"}${removed.length ? `(\u76F8\u5BF9 base \u5C11:${removed.join(", ")})` : ""}${added.length ? `(\u76F8\u5BF9 base \u591A:${added.join(", ")})` : ""}`);
|
|
151927
|
-
if (r.deferBuiltinTools.length) lines.push(`defer ${r.deferBuiltinTools.join(", ")}`);
|
|
151928
|
-
if (r.pinnedTools.length) lines.push(`pin ${r.pinnedTools.join(", ")}`);
|
|
151929
|
-
const skillsDisabled = computeDisabledFrom(r.skillsSpec, ctx.allSkillNames);
|
|
151930
|
-
const agentsDisabled = computeDisabledFrom(r.agentsSpec, ctx.allAgentNames);
|
|
151931
|
-
lines.push(`skill ${skillsDisabled.size ? `\u7981\u7528 ${[...skillsDisabled].join(", ")}` : "\u5168\u90E8\u53EF\u89C1"}`);
|
|
151932
|
-
lines.push(`agent ${agentsDisabled.size ? `\u7981\u7528 ${[...agentsDisabled].join(", ")}` : "\u5168\u90E8\u53EF\u89C1"}`);
|
|
151933
|
-
lines.push(`\u89C4\u5219\u6BB5 ${r.customRules ? `${r.customRules.split("\n").length} \u884C` : "\u65E0"}`);
|
|
151934
|
-
const p = r.promptOverrides;
|
|
151935
|
-
const promptDesc = p ? [
|
|
151936
|
-
p.replace && Object.keys(p.replace).length ? `\u66FF\u6362 ${Object.keys(p.replace).join(", ")}` : "",
|
|
151937
|
-
p.disable?.length ? `\u7981\u7528 ${p.disable.join(", ")}` : "",
|
|
151938
|
-
p.insert?.length ? `\u63D2\u5165 ${p.insert.map((i) => i.name).join(", ")}` : ""
|
|
151939
|
-
].filter(Boolean).join(";") : "\u9ED8\u8BA4";
|
|
151940
|
-
lines.push(`\u63D0\u793A\u6BB5 ${promptDesc}`);
|
|
151941
|
-
const mo = overrideOf(r.memoryFiles, ctx.baseline.memoryFiles);
|
|
151942
|
-
if (mo === "off") lines.push("\u8BB0\u5FC6 \u5173(harness memory: off;base \u5F00\u7740,\u5207\u8D70\u5373\u6062\u590D)");
|
|
151943
|
-
else if (mo === "on") lines.push("\u8BB0\u5FC6 \u5F00(harness memory: on;base \u5173\u7740,\u5207\u8D70\u5373\u5173)");
|
|
151944
|
-
const po = personaOverrideOf(r.personaFile, ctx.baseline.personaFile);
|
|
151945
|
-
if (po === "off") lines.push("\u4EBA\u8BBE \u5173(\u672C harness \u65E0\u4EBA\u8BBE;base \u5F00\u7740,\u5207\u8D70\u5373\u6062\u590D)");
|
|
151946
|
-
else if (po === "swap") lines.push("\u4EBA\u8BBE \u4E13\u5C5E(harness SOUL.md;\u5207\u8D70\u5373\u56DE base)");
|
|
151947
|
-
else if (po === "on") lines.push("\u4EBA\u8BBE \u4E13\u5C5E(harness SOUL.md;base \u5173\u7740,\u5207\u8D70\u5373\u5173)");
|
|
151948
|
-
if (r.warnings.length) lines.push(...r.warnings.map((w) => `\u26A0 ${w}`));
|
|
151949
|
-
return lines.join("\n ");
|
|
151950
|
-
}
|
|
151951
|
-
async function harnessCommand(core, args) {
|
|
151952
|
-
const [sub, ...rest2] = args;
|
|
151953
|
-
const arg = rest2.join(" ").trim() || void 0;
|
|
151954
|
-
const names = listHarnesses();
|
|
151955
|
-
switch (sub) {
|
|
151956
|
-
case void 0:
|
|
151957
|
-
case "list": {
|
|
151958
|
-
const cur = getActiveHarnessName();
|
|
151959
|
-
const lines = names.map((n) => `${n === cur ? "\u25CF" : "\u25CB"} ${n}${n === BASE_HARNESS ? "(\u9ED8\u8BA4\u88C5\u914D)" : ""}`);
|
|
151960
|
-
if (sub === void 0 && active) {
|
|
151961
|
-
const ctx = buildContext(core);
|
|
151962
|
-
lines.unshift(`\u5F53\u524D:${cur}(\u9879\u76EE\u7EA7,${path3.join(".atomix", "harness-state.json")})`, " " + summarize(active, ctx), "");
|
|
151963
|
-
} else if (sub === void 0) {
|
|
151964
|
-
lines.unshift(`\u5F53\u524D:base(\u9ED8\u8BA4\u88C5\u914D,\u672A\u9009\u62E9 harness)`, "");
|
|
151965
|
-
}
|
|
151966
|
-
lines.push("", "\u7528\u6CD5:/harness list | use <\u540D\u79F0> | show <\u540D\u79F0> | diff <\u540D\u79F0> | reset");
|
|
151967
|
-
lines.push(`\u5E93\u76EE\u5F55:${libraryDir()}(\u6BCF\u4E2A harness \u4E00\u4E2A\u5B50\u76EE\u5F55,\u542B harness.yaml + rules.md)`);
|
|
151968
|
-
return lines.join("\n");
|
|
151969
|
-
}
|
|
151970
|
-
case "use": {
|
|
151971
|
-
if (!arg) return "\u7528\u6CD5:/harness use <\u540D\u79F0>";
|
|
151972
|
-
if (!names.includes(arg)) return `\u672A\u627E\u5230 harness:${arg}(\u53EF\u7528:${names.join(" / ")})`;
|
|
151973
|
-
try {
|
|
151974
|
-
return await switchTo(core, arg);
|
|
151975
|
-
} catch (e) {
|
|
151976
|
-
return `\u5207\u6362\u5931\u8D25:${e instanceof Error ? e.message : e}`;
|
|
151977
|
-
}
|
|
151978
|
-
}
|
|
151979
|
-
case "reset":
|
|
151980
|
-
return await switchTo(core, BASE_HARNESS);
|
|
151981
|
-
case "show":
|
|
151982
|
-
case "diff": {
|
|
151983
|
-
if (!arg) return `\u7528\u6CD5:/harness ${sub} <\u540D\u79F0>`;
|
|
151984
|
-
if (arg === BASE_HARNESS) return "base = \u9ED8\u8BA4\u88C5\u914D\u57FA\u7EBF,\u65E0\u53D6\u820D\u9879";
|
|
151985
|
-
try {
|
|
151986
|
-
const ctx = buildContext(core);
|
|
151987
|
-
const r = resolveHarness(loadHarnessDoc(arg), ctx);
|
|
151988
|
-
return `${r.name}${arg === getActiveHarnessName() ? "(\u5F53\u524D)" : ""}
|
|
151989
|
-
${summarize(r, ctx)}`;
|
|
151990
|
-
} catch (e) {
|
|
151991
|
-
return `\u8BFB\u53D6\u5931\u8D25:${e instanceof Error ? e.message : e}`;
|
|
151992
|
-
}
|
|
151993
|
-
}
|
|
151994
|
-
default:
|
|
151995
|
-
return `\u672A\u77E5\u5B50\u547D\u4EE4:${sub}(\u53EF\u7528:list / use / show / diff / reset)`;
|
|
151996
|
-
}
|
|
151997
|
-
}
|
|
151998
|
-
var import_yaml, import_atomix_core2, BASE_HARNESS, baseline, activeMemoryFiles, activePersonaFile, projectDir, active, fullSkillNames, fullAgentNames;
|
|
151999
|
-
var init_harness = __esm({
|
|
152000
|
-
"src/harness.ts"() {
|
|
152001
|
-
"use strict";
|
|
152002
|
-
import_yaml = __toESM(require_dist5());
|
|
152003
|
-
import_atomix_core2 = __toESM(require_dist4());
|
|
152004
|
-
init_paths();
|
|
152005
|
-
BASE_HARNESS = "base";
|
|
152006
|
-
baseline = { useTools: null };
|
|
152007
|
-
projectDir = null;
|
|
152008
|
-
active = null;
|
|
152009
|
-
fullSkillNames = null;
|
|
152010
|
-
fullAgentNames = null;
|
|
152011
|
-
}
|
|
152012
|
-
});
|
|
152013
|
-
|
|
152014
|
-
// src/memoryPaths.ts
|
|
152015
|
-
import * as fs4 from "fs";
|
|
152016
|
-
import * as path4 from "path";
|
|
152017
151922
|
function getMemoryPaths(cwd2) {
|
|
152018
151923
|
const root2 = realpathOrSelf(getAtomixRoot());
|
|
152019
|
-
const slug = (0,
|
|
152020
|
-
const
|
|
151924
|
+
const slug = (0, import_atomix_core2.projectPathToDirName)(cwd2);
|
|
151925
|
+
const projectDir = path2.join(root2, "projects", slug);
|
|
152021
151926
|
return {
|
|
152022
151927
|
root: root2,
|
|
152023
151928
|
slug,
|
|
152024
|
-
soul:
|
|
152025
|
-
globalMemory:
|
|
152026
|
-
projectDir
|
|
152027
|
-
projectMemory:
|
|
151929
|
+
soul: path2.join(root2, "SOUL.md"),
|
|
151930
|
+
globalMemory: path2.join(root2, "MEMORY.md"),
|
|
151931
|
+
projectDir,
|
|
151932
|
+
projectMemory: path2.join(projectDir, "MEMORY.md")
|
|
152028
151933
|
};
|
|
152029
151934
|
}
|
|
152030
151935
|
function realpathOrSelf(p) {
|
|
152031
151936
|
try {
|
|
152032
|
-
return
|
|
151937
|
+
return fs2.realpathSync(p);
|
|
152033
151938
|
} catch {
|
|
152034
151939
|
return p;
|
|
152035
151940
|
}
|
|
152036
151941
|
}
|
|
152037
|
-
var
|
|
151942
|
+
var import_atomix_core2;
|
|
152038
151943
|
var init_memoryPaths = __esm({
|
|
152039
151944
|
"src/memoryPaths.ts"() {
|
|
152040
151945
|
"use strict";
|
|
152041
|
-
|
|
151946
|
+
import_atomix_core2 = __toESM(require_dist4());
|
|
152042
151947
|
init_paths();
|
|
152043
151948
|
}
|
|
152044
151949
|
});
|
|
152045
151950
|
|
|
152046
151951
|
// src/appConfig.ts
|
|
152047
|
-
import * as
|
|
152048
|
-
import * as
|
|
151952
|
+
import * as fs3 from "fs";
|
|
151953
|
+
import * as path3 from "path";
|
|
152049
151954
|
function configPath() {
|
|
152050
|
-
return
|
|
151955
|
+
return path3.join(getAtomixRoot(), "config.json");
|
|
152051
151956
|
}
|
|
152052
151957
|
function configFilePath() {
|
|
152053
151958
|
return configPath();
|
|
152054
151959
|
}
|
|
152055
151960
|
function readConfig() {
|
|
152056
151961
|
try {
|
|
152057
|
-
return JSON.parse(
|
|
151962
|
+
return JSON.parse(fs3.readFileSync(configPath(), "utf8"));
|
|
152058
151963
|
} catch {
|
|
152059
151964
|
return {};
|
|
152060
151965
|
}
|
|
@@ -152062,7 +151967,7 @@ function readConfig() {
|
|
|
152062
151967
|
function readConfigForWrite() {
|
|
152063
151968
|
let text;
|
|
152064
151969
|
try {
|
|
152065
|
-
text =
|
|
151970
|
+
text = fs3.readFileSync(configPath(), "utf8");
|
|
152066
151971
|
} catch (e) {
|
|
152067
151972
|
if (e.code === "ENOENT") return {};
|
|
152068
151973
|
throw e;
|
|
@@ -152075,8 +151980,8 @@ function readConfigForWrite() {
|
|
|
152075
151980
|
}
|
|
152076
151981
|
function writeConfig(patch) {
|
|
152077
151982
|
const next = { ...readConfigForWrite(), ...patch };
|
|
152078
|
-
|
|
152079
|
-
|
|
151983
|
+
fs3.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
151984
|
+
fs3.writeFileSync(configPath(), JSON.stringify(next, null, 2) + "\n");
|
|
152080
151985
|
}
|
|
152081
151986
|
function applyConfiguredTheme() {
|
|
152082
151987
|
const name = readConfig().theme;
|
|
@@ -152100,7 +152005,7 @@ function buildContextFilesConfig(cwd2, cfg) {
|
|
|
152100
152005
|
if (s.memoryGlobal) memoryFiles.push({ path: p.globalMemory, label: "user-level" });
|
|
152101
152006
|
if (s.memoryProject) {
|
|
152102
152007
|
try {
|
|
152103
|
-
|
|
152008
|
+
fs3.mkdirSync(p.projectDir, { recursive: true });
|
|
152104
152009
|
} catch {
|
|
152105
152010
|
}
|
|
152106
152011
|
memoryFiles.push({ path: p.projectMemory, label: "project-level" });
|
|
@@ -152116,7 +152021,7 @@ function buildPotentialContextFiles(cwd2, cfg) {
|
|
|
152116
152021
|
if (cfg.memory?.global !== false) memoryFiles.push({ path: p.globalMemory, label: "user-level" });
|
|
152117
152022
|
if (cfg.memory?.project !== false) {
|
|
152118
152023
|
try {
|
|
152119
|
-
|
|
152024
|
+
fs3.mkdirSync(p.projectDir, { recursive: true });
|
|
152120
152025
|
} catch {
|
|
152121
152026
|
}
|
|
152122
152027
|
memoryFiles.push({ path: p.projectMemory, label: "project-level" });
|
|
@@ -152150,39 +152055,39 @@ var init_appConfig = __esm({
|
|
|
152150
152055
|
});
|
|
152151
152056
|
|
|
152152
152057
|
// src/marketplace.ts
|
|
152153
|
-
import * as
|
|
152058
|
+
import * as fs4 from "fs";
|
|
152154
152059
|
import * as os4 from "os";
|
|
152155
|
-
import * as
|
|
152060
|
+
import * as path4 from "path";
|
|
152156
152061
|
import { randomUUID } from "crypto";
|
|
152157
152062
|
import { execFile } from "child_process";
|
|
152158
152063
|
import { promisify } from "util";
|
|
152159
152064
|
function ownConfigPath() {
|
|
152160
|
-
return
|
|
152065
|
+
return path4.join(getAtomixRoot(), "marketplace.json");
|
|
152161
152066
|
}
|
|
152162
152067
|
function clonesDir() {
|
|
152163
|
-
return
|
|
152068
|
+
return path4.join(getAtomixRoot(), "marketplace");
|
|
152164
152069
|
}
|
|
152165
|
-
function
|
|
152166
|
-
return
|
|
152070
|
+
function statePath() {
|
|
152071
|
+
return path4.join(getAtomixRoot(), "marketplace-state.json");
|
|
152167
152072
|
}
|
|
152168
152073
|
function initMarketplaceProject(cwd2) {
|
|
152169
|
-
activeProjectDir =
|
|
152074
|
+
activeProjectDir = path4.resolve(cwd2);
|
|
152170
152075
|
if (_instance) _instance.reload();
|
|
152171
152076
|
}
|
|
152172
152077
|
function projectStatePath() {
|
|
152173
|
-
return activeProjectDir ?
|
|
152078
|
+
return activeProjectDir ? path4.join(activeProjectDir, ".atomix", "marketplace-state.json") : null;
|
|
152174
152079
|
}
|
|
152175
152080
|
function resolveTilde(p) {
|
|
152176
|
-
return p.startsWith("~/") ?
|
|
152081
|
+
return p.startsWith("~/") ? path4.join(os4.homedir(), p.slice(2)) : path4.resolve(p);
|
|
152177
152082
|
}
|
|
152178
152083
|
async function cloneOrPull(url, branch, localPath) {
|
|
152179
|
-
if (
|
|
152084
|
+
if (fs4.existsSync(path4.join(localPath, ".git"))) {
|
|
152180
152085
|
await execFileP("git", ["-C", localPath, "fetch", "origin"], { timeout: 12e4 });
|
|
152181
152086
|
await execFileP("git", ["-C", localPath, "checkout", branch], { timeout: 3e4 });
|
|
152182
152087
|
await execFileP("git", ["-C", localPath, "pull", "origin", branch], { timeout: 12e4 });
|
|
152183
152088
|
} else {
|
|
152184
|
-
if (
|
|
152185
|
-
|
|
152089
|
+
if (fs4.existsSync(localPath)) fs4.rmSync(localPath, { recursive: true, force: true });
|
|
152090
|
+
fs4.mkdirSync(path4.dirname(localPath), { recursive: true });
|
|
152186
152091
|
await execFileP("git", ["clone", "--depth", "1", "--branch", branch, url, localPath], { timeout: 3e5 });
|
|
152187
152092
|
}
|
|
152188
152093
|
}
|
|
@@ -152190,22 +152095,31 @@ function getMarketplace() {
|
|
|
152190
152095
|
if (!_instance) _instance = new Marketplace();
|
|
152191
152096
|
return _instance;
|
|
152192
152097
|
}
|
|
152098
|
+
function registerSessionDirs(core, dirs) {
|
|
152099
|
+
sessionRegistry.set(core, dirs);
|
|
152100
|
+
}
|
|
152101
|
+
function unregisterSessionDirs(core) {
|
|
152102
|
+
sessionRegistry.delete(core);
|
|
152103
|
+
}
|
|
152104
|
+
function listSessionDirs() {
|
|
152105
|
+
return [...sessionRegistry.entries()];
|
|
152106
|
+
}
|
|
152193
152107
|
function buildAgentsExtraDirs() {
|
|
152194
|
-
|
|
152195
|
-
return activeAgentsDirs;
|
|
152108
|
+
return getMarketplace().getSubagentDirs();
|
|
152196
152109
|
}
|
|
152197
152110
|
function refreshAgentsExtraDirs() {
|
|
152198
|
-
|
|
152111
|
+
const fresh = getMarketplace().getSubagentDirs();
|
|
152112
|
+
for (const [, d] of sessionRegistry) d.agents.splice(0, d.agents.length, ...fresh);
|
|
152199
152113
|
}
|
|
152200
152114
|
function buildCommandsExtraDirs() {
|
|
152201
|
-
|
|
152202
|
-
return activeCommandDirs;
|
|
152115
|
+
return getMarketplace().getCommandDirs();
|
|
152203
152116
|
}
|
|
152204
152117
|
function refreshCommandsExtraDirs() {
|
|
152205
|
-
|
|
152118
|
+
const fresh = getMarketplace().getCommandDirs();
|
|
152119
|
+
for (const [, d] of sessionRegistry) d.commands.splice(0, d.commands.length, ...fresh);
|
|
152206
152120
|
}
|
|
152207
152121
|
function syncMarketplaceMcp() {
|
|
152208
|
-
const mcpPath =
|
|
152122
|
+
const mcpPath = path4.join(getAtomixRoot(), "mcp.json");
|
|
152209
152123
|
const file = readJson(mcpPath) ?? { mcpServers: {} };
|
|
152210
152124
|
if (!file.mcpServers || typeof file.mcpServers !== "object") file.mcpServers = {};
|
|
152211
152125
|
const before2 = JSON.stringify(file.mcpServers);
|
|
@@ -152230,13 +152144,13 @@ function syncMarketplaceMcp() {
|
|
|
152230
152144
|
}
|
|
152231
152145
|
const removed = [...localCopies.keys()].filter((k) => !synced.includes(k));
|
|
152232
152146
|
if (JSON.stringify(file.mcpServers) !== before2) {
|
|
152233
|
-
|
|
152234
|
-
|
|
152147
|
+
fs4.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
152148
|
+
fs4.writeFileSync(mcpPath, JSON.stringify(file, null, 2) + "\n");
|
|
152235
152149
|
}
|
|
152236
152150
|
return { synced, removed, entries };
|
|
152237
152151
|
}
|
|
152238
152152
|
function getEffectiveMcpEntries() {
|
|
152239
|
-
const mcpPath =
|
|
152153
|
+
const mcpPath = path4.join(getAtomixRoot(), "mcp.json");
|
|
152240
152154
|
const file = readJson(mcpPath);
|
|
152241
152155
|
const local = file?.mcpServers ?? {};
|
|
152242
152156
|
return getMarketplace().getMCPServerDefs("effective").map((def) => ({
|
|
@@ -152246,17 +152160,17 @@ function getEffectiveMcpEntries() {
|
|
|
152246
152160
|
}
|
|
152247
152161
|
function readJson(p) {
|
|
152248
152162
|
try {
|
|
152249
|
-
return JSON.parse(
|
|
152163
|
+
return JSON.parse(fs4.readFileSync(p, "utf8"));
|
|
152250
152164
|
} catch {
|
|
152251
152165
|
return null;
|
|
152252
152166
|
}
|
|
152253
152167
|
}
|
|
152254
152168
|
function listDirs(p) {
|
|
152255
152169
|
try {
|
|
152256
|
-
return
|
|
152170
|
+
return fs4.readdirSync(p).filter((e) => {
|
|
152257
152171
|
if (e.startsWith(".")) return false;
|
|
152258
152172
|
try {
|
|
152259
|
-
return
|
|
152173
|
+
return fs4.statSync(path4.join(p, e)).isDirectory();
|
|
152260
152174
|
} catch {
|
|
152261
152175
|
return false;
|
|
152262
152176
|
}
|
|
@@ -152266,9 +152180,9 @@ function listDirs(p) {
|
|
|
152266
152180
|
}
|
|
152267
152181
|
}
|
|
152268
152182
|
function readPluginMCPConfig(pluginDir) {
|
|
152269
|
-
const dotMcp = readJson(
|
|
152183
|
+
const dotMcp = readJson(path4.join(pluginDir, ".mcp.json"));
|
|
152270
152184
|
if (dotMcp) return parseDotMcpJson(dotMcp, pluginDir);
|
|
152271
|
-
const mcpFile = readJson(
|
|
152185
|
+
const mcpFile = readJson(path4.join(pluginDir, "mcp", "mcp.json"));
|
|
152272
152186
|
return Array.isArray(mcpFile?.servers) ? mcpFile.servers : [];
|
|
152273
152187
|
}
|
|
152274
152188
|
function parseDotMcpJson(data, pluginDir) {
|
|
@@ -152300,23 +152214,23 @@ function parseDotMcpJson(data, pluginDir) {
|
|
|
152300
152214
|
}
|
|
152301
152215
|
function countPluginContents(dir) {
|
|
152302
152216
|
let skillCount = 0;
|
|
152303
|
-
const skillsDir =
|
|
152217
|
+
const skillsDir = path4.join(dir, "skills");
|
|
152304
152218
|
for (const entry of listDirs(skillsDir)) {
|
|
152305
|
-
if (["SKILL.md", "skill.md", "Skill.md"].some((n) =>
|
|
152219
|
+
if (["SKILL.md", "skill.md", "Skill.md"].some((n) => fs4.existsSync(path4.join(skillsDir, entry, n)))) skillCount++;
|
|
152306
152220
|
}
|
|
152307
152221
|
let commandCount = 0;
|
|
152308
152222
|
try {
|
|
152309
|
-
commandCount =
|
|
152223
|
+
commandCount = fs4.readdirSync(path4.join(dir, "commands")).filter((e) => e.endsWith(".md") && !e.startsWith(".")).length;
|
|
152310
152224
|
} catch {
|
|
152311
152225
|
}
|
|
152312
152226
|
return {
|
|
152313
152227
|
skillCount,
|
|
152314
152228
|
commandCount,
|
|
152315
152229
|
mcpServerCount: readPluginMCPConfig(dir).length,
|
|
152316
|
-
hasHooks:
|
|
152230
|
+
hasHooks: fs4.existsSync(path4.join(dir, "hooks", "hooks.json"))
|
|
152317
152231
|
};
|
|
152318
152232
|
}
|
|
152319
|
-
var execFileP, MKT_PREFIX, activeProjectDir, Marketplace, _instance,
|
|
152233
|
+
var execFileP, MKT_PREFIX, activeProjectDir, Marketplace, _instance, sessionRegistry;
|
|
152320
152234
|
var init_marketplace = __esm({
|
|
152321
152235
|
"src/marketplace.ts"() {
|
|
152322
152236
|
"use strict";
|
|
@@ -152337,7 +152251,7 @@ var init_marketplace = __esm({
|
|
|
152337
152251
|
reload() {
|
|
152338
152252
|
this.own = readJson(ownConfigPath()) ?? { sources: [] };
|
|
152339
152253
|
if (!Array.isArray(this.own.sources)) this.own = { sources: [] };
|
|
152340
|
-
this.state = readJson(
|
|
152254
|
+
this.state = readJson(statePath()) ?? {};
|
|
152341
152255
|
const pp = projectStatePath();
|
|
152342
152256
|
this.projectState = (pp ? readJson(pp) : null) ?? {};
|
|
152343
152257
|
this.external = [];
|
|
@@ -152365,7 +152279,7 @@ var init_marketplace = __esm({
|
|
|
152365
152279
|
type: data.type,
|
|
152366
152280
|
url: data.url,
|
|
152367
152281
|
branch: data.branch ?? "main",
|
|
152368
|
-
localPath: data.type === "git" ?
|
|
152282
|
+
localPath: data.type === "git" ? path4.join(clonesDir(), id) : resolveTilde(data.localPath ?? ""),
|
|
152369
152283
|
priority: maxPriority + 1,
|
|
152370
152284
|
enabled: true,
|
|
152371
152285
|
lastSynced: null
|
|
@@ -152399,7 +152313,7 @@ var init_marketplace = __esm({
|
|
|
152399
152313
|
this.saveState();
|
|
152400
152314
|
if (source.type === "git") {
|
|
152401
152315
|
try {
|
|
152402
|
-
|
|
152316
|
+
fs4.rmSync(path4.join(clonesDir(), source.id), { recursive: true, force: true });
|
|
152403
152317
|
} catch {
|
|
152404
152318
|
}
|
|
152405
152319
|
}
|
|
@@ -152468,26 +152382,26 @@ var init_marketplace = __esm({
|
|
|
152468
152382
|
/** 插件配置目录优先级:.atomix-plugin > .semaclaw-plugin > .claude-plugin */
|
|
152469
152383
|
resolvePluginJson(dir) {
|
|
152470
152384
|
for (const conf of [".atomix-plugin", ".semaclaw-plugin", ".claude-plugin"]) {
|
|
152471
|
-
const p =
|
|
152472
|
-
if (
|
|
152385
|
+
const p = path4.join(dir, conf, "plugin.json");
|
|
152386
|
+
if (fs4.existsSync(p)) return p;
|
|
152473
152387
|
}
|
|
152474
152388
|
return null;
|
|
152475
152389
|
}
|
|
152476
152390
|
/** 三种布局:源根即插件 / 平铺插件子目录 / 分组目录再下一层 */
|
|
152477
152391
|
findPlugins(localPath) {
|
|
152478
|
-
if (!
|
|
152392
|
+
if (!fs4.existsSync(localPath)) return [];
|
|
152479
152393
|
const rootJson = this.resolvePluginJson(localPath);
|
|
152480
152394
|
if (rootJson) return [{ dir: localPath, pluginJsonPath: rootJson }];
|
|
152481
152395
|
const results = [];
|
|
152482
152396
|
for (const entry of listDirs(localPath)) {
|
|
152483
|
-
const entryPath =
|
|
152397
|
+
const entryPath = path4.join(localPath, entry);
|
|
152484
152398
|
const pluginJson = this.resolvePluginJson(entryPath);
|
|
152485
152399
|
if (pluginJson) {
|
|
152486
152400
|
results.push({ dir: entryPath, pluginJsonPath: pluginJson });
|
|
152487
152401
|
continue;
|
|
152488
152402
|
}
|
|
152489
152403
|
for (const sub of listDirs(entryPath)) {
|
|
152490
|
-
const subPath =
|
|
152404
|
+
const subPath = path4.join(entryPath, sub);
|
|
152491
152405
|
const subJson = this.resolvePluginJson(subPath);
|
|
152492
152406
|
if (subJson) results.push({ dir: subPath, pluginJsonPath: subJson });
|
|
152493
152407
|
}
|
|
@@ -152496,7 +152410,7 @@ var init_marketplace = __esm({
|
|
|
152496
152410
|
}
|
|
152497
152411
|
pluginName(def) {
|
|
152498
152412
|
const meta = readJson(def.pluginJsonPath) ?? {};
|
|
152499
|
-
return meta.name ||
|
|
152413
|
+
return meta.name || path4.basename(def.dir);
|
|
152500
152414
|
}
|
|
152501
152415
|
/** 启用的源,按 priority 降序(高优先级源后处理 = 覆盖生效) */
|
|
152502
152416
|
enabledSourcesByDescPriority() {
|
|
@@ -152517,8 +152431,8 @@ var init_marketplace = __esm({
|
|
|
152517
152431
|
getSkillExtraDirs() {
|
|
152518
152432
|
const result2 = [];
|
|
152519
152433
|
for (const { def } of this.enabledPluginDirs()) {
|
|
152520
|
-
const dir =
|
|
152521
|
-
if (
|
|
152434
|
+
const dir = path4.join(def.dir, "skills");
|
|
152435
|
+
if (fs4.existsSync(dir)) result2.push({ dir, locate: "managed" });
|
|
152522
152436
|
}
|
|
152523
152437
|
return result2;
|
|
152524
152438
|
}
|
|
@@ -152526,8 +152440,8 @@ var init_marketplace = __esm({
|
|
|
152526
152440
|
getCommandDirs() {
|
|
152527
152441
|
const result2 = [];
|
|
152528
152442
|
for (const { def } of this.enabledPluginDirs()) {
|
|
152529
|
-
const dir =
|
|
152530
|
-
if (
|
|
152443
|
+
const dir = path4.join(def.dir, "commands");
|
|
152444
|
+
if (fs4.existsSync(dir)) result2.push(dir);
|
|
152531
152445
|
}
|
|
152532
152446
|
return result2;
|
|
152533
152447
|
}
|
|
@@ -152536,8 +152450,8 @@ var init_marketplace = __esm({
|
|
|
152536
152450
|
const result2 = [];
|
|
152537
152451
|
for (const { def } of this.enabledPluginDirs()) {
|
|
152538
152452
|
for (const dirName of ["subagents", "agents"]) {
|
|
152539
|
-
const dir =
|
|
152540
|
-
if (
|
|
152453
|
+
const dir = path4.join(def.dir, dirName);
|
|
152454
|
+
if (fs4.existsSync(dir)) result2.push(dir);
|
|
152541
152455
|
}
|
|
152542
152456
|
}
|
|
152543
152457
|
return result2;
|
|
@@ -152546,8 +152460,8 @@ var init_marketplace = __esm({
|
|
|
152546
152460
|
getHookEntries() {
|
|
152547
152461
|
const result2 = [];
|
|
152548
152462
|
for (const { def } of this.enabledPluginDirs()) {
|
|
152549
|
-
const file =
|
|
152550
|
-
if (
|
|
152463
|
+
const file = path4.join(def.dir, "hooks", "hooks.json");
|
|
152464
|
+
if (fs4.existsSync(file)) result2.push({ file, pluginDir: def.dir });
|
|
152551
152465
|
}
|
|
152552
152466
|
return result2;
|
|
152553
152467
|
}
|
|
@@ -152572,7 +152486,7 @@ var init_marketplace = __esm({
|
|
|
152572
152486
|
for (const source of this.getSources()) {
|
|
152573
152487
|
for (const def of this.findPlugins(source.localPath)) {
|
|
152574
152488
|
const meta = readJson(def.pluginJsonPath) ?? {};
|
|
152575
|
-
const name = meta.name ||
|
|
152489
|
+
const name = meta.name || path4.basename(def.dir);
|
|
152576
152490
|
result2.push({
|
|
152577
152491
|
name,
|
|
152578
152492
|
description: meta.description ?? "",
|
|
@@ -152593,23 +152507,22 @@ var init_marketplace = __esm({
|
|
|
152593
152507
|
}
|
|
152594
152508
|
// ===== 持久化 =====
|
|
152595
152509
|
saveOwn() {
|
|
152596
|
-
|
|
152597
|
-
|
|
152510
|
+
fs4.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
152511
|
+
fs4.writeFileSync(ownConfigPath(), JSON.stringify(this.own, null, 2) + "\n");
|
|
152598
152512
|
}
|
|
152599
152513
|
saveState() {
|
|
152600
|
-
|
|
152601
|
-
|
|
152514
|
+
fs4.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
152515
|
+
fs4.writeFileSync(statePath(), JSON.stringify(this.state, null, 2) + "\n");
|
|
152602
152516
|
}
|
|
152603
152517
|
saveProjectState() {
|
|
152604
152518
|
const pp = projectStatePath();
|
|
152605
152519
|
if (!pp) throw new Error("\u9879\u76EE\u7EA7 override \u9700\u8981\u5148 initMarketplaceProject(cwd)");
|
|
152606
|
-
|
|
152607
|
-
|
|
152520
|
+
fs4.mkdirSync(path4.dirname(pp), { recursive: true });
|
|
152521
|
+
fs4.writeFileSync(pp, JSON.stringify(this.projectState, null, 2) + "\n");
|
|
152608
152522
|
}
|
|
152609
152523
|
};
|
|
152610
152524
|
_instance = null;
|
|
152611
|
-
|
|
152612
|
-
activeCommandDirs = null;
|
|
152525
|
+
sessionRegistry = /* @__PURE__ */ new Map();
|
|
152613
152526
|
}
|
|
152614
152527
|
});
|
|
152615
152528
|
|
|
@@ -152624,23 +152537,23 @@ __export(skills_exports, {
|
|
|
152624
152537
|
refreshSkillsExtraDirs: () => refreshSkillsExtraDirs,
|
|
152625
152538
|
skillsCommand: () => skillsCommand
|
|
152626
152539
|
});
|
|
152627
|
-
import * as
|
|
152540
|
+
import * as fs5 from "fs";
|
|
152628
152541
|
import * as os5 from "os";
|
|
152629
|
-
import * as
|
|
152630
|
-
function
|
|
152631
|
-
return
|
|
152542
|
+
import * as path5 from "path";
|
|
152543
|
+
function disabledFile() {
|
|
152544
|
+
return path5.join(getAtomixRoot(), "disabled-skills.json");
|
|
152632
152545
|
}
|
|
152633
152546
|
function readDisabledSkills() {
|
|
152634
152547
|
try {
|
|
152635
|
-
const parsed = JSON.parse(
|
|
152548
|
+
const parsed = JSON.parse(fs5.readFileSync(disabledFile(), "utf8"));
|
|
152636
152549
|
if (Array.isArray(parsed.disabled)) return new Set(parsed.disabled);
|
|
152637
152550
|
} catch {
|
|
152638
152551
|
}
|
|
152639
152552
|
return /* @__PURE__ */ new Set();
|
|
152640
152553
|
}
|
|
152641
152554
|
function writeDisabledSkills(disabled) {
|
|
152642
|
-
|
|
152643
|
-
|
|
152555
|
+
fs5.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
152556
|
+
fs5.writeFileSync(disabledFile(), JSON.stringify({ disabled: [...disabled].sort() }, null, 2) + "\n");
|
|
152644
152557
|
}
|
|
152645
152558
|
function disableSkill(name) {
|
|
152646
152559
|
const s = readDisabledSkills();
|
|
@@ -152654,50 +152567,50 @@ function enableSkill(name) {
|
|
|
152654
152567
|
return true;
|
|
152655
152568
|
}
|
|
152656
152569
|
function resolveTilde2(p) {
|
|
152657
|
-
return p.startsWith("~/") ?
|
|
152570
|
+
return p.startsWith("~/") ? path5.join(os5.homedir(), p.slice(2)) : path5.resolve(p);
|
|
152658
152571
|
}
|
|
152659
152572
|
function computeSkillsExtraDirs() {
|
|
152660
152573
|
const eco = readConfig().ecosystem ?? {};
|
|
152661
152574
|
const dirs = [];
|
|
152662
|
-
const claudeSkills =
|
|
152663
|
-
if ((eco.inheritClaudeSkills ?? true) &&
|
|
152575
|
+
const claudeSkills = path5.join(os5.homedir(), ".claude", "skills");
|
|
152576
|
+
if ((eco.inheritClaudeSkills ?? true) && fs5.existsSync(claudeSkills)) {
|
|
152664
152577
|
dirs.push({ dir: claudeSkills, locate: "user" });
|
|
152665
152578
|
}
|
|
152666
|
-
const semaclawHome = process.env.SEMACLAW_CONFIG_HOME ?
|
|
152667
|
-
const managedSkills =
|
|
152668
|
-
if ((eco.inheritSemaclawManagedSkills ?? true) &&
|
|
152579
|
+
const semaclawHome = process.env.SEMACLAW_CONFIG_HOME ? path5.resolve(process.env.SEMACLAW_CONFIG_HOME) : path5.join(os5.homedir(), ".semaclaw");
|
|
152580
|
+
const managedSkills = path5.join(semaclawHome, "managed", "skills");
|
|
152581
|
+
if ((eco.inheritSemaclawManagedSkills ?? true) && fs5.existsSync(managedSkills)) {
|
|
152669
152582
|
dirs.push({ dir: managedSkills, locate: "managed" });
|
|
152670
152583
|
}
|
|
152671
152584
|
for (const d of eco.sharedSkillDirs ?? []) {
|
|
152672
152585
|
const resolved = resolveTilde2(d);
|
|
152673
|
-
if (
|
|
152586
|
+
if (fs5.existsSync(resolved)) dirs.push({ dir: resolved, locate: "managed" });
|
|
152674
152587
|
}
|
|
152675
152588
|
dirs.push(...getMarketplace().getSkillExtraDirs());
|
|
152676
152589
|
return dirs;
|
|
152677
152590
|
}
|
|
152678
152591
|
function buildSkillsExtraDirs() {
|
|
152679
|
-
|
|
152680
|
-
return activeExtraDirs;
|
|
152592
|
+
return computeSkillsExtraDirs();
|
|
152681
152593
|
}
|
|
152682
152594
|
function refreshSkillsExtraDirs() {
|
|
152683
|
-
|
|
152595
|
+
const fresh = computeSkillsExtraDirs();
|
|
152596
|
+
for (const [, d] of listSessionDirs()) d.skills.splice(0, d.skills.length, ...fresh);
|
|
152684
152597
|
}
|
|
152685
152598
|
function applyDisabledSkills(core) {
|
|
152686
152599
|
core.reloadSkills();
|
|
152687
|
-
const allNames = core.getSkillsInfo().map((s) => s.name);
|
|
152688
|
-
recordSkillUniverse(allNames);
|
|
152689
|
-
const disabled = /* @__PURE__ */ new Set([...readDisabledSkills(), ...harnessDisabledSkills(allNames)]);
|
|
152600
|
+
const allNames = core.getSkillsInfo({ includeDisabled: true }).map((s) => s.name);
|
|
152601
|
+
recordSkillUniverse(core, allNames);
|
|
152602
|
+
const disabled = /* @__PURE__ */ new Set([...readDisabledSkills(), ...harnessDisabledSkills(core, allNames)]);
|
|
152690
152603
|
core.reloadSkills(disabled);
|
|
152691
152604
|
}
|
|
152692
152605
|
function sourceLabel(s) {
|
|
152693
152606
|
const p = s.filePath ?? "";
|
|
152694
|
-
if (p.includes(`${
|
|
152695
|
-
if (p.includes(`${
|
|
152696
|
-
if (p.includes(`${
|
|
152607
|
+
if (p.includes(`${path5.sep}.claude${path5.sep}`)) return "claude";
|
|
152608
|
+
if (p.includes(`${path5.sep}.semaclaw${path5.sep}`)) return "semaclaw";
|
|
152609
|
+
if (p.includes(`${path5.sep}marketplace${path5.sep}`)) return "marketplace";
|
|
152697
152610
|
return LOCATE_LABEL[s.locate] ?? s.locate;
|
|
152698
152611
|
}
|
|
152699
152612
|
function semaclawConfigHome() {
|
|
152700
|
-
return process.env.SEMACLAW_CONFIG_HOME ?
|
|
152613
|
+
return process.env.SEMACLAW_CONFIG_HOME ? path5.resolve(process.env.SEMACLAW_CONFIG_HOME) : path5.join(os5.homedir(), ".semaclaw");
|
|
152701
152614
|
}
|
|
152702
152615
|
async function skillsCommand(core, args) {
|
|
152703
152616
|
const [sub, ...rest2] = args;
|
|
@@ -152734,7 +152647,7 @@ async function skillsCommand(core, args) {
|
|
|
152734
152647
|
const semaclawDisabled = (() => {
|
|
152735
152648
|
try {
|
|
152736
152649
|
const parsed = JSON.parse(
|
|
152737
|
-
|
|
152650
|
+
fs5.readFileSync(path5.join(semaclawConfigHome(), "disabled-skills.json"), "utf8")
|
|
152738
152651
|
);
|
|
152739
152652
|
return Array.isArray(parsed.disabled) ? parsed.disabled : [];
|
|
152740
152653
|
} catch {
|
|
@@ -152755,7 +152668,7 @@ async function skillsCommand(core, args) {
|
|
|
152755
152668
|
return `\u672A\u77E5\u5B50\u547D\u4EE4\uFF1A${sub}\uFF08\u7528\u6CD5\uFF1A/skills list | enable <\u540D\u79F0> | disable <\u540D\u79F0> | import-disabled\uFF09`;
|
|
152756
152669
|
}
|
|
152757
152670
|
}
|
|
152758
|
-
var
|
|
152671
|
+
var LOCATE_LABEL;
|
|
152759
152672
|
var init_skills = __esm({
|
|
152760
152673
|
"src/skills.ts"() {
|
|
152761
152674
|
"use strict";
|
|
@@ -152763,7 +152676,6 @@ var init_skills = __esm({
|
|
|
152763
152676
|
init_harness();
|
|
152764
152677
|
init_appConfig();
|
|
152765
152678
|
init_marketplace();
|
|
152766
|
-
activeExtraDirs = null;
|
|
152767
152679
|
LOCATE_LABEL = {
|
|
152768
152680
|
user: "user",
|
|
152769
152681
|
project: "project",
|
|
@@ -152773,6 +152685,905 @@ var init_skills = __esm({
|
|
|
152773
152685
|
}
|
|
152774
152686
|
});
|
|
152775
152687
|
|
|
152688
|
+
// src/agents.ts
|
|
152689
|
+
var agents_exports = {};
|
|
152690
|
+
__export(agents_exports, {
|
|
152691
|
+
agentsCommand: () => agentsCommand,
|
|
152692
|
+
applyDisabledAgents: () => applyDisabledAgents,
|
|
152693
|
+
disableAgent: () => disableAgent,
|
|
152694
|
+
enableAgent: () => enableAgent,
|
|
152695
|
+
readDisabledAgents: () => readDisabledAgents
|
|
152696
|
+
});
|
|
152697
|
+
import * as fs6 from "fs";
|
|
152698
|
+
import * as path6 from "path";
|
|
152699
|
+
function disabledFile2() {
|
|
152700
|
+
return path6.join(getAtomixRoot(), "disabled-agents.json");
|
|
152701
|
+
}
|
|
152702
|
+
function readDisabledAgents() {
|
|
152703
|
+
try {
|
|
152704
|
+
const parsed = JSON.parse(fs6.readFileSync(disabledFile2(), "utf8"));
|
|
152705
|
+
if (Array.isArray(parsed.disabled)) return new Set(parsed.disabled);
|
|
152706
|
+
} catch {
|
|
152707
|
+
}
|
|
152708
|
+
return /* @__PURE__ */ new Set();
|
|
152709
|
+
}
|
|
152710
|
+
function writeDisabledAgents(disabled) {
|
|
152711
|
+
fs6.mkdirSync(getAtomixRoot(), { recursive: true });
|
|
152712
|
+
fs6.writeFileSync(disabledFile2(), JSON.stringify({ disabled: [...disabled].sort() }, null, 2) + "\n");
|
|
152713
|
+
}
|
|
152714
|
+
function disableAgent(name) {
|
|
152715
|
+
const s = readDisabledAgents();
|
|
152716
|
+
s.add(name);
|
|
152717
|
+
writeDisabledAgents(s);
|
|
152718
|
+
}
|
|
152719
|
+
function enableAgent(name) {
|
|
152720
|
+
const s = readDisabledAgents();
|
|
152721
|
+
if (!s.delete(name)) return false;
|
|
152722
|
+
writeDisabledAgents(s);
|
|
152723
|
+
return true;
|
|
152724
|
+
}
|
|
152725
|
+
async function applyDisabledAgents(core) {
|
|
152726
|
+
await core.reloadAgents(/* @__PURE__ */ new Set());
|
|
152727
|
+
const allNames = core.getAgentsInfo().map((a) => a.name);
|
|
152728
|
+
recordAgentUniverse(core, allNames);
|
|
152729
|
+
const disabled = /* @__PURE__ */ new Set([...readDisabledAgents(), ...harnessDisabledAgents(core, allNames)]);
|
|
152730
|
+
await core.reloadAgents(disabled);
|
|
152731
|
+
}
|
|
152732
|
+
async function agentsCommand(core, args) {
|
|
152733
|
+
const [sub, ...rest2] = args;
|
|
152734
|
+
const name = rest2.join(" ").trim();
|
|
152735
|
+
switch (sub) {
|
|
152736
|
+
case void 0:
|
|
152737
|
+
case "list": {
|
|
152738
|
+
const infos = [...core.getAgentsInfo()].sort(
|
|
152739
|
+
(a, b) => a.locate.localeCompare(b.locate) || a.name.localeCompare(b.name)
|
|
152740
|
+
);
|
|
152741
|
+
const disabledSet = readDisabledAgents();
|
|
152742
|
+
const lines = infos.filter((a) => !disabledSet.has(a.name)).map((a) => {
|
|
152743
|
+
const desc = a.description ? ` \u2014 ${a.description.length > 60 ? a.description.slice(0, 60) + "\u2026" : a.description}` : "";
|
|
152744
|
+
return `\u25CF ${a.name} [${a.locate}]${desc}`;
|
|
152745
|
+
});
|
|
152746
|
+
for (const n of [...disabledSet].sort()) lines.push(`\u25CB ${n} \uFF08\u5DF2\u7981\u7528\uFF09`);
|
|
152747
|
+
if (!lines.length) lines.push("\uFF08\u65E0\u53EF\u7528\u4EBA\u8BBE\uFF09");
|
|
152748
|
+
lines.push(`\u25CF \u542F\u7528\u4E2D \u25CB \u5DF2\u7981\u7528${disabledSet.size === 0 ? "\uFF08\u5F53\u524D\u65E0\u7981\u7528\u9879\uFF09" : ""} \xB7 \u7528\u6CD5\uFF1A/agents list | enable <\u540D\u79F0> | disable <\u540D\u79F0>`);
|
|
152749
|
+
return lines.join("\n ");
|
|
152750
|
+
}
|
|
152751
|
+
case "disable": {
|
|
152752
|
+
if (!name) return "\u7528\u6CD5\uFF1A/agents disable <\u540D\u79F0>";
|
|
152753
|
+
disableAgent(name);
|
|
152754
|
+
await applyDisabledAgents(core);
|
|
152755
|
+
return `\u5DF2\u7981\u7528\u4EBA\u8BBE\uFF1A${name}`;
|
|
152756
|
+
}
|
|
152757
|
+
case "enable": {
|
|
152758
|
+
if (!name) return "\u7528\u6CD5\uFF1A/agents enable <\u540D\u79F0>";
|
|
152759
|
+
if (!enableAgent(name)) return `${name} \u672A\u88AB\u7981\u7528`;
|
|
152760
|
+
await applyDisabledAgents(core);
|
|
152761
|
+
return `\u5DF2\u542F\u7528\u4EBA\u8BBE\uFF1A${name}`;
|
|
152762
|
+
}
|
|
152763
|
+
default:
|
|
152764
|
+
return `\u672A\u77E5\u5B50\u547D\u4EE4\uFF1A${sub}\uFF08\u7528\u6CD5\uFF1A/agents list | enable <\u540D\u79F0> | disable <\u540D\u79F0>\uFF09`;
|
|
152765
|
+
}
|
|
152766
|
+
}
|
|
152767
|
+
var init_agents = __esm({
|
|
152768
|
+
"src/agents.ts"() {
|
|
152769
|
+
"use strict";
|
|
152770
|
+
init_paths();
|
|
152771
|
+
init_harness();
|
|
152772
|
+
}
|
|
152773
|
+
});
|
|
152774
|
+
|
|
152775
|
+
// src/harness.ts
|
|
152776
|
+
import * as fs7 from "fs";
|
|
152777
|
+
import * as path7 from "path";
|
|
152778
|
+
function runtimeOf(core) {
|
|
152779
|
+
return runtimes.get(core) ?? null;
|
|
152780
|
+
}
|
|
152781
|
+
function requireRuntime(core) {
|
|
152782
|
+
const rt = runtimeOf(core);
|
|
152783
|
+
if (!rt) throw new Error("harness \u672A\u521D\u59CB\u5316(initHarness \u672A\u8C03\u7528)");
|
|
152784
|
+
return rt;
|
|
152785
|
+
}
|
|
152786
|
+
function overrideOf(activeValue, baseValue) {
|
|
152787
|
+
if (baseValue === void 0 || activeValue === void 0) return null;
|
|
152788
|
+
const baseOn = baseValue !== null;
|
|
152789
|
+
const activeOn = activeValue !== null;
|
|
152790
|
+
return activeOn === baseOn ? null : activeOn ? "on" : "off";
|
|
152791
|
+
}
|
|
152792
|
+
function personaOverrideOf(activeValue, baseValue) {
|
|
152793
|
+
const basic = overrideOf(activeValue, baseValue);
|
|
152794
|
+
if (basic !== null) return basic;
|
|
152795
|
+
if (activeValue && baseValue && activeValue !== baseValue) return "swap";
|
|
152796
|
+
return null;
|
|
152797
|
+
}
|
|
152798
|
+
function harnessMemoryOverride(core) {
|
|
152799
|
+
const rt = runtimeOf(core);
|
|
152800
|
+
return rt ? overrideOf(rt.activeMemoryFiles, rt.baseline.memoryFiles) : null;
|
|
152801
|
+
}
|
|
152802
|
+
function harnessPersonaOverride(core) {
|
|
152803
|
+
const rt = runtimeOf(core);
|
|
152804
|
+
return rt ? personaOverrideOf(rt.activePersonaFile, rt.baseline.personaFile) : null;
|
|
152805
|
+
}
|
|
152806
|
+
function getActivePersonaFile(core) {
|
|
152807
|
+
return runtimeOf(core)?.activePersonaFile;
|
|
152808
|
+
}
|
|
152809
|
+
function getActiveHarnessName(core) {
|
|
152810
|
+
return runtimeOf(core)?.active?.name ?? BASE_HARNESS;
|
|
152811
|
+
}
|
|
152812
|
+
function getActiveHarnessDir(core) {
|
|
152813
|
+
return runtimeOf(core)?.active?.dirName ?? BASE_HARNESS;
|
|
152814
|
+
}
|
|
152815
|
+
function isHarnessActive(core) {
|
|
152816
|
+
return !!runtimeOf(core)?.active;
|
|
152817
|
+
}
|
|
152818
|
+
function harnessThinking(core) {
|
|
152819
|
+
return runtimeOf(core)?.active?.thinkingDeclared ?? null;
|
|
152820
|
+
}
|
|
152821
|
+
function appliedThinking(core) {
|
|
152822
|
+
return runtimeOf(core)?.activeThinking;
|
|
152823
|
+
}
|
|
152824
|
+
function thinkingStatusLine(core, current) {
|
|
152825
|
+
const on = (v) => v ? "on" : "off";
|
|
152826
|
+
const declared = harnessThinking(core);
|
|
152827
|
+
if (declared === null) return on(current);
|
|
152828
|
+
const dir = getActiveHarnessDir(core);
|
|
152829
|
+
return declared === current ? `${on(current)}(harness ${dir},\u4EC5 main;quick \u6052\u5173)` : `${on(current)}(\u4F1A\u8BDD\u4E34\u65F6\u5207\u6362;harness ${dir} \u58F0\u660E ${on(declared)},/harness use ${dir} \u91CD\u65B0\u5E94\u7528\u5373\u6062\u590D)`;
|
|
152830
|
+
}
|
|
152831
|
+
function harnessTemperatureOverride(core) {
|
|
152832
|
+
return runtimeOf(core)?.active?.temperatureOverrides ?? null;
|
|
152833
|
+
}
|
|
152834
|
+
function effectiveTemperatures(core) {
|
|
152835
|
+
const models = effectiveModels(core);
|
|
152836
|
+
const profiles = core.getModelProfiles();
|
|
152837
|
+
const over2 = harnessTemperatureOverride(core);
|
|
152838
|
+
const one = (slot) => {
|
|
152839
|
+
const prof = profiles.find((p) => p.name === models[slot]);
|
|
152840
|
+
const mn = prof?.modelName;
|
|
152841
|
+
if (mn && (0, import_atomix_core4.modelForcesTemperatureOne)(mn)) return { value: 1, from: "fixed" };
|
|
152842
|
+
if (mn && (0, import_atomix_core4.modelRejectsTemperature)(mn)) return { value: null, from: "unsupported" };
|
|
152843
|
+
const anthropic = prof?.adapt === "anthropic";
|
|
152844
|
+
const gatedByThinking = anthropic || (mn ? (0, import_atomix_core4.modelTemperatureGatedByThinking)(mn) : false);
|
|
152845
|
+
const notes = [];
|
|
152846
|
+
let from = "default";
|
|
152847
|
+
let raw;
|
|
152848
|
+
const o = over2?.[slot];
|
|
152849
|
+
if (o !== void 0) {
|
|
152850
|
+
if ((0, import_atomix_core4.isValidTemperature)(o)) {
|
|
152851
|
+
raw = o;
|
|
152852
|
+
from = "harness";
|
|
152853
|
+
} else notes.push(`harness \u503C ${JSON.stringify(o)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
|
|
152854
|
+
}
|
|
152855
|
+
if (raw === void 0 && prof?.temperature !== void 0) {
|
|
152856
|
+
if ((0, import_atomix_core4.isValidTemperature)(prof.temperature)) {
|
|
152857
|
+
raw = prof.temperature;
|
|
152858
|
+
from = "profile";
|
|
152859
|
+
} else notes.push(`profile \u503C ${JSON.stringify(prof.temperature)} \u975E\u6CD5(\u987B 0\u20132),\u5DF2\u5FFD\u7565`);
|
|
152860
|
+
}
|
|
152861
|
+
if (raw === void 0) {
|
|
152862
|
+
return { value: anthropic ? import_atomix_core4.DEFAULT_ANTHROPIC_TEMPERATURE : null, from: "default", ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
|
|
152863
|
+
}
|
|
152864
|
+
let value = raw;
|
|
152865
|
+
if (anthropic && value > 1) {
|
|
152866
|
+
value = 1;
|
|
152867
|
+
notes.push(`\u58F0\u660E ${raw} \u8D85 anthropic \u534F\u8BAE\u4E0A\u9650,\u5B9E\u9645\u6309 1 \u53D1`);
|
|
152868
|
+
}
|
|
152869
|
+
return { value, from, configured: raw, ...gatedByThinking ? { gatedByThinking } : {}, ...notes.length ? { notes } : {} };
|
|
152870
|
+
};
|
|
152871
|
+
return { main: one("main"), quick: one("quick") };
|
|
152872
|
+
}
|
|
152873
|
+
function formatTemperature(e, thinkingOn) {
|
|
152874
|
+
if (e.from === "fixed") return "1(\u6A21\u578B\u56FA\u5B9A)";
|
|
152875
|
+
if (e.from === "unsupported") return "\u4E0D\u652F\u6301";
|
|
152876
|
+
const notes = e.notes?.length ? ";" + e.notes.join(";") : "";
|
|
152877
|
+
const hint = e.gatedByThinking && thinkingOn === void 0 ? ";thinking \u5F00\u65F6\u4E0D\u53D1" : "";
|
|
152878
|
+
if (e.from === "default") {
|
|
152879
|
+
if (thinkingOn && e.gatedByThinking) return `\u4E0D\u53D1(thinking \u5F00;${e.value === null ? "\u5173\u65F6\u4E3A\u670D\u52A1\u7AEF\u9ED8\u8BA4" : `\u5173\u65F6\u4E3A\u9ED8\u8BA4 ${e.value}`}${notes})`;
|
|
152880
|
+
return `\u9ED8\u8BA4(${e.value === null ? "\u670D\u52A1\u7AEF" : e.value}${notes}${hint})`;
|
|
152881
|
+
}
|
|
152882
|
+
const cfg = `${e.configured ?? e.value}(${e.from})`;
|
|
152883
|
+
if (thinkingOn && e.gatedByThinking) return `\u4E0D\u53D1(thinking \u5F00;\u914D\u7F6E ${cfg}${notes})`;
|
|
152884
|
+
return `${e.value}(${e.from}${notes}${hint})`;
|
|
152885
|
+
}
|
|
152886
|
+
function temperatureStatusLine(core, thinkingOn) {
|
|
152887
|
+
const t = effectiveTemperatures(core);
|
|
152888
|
+
return `main=${formatTemperature(t.main, thinkingOn)} quick=${formatTemperature(t.quick, false)}`;
|
|
152889
|
+
}
|
|
152890
|
+
function harnessModelOverride(core) {
|
|
152891
|
+
return runtimeOf(core)?.active?.modelOverrides ?? null;
|
|
152892
|
+
}
|
|
152893
|
+
function harnessModelFallback(core) {
|
|
152894
|
+
return runtimeOf(core)?.active?.modelFallback ?? null;
|
|
152895
|
+
}
|
|
152896
|
+
function harnessModelDeclared(core) {
|
|
152897
|
+
return runtimeOf(core)?.active?.modelDeclared ?? null;
|
|
152898
|
+
}
|
|
152899
|
+
function effectiveModels(core) {
|
|
152900
|
+
const base = core.getModelPointers();
|
|
152901
|
+
const over2 = harnessModelOverride(core);
|
|
152902
|
+
const fb = harnessModelFallback(core);
|
|
152903
|
+
const pick2 = (slot) => over2?.[slot] ? [over2[slot], "harness"] : [base[slot], fb?.[slot] ? "fallback" : "base"];
|
|
152904
|
+
const [main, mainFrom] = pick2("main");
|
|
152905
|
+
const [quick, quickFrom] = pick2("quick");
|
|
152906
|
+
return { main, quick, mainFrom, quickFrom, ...fb ? { fallback: fb } : {} };
|
|
152907
|
+
}
|
|
152908
|
+
function modelStatusLine(core) {
|
|
152909
|
+
const m = effectiveModels(core);
|
|
152910
|
+
if (m.mainFrom === "base" && m.quickFrom === "base") return `main=${m.main || "-"} quick=${m.quick || "-"}`;
|
|
152911
|
+
const part = (slot) => {
|
|
152912
|
+
const v = m[slot] || "-";
|
|
152913
|
+
const from = slot === "main" ? m.mainFrom : m.quickFrom;
|
|
152914
|
+
if (from === "fallback") return `${slot}=${v} (base;harness \u58F0\u660E ${m.fallback?.[slot]} \u4E0D\u5B58\u5728,\u5DF2\u56DE\u843D)`;
|
|
152915
|
+
return `${slot}=${v} (${from})`;
|
|
152916
|
+
};
|
|
152917
|
+
return `${m.fallback ? "\u26A0 " : ""}${part("main")} ${part("quick")}`;
|
|
152918
|
+
}
|
|
152919
|
+
function isHarnessOverridden(core) {
|
|
152920
|
+
return runtimeOf(core)?.overridden ?? false;
|
|
152921
|
+
}
|
|
152922
|
+
function recordSkillUniverse(core, names) {
|
|
152923
|
+
const rt = runtimeOf(core);
|
|
152924
|
+
if (rt) rt.fullSkillNames = names.slice();
|
|
152925
|
+
}
|
|
152926
|
+
function recordAgentUniverse(core, names) {
|
|
152927
|
+
const rt = runtimeOf(core);
|
|
152928
|
+
if (rt) rt.fullAgentNames = names.slice();
|
|
152929
|
+
}
|
|
152930
|
+
function computeDisabledFrom(spec, allNames) {
|
|
152931
|
+
if (!spec) return /* @__PURE__ */ new Set();
|
|
152932
|
+
return spec.mode === "whitelist" ? new Set(allNames.filter((n) => !spec.enable.includes(n))) : new Set(spec.disable);
|
|
152933
|
+
}
|
|
152934
|
+
function harnessDisabledSkills(core, allNames) {
|
|
152935
|
+
return computeDisabledFrom(runtimeOf(core)?.active?.skillsSpec ?? null, allNames);
|
|
152936
|
+
}
|
|
152937
|
+
function harnessDisabledAgents(core, allNames) {
|
|
152938
|
+
return computeDisabledFrom(runtimeOf(core)?.active?.agentsSpec ?? null, allNames);
|
|
152939
|
+
}
|
|
152940
|
+
function libraryDir() {
|
|
152941
|
+
return path7.join(getAtomixRoot(), "harness");
|
|
152942
|
+
}
|
|
152943
|
+
function statePath2(cwd2) {
|
|
152944
|
+
return path7.join(cwd2, ".atomix", "harness-state.json");
|
|
152945
|
+
}
|
|
152946
|
+
function readState(cwd2) {
|
|
152947
|
+
try {
|
|
152948
|
+
const parsed = JSON.parse(fs7.readFileSync(statePath2(cwd2), "utf8"));
|
|
152949
|
+
return typeof parsed.active === "string" && parsed.active ? parsed.active : BASE_HARNESS;
|
|
152950
|
+
} catch {
|
|
152951
|
+
return BASE_HARNESS;
|
|
152952
|
+
}
|
|
152953
|
+
}
|
|
152954
|
+
function writeState(cwd2, name) {
|
|
152955
|
+
const p = statePath2(cwd2);
|
|
152956
|
+
if (name === BASE_HARNESS) {
|
|
152957
|
+
try {
|
|
152958
|
+
fs7.unlinkSync(p);
|
|
152959
|
+
} catch {
|
|
152960
|
+
}
|
|
152961
|
+
return;
|
|
152962
|
+
}
|
|
152963
|
+
fs7.mkdirSync(path7.dirname(p), { recursive: true });
|
|
152964
|
+
fs7.writeFileSync(p, JSON.stringify({ active: name }, null, 2) + "\n");
|
|
152965
|
+
}
|
|
152966
|
+
function listHarnesses() {
|
|
152967
|
+
let names = [];
|
|
152968
|
+
try {
|
|
152969
|
+
names = fs7.readdirSync(libraryDir(), { withFileTypes: true }).filter((e) => e.isDirectory() && fs7.existsSync(path7.join(libraryDir(), e.name, "harness.yaml"))).map((e) => e.name).sort();
|
|
152970
|
+
} catch {
|
|
152971
|
+
}
|
|
152972
|
+
return [BASE_HARNESS, ...names.filter((n) => n !== BASE_HARNESS)];
|
|
152973
|
+
}
|
|
152974
|
+
function asStrArr(v) {
|
|
152975
|
+
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
152976
|
+
}
|
|
152977
|
+
function asMode(v) {
|
|
152978
|
+
return v === "whitelist" ? "whitelist" : "blacklist";
|
|
152979
|
+
}
|
|
152980
|
+
function normalizePromptGroup(raw) {
|
|
152981
|
+
const warnings = [];
|
|
152982
|
+
if (!raw || typeof raw !== "object") return { overrides: null, warnings };
|
|
152983
|
+
const g = raw;
|
|
152984
|
+
const meta = new Map(import_atomix_core3.PROMPT_SECTION_CATALOG.map((m) => [m.name, m]));
|
|
152985
|
+
const replace2 = {};
|
|
152986
|
+
if (g.replace && typeof g.replace === "object") {
|
|
152987
|
+
for (const [name, text] of Object.entries(g.replace)) {
|
|
152988
|
+
const m = meta.get(name);
|
|
152989
|
+
if (!m) {
|
|
152990
|
+
warnings.push(`prompt.replace \u672A\u77E5\u6BB5\u540D ${name}(\u53EF\u7528:${[...meta.keys()].join(" / ")})`);
|
|
152991
|
+
continue;
|
|
152992
|
+
}
|
|
152993
|
+
if (m.locked) {
|
|
152994
|
+
warnings.push(`prompt.replace \u5FFD\u7565 ${name}:\u5B89\u5168\u6761\u6B3E\u6BB5\u4EE3\u7801\u7EA7\u9501\u5B9A`);
|
|
152995
|
+
continue;
|
|
152996
|
+
}
|
|
152997
|
+
if (m.dynamic) {
|
|
152998
|
+
warnings.push(`prompt.replace \u5FFD\u7565 ${name}:\u52A8\u6001\u6BB5(\u6BCF\u8F6E\u91CD\u7B97)\u53EA\u53EF disable`);
|
|
152999
|
+
continue;
|
|
153000
|
+
}
|
|
153001
|
+
if (typeof text !== "string") {
|
|
153002
|
+
warnings.push(`prompt.replace.${name} \u975E\u5B57\u7B26\u4E32,\u5FFD\u7565`);
|
|
153003
|
+
continue;
|
|
153004
|
+
}
|
|
153005
|
+
replace2[name] = text;
|
|
153006
|
+
}
|
|
153007
|
+
}
|
|
153008
|
+
const disable = [];
|
|
153009
|
+
for (const name of asStrArr(g.disable)) {
|
|
153010
|
+
const m = meta.get(name);
|
|
153011
|
+
if (!m) {
|
|
153012
|
+
warnings.push(`prompt.disable \u672A\u77E5\u6BB5\u540D ${name}`);
|
|
153013
|
+
continue;
|
|
153014
|
+
}
|
|
153015
|
+
if (m.locked) {
|
|
153016
|
+
warnings.push(`prompt.disable \u5FFD\u7565 ${name}:\u5B89\u5168\u6761\u6B3E\u6BB5\u4EE3\u7801\u7EA7\u9501\u5B9A`);
|
|
153017
|
+
continue;
|
|
153018
|
+
}
|
|
153019
|
+
disable.push(name);
|
|
153020
|
+
}
|
|
153021
|
+
const insert = [];
|
|
153022
|
+
if (Array.isArray(g.insert)) {
|
|
153023
|
+
for (const item of g.insert) {
|
|
153024
|
+
if (!item || typeof item !== "object") continue;
|
|
153025
|
+
const it = item;
|
|
153026
|
+
const name = typeof it.name === "string" ? it.name : "";
|
|
153027
|
+
const text = typeof it.text === "string" ? it.text : "";
|
|
153028
|
+
if (!name || !text.trim()) {
|
|
153029
|
+
warnings.push("prompt.insert \u5FFD\u7565\u7F3A name/text \u7684\u6761\u76EE");
|
|
153030
|
+
continue;
|
|
153031
|
+
}
|
|
153032
|
+
if (meta.has(name)) {
|
|
153033
|
+
warnings.push(`prompt.insert \u5FFD\u7565 ${name}:\u4E0E\u5185\u7F6E\u6BB5\u91CD\u540D(\u6539\u5185\u7F6E\u6BB5\u7528 replace)`);
|
|
153034
|
+
continue;
|
|
153035
|
+
}
|
|
153036
|
+
const order = typeof it.order === "number" && Number.isFinite(it.order) ? it.order : 999;
|
|
153037
|
+
insert.push({ name, order, text });
|
|
153038
|
+
}
|
|
153039
|
+
}
|
|
153040
|
+
const overrides = {};
|
|
153041
|
+
if (Object.keys(replace2).length) overrides.replace = replace2;
|
|
153042
|
+
if (disable.length) overrides.disable = disable;
|
|
153043
|
+
if (insert.length) overrides.insert = insert;
|
|
153044
|
+
return { overrides: Object.keys(overrides).length ? overrides : null, warnings };
|
|
153045
|
+
}
|
|
153046
|
+
function assertSafeHarnessName(name) {
|
|
153047
|
+
if (!name || name === "." || name === ".." || name.includes("/") || name.includes("\\") || path7.basename(name) !== name) {
|
|
153048
|
+
throw new Error(`\u975E\u6CD5 harness \u540D\u79F0:${JSON.stringify(name)}`);
|
|
153049
|
+
}
|
|
153050
|
+
}
|
|
153051
|
+
function assertInsideDir(dir, target, what) {
|
|
153052
|
+
const rel = path7.relative(dir, target);
|
|
153053
|
+
if (rel === ".." || rel.startsWith(`..${path7.sep}`) || path7.isAbsolute(rel)) {
|
|
153054
|
+
throw new Error(`${what}\u5FC5\u987B\u4F4D\u4E8E harness \u76EE\u5F55\u5185:${target}`);
|
|
153055
|
+
}
|
|
153056
|
+
}
|
|
153057
|
+
function loadHarnessDoc(name) {
|
|
153058
|
+
assertSafeHarnessName(name);
|
|
153059
|
+
const dir = path7.join(libraryDir(), name);
|
|
153060
|
+
const yamlPath = path7.join(dir, "harness.yaml");
|
|
153061
|
+
const raw = import_yaml.default.parse(fs7.readFileSync(yamlPath, "utf8"));
|
|
153062
|
+
if (!raw || typeof raw !== "object") throw new Error(`harness.yaml \u4E3A\u7A7A\u6216\u975E\u5BF9\u8C61:${yamlPath}`);
|
|
153063
|
+
const t = raw.tools ?? {};
|
|
153064
|
+
const sk = raw.skills ?? {};
|
|
153065
|
+
const ag = raw.agents ?? {};
|
|
153066
|
+
let rulesText = "";
|
|
153067
|
+
const rulesFile = typeof raw.rules === "string" ? raw.rules : "rules.md";
|
|
153068
|
+
const rulesPath = path7.resolve(dir, rulesFile);
|
|
153069
|
+
assertInsideDir(path7.resolve(dir), rulesPath, "rules \u6587\u4EF6");
|
|
153070
|
+
let rulesReal = null;
|
|
153071
|
+
try {
|
|
153072
|
+
rulesReal = fs7.realpathSync(rulesPath);
|
|
153073
|
+
} catch {
|
|
153074
|
+
}
|
|
153075
|
+
if (rulesReal !== null) {
|
|
153076
|
+
assertInsideDir(fs7.realpathSync(dir), rulesReal, "rules \u6587\u4EF6(symlink \u89E3\u6790\u540E)");
|
|
153077
|
+
rulesText = fs7.readFileSync(rulesReal, "utf8").trim();
|
|
153078
|
+
}
|
|
153079
|
+
let soulPath = null;
|
|
153080
|
+
let soulReal = null;
|
|
153081
|
+
try {
|
|
153082
|
+
soulReal = fs7.realpathSync(path7.resolve(dir, "SOUL.md"));
|
|
153083
|
+
} catch (e) {
|
|
153084
|
+
if (e.code !== "ENOENT") throw e;
|
|
153085
|
+
}
|
|
153086
|
+
if (soulReal !== null) {
|
|
153087
|
+
assertInsideDir(fs7.realpathSync(dir), soulReal, "SOUL \u6587\u4EF6(symlink \u89E3\u6790\u540E)");
|
|
153088
|
+
const soulStat = fs7.statSync(soulReal);
|
|
153089
|
+
if (!soulStat.isFile()) throw new Error(`SOUL.md \u4E0D\u662F\u666E\u901A\u6587\u4EF6:${soulReal}`);
|
|
153090
|
+
if (soulStat.nlink > 1) throw new Error(`SOUL.md \u662F\u591A\u786C\u94FE\u63A5\u6587\u4EF6,\u62D2\u7EDD\u52A0\u8F7D:${soulReal}`);
|
|
153091
|
+
soulPath = soulReal;
|
|
153092
|
+
}
|
|
153093
|
+
const promptGroup = normalizePromptGroup(raw.prompt);
|
|
153094
|
+
const toggleWarnings = [];
|
|
153095
|
+
const parseToggle = (v, key) => {
|
|
153096
|
+
if (v === void 0 || v === null) return null;
|
|
153097
|
+
if (v === "off" || v === false) return "off";
|
|
153098
|
+
if (v === "on" || v === true) return "on";
|
|
153099
|
+
toggleWarnings.push(`${key} \u53EA\u8BA4 on/off,\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
|
|
153100
|
+
return null;
|
|
153101
|
+
};
|
|
153102
|
+
const memory = parseToggle(raw.memory, "memory");
|
|
153103
|
+
const persona = parseToggle(raw.persona, "persona");
|
|
153104
|
+
const parseModel = (v) => {
|
|
153105
|
+
if (v === void 0 || v === null) return null;
|
|
153106
|
+
if (typeof v === "string") {
|
|
153107
|
+
const id = v.trim();
|
|
153108
|
+
if (id) return { main: id, quick: id };
|
|
153109
|
+
toggleWarnings.push("model \u4E3A\u7A7A\u5B57\u7B26\u4E32,\u5FFD\u7565(\u89C6\u4E3A\u672A\u58F0\u660E,\u8DDF\u968F base)");
|
|
153110
|
+
return null;
|
|
153111
|
+
}
|
|
153112
|
+
if (typeof v === "object" && !Array.isArray(v)) {
|
|
153113
|
+
const o = v;
|
|
153114
|
+
const out = {};
|
|
153115
|
+
for (const slot of MODEL_SLOTS) {
|
|
153116
|
+
const x = o[slot];
|
|
153117
|
+
if (x === void 0 || x === null) continue;
|
|
153118
|
+
if (typeof x === "string" && x.trim()) out[slot] = x.trim();
|
|
153119
|
+
else toggleWarnings.push(`model.${slot} \u987B\u4E3A\u6A21\u578B\u6807\u8BC6\u5B57\u7B26\u4E32(modelName[provider]),\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
|
|
153120
|
+
}
|
|
153121
|
+
for (const k of Object.keys(o)) if (!MODEL_SLOTS.includes(k)) toggleWarnings.push(`model \u672A\u77E5\u69FD\u4F4D ${k}(\u53EA\u8BA4 main / quick),\u5FFD\u7565`);
|
|
153122
|
+
if (!out.main && !out.quick) {
|
|
153123
|
+
toggleWarnings.push("model \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E(\u8DDF\u968F base)");
|
|
153124
|
+
return null;
|
|
153125
|
+
}
|
|
153126
|
+
return out;
|
|
153127
|
+
}
|
|
153128
|
+
toggleWarnings.push(`model \u53EA\u8BA4\u5B57\u7B26\u4E32\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
|
|
153129
|
+
return null;
|
|
153130
|
+
};
|
|
153131
|
+
const model = parseModel(raw.model);
|
|
153132
|
+
const thinkingToggle = parseToggle(raw.thinking, "thinking");
|
|
153133
|
+
const thinking = thinkingToggle === null ? null : thinkingToggle === "on";
|
|
153134
|
+
const parseTemperature = (v) => {
|
|
153135
|
+
if (v === void 0 || v === null) return null;
|
|
153136
|
+
const num = (x, label) => {
|
|
153137
|
+
if ((0, import_atomix_core4.isValidTemperature)(x)) return x;
|
|
153138
|
+
toggleWarnings.push(`${label} \u987B\u4E3A 0\u20132 \u7684\u6570\u5B57,\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(x)}`);
|
|
153139
|
+
return void 0;
|
|
153140
|
+
};
|
|
153141
|
+
if (typeof v === "number") {
|
|
153142
|
+
const t2 = num(v, "temperature");
|
|
153143
|
+
return t2 === void 0 ? null : { main: t2 };
|
|
153144
|
+
}
|
|
153145
|
+
if (typeof v === "object" && !Array.isArray(v)) {
|
|
153146
|
+
const o = v;
|
|
153147
|
+
const out = {};
|
|
153148
|
+
for (const slot of MODEL_SLOTS) {
|
|
153149
|
+
const x = o[slot];
|
|
153150
|
+
if (x === void 0 || x === null) continue;
|
|
153151
|
+
const t2 = num(x, `temperature.${slot}`);
|
|
153152
|
+
if (t2 !== void 0) out[slot] = t2;
|
|
153153
|
+
}
|
|
153154
|
+
for (const k of Object.keys(o)) if (!MODEL_SLOTS.includes(k)) toggleWarnings.push(`temperature \u672A\u77E5\u69FD\u4F4D ${k}(\u53EA\u8BA4 main / quick),\u5FFD\u7565`);
|
|
153155
|
+
if (out.main === void 0 && out.quick === void 0) {
|
|
153156
|
+
toggleWarnings.push("temperature \u672A\u58F0\u660E\u4EFB\u4F55\u6709\u6548\u69FD\u4F4D,\u89C6\u4E3A\u672A\u58F0\u660E");
|
|
153157
|
+
return null;
|
|
153158
|
+
}
|
|
153159
|
+
return out;
|
|
153160
|
+
}
|
|
153161
|
+
toggleWarnings.push(`temperature \u53EA\u8BA4\u6570\u5B57\u6216 { main, quick },\u5FFD\u7565\u975E\u6CD5\u503C ${JSON.stringify(v)}`);
|
|
153162
|
+
return null;
|
|
153163
|
+
};
|
|
153164
|
+
const temperature = parseTemperature(raw.temperature);
|
|
153165
|
+
return {
|
|
153166
|
+
name: typeof raw.name === "string" && raw.name ? raw.name : name,
|
|
153167
|
+
description: typeof raw.description === "string" ? raw.description : void 0,
|
|
153168
|
+
version: typeof raw.version === "string" ? raw.version : void 0,
|
|
153169
|
+
rulesText,
|
|
153170
|
+
tools: {
|
|
153171
|
+
mode: asMode(t.mode),
|
|
153172
|
+
useTools: Array.isArray(t.useTools) ? asStrArr(t.useTools) : null,
|
|
153173
|
+
disable: asStrArr(t.disable),
|
|
153174
|
+
enable: asStrArr(t.enable),
|
|
153175
|
+
defer: asStrArr(t.defer),
|
|
153176
|
+
pin: asStrArr(t.pin)
|
|
153177
|
+
},
|
|
153178
|
+
skills: { mode: asMode(sk.mode), disable: asStrArr(sk.disable), enable: asStrArr(sk.enable) },
|
|
153179
|
+
agents: { mode: asMode(ag.mode), disable: asStrArr(ag.disable), enable: asStrArr(ag.enable) },
|
|
153180
|
+
prompt: promptGroup.overrides,
|
|
153181
|
+
promptWarnings: promptGroup.warnings,
|
|
153182
|
+
memory,
|
|
153183
|
+
persona,
|
|
153184
|
+
soulPath,
|
|
153185
|
+
model,
|
|
153186
|
+
thinking,
|
|
153187
|
+
temperature,
|
|
153188
|
+
toggleWarnings,
|
|
153189
|
+
dir
|
|
153190
|
+
};
|
|
153191
|
+
}
|
|
153192
|
+
function resolveBase(ctx) {
|
|
153193
|
+
return {
|
|
153194
|
+
name: BASE_HARNESS,
|
|
153195
|
+
useTools: ctx.baseline.useTools,
|
|
153196
|
+
deferBuiltinTools: ctx.baseline.deferBuiltinTools ?? [],
|
|
153197
|
+
pinnedTools: [],
|
|
153198
|
+
customRules: "",
|
|
153199
|
+
promptOverrides: null,
|
|
153200
|
+
memoryFiles: ctx.baseline.memoryFiles,
|
|
153201
|
+
personaFile: ctx.baseline.personaFile,
|
|
153202
|
+
warnings: [],
|
|
153203
|
+
dirName: BASE_HARNESS,
|
|
153204
|
+
modelOverrides: null,
|
|
153205
|
+
modelDeclared: null,
|
|
153206
|
+
modelFallback: null,
|
|
153207
|
+
thinkingDeclared: null,
|
|
153208
|
+
temperatureOverrides: null,
|
|
153209
|
+
temperatureDeclared: null,
|
|
153210
|
+
thinking: ctx.baseline.thinking,
|
|
153211
|
+
skillsSpec: null,
|
|
153212
|
+
agentsSpec: null,
|
|
153213
|
+
skillsDisabled: /* @__PURE__ */ new Set(),
|
|
153214
|
+
agentsDisabled: /* @__PURE__ */ new Set()
|
|
153215
|
+
};
|
|
153216
|
+
}
|
|
153217
|
+
function resolveHarness(doc, ctx) {
|
|
153218
|
+
if (!doc) return resolveBase(ctx);
|
|
153219
|
+
let useTools;
|
|
153220
|
+
if (doc.tools.mode === "whitelist") {
|
|
153221
|
+
useTools = doc.tools.enable.slice();
|
|
153222
|
+
} else {
|
|
153223
|
+
useTools = doc.tools.useTools ?? ctx.baseline.useTools;
|
|
153224
|
+
if (doc.tools.disable.length) {
|
|
153225
|
+
const src = useTools ?? ctx.allToolNames;
|
|
153226
|
+
const drop2 = new Set(doc.tools.disable);
|
|
153227
|
+
useTools = src.filter((n) => !drop2.has(n));
|
|
153228
|
+
}
|
|
153229
|
+
}
|
|
153230
|
+
const warnings = [...doc.promptWarnings, ...doc.toggleWarnings];
|
|
153231
|
+
const resolveToggle = (toggle, base, potential, emptyWarning) => {
|
|
153232
|
+
if (base === void 0) return void 0;
|
|
153233
|
+
if (toggle === "off") return null;
|
|
153234
|
+
if (toggle === "on") {
|
|
153235
|
+
const p = potential === void 0 ? base : potential;
|
|
153236
|
+
if (p === null) {
|
|
153237
|
+
warnings.push(emptyWarning);
|
|
153238
|
+
return null;
|
|
153239
|
+
}
|
|
153240
|
+
return p;
|
|
153241
|
+
}
|
|
153242
|
+
return base;
|
|
153243
|
+
};
|
|
153244
|
+
const memoryFiles = resolveToggle(
|
|
153245
|
+
doc.memory,
|
|
153246
|
+
ctx.baseline.memoryFiles,
|
|
153247
|
+
ctx.baseline.potentialMemoryFiles,
|
|
153248
|
+
"memory: on \u65E0\u8D27\u53EF\u5F00:config.json \u5DF2\u628A global/project \u90FD\u663E\u5F0F\u5173\u6B7B"
|
|
153249
|
+
);
|
|
153250
|
+
let personaFile;
|
|
153251
|
+
if (ctx.baseline.personaFile === void 0) {
|
|
153252
|
+
personaFile = void 0;
|
|
153253
|
+
} else if (doc.persona === "off") {
|
|
153254
|
+
personaFile = null;
|
|
153255
|
+
} else if (doc.soulPath) {
|
|
153256
|
+
personaFile = doc.soulPath;
|
|
153257
|
+
} else {
|
|
153258
|
+
if (doc.persona === "on") warnings.push("persona: on \u65E0\u6548:\u672C harness \u672A\u5E26\u4E13\u5C5E SOUL.md(\u4E25\u683C\u9694\u79BB,\u4E0D\u501F base \u4EBA\u8BBE;\u653E\u4E00\u4EFD SOUL.md \u8FDB harness \u76EE\u5F55\u5373\u751F\u6548)");
|
|
153259
|
+
personaFile = null;
|
|
153260
|
+
}
|
|
153261
|
+
const dirName = path7.basename(doc.dir);
|
|
153262
|
+
const modelOverrides = {};
|
|
153263
|
+
const modelFallback = {};
|
|
153264
|
+
if (doc.model) {
|
|
153265
|
+
for (const slot of MODEL_SLOTS) {
|
|
153266
|
+
const want = doc.model[slot];
|
|
153267
|
+
if (!want) continue;
|
|
153268
|
+
if (ctx.modelNames.includes(want)) modelOverrides[slot] = want;
|
|
153269
|
+
else {
|
|
153270
|
+
modelFallback[slot] = want;
|
|
153271
|
+
warnings.push(`\u6A21\u578B\u56DE\u843D:harness.yaml \u58F0\u660E ${slot}=${want},model.conf \u4E2D\u4E0D\u5B58\u5728,\u5F53\u524D ${slot} \u4F7F\u7528 base \u7684 ${ctx.baseModels[slot] || "-"}(/model add \u6DFB\u52A0\u540E /harness use ${dirName} \u91CD\u65B0\u5E94\u7528)`);
|
|
153272
|
+
}
|
|
153273
|
+
}
|
|
153274
|
+
}
|
|
153275
|
+
const temperatureOverrides = {};
|
|
153276
|
+
if (doc.temperature) {
|
|
153277
|
+
for (const slot of MODEL_SLOTS) {
|
|
153278
|
+
const t = doc.temperature[slot];
|
|
153279
|
+
if (t === void 0) continue;
|
|
153280
|
+
const effModel = modelOverrides[slot] ?? ctx.baseModels[slot];
|
|
153281
|
+
const mn = ctx.modelProfiles?.find((p) => p.name === effModel)?.modelName;
|
|
153282
|
+
if (mn && (0, import_atomix_core4.modelForcesTemperatureOne)(mn)) {
|
|
153283
|
+
warnings.push(`\u6E29\u5EA6\u5FFD\u7565:harness.yaml \u58F0\u660E ${slot} temperature=${t},\u4F46\u6A21\u578B ${effModel} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1`);
|
|
153284
|
+
continue;
|
|
153285
|
+
}
|
|
153286
|
+
if (mn && (0, import_atomix_core4.modelRejectsTemperature)(mn)) {
|
|
153287
|
+
warnings.push(`\u6E29\u5EA6\u5FFD\u7565:harness.yaml \u58F0\u660E ${slot} temperature=${t},\u4F46\u6A21\u578B ${effModel} \u4E0D\u652F\u6301 temperature \u53C2\u6570`);
|
|
153288
|
+
continue;
|
|
153289
|
+
}
|
|
153290
|
+
temperatureOverrides[slot] = t;
|
|
153291
|
+
}
|
|
153292
|
+
}
|
|
153293
|
+
return {
|
|
153294
|
+
name: doc.name,
|
|
153295
|
+
dirName,
|
|
153296
|
+
temperatureOverrides: Object.keys(temperatureOverrides).length ? temperatureOverrides : null,
|
|
153297
|
+
temperatureDeclared: doc.temperature,
|
|
153298
|
+
modelOverrides: Object.keys(modelOverrides).length ? modelOverrides : null,
|
|
153299
|
+
modelDeclared: doc.model,
|
|
153300
|
+
modelFallback: Object.keys(modelFallback).length ? modelFallback : null,
|
|
153301
|
+
// thinking:声明即下发;未声明跟随基线(基线未知则不下发该键,与 memoryFiles 同规则)
|
|
153302
|
+
thinkingDeclared: doc.thinking,
|
|
153303
|
+
thinking: doc.thinking ?? ctx.baseline.thinking,
|
|
153304
|
+
useTools,
|
|
153305
|
+
deferBuiltinTools: doc.tools.defer.length ? doc.tools.defer : ctx.baseline.deferBuiltinTools ?? [],
|
|
153306
|
+
pinnedTools: doc.tools.pin,
|
|
153307
|
+
customRules: doc.rulesText,
|
|
153308
|
+
promptOverrides: doc.prompt,
|
|
153309
|
+
memoryFiles,
|
|
153310
|
+
personaFile,
|
|
153311
|
+
warnings,
|
|
153312
|
+
skillsSpec: doc.skills,
|
|
153313
|
+
agentsSpec: doc.agents,
|
|
153314
|
+
skillsDisabled: computeDisabledFrom(doc.skills, ctx.allSkillNames),
|
|
153315
|
+
agentsDisabled: computeDisabledFrom(doc.agents, ctx.allAgentNames)
|
|
153316
|
+
};
|
|
153317
|
+
}
|
|
153318
|
+
function buildContext(core) {
|
|
153319
|
+
const rt = requireRuntime(core);
|
|
153320
|
+
return {
|
|
153321
|
+
baseline: rt.baseline,
|
|
153322
|
+
// 工具:getToolInfos 恒返回内置全集(禁用项带 status),可直读;
|
|
153323
|
+
// skill:core 按 session 读取时过滤,includeDisabled 直接取供给全集;
|
|
153324
|
+
// agent:注册表是已过滤视图,优先用 applyDisabledAgents 回写的全集缓存,
|
|
153325
|
+
// 缓存为空只在启动初始化时(此刻尚未过滤,直读即全集)
|
|
153326
|
+
allToolNames: core.getToolInfos().map((t) => t.name),
|
|
153327
|
+
allSkillNames: rt.fullSkillNames ?? core.getSkillsInfo({ includeDisabled: true }).map((s) => s.name),
|
|
153328
|
+
allAgentNames: rt.fullAgentNames ?? core.getAgentsInfo().map((a) => a.name),
|
|
153329
|
+
modelNames: core.getModelNames(),
|
|
153330
|
+
baseModels: core.getModelPointers(),
|
|
153331
|
+
modelProfiles: core.getModelProfiles()
|
|
153332
|
+
};
|
|
153333
|
+
}
|
|
153334
|
+
function applyAssembly(core, rt, r, opts = {}) {
|
|
153335
|
+
core.updateAssemblyConfig({
|
|
153336
|
+
useTools: r.useTools,
|
|
153337
|
+
deferBuiltinTools: r.deferBuiltinTools,
|
|
153338
|
+
pinnedTools: r.pinnedTools,
|
|
153339
|
+
customRules: r.customRules,
|
|
153340
|
+
promptOverrides: r.promptOverrides,
|
|
153341
|
+
// null = 回默认组装(base 清场)
|
|
153342
|
+
// 基线未知(宿主没给快照)时不下发该键:传 undefined 会被 core 当 null 落,把供给层开着的注入误关
|
|
153343
|
+
...r.memoryFiles !== void 0 ? { memoryFiles: r.memoryFiles } : {},
|
|
153344
|
+
...r.personaFile !== void 0 ? { personaFile: r.personaFile } : {},
|
|
153345
|
+
modelOverrides: r.modelOverrides,
|
|
153346
|
+
// null = 回 model.conf 指针(base 清场)
|
|
153347
|
+
temperatureOverrides: r.temperatureOverrides,
|
|
153348
|
+
// null = 回 profile / 协议默认(base 清场)
|
|
153349
|
+
...!opts.preserveThinking && r.thinking !== void 0 ? { thinking: r.thinking } : {}
|
|
153350
|
+
// 声明 ?? 基线;只在 use/reset/启动 下发,不做热切换
|
|
153351
|
+
});
|
|
153352
|
+
rt.activeMemoryFiles = r.memoryFiles;
|
|
153353
|
+
rt.activePersonaFile = r.personaFile;
|
|
153354
|
+
if (!opts.preserveThinking) rt.activeThinking = r.thinking;
|
|
153355
|
+
rt.active = r.dirName === BASE_HARNESS ? null : r;
|
|
153356
|
+
}
|
|
153357
|
+
function initHarness(core, cwd2, base, opts = {}) {
|
|
153358
|
+
const rt = {
|
|
153359
|
+
baseline: {
|
|
153360
|
+
useTools: base.useTools ? [...base.useTools] : null,
|
|
153361
|
+
deferBuiltinTools: base.deferBuiltinTools?.slice(),
|
|
153362
|
+
memoryFiles: base.memoryFiles,
|
|
153363
|
+
personaFile: base.personaFile,
|
|
153364
|
+
potentialMemoryFiles: base.potentialMemoryFiles,
|
|
153365
|
+
thinking: base.thinking
|
|
153366
|
+
},
|
|
153367
|
+
activeMemoryFiles: base.memoryFiles,
|
|
153368
|
+
activePersonaFile: base.personaFile,
|
|
153369
|
+
activeThinking: base.thinking,
|
|
153370
|
+
projectDir: cwd2,
|
|
153371
|
+
active: null,
|
|
153372
|
+
overridden: opts.harness !== void 0,
|
|
153373
|
+
fullSkillNames: null,
|
|
153374
|
+
fullAgentNames: null
|
|
153375
|
+
};
|
|
153376
|
+
runtimes.set(core, rt);
|
|
153377
|
+
const name = opts.harness ?? readState(cwd2);
|
|
153378
|
+
const source = rt.overridden ? "\u4F1A\u8BDD\u7EA7\u6307\u5B9A" : "\u6765\u81EA .atomix/harness-state.json";
|
|
153379
|
+
if (name === BASE_HARNESS) return null;
|
|
153380
|
+
try {
|
|
153381
|
+
const doc = loadHarnessDoc(name);
|
|
153382
|
+
const r = resolveHarness(doc, buildContext(core));
|
|
153383
|
+
applyAssembly(core, rt, r);
|
|
153384
|
+
return r.warnings.length ? `harness "${r.name}"(${source})\u5DF2\u52A0\u8F7D:
|
|
153385
|
+
\u26A0 ${r.warnings.join("\n \u26A0 ")}` : null;
|
|
153386
|
+
} catch (e) {
|
|
153387
|
+
if (rt.overridden) throw new Error(`harness "${name}" \u52A0\u8F7D\u5931\u8D25:${e instanceof Error ? e.message : e}`);
|
|
153388
|
+
return `harness "${name}"(${source})\u52A0\u8F7D\u5931\u8D25,\u5DF2\u56DE\u843D base:${e instanceof Error ? e.message : e}`;
|
|
153389
|
+
}
|
|
153390
|
+
}
|
|
153391
|
+
async function switchTo(core, name) {
|
|
153392
|
+
const rt = requireRuntime(core);
|
|
153393
|
+
const ctx = buildContext(core);
|
|
153394
|
+
const r = name === BASE_HARNESS ? resolveBase(ctx) : resolveHarness(loadHarnessDoc(name), ctx);
|
|
153395
|
+
const wasOn = (v) => v !== null && v !== void 0;
|
|
153396
|
+
const memWasOn = wasOn(rt.activeMemoryFiles);
|
|
153397
|
+
const personaWas = rt.activePersonaFile;
|
|
153398
|
+
applyAssembly(core, rt, r);
|
|
153399
|
+
const memNowOn = wasOn(rt.activeMemoryFiles);
|
|
153400
|
+
const personaNow = rt.activePersonaFile;
|
|
153401
|
+
writeState(rt.projectDir, name);
|
|
153402
|
+
rt.overridden = false;
|
|
153403
|
+
const { applyDisabledSkills: applyDisabledSkills2 } = await Promise.resolve().then(() => (init_skills(), skills_exports));
|
|
153404
|
+
const { applyDisabledAgents: applyDisabledAgents2 } = await Promise.resolve().then(() => (init_agents(), agents_exports));
|
|
153405
|
+
applyDisabledSkills2(core);
|
|
153406
|
+
await applyDisabledAgents2(core);
|
|
153407
|
+
const warn = r.warnings.length ? "\n \u26A0 " + r.warnings.join("\n \u26A0 ") : "";
|
|
153408
|
+
const hints = [];
|
|
153409
|
+
if (memWasOn !== memNowOn) hints.push(memNowOn ? "\u8BB0\u5FC6\u6CE8\u5165\u5DF2\u5F00;\u9700 /compact\u3001/clear \u6216\u65B0\u4F1A\u8BDD\u540E\u91CD\u65B0\u6CE8\u5165" : "\u8BB0\u5FC6\u6CE8\u5165\u5DF2\u5173;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u8BB0\u5FC6\u9700 /compact \u6216 /clear \u624D\u64A4\u51FA");
|
|
153410
|
+
const pWasOn = wasOn(personaWas);
|
|
153411
|
+
const pNowOn = wasOn(personaNow);
|
|
153412
|
+
if (pWasOn !== pNowOn) hints.push(pNowOn ? "\u4EBA\u8BBE\u6CE8\u5165\u5DF2\u5F00;\u9700 /compact\u3001/clear \u6216\u65B0\u4F1A\u8BDD\u540E\u91CD\u65B0\u6CE8\u5165" : "\u4EBA\u8BBE\u6CE8\u5165\u5DF2\u5173;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u4EBA\u8BBE\u9700 /compact \u6216 /clear \u624D\u64A4\u51FA");
|
|
153413
|
+
else if (pWasOn && pNowOn && personaWas !== personaNow) hints.push("\u4EBA\u8BBE\u6765\u6E90\u5DF2\u5207\u6362;\u5386\u53F2\u91CC\u5DF2\u6CE8\u5165\u7684\u4EBA\u8BBE\u9700 /compact \u6216 /clear \u624D\u66F4\u65B0");
|
|
153414
|
+
const hintText = hints.map((h) => `
|
|
153415
|
+
${h}`).join("");
|
|
153416
|
+
return (name === BASE_HARNESS ? "\u5DF2\u56DE\u5230 base(\u9ED8\u8BA4\u88C5\u914D)" : `\u5DF2\u5207\u6362 harness:${r.name}(\u4EC5\u5F53\u524D\u9879\u76EE\u751F\u6548)`) + hintText + warn;
|
|
153417
|
+
}
|
|
153418
|
+
function reapply(core, rt) {
|
|
153419
|
+
const r = resolveHarness(loadHarnessDoc(rt.active.dirName), buildContext(core));
|
|
153420
|
+
applyAssembly(core, rt, r, { preserveThinking: true });
|
|
153421
|
+
return r;
|
|
153422
|
+
}
|
|
153423
|
+
function setActiveHarnessModel(core, slot, name) {
|
|
153424
|
+
const rt = requireRuntime(core);
|
|
153425
|
+
if (!rt.active) throw new Error("\u5F53\u524D\u4E3A base,\u6A21\u578B\u6307\u9488\u76F4\u63A5\u7531 model.conf \u7BA1\u7406");
|
|
153426
|
+
if (!core.getModelNames().includes(name)) throw new Error(`\u6A21\u578B\u4E0D\u5B58\u5728: ${name}(/model list \u67E5\u770B,/model add \u6DFB\u52A0)`);
|
|
153427
|
+
const dirName = rt.active.dirName;
|
|
153428
|
+
const declared = { ...rt.active.modelDeclared ?? {} };
|
|
153429
|
+
declared[slot] = name;
|
|
153430
|
+
const value = declared.main && declared.quick && declared.main === declared.quick ? declared.main : declared;
|
|
153431
|
+
const yamlPath = path7.join(libraryDir(), dirName, "harness.yaml");
|
|
153432
|
+
const ydoc = import_yaml.default.parseDocument(fs7.readFileSync(yamlPath, "utf8"));
|
|
153433
|
+
ydoc.set("model", typeof value === "string" ? value : ydoc.createNode(value));
|
|
153434
|
+
fs7.writeFileSync(yamlPath, ydoc.toString());
|
|
153435
|
+
const r = reapply(core, rt);
|
|
153436
|
+
const warn = r.warnings.length ? "\n \u26A0 " + r.warnings.join("\n \u26A0 ") : "";
|
|
153437
|
+
return `harness ${dirName} \u7684 ${slot} \u2192 ${name}(\u5DF2\u5199\u5165 harness.yaml,base \u672A\u53D8)` + warn;
|
|
153438
|
+
}
|
|
153439
|
+
function setActiveHarnessTemperature(core, slot, value) {
|
|
153440
|
+
const rt = requireRuntime(core);
|
|
153441
|
+
if (!rt.active) throw new Error("\u5F53\u524D\u4E3A base,\u6E29\u5EA6\u76F4\u63A5\u7531 model.conf \u7684 profile \u7BA1\u7406(/model temp <\u6A21\u578B\u540D> <\u503C|default>)");
|
|
153442
|
+
if (value !== null) {
|
|
153443
|
+
if (!(0, import_atomix_core4.isValidTemperature)(value)) throw new Error(`temperature \u987B\u4E3A 0\u20132 \u7684\u6570\u5B57,\u6536\u5230 ${JSON.stringify(value)}`);
|
|
153444
|
+
const effModel = effectiveModels(core)[slot];
|
|
153445
|
+
const mn = core.getModelProfiles().find((p) => p.name === effModel)?.modelName;
|
|
153446
|
+
if (mn && (0, import_atomix_core4.modelForcesTemperatureOne)(mn)) throw new Error(`\u6A21\u578B ${effModel} \u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1,\u4E0D\u80FD\u8BBE\u7F6E temperature`);
|
|
153447
|
+
if (mn && (0, import_atomix_core4.modelRejectsTemperature)(mn)) throw new Error(`\u6A21\u578B ${effModel} \u4E0D\u652F\u6301 temperature \u53C2\u6570(\u63A8\u7406\u6A21\u578B),\u4E0D\u80FD\u8BBE\u7F6E`);
|
|
153448
|
+
}
|
|
153449
|
+
const dirName = rt.active.dirName;
|
|
153450
|
+
const declared = { ...rt.active.temperatureDeclared ?? {} };
|
|
153451
|
+
if (value === null) delete declared[slot];
|
|
153452
|
+
else declared[slot] = value;
|
|
153453
|
+
const yamlPath = path7.join(libraryDir(), dirName, "harness.yaml");
|
|
153454
|
+
const ydoc = import_yaml.default.parseDocument(fs7.readFileSync(yamlPath, "utf8"));
|
|
153455
|
+
if (declared.main === void 0 && declared.quick === void 0) ydoc.delete("temperature");
|
|
153456
|
+
else if (declared.quick === void 0) ydoc.set("temperature", declared.main);
|
|
153457
|
+
else ydoc.set("temperature", ydoc.createNode(declared));
|
|
153458
|
+
fs7.writeFileSync(yamlPath, ydoc.toString());
|
|
153459
|
+
const r = reapply(core, rt);
|
|
153460
|
+
const warn = r.warnings.length ? "\n \u26A0 " + r.warnings.join("\n \u26A0 ") : "";
|
|
153461
|
+
return `harness ${dirName} \u7684 ${slot} temperature \u2192 ${value === null ? "\u9ED8\u8BA4(\u5DF2\u6E05\u9664\u58F0\u660E)" : value}(\u5DF2\u5199\u5165 harness.yaml,model.conf \u672A\u53D8)` + warn;
|
|
153462
|
+
}
|
|
153463
|
+
function harnessesReferencingModel(name) {
|
|
153464
|
+
const out = [];
|
|
153465
|
+
for (const n of listHarnesses()) {
|
|
153466
|
+
if (n === BASE_HARNESS) continue;
|
|
153467
|
+
try {
|
|
153468
|
+
const m = loadHarnessDoc(n).model;
|
|
153469
|
+
if (m && (m.main === name || m.quick === name)) out.push(n);
|
|
153470
|
+
} catch {
|
|
153471
|
+
}
|
|
153472
|
+
}
|
|
153473
|
+
return out;
|
|
153474
|
+
}
|
|
153475
|
+
function summarize(r, ctx) {
|
|
153476
|
+
const lines = [];
|
|
153477
|
+
const base = resolveBase(ctx);
|
|
153478
|
+
const baseSet2 = new Set(base.useTools ?? ctx.allToolNames);
|
|
153479
|
+
const curSet = new Set(r.useTools ?? ctx.allToolNames);
|
|
153480
|
+
const removed = [...baseSet2].filter((n) => !curSet.has(n));
|
|
153481
|
+
const added = [...curSet].filter((n) => !baseSet2.has(n));
|
|
153482
|
+
lines.push(`\u5DE5\u5177 ${r.useTools ? `${curSet.size} \u4E2A` : "\u5168\u90E8"}${removed.length ? `(\u76F8\u5BF9 base \u5C11:${removed.join(", ")})` : ""}${added.length ? `(\u76F8\u5BF9 base \u591A:${added.join(", ")})` : ""}`);
|
|
153483
|
+
if (r.deferBuiltinTools.length) lines.push(`defer ${r.deferBuiltinTools.join(", ")}`);
|
|
153484
|
+
if (r.pinnedTools.length) lines.push(`pin ${r.pinnedTools.join(", ")}`);
|
|
153485
|
+
const skillsDisabled = computeDisabledFrom(r.skillsSpec, ctx.allSkillNames);
|
|
153486
|
+
const agentsDisabled = computeDisabledFrom(r.agentsSpec, ctx.allAgentNames);
|
|
153487
|
+
lines.push(`skill ${skillsDisabled.size ? `\u7981\u7528 ${[...skillsDisabled].join(", ")}` : "\u5168\u90E8\u53EF\u89C1"}`);
|
|
153488
|
+
lines.push(`agent ${agentsDisabled.size ? `\u7981\u7528 ${[...agentsDisabled].join(", ")}` : "\u5168\u90E8\u53EF\u89C1"}`);
|
|
153489
|
+
lines.push(`\u89C4\u5219\u6BB5 ${r.customRules ? `${r.customRules.split("\n").length} \u884C` : "\u65E0"}`);
|
|
153490
|
+
const p = r.promptOverrides;
|
|
153491
|
+
const promptDesc = p ? [
|
|
153492
|
+
p.replace && Object.keys(p.replace).length ? `\u66FF\u6362 ${Object.keys(p.replace).join(", ")}` : "",
|
|
153493
|
+
p.disable?.length ? `\u7981\u7528 ${p.disable.join(", ")}` : "",
|
|
153494
|
+
p.insert?.length ? `\u63D2\u5165 ${p.insert.map((i) => i.name).join(", ")}` : ""
|
|
153495
|
+
].filter(Boolean).join(";") : "\u9ED8\u8BA4";
|
|
153496
|
+
lines.push(`\u63D0\u793A\u6BB5 ${promptDesc}`);
|
|
153497
|
+
const mo = overrideOf(r.memoryFiles, ctx.baseline.memoryFiles);
|
|
153498
|
+
if (mo === "off") lines.push("\u8BB0\u5FC6 \u5173(harness memory: off;base \u5F00\u7740,\u5207\u8D70\u5373\u6062\u590D)");
|
|
153499
|
+
else if (mo === "on") lines.push("\u8BB0\u5FC6 \u5F00(harness memory: on;base \u5173\u7740,\u5207\u8D70\u5373\u5173)");
|
|
153500
|
+
const po = personaOverrideOf(r.personaFile, ctx.baseline.personaFile);
|
|
153501
|
+
if (po === "off") lines.push("\u4EBA\u8BBE \u5173(\u672C harness \u65E0\u4EBA\u8BBE;base \u5F00\u7740,\u5207\u8D70\u5373\u6062\u590D)");
|
|
153502
|
+
else if (po === "swap") lines.push("\u4EBA\u8BBE \u4E13\u5C5E(harness SOUL.md;\u5207\u8D70\u5373\u56DE base)");
|
|
153503
|
+
else if (po === "on") lines.push("\u4EBA\u8BBE \u4E13\u5C5E(harness SOUL.md;base \u5173\u7740,\u5207\u8D70\u5373\u5173)");
|
|
153504
|
+
if (r.modelDeclared) {
|
|
153505
|
+
const parts = MODEL_SLOTS.map((slot) => {
|
|
153506
|
+
const d = r.modelDeclared[slot];
|
|
153507
|
+
if (!d) return `${slot}=${ctx.baseModels[slot] || "-"}(base)`;
|
|
153508
|
+
return r.modelFallback?.[slot] ? `${slot}=${ctx.baseModels[slot] || "-"}(base;\u58F0\u660E ${d} \u4E0D\u5B58\u5728,\u5DF2\u56DE\u843D)` : `${slot}=${d}`;
|
|
153509
|
+
});
|
|
153510
|
+
lines.push(`${r.modelFallback ? "\u26A0 " : ""}\u6A21\u578B ${parts.join(" ")}`);
|
|
153511
|
+
}
|
|
153512
|
+
if (r.thinkingDeclared !== null) lines.push(`\u601D\u8003 ${r.thinkingDeclared ? "\u5F00" : "\u5173"}(harness thinking: ${r.thinkingDeclared ? "on" : "off"};\u4EC5 main,quick \u6052\u5173;\u5207\u8D70\u5373\u56DE base)`);
|
|
153513
|
+
if (r.temperatureDeclared) {
|
|
153514
|
+
const parts = MODEL_SLOTS.map((slot) => {
|
|
153515
|
+
const d = r.temperatureDeclared[slot];
|
|
153516
|
+
if (d === void 0) return `${slot}=\u8DDF\u968F(profile / \u534F\u8BAE\u9ED8\u8BA4)`;
|
|
153517
|
+
return r.temperatureOverrides?.[slot] === void 0 ? `${slot}=${d}(\u5DF2\u5FFD\u7565,\u89C1\u544A\u8B66)` : `${slot}=${d}`;
|
|
153518
|
+
});
|
|
153519
|
+
lines.push(`\u6E29\u5EA6 ${parts.join(" ")}(harness \u58F0\u660E;\u5207\u8D70\u5373\u56DE profile / \u9ED8\u8BA4)`);
|
|
153520
|
+
}
|
|
153521
|
+
if (r.warnings.length) lines.push(...r.warnings.map((w) => `\u26A0 ${w}`));
|
|
153522
|
+
return lines.join("\n ");
|
|
153523
|
+
}
|
|
153524
|
+
async function harnessCommand(core, args) {
|
|
153525
|
+
const [sub, ...rest2] = args;
|
|
153526
|
+
const arg = rest2.join(" ").trim() || void 0;
|
|
153527
|
+
const names = listHarnesses();
|
|
153528
|
+
switch (sub) {
|
|
153529
|
+
case void 0:
|
|
153530
|
+
case "list": {
|
|
153531
|
+
const cur = getActiveHarnessDir(core);
|
|
153532
|
+
const rt = runtimeOf(core);
|
|
153533
|
+
const lines = names.map((n) => `${n === cur ? "\u25CF" : "\u25CB"} ${n}${n === BASE_HARNESS ? "(\u9ED8\u8BA4\u88C5\u914D)" : ""}`);
|
|
153534
|
+
if (sub === void 0 && rt?.active) {
|
|
153535
|
+
const ctx = buildContext(core);
|
|
153536
|
+
const where = rt.overridden ? "\u4F1A\u8BDD\u7EA7\u6307\u5B9A,\u672A\u5199\u5165\u9879\u76EE\u6001" : `\u9879\u76EE\u7EA7,${path7.join(".atomix", "harness-state.json")}`;
|
|
153537
|
+
lines.unshift(`\u5F53\u524D:${cur}(${where})`, " " + summarize(rt.active, ctx), "");
|
|
153538
|
+
} else if (sub === void 0) {
|
|
153539
|
+
lines.unshift(rt?.overridden ? "\u5F53\u524D:base(\u4F1A\u8BDD\u7EA7\u6307\u5B9A\u9ED8\u8BA4\u88C5\u914D)" : "\u5F53\u524D:base(\u9ED8\u8BA4\u88C5\u914D,\u672A\u9009\u62E9 harness)", "");
|
|
153540
|
+
}
|
|
153541
|
+
lines.push("", "\u7528\u6CD5:/harness list | use <\u540D\u79F0> | show <\u540D\u79F0> | diff <\u540D\u79F0> | reset");
|
|
153542
|
+
lines.push(`\u5E93\u76EE\u5F55:${libraryDir()}(\u6BCF\u4E2A harness \u4E00\u4E2A\u5B50\u76EE\u5F55,\u542B harness.yaml + rules.md)`);
|
|
153543
|
+
return lines.join("\n");
|
|
153544
|
+
}
|
|
153545
|
+
case "use": {
|
|
153546
|
+
if (!arg) return "\u7528\u6CD5:/harness use <\u540D\u79F0>";
|
|
153547
|
+
if (!names.includes(arg)) return `\u672A\u627E\u5230 harness:${arg}(\u53EF\u7528:${names.join(" / ")})`;
|
|
153548
|
+
try {
|
|
153549
|
+
return await switchTo(core, arg);
|
|
153550
|
+
} catch (e) {
|
|
153551
|
+
return `\u5207\u6362\u5931\u8D25:${e instanceof Error ? e.message : e}`;
|
|
153552
|
+
}
|
|
153553
|
+
}
|
|
153554
|
+
case "reset":
|
|
153555
|
+
return await switchTo(core, BASE_HARNESS);
|
|
153556
|
+
case "show":
|
|
153557
|
+
case "diff": {
|
|
153558
|
+
if (!arg) return `\u7528\u6CD5:/harness ${sub} <\u540D\u79F0>`;
|
|
153559
|
+
if (arg === BASE_HARNESS) return "base = \u9ED8\u8BA4\u88C5\u914D\u57FA\u7EBF,\u65E0\u53D6\u820D\u9879";
|
|
153560
|
+
try {
|
|
153561
|
+
const ctx = buildContext(core);
|
|
153562
|
+
const r = resolveHarness(loadHarnessDoc(arg), ctx);
|
|
153563
|
+
return `${r.name}${arg === getActiveHarnessDir(core) ? "(\u5F53\u524D)" : ""}
|
|
153564
|
+
${summarize(r, ctx)}`;
|
|
153565
|
+
} catch (e) {
|
|
153566
|
+
return `\u8BFB\u53D6\u5931\u8D25:${e instanceof Error ? e.message : e}`;
|
|
153567
|
+
}
|
|
153568
|
+
}
|
|
153569
|
+
default:
|
|
153570
|
+
return `\u672A\u77E5\u5B50\u547D\u4EE4:${sub}(\u53EF\u7528:list / use / show / diff / reset)`;
|
|
153571
|
+
}
|
|
153572
|
+
}
|
|
153573
|
+
var import_yaml, import_atomix_core3, import_atomix_core4, MODEL_SLOTS, BASE_HARNESS, runtimes;
|
|
153574
|
+
var init_harness = __esm({
|
|
153575
|
+
"src/harness.ts"() {
|
|
153576
|
+
"use strict";
|
|
153577
|
+
import_yaml = __toESM(require_dist5());
|
|
153578
|
+
import_atomix_core3 = __toESM(require_dist4());
|
|
153579
|
+
import_atomix_core4 = __toESM(require_dist4());
|
|
153580
|
+
init_paths();
|
|
153581
|
+
MODEL_SLOTS = ["main", "quick"];
|
|
153582
|
+
BASE_HARNESS = "base";
|
|
153583
|
+
runtimes = /* @__PURE__ */ new WeakMap();
|
|
153584
|
+
}
|
|
153585
|
+
});
|
|
153586
|
+
|
|
152776
153587
|
// node_modules/react/cjs/react-jsx-runtime.production.min.js
|
|
152777
153588
|
var require_react_jsx_runtime_production_min = __commonJS({
|
|
152778
153589
|
"node_modules/react/cjs/react-jsx-runtime.production.min.js"(exports2) {
|
|
@@ -159339,26 +160150,6 @@ var import_react20 = __toESM(require_react(), 1);
|
|
|
159339
160150
|
// node_modules/ink/build/hooks/use-focus-manager.js
|
|
159340
160151
|
var import_react21 = __toESM(require_react(), 1);
|
|
159341
160152
|
|
|
159342
|
-
// src/tui/index.tsx
|
|
159343
|
-
var import_atomix_core8 = __toESM(require_dist4());
|
|
159344
|
-
|
|
159345
|
-
// src/tools.ts
|
|
159346
|
-
var ATOMIX_TOOLS = [
|
|
159347
|
-
"Bash",
|
|
159348
|
-
"Glob",
|
|
159349
|
-
"Grep",
|
|
159350
|
-
"Read",
|
|
159351
|
-
"Write",
|
|
159352
|
-
"Edit",
|
|
159353
|
-
"TodoWrite",
|
|
159354
|
-
"Skill",
|
|
159355
|
-
"AgentTeam",
|
|
159356
|
-
"NotebookEdit",
|
|
159357
|
-
"AskUser",
|
|
159358
|
-
"ToolSearch"
|
|
159359
|
-
];
|
|
159360
|
-
var ATOMIX_DEFER_TOOLS = ["NotebookEdit"];
|
|
159361
|
-
|
|
159362
160153
|
// src/tui/index.tsx
|
|
159363
160154
|
init_paths();
|
|
159364
160155
|
|
|
@@ -159382,6 +160173,9 @@ function filterSemaDebugConsole() {
|
|
|
159382
160173
|
};
|
|
159383
160174
|
}
|
|
159384
160175
|
|
|
160176
|
+
// src/modelWizard.ts
|
|
160177
|
+
var import_atomix_core5 = __toESM(require_dist4());
|
|
160178
|
+
|
|
159385
160179
|
// src/ui.ts
|
|
159386
160180
|
init_theme();
|
|
159387
160181
|
var wrap3 = (code) => (s) => `\x1B[${code}m${s}\x1B[0m`;
|
|
@@ -159558,6 +160352,7 @@ function makeCancellableAsk(rl) {
|
|
|
159558
160352
|
}
|
|
159559
160353
|
|
|
159560
160354
|
// src/modelWizard.ts
|
|
160355
|
+
init_harness();
|
|
159561
160356
|
function modelId(modelName, provider) {
|
|
159562
160357
|
return `${modelName}[${provider}]`;
|
|
159563
160358
|
}
|
|
@@ -159579,6 +160374,15 @@ async function askPositiveInt(ask, label, def) {
|
|
|
159579
160374
|
console.log(red(" \u8BF7\u8F93\u5165\u6B63\u6574\u6570\uFF0C\u6216\u56DE\u8F66\u7528\u9ED8\u8BA4"));
|
|
159580
160375
|
}
|
|
159581
160376
|
}
|
|
160377
|
+
async function askOptionalTemperature(ask, defHint) {
|
|
160378
|
+
for (; ; ) {
|
|
160379
|
+
const raw = (await ask(` temperature [${gray("0\u20132,\u56DE\u8F66\u7528" + defHint)}${gray("]")}: `)).trim();
|
|
160380
|
+
if (!raw) return void 0;
|
|
160381
|
+
const n = Number(raw);
|
|
160382
|
+
if ((0, import_atomix_core5.isValidTemperature)(n)) return n;
|
|
160383
|
+
console.log(red(" \u8BF7\u8F93\u5165 0\u20132 \u7684\u6570\u5B57\uFF0C\u6216\u56DE\u8F66\u7528\u9ED8\u8BA4"));
|
|
160384
|
+
}
|
|
160385
|
+
}
|
|
159582
160386
|
async function askSelect(ask, label, items, defaultIdx = 0) {
|
|
159583
160387
|
items.forEach((it, i) => console.log(` ${cyan(String(i + 1))}. ${it}`));
|
|
159584
160388
|
for (; ; ) {
|
|
@@ -159667,9 +160471,16 @@ async function runAddWizard(core, ask) {
|
|
|
159667
160471
|
if (limits) console.log(gray(` \u5DF2\u6309\u6A21\u578B\u81EA\u52A8\u8BC6\u522B\u9650\u989D\uFF1AmaxTokens=${defMax} contextLength=${defCtx}`));
|
|
159668
160472
|
const maxTokens = await askPositiveInt(ask, "maxTokens", defMax);
|
|
159669
160473
|
const contextLength = await askPositiveInt(ask, "contextLength", defCtx);
|
|
160474
|
+
let temperature;
|
|
160475
|
+
if ((0, import_atomix_core5.modelForcesTemperatureOne)(modelName)) console.log(gray(" \u8BE5\u6A21\u578B\u53EA\u63A5\u53D7\u9ED8\u8BA4\u6E29\u5EA6 1\uFF0C\u8DF3\u8FC7 temperature"));
|
|
160476
|
+
else if ((0, import_atomix_core5.modelRejectsTemperature)(modelName)) console.log(gray(" \u8BE5\u6A21\u578B\u4E0D\u652F\u6301 temperature \u53C2\u6570\uFF0C\u8DF3\u8FC7"));
|
|
160477
|
+
else {
|
|
160478
|
+
if ((0, import_atomix_core5.modelTemperatureGatedByThinking)(modelName)) console.log(gray(" \u8BE5\u6A21\u578B\u4EC5 thinking \u5173\u95ED\u65F6\u4F7F\u7528 temperature\uFF0C\u5F00\u542F\u65F6\u4E0D\u53D1\u9001"));
|
|
160479
|
+
temperature = await askOptionalTemperature(ask, adapt === "anthropic" ? `\u9ED8\u8BA4 ${import_atomix_core5.DEFAULT_ANTHROPIC_TEMPERATURE}` : "\u670D\u52A1\u7AEF\u9ED8\u8BA4");
|
|
160480
|
+
}
|
|
159670
160481
|
console.log(gray(" \u9A8C\u8BC1\u8FDE\u901A\u6027\u5E76\u4FDD\u5B58\u2026"));
|
|
159671
160482
|
try {
|
|
159672
|
-
await core.addModel({ provider, modelName, baseURL, apiKey, maxTokens, contextLength, adapt });
|
|
160483
|
+
await core.addModel({ provider, modelName, baseURL, apiKey, maxTokens, contextLength, adapt, ...temperature !== void 0 ? { temperature } : {} });
|
|
159673
160484
|
} catch (e) {
|
|
159674
160485
|
console.log(red(` \u6DFB\u52A0\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`));
|
|
159675
160486
|
return false;
|
|
@@ -159696,13 +160507,33 @@ async function printModelList(core) {
|
|
|
159696
160507
|
console.log(gray(" \uFF08\u65E0\u5DF2\u914D\u7F6E\u6A21\u578B\uFF0C`/model add` \u6DFB\u52A0\uFF09"));
|
|
159697
160508
|
return;
|
|
159698
160509
|
}
|
|
160510
|
+
const eff = effectiveModels(core);
|
|
160511
|
+
const profiles = new Map(core.getModelProfiles().map((p) => [p.name, p]));
|
|
160512
|
+
const tempOf = (name) => {
|
|
160513
|
+
const p = profiles.get(name);
|
|
160514
|
+
if (!p) return "";
|
|
160515
|
+
if ((0, import_atomix_core5.modelForcesTemperatureOne)(p.modelName)) return "temp=\u56FA\u5B9A1";
|
|
160516
|
+
if ((0, import_atomix_core5.modelRejectsTemperature)(p.modelName)) return "temp=\u4E0D\u652F\u6301";
|
|
160517
|
+
return p.temperature !== void 0 ? `temp=${p.temperature}` : "temp=\u9ED8\u8BA4";
|
|
160518
|
+
};
|
|
159699
160519
|
for (const name of data.modelList) {
|
|
159700
|
-
const marks = [
|
|
159701
|
-
|
|
159702
|
-
|
|
159703
|
-
|
|
159704
|
-
|
|
160520
|
+
const marks = [];
|
|
160521
|
+
if (name === eff.main) marks.push(green(eff.mainFrom === "harness" ? "main(harness)" : "main"));
|
|
160522
|
+
else if (name === data.taskConfig?.main && eff.mainFrom === "harness") marks.push(gray("main(base)"));
|
|
160523
|
+
if (name === eff.quick) marks.push(cyan(eff.quickFrom === "harness" ? "quick(harness)" : "quick"));
|
|
160524
|
+
else if (name === data.taskConfig?.quick && eff.quickFrom === "harness") marks.push(gray("quick(base)"));
|
|
160525
|
+
const m = marks.join(" ");
|
|
160526
|
+
console.log(` ${m ? "\u25CF " : " "}${name}${gray(" " + tempOf(name))}${m ? gray(" \u2190 ") + m : ""}`);
|
|
159705
160527
|
}
|
|
160528
|
+
console.log(gray(` temperature: ${temperatureStatusLine(core)}`));
|
|
160529
|
+
if (eff.fallback) {
|
|
160530
|
+
for (const slot of ["main", "quick"]) {
|
|
160531
|
+
if (eff.fallback[slot]) console.log(yellow(` \u26A0 harness \u58F0\u660E ${slot}=${eff.fallback[slot]} \u4E0D\u5B58\u5728,${slot} \u5DF2\u56DE\u843D base \u7684 ${eff[slot] || "-"}`));
|
|
160532
|
+
}
|
|
160533
|
+
}
|
|
160534
|
+
}
|
|
160535
|
+
function inHarness(core) {
|
|
160536
|
+
return isHarnessActive(core);
|
|
159706
160537
|
}
|
|
159707
160538
|
async function modelCommand(core, args, ask) {
|
|
159708
160539
|
const [sub, ...rest2] = args;
|
|
@@ -159712,40 +160543,113 @@ async function modelCommand(core, args, ask) {
|
|
|
159712
160543
|
case void 0:
|
|
159713
160544
|
case "list":
|
|
159714
160545
|
await printModelList(core);
|
|
159715
|
-
if (!sub) console.log(gray(" \u7528\u6CD5\uFF1A/model list | add | use <\u540D\u79F0> | quick <\u540D\u79F0> | del <\u540D\u79F0>"));
|
|
160546
|
+
if (!sub) console.log(gray(" \u7528\u6CD5\uFF1A/model list | add | use <\u540D\u79F0> | quick <\u540D\u79F0> | temp [<\u540D\u79F0>] <\u503C|default> | del <\u540D\u79F0>"));
|
|
159716
160547
|
break;
|
|
159717
160548
|
case "add":
|
|
159718
160549
|
await addModelWizard(core, ask);
|
|
159719
160550
|
break;
|
|
159720
160551
|
case "use": {
|
|
159721
160552
|
if (!name) return console.log(red(" \u7528\u6CD5\uFF1A/model use <\u540D\u79F0>"));
|
|
160553
|
+
if (inHarness(core)) {
|
|
160554
|
+
console.log(green(` \u2713 ${setActiveHarnessModel(core, "main", name)}`));
|
|
160555
|
+
break;
|
|
160556
|
+
}
|
|
159722
160557
|
const r = await core.switchModel(name);
|
|
159723
160558
|
console.log(green(` \u2713 \u4E3B\u6A21\u578B \u2192 ${r.taskConfig.main}`));
|
|
159724
160559
|
break;
|
|
159725
160560
|
}
|
|
159726
160561
|
case "quick": {
|
|
159727
160562
|
if (!name) return console.log(red(" \u7528\u6CD5\uFF1A/model quick <\u540D\u79F0>"));
|
|
160563
|
+
if (inHarness(core)) {
|
|
160564
|
+
console.log(green(` \u2713 ${setActiveHarnessModel(core, "quick", name)}`));
|
|
160565
|
+
break;
|
|
160566
|
+
}
|
|
159728
160567
|
const cur = await core.getModelData();
|
|
159729
160568
|
const r = await core.applyTaskModel({ main: cur.taskConfig.main, quick: name });
|
|
159730
160569
|
console.log(green(` \u2713 \u5FEB\u901F\u6A21\u578B \u2192 ${r.taskConfig.quick}`));
|
|
159731
160570
|
break;
|
|
159732
160571
|
}
|
|
160572
|
+
case "temp": {
|
|
160573
|
+
if (!rest2.length) {
|
|
160574
|
+
console.log(gray(` temperature: ${temperatureStatusLine(core)}`));
|
|
160575
|
+
console.log(gray(" \u7528\u6CD5\uFF1A/model temp <\u503C|default> | temp <\u6A21\u578B\u540D> <\u503C|default>"));
|
|
160576
|
+
break;
|
|
160577
|
+
}
|
|
160578
|
+
const parseVal = (s) => {
|
|
160579
|
+
if (s === "default") return null;
|
|
160580
|
+
const n = Number(s);
|
|
160581
|
+
if (!s || !(0, import_atomix_core5.isValidTemperature)(n)) throw new Error(`temperature \u987B\u4E3A 0\u20132 \u7684\u6570\u5B57\u6216 default\uFF0C\u6536\u5230 ${JSON.stringify(s)}`);
|
|
160582
|
+
return n;
|
|
160583
|
+
};
|
|
160584
|
+
const fmt = (v2) => v2 === null ? "\u9ED8\u8BA4" : String(v2);
|
|
160585
|
+
if (rest2.length >= 2) {
|
|
160586
|
+
const target = rest2.slice(0, -1).join(" ");
|
|
160587
|
+
const v2 = parseVal(rest2[rest2.length - 1]);
|
|
160588
|
+
await core.updateModel(target, { temperature: v2 ?? void 0 });
|
|
160589
|
+
console.log(green(` \u2713 ${target} \u7684 temperature \u2192 ${fmt(v2)}\uFF08model.conf\uFF09`));
|
|
160590
|
+
const eff = effectiveModels(core);
|
|
160591
|
+
const over2 = harnessTemperatureOverride(core);
|
|
160592
|
+
for (const slot of ["main", "quick"]) {
|
|
160593
|
+
if (eff[slot] === target && over2?.[slot] !== void 0) console.log(yellow(` \u26A0 \u5F53\u524D harness ${getActiveHarnessDir(core)} \u5BF9 ${slot} \u58F0\u660E\u4E86 temperature=${over2[slot]}\uFF0C\u4F18\u5148\u4E8E profile\uFF1B\u6539 harness \u7528 /model temp <\u503C>`));
|
|
160594
|
+
}
|
|
160595
|
+
break;
|
|
160596
|
+
}
|
|
160597
|
+
const v = parseVal(rest2[0]);
|
|
160598
|
+
if (inHarness(core)) {
|
|
160599
|
+
console.log(green(` \u2713 ${setActiveHarnessTemperature(core, "main", v)}`));
|
|
160600
|
+
break;
|
|
160601
|
+
}
|
|
160602
|
+
const main = effectiveModels(core).main;
|
|
160603
|
+
if (!main) return console.log(red(" \u5C1A\u672A\u914D\u7F6E\u4E3B\u6A21\u578B\uFF08/model add\uFF09"));
|
|
160604
|
+
await core.updateModel(main, { temperature: v ?? void 0 });
|
|
160605
|
+
console.log(green(` \u2713 ${main} \u7684 temperature \u2192 ${fmt(v)}\uFF08model.conf\uFF09`));
|
|
160606
|
+
break;
|
|
160607
|
+
}
|
|
159733
160608
|
case "del": {
|
|
159734
160609
|
if (!name) return console.log(red(" \u7528\u6CD5\uFF1A/model del <\u540D\u79F0>"));
|
|
160610
|
+
const decl = harnessModelDeclared(core);
|
|
160611
|
+
if (decl && (decl.main === name || decl.quick === name)) {
|
|
160612
|
+
return console.log(red(` \u6A21\u578B\u6B63\u5728\u88AB\u5F53\u524D harness ${getActiveHarnessDir(core)} \u58F0\u660E\u4F7F\u7528,\u65E0\u6CD5\u5220\u9664(\u5148\u6539\u5176 harness.yaml \u7684 model \u5B57\u6BB5)`));
|
|
160613
|
+
}
|
|
159735
160614
|
await core.delModel(name);
|
|
159736
160615
|
console.log(green(` \u2713 \u5DF2\u5220\u9664\uFF1A${name}`));
|
|
160616
|
+
const refs = harnessesReferencingModel(name);
|
|
160617
|
+
if (refs.length) console.log(yellow(` \u26A0 \u4EE5\u4E0B harness \u4ECD\u58F0\u660E\u8BE5\u6A21\u578B,\u4E0B\u6B21\u52A0\u8F7D\u4F1A\u56DE\u843D base:${refs.join(" / ")}(\u8BF7\u6539\u5176 harness.yaml \u7684 model \u5B57\u6BB5)`));
|
|
159737
160618
|
break;
|
|
159738
160619
|
}
|
|
159739
160620
|
default:
|
|
159740
160621
|
console.log(bold(` \u672A\u77E5\u5B50\u547D\u4EE4\uFF1A${sub}`));
|
|
159741
|
-
console.log(gray(" \u7528\u6CD5\uFF1A/model list | add | use <\u540D\u79F0> | quick <\u540D\u79F0> | del <\u540D\u79F0>"));
|
|
160622
|
+
console.log(gray(" \u7528\u6CD5\uFF1A/model list | add | use <\u540D\u79F0> | quick <\u540D\u79F0> | temp [<\u540D\u79F0>] <\u503C|default> | del <\u540D\u79F0>"));
|
|
159742
160623
|
}
|
|
159743
160624
|
} catch (e) {
|
|
159744
160625
|
console.log(red(` \u6A21\u578B\u64CD\u4F5C\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`));
|
|
159745
160626
|
}
|
|
159746
160627
|
}
|
|
159747
160628
|
|
|
159748
|
-
// src/
|
|
160629
|
+
// src/session.ts
|
|
160630
|
+
var import_atomix_core7 = __toESM(require_dist4());
|
|
160631
|
+
|
|
160632
|
+
// src/sessionTypes.ts
|
|
160633
|
+
var SESSION_HANDLE_BRAND = /* @__PURE__ */ Symbol.for("atomix-cli.sessionHandle");
|
|
160634
|
+
|
|
160635
|
+
// src/tools.ts
|
|
160636
|
+
var ATOMIX_TOOLS = [
|
|
160637
|
+
"Bash",
|
|
160638
|
+
"Glob",
|
|
160639
|
+
"Grep",
|
|
160640
|
+
"Read",
|
|
160641
|
+
"Write",
|
|
160642
|
+
"Edit",
|
|
160643
|
+
"TodoWrite",
|
|
160644
|
+
"Skill",
|
|
160645
|
+
"AgentTeam",
|
|
160646
|
+
"NotebookEdit",
|
|
160647
|
+
"AskUser",
|
|
160648
|
+
"ToolSearch"
|
|
160649
|
+
];
|
|
160650
|
+
var ATOMIX_DEFER_TOOLS = ["NotebookEdit"];
|
|
160651
|
+
|
|
160652
|
+
// src/session.ts
|
|
159749
160653
|
init_skills();
|
|
159750
160654
|
init_agents();
|
|
159751
160655
|
init_harness();
|
|
@@ -159820,7 +160724,7 @@ async function mcpCommand(core, args) {
|
|
|
159820
160724
|
return lines.join("\n ");
|
|
159821
160725
|
}
|
|
159822
160726
|
|
|
159823
|
-
// src/
|
|
160727
|
+
// src/session.ts
|
|
159824
160728
|
init_marketplace();
|
|
159825
160729
|
|
|
159826
160730
|
// src/marketplaceCommand.ts
|
|
@@ -159878,6 +160782,19 @@ async function applyMcpHotUpdates(core) {
|
|
|
159878
160782
|
}
|
|
159879
160783
|
return notes;
|
|
159880
160784
|
}
|
|
160785
|
+
async function refreshRegisteredSessions(invoker) {
|
|
160786
|
+
refreshSkillsExtraDirs();
|
|
160787
|
+
refreshAgentsExtraDirs();
|
|
160788
|
+
refreshCommandsExtraDirs();
|
|
160789
|
+
const cores = new Set(listSessionDirs().map(([c]) => c));
|
|
160790
|
+
if (invoker) cores.add(invoker);
|
|
160791
|
+
for (const c of cores) {
|
|
160792
|
+
applyDisabledSkills(c);
|
|
160793
|
+
await applyDisabledAgents(c).catch(() => {
|
|
160794
|
+
});
|
|
160795
|
+
c.reloadCustomCommands();
|
|
160796
|
+
}
|
|
160797
|
+
}
|
|
159881
160798
|
async function applyChanges(core, opts) {
|
|
159882
160799
|
const notes = [];
|
|
159883
160800
|
const { synced, removed } = syncMarketplaceMcp();
|
|
@@ -159885,13 +160802,7 @@ async function applyChanges(core, opts) {
|
|
|
159885
160802
|
if (synced.length || removed.length) notes.push(`MCP \u5168\u5C40\u540C\u6B65\uFF1A+${synced.length} \u2212${removed.length}\uFF08\u4E0B\u6B21\u542F\u52A8\u8FDE\u63A5\uFF09`);
|
|
159886
160803
|
return notes;
|
|
159887
160804
|
}
|
|
159888
|
-
|
|
159889
|
-
applyDisabledSkills(core);
|
|
159890
|
-
refreshAgentsExtraDirs();
|
|
159891
|
-
await applyDisabledAgents(core).catch(() => {
|
|
159892
|
-
});
|
|
159893
|
-
refreshCommandsExtraDirs();
|
|
159894
|
-
core.reloadCustomCommands();
|
|
160805
|
+
await refreshRegisteredSessions(core);
|
|
159895
160806
|
notes.push(...await applyMcpHotUpdates(core));
|
|
159896
160807
|
const hooksNow = getMarketplace().getHookEntries().map((h) => h.file).sort();
|
|
159897
160808
|
const hooksBefore = [...opts?.hooksBefore ?? hooksNow].sort();
|
|
@@ -160038,12 +160949,12 @@ async function marketplaceCommand(core, args) {
|
|
|
160038
160949
|
}
|
|
160039
160950
|
|
|
160040
160951
|
// src/hooksLoader.ts
|
|
160041
|
-
var
|
|
160952
|
+
var import_atomix_core6 = __toESM(require_dist4());
|
|
160042
160953
|
init_paths();
|
|
160043
160954
|
init_marketplace();
|
|
160044
160955
|
import * as fs9 from "fs";
|
|
160045
160956
|
import * as path9 from "path";
|
|
160046
|
-
var VALID_EVENTS = new Set(
|
|
160957
|
+
var VALID_EVENTS = new Set(import_atomix_core6.HOOK_EVENTS);
|
|
160047
160958
|
function readHookFile(p) {
|
|
160048
160959
|
if (!fs9.existsSync(p)) return null;
|
|
160049
160960
|
try {
|
|
@@ -160104,8 +161015,258 @@ function loadHooks(cwd2) {
|
|
|
160104
161015
|
};
|
|
160105
161016
|
}
|
|
160106
161017
|
|
|
161018
|
+
// src/session.ts
|
|
161019
|
+
init_appConfig();
|
|
161020
|
+
function internalHandle(handle) {
|
|
161021
|
+
if (!handle || handle[SESSION_HANDLE_BRAND] !== true) {
|
|
161022
|
+
throw new Error("\u975E\u6CD5\u4F1A\u8BDD\u53E5\u67C4:\u5FC5\u987B\u6765\u81EA createSessionCore()");
|
|
161023
|
+
}
|
|
161024
|
+
return handle;
|
|
161025
|
+
}
|
|
161026
|
+
var MAIN = "main";
|
|
161027
|
+
var DEFAULT_SYSTEM_PROMPT = "You are Atomix, a CLI coding agent bound to the current working directory.";
|
|
161028
|
+
var DEFAULT_SEND_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
161029
|
+
var SESSION_ID_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;
|
|
161030
|
+
function validateSessionId(id) {
|
|
161031
|
+
if (!SESSION_ID_PATTERN.test(id) || id === "." || id === "..") {
|
|
161032
|
+
throw new Error(`\u975E\u6CD5 session id:${JSON.stringify(id)}(\u53EA\u5141\u8BB8 1\u2013128 \u4E2A\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u4E0B\u5212\u7EBF\u3001\u8FDE\u5B57\u7B26)`);
|
|
161033
|
+
}
|
|
161034
|
+
}
|
|
161035
|
+
var preparedCwd = null;
|
|
161036
|
+
function prepareProcess(cwd2) {
|
|
161037
|
+
if (preparedCwd === null) {
|
|
161038
|
+
initMarketplaceProject(cwd2);
|
|
161039
|
+
syncInheritedMcp();
|
|
161040
|
+
syncMarketplaceMcp();
|
|
161041
|
+
preparedCwd = cwd2;
|
|
161042
|
+
return null;
|
|
161043
|
+
}
|
|
161044
|
+
if (preparedCwd !== cwd2) {
|
|
161045
|
+
return `marketplace \u9879\u76EE\u7EA7 override \u4ECD\u7ED1\u5B9A\u9996\u4E2A\u4F1A\u8BDD\u76EE\u5F55 ${preparedCwd}(\u672C\u8FDB\u7A0B\u5185\u591A\u4F1A\u8BDD\u5171\u7528\u4E00\u4E2A\u9879\u76EE\u57DF)`;
|
|
161046
|
+
}
|
|
161047
|
+
return null;
|
|
161048
|
+
}
|
|
161049
|
+
function createSessionCore(opts) {
|
|
161050
|
+
const interactive = opts.interactive ?? false;
|
|
161051
|
+
const permissionMode = opts.permissionMode ?? (interactive ? import_atomix_core7.DEFAULT_PERMISSION_MODE : "free-style");
|
|
161052
|
+
const notes = [];
|
|
161053
|
+
const prepNote = prepareProcess(opts.cwd);
|
|
161054
|
+
if (prepNote) notes.push(prepNote);
|
|
161055
|
+
const appConfig = readConfig();
|
|
161056
|
+
const contextFiles = buildContextFilesConfig(opts.cwd, appConfig);
|
|
161057
|
+
const hookCfg = opts.hooks ?? interactive ? loadHooks(opts.cwd) : {};
|
|
161058
|
+
const dirs = { skills: buildSkillsExtraDirs(), agents: buildAgentsExtraDirs(), commands: buildCommandsExtraDirs() };
|
|
161059
|
+
const core = new import_atomix_core7.AtomixCore({
|
|
161060
|
+
workingDir: opts.cwd,
|
|
161061
|
+
logLevel: opts.logLevel ?? atomixLogLevel(),
|
|
161062
|
+
stream: opts.stream ?? interactive,
|
|
161063
|
+
useTools: ATOMIX_TOOLS,
|
|
161064
|
+
deferBuiltinTools: ATOMIX_DEFER_TOOLS,
|
|
161065
|
+
skillsExtraDirs: dirs.skills,
|
|
161066
|
+
agentsExtraDirs: dirs.agents,
|
|
161067
|
+
commandsExtraDirs: dirs.commands,
|
|
161068
|
+
...hookCfg,
|
|
161069
|
+
...contextFiles,
|
|
161070
|
+
permissionMode,
|
|
161071
|
+
// 交互模式下文件编辑必须过权限卡;无人值守靠 permissionMode(free-style 全放行,其余由自动应答器 fail-closed)
|
|
161072
|
+
skipFileEditPermission: false,
|
|
161073
|
+
multiSession: opts.multiSession ?? false,
|
|
161074
|
+
systemPrompt: opts.systemPrompt ?? DEFAULT_SYSTEM_PROMPT
|
|
161075
|
+
});
|
|
161076
|
+
registerSessionDirs(core, dirs);
|
|
161077
|
+
const potential = buildPotentialContextFiles(opts.cwd, appConfig);
|
|
161078
|
+
const baseline = {
|
|
161079
|
+
useTools: ATOMIX_TOOLS,
|
|
161080
|
+
deferBuiltinTools: ATOMIX_DEFER_TOOLS,
|
|
161081
|
+
memoryFiles: contextFiles.memoryFiles,
|
|
161082
|
+
personaFile: contextFiles.personaFile,
|
|
161083
|
+
potentialMemoryFiles: potential.memoryFiles,
|
|
161084
|
+
thinking: false
|
|
161085
|
+
// cli 构造 core 时 thinking 关;harness 未声明即回到这里
|
|
161086
|
+
};
|
|
161087
|
+
return { [SESSION_HANDLE_BRAND]: true, core, cwd: opts.cwd, interactive, permissionMode, appConfig, contextFiles, baseline, notes };
|
|
161088
|
+
}
|
|
161089
|
+
async function discardSessionCore(handle) {
|
|
161090
|
+
const h = internalHandle(handle);
|
|
161091
|
+
unregisterSessionDirs(h.core);
|
|
161092
|
+
await h.core.dispose().catch(() => {
|
|
161093
|
+
});
|
|
161094
|
+
}
|
|
161095
|
+
async function startSession(handle, opts = {}) {
|
|
161096
|
+
const h = internalHandle(handle);
|
|
161097
|
+
const { core, cwd: cwd2 } = h;
|
|
161098
|
+
if (opts.sessionId !== void 0) validateSessionId(opts.sessionId);
|
|
161099
|
+
const notes = [...h.notes];
|
|
161100
|
+
const warn = initHarness(core, cwd2, h.baseline, opts.harness !== void 0 ? { harness: opts.harness } : {});
|
|
161101
|
+
if (warn) notes.push(warn);
|
|
161102
|
+
let ready;
|
|
161103
|
+
const onReady = (d) => {
|
|
161104
|
+
ready = d;
|
|
161105
|
+
};
|
|
161106
|
+
core.once("session:ready", onReady);
|
|
161107
|
+
try {
|
|
161108
|
+
await core.createSession(opts.sessionId);
|
|
161109
|
+
} finally {
|
|
161110
|
+
core.off("session:ready", onReady);
|
|
161111
|
+
}
|
|
161112
|
+
if (!ready) throw new Error("createSession \u5DF2\u8FD4\u56DE\u4F46\u672A\u6536\u5230 session:ready");
|
|
161113
|
+
applyDisabledSkills(core);
|
|
161114
|
+
await applyDisabledAgents(core).catch((e) => {
|
|
161115
|
+
notes.push(`subagent \u542F\u505C\u540D\u5355\u5E94\u7528\u5931\u8D25(harness agent \u53D6\u820D\u53EF\u80FD\u672A\u751F\u6548):${e instanceof Error ? e.message : String(e)}`);
|
|
161116
|
+
});
|
|
161117
|
+
const mcpNotes = await applyMcpHotUpdates(core).catch(() => []);
|
|
161118
|
+
notes.push(...mcpNotes.map((n) => `${n}\uFF08\u9879\u76EE\u7EA7 override\uFF09`));
|
|
161119
|
+
const responder = h.interactive ? null : attachHeadlessResponder(core);
|
|
161120
|
+
return new SessionImpl(h, ready, notes, responder);
|
|
161121
|
+
}
|
|
161122
|
+
function attachHeadlessResponder(core) {
|
|
161123
|
+
const blocked = [];
|
|
161124
|
+
const onPermission = (d) => {
|
|
161125
|
+
blocked.push({ kind: "permission", name: d.toolName, title: d.title, agentId: d.agentId });
|
|
161126
|
+
setImmediate(() => core.respondToToolPermission({ toolName: d.toolName, selected: "refuse", agentId: d.agentId }));
|
|
161127
|
+
};
|
|
161128
|
+
const onQuestion = (d) => {
|
|
161129
|
+
blocked.push({ kind: "question", name: "AskUserQuestion", title: d.questions.map((q) => q.question).join(" / "), agentId: d.agentId });
|
|
161130
|
+
setImmediate(() => core.respondToAskQuestion({ agentId: d.agentId, answers: {} }));
|
|
161131
|
+
};
|
|
161132
|
+
const onForm = (d) => {
|
|
161133
|
+
blocked.push({ kind: "form", name: "FormUI", title: d.title, agentId: d.agentId });
|
|
161134
|
+
setImmediate(() => core.respondToForm({ agentId: d.agentId, values: {}, submitted: false }));
|
|
161135
|
+
};
|
|
161136
|
+
core.on("tool:permission:request", onPermission);
|
|
161137
|
+
core.on("ask:question:request", onQuestion);
|
|
161138
|
+
core.on("form:request", onForm);
|
|
161139
|
+
return {
|
|
161140
|
+
blocked,
|
|
161141
|
+
detach() {
|
|
161142
|
+
core.off("tool:permission:request", onPermission);
|
|
161143
|
+
core.off("ask:question:request", onQuestion);
|
|
161144
|
+
core.off("form:request", onForm);
|
|
161145
|
+
}
|
|
161146
|
+
};
|
|
161147
|
+
}
|
|
161148
|
+
var DISPOSED_ERROR = "session \u5DF2\u91CA\u653E";
|
|
161149
|
+
var SessionImpl = class {
|
|
161150
|
+
constructor(handle, ready, notes, responder) {
|
|
161151
|
+
this.responder = responder;
|
|
161152
|
+
this.core = handle.core;
|
|
161153
|
+
this.cwd = handle.cwd;
|
|
161154
|
+
this.permissionMode = handle.permissionMode;
|
|
161155
|
+
this.ready = ready;
|
|
161156
|
+
this.notes = notes;
|
|
161157
|
+
}
|
|
161158
|
+
responder;
|
|
161159
|
+
core;
|
|
161160
|
+
cwd;
|
|
161161
|
+
permissionMode;
|
|
161162
|
+
ready;
|
|
161163
|
+
notes;
|
|
161164
|
+
queue = Promise.resolve();
|
|
161165
|
+
disposed = false;
|
|
161166
|
+
/** 进行中一轮的强制收尾(dispose 用):以给定错误结束 send 并中断 core */
|
|
161167
|
+
abortCurrent = null;
|
|
161168
|
+
get sessionId() {
|
|
161169
|
+
return this.core.getCurrentSessionId() ?? this.ready.sessionId;
|
|
161170
|
+
}
|
|
161171
|
+
get harness() {
|
|
161172
|
+
return getActiveHarnessName(this.core);
|
|
161173
|
+
}
|
|
161174
|
+
get model() {
|
|
161175
|
+
const m = effectiveModels(this.core);
|
|
161176
|
+
const t = effectiveTemperatures(this.core);
|
|
161177
|
+
const temperature = {};
|
|
161178
|
+
for (const slot of ["main", "quick"]) {
|
|
161179
|
+
const e = t[slot];
|
|
161180
|
+
if ((e.from === "harness" || e.from === "profile") && e.value !== null) temperature[slot] = e.value;
|
|
161181
|
+
}
|
|
161182
|
+
return { main: m.main, quick: m.quick, ...m.fallback ? { fallback: m.fallback } : {}, ...Object.keys(temperature).length ? { temperature } : {} };
|
|
161183
|
+
}
|
|
161184
|
+
on(event, listener) {
|
|
161185
|
+
this.core.on(event, listener);
|
|
161186
|
+
}
|
|
161187
|
+
off(event, listener) {
|
|
161188
|
+
this.core.off(event, listener);
|
|
161189
|
+
}
|
|
161190
|
+
send(input, opts = {}) {
|
|
161191
|
+
if (this.disposed) return Promise.reject(new Error(DISPOSED_ERROR));
|
|
161192
|
+
const run = this.queue.then(() => this.sendNow(input, opts));
|
|
161193
|
+
this.queue = run.catch(() => void 0);
|
|
161194
|
+
return run;
|
|
161195
|
+
}
|
|
161196
|
+
sendNow(input, opts) {
|
|
161197
|
+
if (this.disposed) return Promise.reject(new Error(DISPOSED_ERROR));
|
|
161198
|
+
const core = this.core;
|
|
161199
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_SEND_TIMEOUT_MS;
|
|
161200
|
+
const blockedStart = this.responder?.blocked.length ?? 0;
|
|
161201
|
+
return new Promise((resolve9) => {
|
|
161202
|
+
const texts = [];
|
|
161203
|
+
let usage2;
|
|
161204
|
+
let sawProcessing = false;
|
|
161205
|
+
let done = false;
|
|
161206
|
+
const onMessage = (d) => {
|
|
161207
|
+
if (d.agentId === MAIN && d.content.trim()) texts.push(d.content);
|
|
161208
|
+
};
|
|
161209
|
+
const onState = (d) => {
|
|
161210
|
+
if (d.state === "processing") sawProcessing = true;
|
|
161211
|
+
else if (d.state === "idle" && sawProcessing) finish();
|
|
161212
|
+
};
|
|
161213
|
+
const onError = (d) => {
|
|
161214
|
+
finish({ type: d.type, message: d.error?.message ?? d.error?.code ?? "" });
|
|
161215
|
+
};
|
|
161216
|
+
const onUsage = (d) => {
|
|
161217
|
+
if (d.agentId === void 0 || d.agentId === MAIN) usage2 = d.usage;
|
|
161218
|
+
};
|
|
161219
|
+
const interruptWith = (error) => {
|
|
161220
|
+
if (done) return;
|
|
161221
|
+
finish(error);
|
|
161222
|
+
core.interruptSession();
|
|
161223
|
+
};
|
|
161224
|
+
const onAbort = () => interruptWith({ type: "aborted", message: "\u8C03\u7528\u65B9\u4E2D\u6B62" });
|
|
161225
|
+
const timer = setTimeout(() => interruptWith({ type: "timeout", message: `\u8D85\u65F6\uFF08${timeoutMs / 1e3}s\uFF09` }), timeoutMs);
|
|
161226
|
+
const finish = (error) => {
|
|
161227
|
+
if (done) return;
|
|
161228
|
+
done = true;
|
|
161229
|
+
clearTimeout(timer);
|
|
161230
|
+
this.abortCurrent = null;
|
|
161231
|
+
core.off("message:complete", onMessage);
|
|
161232
|
+
core.off("state:update", onState);
|
|
161233
|
+
core.off("session:error", onError);
|
|
161234
|
+
core.off("conversation:usage", onUsage);
|
|
161235
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
161236
|
+
resolve9({
|
|
161237
|
+
text: texts[texts.length - 1] ?? "",
|
|
161238
|
+
texts,
|
|
161239
|
+
blocked: this.responder ? this.responder.blocked.slice(blockedStart) : [],
|
|
161240
|
+
usage: usage2,
|
|
161241
|
+
...error ? { error } : {}
|
|
161242
|
+
});
|
|
161243
|
+
};
|
|
161244
|
+
this.abortCurrent = interruptWith;
|
|
161245
|
+
core.on("message:complete", onMessage);
|
|
161246
|
+
core.on("state:update", onState);
|
|
161247
|
+
core.on("session:error", onError);
|
|
161248
|
+
core.on("conversation:usage", onUsage);
|
|
161249
|
+
if (opts.signal) {
|
|
161250
|
+
if (opts.signal.aborted) return onAbort();
|
|
161251
|
+
opts.signal.addEventListener("abort", onAbort, { once: true });
|
|
161252
|
+
}
|
|
161253
|
+
core.processUserInput(input);
|
|
161254
|
+
});
|
|
161255
|
+
}
|
|
161256
|
+
async dispose() {
|
|
161257
|
+
if (this.disposed) return;
|
|
161258
|
+
this.disposed = true;
|
|
161259
|
+
this.abortCurrent?.({ type: "disposed", message: DISPOSED_ERROR });
|
|
161260
|
+
await this.queue.catch(() => void 0);
|
|
161261
|
+
this.responder?.detach();
|
|
161262
|
+
unregisterSessionDirs(this.core);
|
|
161263
|
+
await this.core.dispose().catch(() => {
|
|
161264
|
+
});
|
|
161265
|
+
}
|
|
161266
|
+
};
|
|
161267
|
+
|
|
160107
161268
|
// src/resume.ts
|
|
160108
|
-
var
|
|
161269
|
+
var import_atomix_core8 = __toESM(require_dist4());
|
|
160109
161270
|
import * as fs10 from "fs";
|
|
160110
161271
|
import * as path10 from "path";
|
|
160111
161272
|
function extractText(content) {
|
|
@@ -160124,7 +161285,7 @@ function readMessages(file) {
|
|
|
160124
161285
|
}
|
|
160125
161286
|
}
|
|
160126
161287
|
function listSessions(cwd2) {
|
|
160127
|
-
const dir = (0,
|
|
161288
|
+
const dir = (0, import_atomix_core8.getProjectHistoryDir)(cwd2);
|
|
160128
161289
|
if (!fs10.existsSync(dir)) return [];
|
|
160129
161290
|
const entries = [];
|
|
160130
161291
|
for (const f of fs10.readdirSync(dir)) {
|
|
@@ -160263,16 +161424,19 @@ function setGlyphMode(mode) {
|
|
|
160263
161424
|
return true;
|
|
160264
161425
|
}
|
|
160265
161426
|
|
|
161427
|
+
// src/tui/index.tsx
|
|
161428
|
+
init_harness();
|
|
161429
|
+
|
|
160266
161430
|
// src/permissionMode.ts
|
|
160267
|
-
var
|
|
161431
|
+
var import_atomix_core9 = __toESM(require_dist4());
|
|
160268
161432
|
var META = {
|
|
160269
161433
|
"step-by-step": { label: "step by step", hint: "\u6BCF\u4E2A\u654F\u611F\u64CD\u4F5C\u9010\u9879\u786E\u8BA4", tone: "muted" },
|
|
160270
161434
|
"action-check": { label: "action check", hint: "\u53EA\u8BFB\u64CD\u4F5C\u514D\u786E\u8BA4\uFF0C\u5176\u4F59\u9010\u9879\u786E\u8BA4", tone: "accent" },
|
|
160271
161435
|
"free-style": { label: "free style", hint: "\u5168\u90E8\u514D\u786E\u8BA4\uFF08\u5B89\u5168\u6821\u9A8C\u4ECD\u751F\u6548\uFF09", tone: "warning" }
|
|
160272
161436
|
};
|
|
160273
|
-
var PERMISSION_MODE_ORDER =
|
|
161437
|
+
var PERMISSION_MODE_ORDER = import_atomix_core9.PERMISSION_MODES;
|
|
160274
161438
|
function permissionModeMeta(mode) {
|
|
160275
|
-
return META[mode] ?? META[
|
|
161439
|
+
return META[mode] ?? META[import_atomix_core9.DEFAULT_PERMISSION_MODE];
|
|
160276
161440
|
}
|
|
160277
161441
|
function nextPermissionMode(mode) {
|
|
160278
161442
|
const i = PERMISSION_MODE_ORDER.indexOf(mode);
|
|
@@ -160490,7 +161654,7 @@ function windowAroundCursor(chars, cursor, budget, newlineGlyph) {
|
|
|
160490
161654
|
}
|
|
160491
161655
|
|
|
160492
161656
|
// src/tui/bridge.ts
|
|
160493
|
-
var
|
|
161657
|
+
var MAIN2 = "main";
|
|
160494
161658
|
function estimateItemRows(item, columns) {
|
|
160495
161659
|
const text = item.kind === "thinking" ? "" : item.kind === "tool" ? `${item.title} ${item.summary ?? ""}` : item.kind === "shell" ? `${item.cmd}
|
|
160496
161660
|
${item.body}
|
|
@@ -160533,7 +161697,7 @@ var Bridge = class {
|
|
|
160533
161697
|
interactions: [],
|
|
160534
161698
|
sessionId: "",
|
|
160535
161699
|
thinkingEnabled: false,
|
|
160536
|
-
permissionMode:
|
|
161700
|
+
permissionMode: import_atomix_core9.DEFAULT_PERMISSION_MODE,
|
|
160537
161701
|
modelName: "",
|
|
160538
161702
|
redrawNonce: 0,
|
|
160539
161703
|
staticEpoch: 0,
|
|
@@ -160592,6 +161756,10 @@ var Bridge = class {
|
|
|
160592
161756
|
this.set({ thinkingEnabled: enabled });
|
|
160593
161757
|
this.core.updateThinking(enabled);
|
|
160594
161758
|
}
|
|
161759
|
+
/** 只同步 UI 镜像,不碰 core(harness 应用时 core 已由 applyAssembly 下发)。 */
|
|
161760
|
+
syncThinking(enabled) {
|
|
161761
|
+
this.set({ thinkingEnabled: enabled });
|
|
161762
|
+
}
|
|
160595
161763
|
setModelName(name) {
|
|
160596
161764
|
this.set({ modelName: name });
|
|
160597
161765
|
}
|
|
@@ -160710,7 +161878,7 @@ var Bridge = class {
|
|
|
160710
161878
|
this.set({ streamText: content ?? "" });
|
|
160711
161879
|
});
|
|
160712
161880
|
core.on("message:complete", (d) => {
|
|
160713
|
-
if (d.agentId !==
|
|
161881
|
+
if (d.agentId !== MAIN2) return;
|
|
160714
161882
|
const items = [...this.state.items];
|
|
160715
161883
|
if (d.reasoning) items.push({ kind: "thinking", chars: d.reasoning.length });
|
|
160716
161884
|
if (d.content.trim()) items.push({ kind: "assistant", text: d.content });
|
|
@@ -160759,7 +161927,7 @@ var Bridge = class {
|
|
|
160759
161927
|
core.on("todos:update", (todos) => {
|
|
160760
161928
|
this.set({ todos: todos ?? [] });
|
|
160761
161929
|
});
|
|
160762
|
-
const isMainEvent = (agentId) => !agentId || agentId ===
|
|
161930
|
+
const isMainEvent = (agentId) => !agentId || agentId === MAIN2;
|
|
160763
161931
|
core.on("conversation:usage", (d) => {
|
|
160764
161932
|
if (isMainEvent(d.agentId)) this.set({ usage: d.usage });
|
|
160765
161933
|
});
|
|
@@ -160790,7 +161958,7 @@ var Bridge = class {
|
|
|
160790
161958
|
});
|
|
160791
161959
|
});
|
|
160792
161960
|
core.on("session:interrupted", (d) => {
|
|
160793
|
-
if (d.agentId ===
|
|
161961
|
+
if (d.agentId === MAIN2) this.notice("\u23F9 \u5DF2\u4E2D\u65AD", "warn");
|
|
160794
161962
|
});
|
|
160795
161963
|
core.on("session:error", (d) => {
|
|
160796
161964
|
this.notice(`\u4F1A\u8BDD\u9519\u8BEF [${d.type}] ${d.error?.message ?? d.error?.code ?? ""}`, "error");
|
|
@@ -161484,9 +162652,9 @@ function SelectList({ options: options2, multi = false, color = theme.accent, on
|
|
|
161484
162652
|
winStart > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: ` \u2026 \u4E0A\u65B9\u8FD8\u6709 ${winStart} \u9879` }) : null,
|
|
161485
162653
|
visible.map((o, vi) => {
|
|
161486
162654
|
const i = winStart + vi;
|
|
161487
|
-
const
|
|
161488
|
-
const mark = multi ? checked.has(i) ? G.radioOn : G.radioOff :
|
|
161489
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color:
|
|
162655
|
+
const active = i === index;
|
|
162656
|
+
const mark = multi ? checked.has(i) ? G.radioOn : G.radioOff : active ? G.pointer : " ";
|
|
162657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: active ? color : void 0, dimColor: !active, children: [
|
|
161490
162658
|
` ${mark} ${i + 1}. ${o.label}`,
|
|
161491
162659
|
o.hint ? ` ${o.hint}` : ""
|
|
161492
162660
|
] }, i);
|
|
@@ -161695,7 +162863,7 @@ function PromptCard({
|
|
|
161695
162863
|
}
|
|
161696
162864
|
|
|
161697
162865
|
// src/tui/images.ts
|
|
161698
|
-
var
|
|
162866
|
+
var import_atomix_core10 = __toESM(require_dist4());
|
|
161699
162867
|
import { execFile as execFile2 } from "child_process";
|
|
161700
162868
|
import * as fs13 from "fs";
|
|
161701
162869
|
import * as os8 from "os";
|
|
@@ -161812,7 +162980,7 @@ async function buildUserInput(text, cwd2) {
|
|
|
161812
162980
|
if (sources.length === 0) return { input: text, display: text };
|
|
161813
162981
|
const blocks = [
|
|
161814
162982
|
{ type: "text", text: rewritten },
|
|
161815
|
-
...await Promise.all(sources.map((src) => (0,
|
|
162983
|
+
...await Promise.all(sources.map((src) => (0, import_atomix_core10.loadImageAsBlock)(src)))
|
|
161816
162984
|
];
|
|
161817
162985
|
for (const placeholder of usedPlaceholders) {
|
|
161818
162986
|
const file = pastedImages.get(placeholder);
|
|
@@ -162042,7 +163210,7 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162042
163210
|
}, [bridge]);
|
|
162043
163211
|
const submittingRef = (0, import_react25.useRef)(false);
|
|
162044
163212
|
const [submitting, setSubmitting] = (0, import_react25.useState)(false);
|
|
162045
|
-
const
|
|
163213
|
+
const active = s.interactions[0];
|
|
162046
163214
|
const shellKillRef = (0, import_react25.useRef)(null);
|
|
162047
163215
|
const [shellCmd, setShellCmd] = (0, import_react25.useState)(null);
|
|
162048
163216
|
use_input_default((input, key) => {
|
|
@@ -162137,8 +163305,7 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162137
163305
|
return;
|
|
162138
163306
|
case "/model": {
|
|
162139
163307
|
await modelCommand(bridge.core, rest2, bridge.ask);
|
|
162140
|
-
|
|
162141
|
-
if (md) bridge.setModelName(md.taskConfig.main);
|
|
163308
|
+
bridge.setModelName(effectiveModels(bridge.core).main);
|
|
162142
163309
|
return;
|
|
162143
163310
|
}
|
|
162144
163311
|
case "/resume": {
|
|
@@ -162177,11 +163344,18 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162177
163344
|
case "/agents":
|
|
162178
163345
|
bridge.notice(await agentsCommand(bridge.core, rest2));
|
|
162179
163346
|
return;
|
|
162180
|
-
case "/harness":
|
|
162181
|
-
|
|
163347
|
+
case "/harness": {
|
|
163348
|
+
const out = await harnessCommand(bridge.core, rest2);
|
|
163349
|
+
bridge.notice(out, out.includes("\u26A0") ? "warn" : "info");
|
|
163350
|
+
bridge.setModelName(effectiveModels(bridge.core).main);
|
|
163351
|
+
if (rest2[0] === "use" || rest2[0] === "reset") {
|
|
163352
|
+
const t = appliedThinking(bridge.core);
|
|
163353
|
+
if (t !== void 0) bridge.syncThinking(t);
|
|
163354
|
+
}
|
|
162182
163355
|
return;
|
|
163356
|
+
}
|
|
162183
163357
|
case "/memory":
|
|
162184
|
-
bridge.notice(await memoryCommand(cwd2, appConfig, rest2, { harnessMemory: harnessMemoryOverride(), harnessPersona: harnessPersonaOverride(), personaPath: getActivePersonaFile() }));
|
|
163358
|
+
bridge.notice(await memoryCommand(cwd2, appConfig, rest2, { harnessMemory: harnessMemoryOverride(bridge.core), harnessPersona: harnessPersonaOverride(bridge.core), personaPath: getActivePersonaFile(bridge.core) }));
|
|
162185
163359
|
return;
|
|
162186
163360
|
case "/mcp":
|
|
162187
163361
|
bridge.notice(await mcpCommand(bridge.core, rest2));
|
|
@@ -162191,18 +163365,21 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162191
163365
|
setSlashCommands(await loadSlashCommands(bridge.core));
|
|
162192
163366
|
return;
|
|
162193
163367
|
case "/status": {
|
|
162194
|
-
const
|
|
163368
|
+
const modelLine = modelStatusLine(bridge.core);
|
|
162195
163369
|
bridge.notice(
|
|
162196
163370
|
[
|
|
162197
163371
|
`session ${s.sessionId}`,
|
|
162198
163372
|
`cwd ${cwd2}`,
|
|
162199
|
-
`harness ${getActiveHarnessName()}`,
|
|
162200
|
-
`memory ${memoryStatusLine(appConfig, { harnessMemory: harnessMemoryOverride(), harnessPersona: harnessPersonaOverride() })}`,
|
|
162201
|
-
`model
|
|
163373
|
+
`harness ${getActiveHarnessName(bridge.core)}${isHarnessOverridden(bridge.core) ? "\uFF08\u4F1A\u8BDD\u7EA7\u6307\u5B9A\uFF09" : ""}`,
|
|
163374
|
+
`memory ${memoryStatusLine(appConfig, { harnessMemory: harnessMemoryOverride(bridge.core), harnessPersona: harnessPersonaOverride(bridge.core) })}`,
|
|
163375
|
+
`model ${modelLine}`,
|
|
163376
|
+
`temp ${temperatureStatusLine(bridge.core, s.thinkingEnabled)}`,
|
|
162202
163377
|
`context ${s.usage ? `${s.usage.useTokens} / ${s.usage.maxTokens} tokens` : "-"}`,
|
|
162203
|
-
`thinking ${s.thinkingEnabled
|
|
163378
|
+
`thinking ${thinkingStatusLine(bridge.core, s.thinkingEnabled)}`,
|
|
162204
163379
|
`perms ${permissionModeMeta(s.permissionMode).label}\uFF08${s.permissionMode}\uFF0CShift+Tab \u5207\u6362\uFF09`
|
|
162205
|
-
].join("\n ")
|
|
163380
|
+
].join("\n "),
|
|
163381
|
+
modelLine.startsWith("\u26A0") ? "warn" : "info"
|
|
163382
|
+
// 模型回落时整条黄色
|
|
162206
163383
|
);
|
|
162207
163384
|
return;
|
|
162208
163385
|
}
|
|
@@ -162324,11 +163501,11 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162324
163501
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { flexDirection: "column", width: previewWidth, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: streamPreview.text }) })
|
|
162325
163502
|
] })
|
|
162326
163503
|
] }) : null,
|
|
162327
|
-
|
|
162328
|
-
|
|
162329
|
-
|
|
162330
|
-
|
|
162331
|
-
|
|
163504
|
+
active?.kind === "permission" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PermissionCard, { data: active.data, respond: active.respond }) : null,
|
|
163505
|
+
active?.kind === "question" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(QuestionCard, { data: active.data, respond: active.respond }) : null,
|
|
163506
|
+
active?.kind === "form" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FormCard, { data: active.data, respond: active.respond }) : null,
|
|
163507
|
+
active?.kind === "prompt" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PromptCard, { question: active.question, respond: active.respond, cancel: active.cancel }) : null,
|
|
163508
|
+
active?.kind === "select" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SelectCard, { question: active.question, options: active.options, respond: active.respond }) : null,
|
|
162332
163509
|
showTodos ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", marginTop: 1, children: [
|
|
162333
163510
|
s.todos.slice(0, 6).map((t, i) => {
|
|
162334
163511
|
const mark = t.status === "completed" ? G.todoDone : t.status === "in_progress" ? G.todoDoing : G.todoPending;
|
|
@@ -162349,9 +163526,9 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162349
163526
|
}
|
|
162350
163527
|
),
|
|
162351
163528
|
redrawPulse ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { children: " " }) : null,
|
|
162352
|
-
s.processing && !
|
|
162353
|
-
shellCmd && !
|
|
162354
|
-
!s.processing && !
|
|
163529
|
+
s.processing && !active ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProcessingLine, {}) : null,
|
|
163530
|
+
shellCmd && !active ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ShellRunningLine, { cmd: shellCmd }) : null,
|
|
163531
|
+
!s.processing && !active && !submitting ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
162355
163532
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { borderStyle: G.border, borderColor: theme.muted, paddingX: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { flexGrow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
162356
163533
|
LineInput,
|
|
162357
163534
|
{
|
|
@@ -162375,32 +163552,15 @@ function App2({ bridge, cwd: cwd2, initialHistory, appConfig }) {
|
|
|
162375
163552
|
// src/tui/index.tsx
|
|
162376
163553
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime());
|
|
162377
163554
|
var VERSION2 = "0.1.0";
|
|
162378
|
-
async function startTui(cwd2,
|
|
163555
|
+
async function startTui(cwd2, options2 = {}) {
|
|
163556
|
+
const { resumeSessionId } = options2;
|
|
162379
163557
|
applyConfiguredTheme();
|
|
162380
163558
|
if (!process.env.ATOMIX_GLYPHS) {
|
|
162381
163559
|
const mode = configuredGlyphMode();
|
|
162382
163560
|
if (mode) setGlyphMode(mode);
|
|
162383
163561
|
}
|
|
162384
|
-
|
|
162385
|
-
|
|
162386
|
-
syncMarketplaceMcp();
|
|
162387
|
-
const hookCfg = loadHooks(cwd2);
|
|
162388
|
-
const appConfig = readConfig();
|
|
162389
|
-
const contextFiles = buildContextFilesConfig(cwd2, appConfig);
|
|
162390
|
-
const core = new import_atomix_core8.AtomixCore({
|
|
162391
|
-
workingDir: cwd2,
|
|
162392
|
-
logLevel: atomixLogLevel(),
|
|
162393
|
-
stream: true,
|
|
162394
|
-
useTools: ATOMIX_TOOLS,
|
|
162395
|
-
deferBuiltinTools: ATOMIX_DEFER_TOOLS,
|
|
162396
|
-
skillsExtraDirs: buildSkillsExtraDirs(),
|
|
162397
|
-
agentsExtraDirs: buildAgentsExtraDirs(),
|
|
162398
|
-
commandsExtraDirs: buildCommandsExtraDirs(),
|
|
162399
|
-
...hookCfg,
|
|
162400
|
-
...contextFiles,
|
|
162401
|
-
skipFileEditPermission: false,
|
|
162402
|
-
systemPrompt: "You are Atomix, a CLI coding agent bound to the current working directory."
|
|
162403
|
-
});
|
|
163562
|
+
const handle = createSessionCore({ cwd: cwd2, interactive: true, permissionMode: options2.permissionMode });
|
|
163563
|
+
const { core, appConfig } = handle;
|
|
162404
163564
|
{
|
|
162405
163565
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
162406
163566
|
const { ask, dispose } = makeCancellableAsk(rl);
|
|
@@ -162413,14 +163573,12 @@ async function startTui(cwd2, resumeSessionId) {
|
|
|
162413
163573
|
}
|
|
162414
163574
|
if (!ok) {
|
|
162415
163575
|
console.log(gray("\u672A\u5B8C\u6210\u6A21\u578B\u914D\u7F6E\uFF0C\u9000\u51FA\u3002"));
|
|
162416
|
-
await
|
|
162417
|
-
});
|
|
163576
|
+
await discardSessionCore(handle);
|
|
162418
163577
|
process.exit(1);
|
|
162419
163578
|
}
|
|
162420
163579
|
}
|
|
162421
163580
|
const bridge = new Bridge(core);
|
|
162422
|
-
|
|
162423
|
-
bridge.setModelName(md.taskConfig.main);
|
|
163581
|
+
bridge.setModelName(effectiveModels(core).main);
|
|
162424
163582
|
const accent = paint("accent");
|
|
162425
163583
|
const muted = paint("muted");
|
|
162426
163584
|
bridge.notice(
|
|
@@ -162428,41 +163586,21 @@ async function startTui(cwd2, resumeSessionId) {
|
|
|
162428
163586
|
accent("\u256D\u2500 ") + bold("\u25C6 atomix") + muted(` v${VERSION2}`),
|
|
162429
163587
|
accent("\u2502 ") + muted(`cwd ${cwd2}`),
|
|
162430
163588
|
accent("\u2502 ") + muted(`root ${getAtomixRoot()}`),
|
|
162431
|
-
accent("\u2502 ") + muted(`model ${
|
|
163589
|
+
accent("\u2502 ") + muted(`model ${effectiveModels(core).main}`),
|
|
162432
163590
|
accent("\u2570\u2500 ") + muted("/help \u67E5\u770B\u547D\u4EE4")
|
|
162433
163591
|
].join("\n")
|
|
162434
163592
|
);
|
|
162435
|
-
|
|
162436
|
-
await new Promise((resolve9, reject2) => {
|
|
162437
|
-
core.once("session:ready", (d) => {
|
|
162438
|
-
bridge.setSessionId(d.sessionId);
|
|
162439
|
-
bridge.setUsage(d.usage);
|
|
162440
|
-
initialHistory = [...d.projectInputHistory ?? []];
|
|
162441
|
-
resolve9();
|
|
162442
|
-
});
|
|
162443
|
-
core.createSession(resumeSessionId).catch(reject2);
|
|
162444
|
-
}).catch(async (e) => {
|
|
163593
|
+
const session = await startSession(handle, { sessionId: resumeSessionId, harness: options2.harness }).catch(async (e) => {
|
|
162445
163594
|
console.error(`\u4F1A\u8BDD\u521D\u59CB\u5316\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
162446
|
-
await
|
|
162447
|
-
});
|
|
163595
|
+
await discardSessionCore(handle);
|
|
162448
163596
|
process.exit(1);
|
|
162449
163597
|
});
|
|
162450
|
-
{
|
|
162451
|
-
|
|
162452
|
-
|
|
162453
|
-
|
|
162454
|
-
|
|
162455
|
-
|
|
162456
|
-
personaFile: contextFiles.personaFile,
|
|
162457
|
-
potentialMemoryFiles: potential.memoryFiles
|
|
162458
|
-
});
|
|
162459
|
-
if (warn) console.error(warn);
|
|
162460
|
-
}
|
|
162461
|
-
applyDisabledSkills(core);
|
|
162462
|
-
await applyDisabledAgents(core).catch(() => {
|
|
162463
|
-
});
|
|
162464
|
-
const mcpNotes = await applyMcpHotUpdates(core).catch(() => []);
|
|
162465
|
-
for (const n of mcpNotes) bridge.notice(`${n}\uFF08\u9879\u76EE\u7EA7 override\uFF09`);
|
|
163598
|
+
bridge.setPermissionMode(handle.permissionMode, { silent: true });
|
|
163599
|
+
bridge.setSessionId(session.ready.sessionId);
|
|
163600
|
+
bridge.setUsage(session.ready.usage);
|
|
163601
|
+
bridge.syncThinking(appliedThinking(core) ?? false);
|
|
163602
|
+
const initialHistory = [...session.ready.projectInputHistory ?? []];
|
|
163603
|
+
for (const n of session.notes) bridge.notice(n, n.startsWith("harness") ? "warn" : "info");
|
|
162466
163604
|
if (resumeSessionId) {
|
|
162467
163605
|
bridge.seedReplay(loadReplay(cwd2, resumeSessionId));
|
|
162468
163606
|
}
|