oasis_test 0.1.45 → 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +853 -618
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1958,9 +1958,9 @@ var init_kernel = __esm({
|
|
|
1958
1958
|
throw new KernelError(`revision not in queue: ${args.revisionId}\uFF08state=${target?.state ?? "missing"}\uFF09`);
|
|
1959
1959
|
}
|
|
1960
1960
|
if (isStale(this.model, head)) {
|
|
1961
|
-
const
|
|
1961
|
+
const path20 = this.pathForStaleHead(artifact, queue);
|
|
1962
1962
|
throw new KernelError(
|
|
1963
|
-
`stale base: ${head.id} based on ${head.base ?? "\u2205"}, head is ${artifact.currentRev ?? "\u2205"} \u2014 ` + (
|
|
1963
|
+
`stale base: ${head.id} based on ${head.base ?? "\u2205"}, head is ${artifact.currentRev ?? "\u2205"} \u2014 ` + (path20 === "rebase" ? `\u9700\u8981 rebase\uFF1A\u4F5C\u8005\u5728\u65B0 head \u4E0A\u91CD\u5199\u540E propose --rebase-of ${head.id}\uFF08\xA75.5\uFF09` : `\u591A\u6761\u7ADE\u4E89\u4E14\u68C0\u67E5\u8D35 \u2192 group-commit\uFF1Aowner \u4E00\u6B21\u96C6\u6210\u6574\u6279\uFF08\xA75.5\uFF09`)
|
|
1964
1964
|
);
|
|
1965
1965
|
}
|
|
1966
1966
|
await this.landHead(args.artifactId, args.actor, head, args.hand);
|
|
@@ -1977,13 +1977,13 @@ var init_kernel = __esm({
|
|
|
1977
1977
|
const head = queue[0];
|
|
1978
1978
|
if (!head) return { landed };
|
|
1979
1979
|
if (isStale(this.model, head)) {
|
|
1980
|
-
const
|
|
1980
|
+
const path20 = this.pathForStaleHead(artifact, queue);
|
|
1981
1981
|
return {
|
|
1982
1982
|
landed,
|
|
1983
1983
|
blockedHead: {
|
|
1984
1984
|
revision: head,
|
|
1985
|
-
path:
|
|
1986
|
-
hint:
|
|
1985
|
+
path: path20,
|
|
1986
|
+
hint: path20 === "rebase" ? `\u4F5C\u8005\u91CD\u5199\u540E propose --rebase-of ${head.id}` : `owner \u96C6\u6210\u6574\u6279\uFF08integrate\uFF09\uFF0CR*.parents = [head, \u2026batch]`
|
|
1987
1987
|
}
|
|
1988
1988
|
};
|
|
1989
1989
|
}
|
|
@@ -3852,7 +3852,7 @@ function computeReviewJobs(model) {
|
|
|
3852
3852
|
}
|
|
3853
3853
|
return out;
|
|
3854
3854
|
}
|
|
3855
|
-
var import_node_crypto2, DEFAULT_PREDISPATCH_TIMEOUT_MS, SpawnAttemptStale, SEED_ROOT_SUCCESSFUL_PRODUCE_LIMIT, Dispatcher;
|
|
3855
|
+
var import_node_crypto2, DEFAULT_PREDISPATCH_TIMEOUT_MS, SpawnAttemptStale, SEED_ROOT_SUCCESSFUL_PRODUCE_LIMIT, CANVAS_RUNTIME_KIND, NON_PRODUCE_FALLBACK_RUNTIME_KIND, Dispatcher;
|
|
3856
3856
|
var init_dispatcher = __esm({
|
|
3857
3857
|
"../core/src/dispatcher.ts"() {
|
|
3858
3858
|
"use strict";
|
|
@@ -3869,6 +3869,8 @@ var init_dispatcher = __esm({
|
|
|
3869
3869
|
}
|
|
3870
3870
|
};
|
|
3871
3871
|
SEED_ROOT_SUCCESSFUL_PRODUCE_LIMIT = 5;
|
|
3872
|
+
CANVAS_RUNTIME_KIND = "open-design";
|
|
3873
|
+
NON_PRODUCE_FALLBACK_RUNTIME_KIND = "claude-code";
|
|
3872
3874
|
Dispatcher = class {
|
|
3873
3875
|
constructor(opts) {
|
|
3874
3876
|
this.opts = opts;
|
|
@@ -4177,6 +4179,28 @@ var init_dispatcher = __esm({
|
|
|
4177
4179
|
});
|
|
4178
4180
|
}
|
|
4179
4181
|
}
|
|
4182
|
+
/**
|
|
4183
|
+
* 员工 → 运行时绑定,按动作校正。
|
|
4184
|
+
*
|
|
4185
|
+
* 背景:design 产物走「画板化」(提案 design-node-canvas-driven)——designer 的 produce 会话跑在
|
|
4186
|
+
* open-design 画板引擎里,产出**真实可打开的界面稿**(HTML + acceptance.md)而非文档。为此
|
|
4187
|
+
* designer 被绑到 `runtimeKind: "open-design"`。但 open-design 是**只会 produce 的专用引擎**:
|
|
4188
|
+
* 它的适配器无视 action,永远驱动画板引擎产界面再 propose。designer 一旦以 reviewer / 被 @ 回复 /
|
|
4189
|
+
* 收口身份被派活(action ≠ produce),仍按绑定路由到 open-design 就必崩(harvest 无 HTML 入口稿、
|
|
4190
|
+
* 或 propose 非己产物 → 会话 code=1 reason=error),评审票永远投不出,评审门只能靠他人凑 quorum 或
|
|
4191
|
+
* 人工 force-conclude。
|
|
4192
|
+
*
|
|
4193
|
+
* 修正:非 produce 的动作忽略画板绑定,回退到节点上的通用编码运行时(claude-code)——保持同一 nodeId,
|
|
4194
|
+
* 只换 runtimeKind。与 assembler 的 `canvasMode`(同样 `action !== "review"` 才进画板模式)语义一致:
|
|
4195
|
+
* 画板只服务于「产界面」,评审/回复/收口回到能真正读写、能投票的通用运行时。
|
|
4196
|
+
*/
|
|
4197
|
+
async resolveBindingFor(spec) {
|
|
4198
|
+
const binding = await this.opts.resolveBinding?.(spec.actor) ?? void 0;
|
|
4199
|
+
if (binding && spec.action !== "produce" && binding.runtimeKind === CANVAS_RUNTIME_KIND) {
|
|
4200
|
+
return { ...binding, runtimeKind: NON_PRODUCE_FALLBACK_RUNTIME_KIND };
|
|
4201
|
+
}
|
|
4202
|
+
return binding;
|
|
4203
|
+
}
|
|
4180
4204
|
async spawnJobInner(jobKey, spec, attempt) {
|
|
4181
4205
|
if (this.inFlight.has(jobKey)) return 0;
|
|
4182
4206
|
const { kernel } = this.opts;
|
|
@@ -4217,7 +4241,7 @@ var init_dispatcher = __esm({
|
|
|
4217
4241
|
const ws = kernel.model.artifacts.get(spec.artifactId)?.workspace;
|
|
4218
4242
|
const codeRepo = ws ? await this.opts.resolveCodeRepo?.(ws) ?? null : null;
|
|
4219
4243
|
this.assertSpawnAttemptCurrent(jobKey, attempt);
|
|
4220
|
-
const binding = await this.
|
|
4244
|
+
const binding = await this.resolveBindingFor(spec);
|
|
4221
4245
|
this.assertSpawnAttemptCurrent(jobKey, attempt);
|
|
4222
4246
|
const materializeSkills = this.opts.materializeSkills ? () => this.opts.materializeSkills(spec.actor, binding?.runtimeKind ?? "claude") : void 0;
|
|
4223
4247
|
const bundle = await assembleContext({
|
|
@@ -5181,8 +5205,8 @@ var init_parseUtil = __esm({
|
|
|
5181
5205
|
init_errors2();
|
|
5182
5206
|
init_en();
|
|
5183
5207
|
makeIssue = (params) => {
|
|
5184
|
-
const { data, path:
|
|
5185
|
-
const fullPath = [...
|
|
5208
|
+
const { data, path: path20, errorMaps, issueData } = params;
|
|
5209
|
+
const fullPath = [...path20, ...issueData.path || []];
|
|
5186
5210
|
const fullIssue = {
|
|
5187
5211
|
...issueData,
|
|
5188
5212
|
path: fullPath
|
|
@@ -5490,11 +5514,11 @@ var init_types = __esm({
|
|
|
5490
5514
|
init_parseUtil();
|
|
5491
5515
|
init_util();
|
|
5492
5516
|
ParseInputLazyPath = class {
|
|
5493
|
-
constructor(parent, value,
|
|
5517
|
+
constructor(parent, value, path20, key) {
|
|
5494
5518
|
this._cachedPath = [];
|
|
5495
5519
|
this.parent = parent;
|
|
5496
5520
|
this.data = value;
|
|
5497
|
-
this._path =
|
|
5521
|
+
this._path = path20;
|
|
5498
5522
|
this._key = key;
|
|
5499
5523
|
}
|
|
5500
5524
|
get path() {
|
|
@@ -9068,10 +9092,10 @@ function assignProp(target, prop, value) {
|
|
|
9068
9092
|
configurable: true
|
|
9069
9093
|
});
|
|
9070
9094
|
}
|
|
9071
|
-
function getElementAtPath(obj,
|
|
9072
|
-
if (!
|
|
9095
|
+
function getElementAtPath(obj, path20) {
|
|
9096
|
+
if (!path20)
|
|
9073
9097
|
return obj;
|
|
9074
|
-
return
|
|
9098
|
+
return path20.reduce((acc, key) => acc?.[key], obj);
|
|
9075
9099
|
}
|
|
9076
9100
|
function promiseAllObject(promisesObj) {
|
|
9077
9101
|
const keys = Object.keys(promisesObj);
|
|
@@ -9320,11 +9344,11 @@ function aborted(x2, startIndex = 0) {
|
|
|
9320
9344
|
}
|
|
9321
9345
|
return false;
|
|
9322
9346
|
}
|
|
9323
|
-
function prefixIssues(
|
|
9347
|
+
function prefixIssues(path20, issues) {
|
|
9324
9348
|
return issues.map((iss) => {
|
|
9325
9349
|
var _a;
|
|
9326
9350
|
(_a = iss).path ?? (_a.path = []);
|
|
9327
|
-
iss.path.unshift(
|
|
9351
|
+
iss.path.unshift(path20);
|
|
9328
9352
|
return iss;
|
|
9329
9353
|
});
|
|
9330
9354
|
}
|
|
@@ -17864,8 +17888,8 @@ var require_utils = __commonJS({
|
|
|
17864
17888
|
}
|
|
17865
17889
|
return ind;
|
|
17866
17890
|
}
|
|
17867
|
-
function removeDotSegments(
|
|
17868
|
-
let input =
|
|
17891
|
+
function removeDotSegments(path20) {
|
|
17892
|
+
let input = path20;
|
|
17869
17893
|
const output = [];
|
|
17870
17894
|
let nextSlash = -1;
|
|
17871
17895
|
let len = 0;
|
|
@@ -18117,8 +18141,8 @@ var require_schemes = __commonJS({
|
|
|
18117
18141
|
wsComponent.secure = void 0;
|
|
18118
18142
|
}
|
|
18119
18143
|
if (wsComponent.resourceName) {
|
|
18120
|
-
const [
|
|
18121
|
-
wsComponent.path =
|
|
18144
|
+
const [path20, query] = wsComponent.resourceName.split("?");
|
|
18145
|
+
wsComponent.path = path20 && path20 !== "/" ? path20 : void 0;
|
|
18122
18146
|
wsComponent.query = query;
|
|
18123
18147
|
wsComponent.resourceName = void 0;
|
|
18124
18148
|
}
|
|
@@ -21511,12 +21535,12 @@ var require_dist = __commonJS({
|
|
|
21511
21535
|
throw new Error(`Unknown format "${name}"`);
|
|
21512
21536
|
return f2;
|
|
21513
21537
|
};
|
|
21514
|
-
function addFormats(ajv, list,
|
|
21538
|
+
function addFormats(ajv, list, fs21, exportName) {
|
|
21515
21539
|
var _a;
|
|
21516
21540
|
var _b;
|
|
21517
21541
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
21518
21542
|
for (const f2 of list)
|
|
21519
|
-
ajv.addFormat(f2,
|
|
21543
|
+
ajv.addFormat(f2, fs21[f2]);
|
|
21520
21544
|
}
|
|
21521
21545
|
module2.exports = exports2 = formatsPlugin;
|
|
21522
21546
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21631,23 +21655,23 @@ var init_router = __esm({
|
|
|
21631
21655
|
};
|
|
21632
21656
|
Router = class {
|
|
21633
21657
|
routes = [];
|
|
21634
|
-
on(method,
|
|
21635
|
-
this.routes.push({ method, segments:
|
|
21658
|
+
on(method, path20, handler) {
|
|
21659
|
+
this.routes.push({ method, segments: path20.split("/").filter(Boolean), handler });
|
|
21636
21660
|
}
|
|
21637
|
-
get(
|
|
21638
|
-
this.on("GET",
|
|
21661
|
+
get(path20, h) {
|
|
21662
|
+
this.on("GET", path20, h);
|
|
21639
21663
|
}
|
|
21640
|
-
post(
|
|
21641
|
-
this.on("POST",
|
|
21664
|
+
post(path20, h) {
|
|
21665
|
+
this.on("POST", path20, h);
|
|
21642
21666
|
}
|
|
21643
|
-
patch(
|
|
21644
|
-
this.on("PATCH",
|
|
21667
|
+
patch(path20, h) {
|
|
21668
|
+
this.on("PATCH", path20, h);
|
|
21645
21669
|
}
|
|
21646
|
-
put(
|
|
21647
|
-
this.on("PUT",
|
|
21670
|
+
put(path20, h) {
|
|
21671
|
+
this.on("PUT", path20, h);
|
|
21648
21672
|
}
|
|
21649
|
-
delete(
|
|
21650
|
-
this.on("DELETE",
|
|
21673
|
+
delete(path20, h) {
|
|
21674
|
+
this.on("DELETE", path20, h);
|
|
21651
21675
|
}
|
|
21652
21676
|
match(method, pathname) {
|
|
21653
21677
|
const parts = pathname.split("/").filter(Boolean);
|
|
@@ -24384,7 +24408,7 @@ async function runView(kernel, oplog, blobs, name, artifactId, params) {
|
|
|
24384
24408
|
}
|
|
24385
24409
|
case "content": {
|
|
24386
24410
|
const id = need2();
|
|
24387
|
-
const
|
|
24411
|
+
const path20 = params?.get("path") ?? null;
|
|
24388
24412
|
const artifact = model.artifacts.get(id);
|
|
24389
24413
|
if (!artifact) throw new Error(`artifact \u4E0D\u5B58\u5728: ${id}`);
|
|
24390
24414
|
const head = artifact.currentRev;
|
|
@@ -24396,11 +24420,11 @@ async function runView(kernel, oplog, blobs, name, artifactId, params) {
|
|
|
24396
24420
|
const dec2 = new TextDecoder();
|
|
24397
24421
|
if (headRev.contentKind === "manifest") {
|
|
24398
24422
|
const entries = await readManifest(blobs, headRev.contentRef);
|
|
24399
|
-
if (
|
|
24400
|
-
const e = entries.find((x2) => x2.path ===
|
|
24401
|
-
if (!e) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${
|
|
24423
|
+
if (path20 !== null) {
|
|
24424
|
+
const e = entries.find((x2) => x2.path === path20);
|
|
24425
|
+
if (!e) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${path20}\uFF08\u672C\u4EA7\u7269\u6709\uFF1A${entries.map((x2) => x2.path).join("\u3001")}\uFF09`);
|
|
24402
24426
|
const isText = !e.bytes.includes(0);
|
|
24403
|
-
return { kind: "file", path:
|
|
24427
|
+
return { kind: "file", path: path20, bytes: e.bytes.length, text: isText ? dec2.decode(e.bytes) : null };
|
|
24404
24428
|
}
|
|
24405
24429
|
return {
|
|
24406
24430
|
kind: "manifest",
|
|
@@ -24695,9 +24719,9 @@ async function startOasisServer(opts) {
|
|
|
24695
24719
|
}
|
|
24696
24720
|
}
|
|
24697
24721
|
if (!target) return;
|
|
24698
|
-
const { randomUUID:
|
|
24722
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
24699
24723
|
if (chatStore) {
|
|
24700
|
-
await chatStore.appendMessage({ id:
|
|
24724
|
+
await chatStore.appendMessage({ id: randomUUID19(), sessionId: target, role: "user", content: message, createdAt: (/* @__PURE__ */ new Date()).toISOString() }).catch(() => void 0);
|
|
24701
24725
|
}
|
|
24702
24726
|
const rt = record5?.runtimeSessionId ?? opts.retainedSession?.({ draftId: review.draftId });
|
|
24703
24727
|
const session = await opts.dispatchChat({
|
|
@@ -24715,7 +24739,7 @@ async function startOasisServer(opts) {
|
|
|
24715
24739
|
});
|
|
24716
24740
|
void session.done.then(async () => {
|
|
24717
24741
|
if (reply || session.runId) {
|
|
24718
|
-
await chatStore.appendMessage({ id:
|
|
24742
|
+
await chatStore.appendMessage({ id: randomUUID19(), sessionId: sid, role: "assistant", content: reply, createdAt: (/* @__PURE__ */ new Date()).toISOString(), ...session.runId ? { runId: session.runId } : {} }).catch(() => void 0);
|
|
24719
24743
|
}
|
|
24720
24744
|
}).catch(() => void 0);
|
|
24721
24745
|
}
|
|
@@ -24785,11 +24809,11 @@ async function startOasisServer(opts) {
|
|
|
24785
24809
|
let chatSessionId;
|
|
24786
24810
|
let createdThisCall = false;
|
|
24787
24811
|
if (chatStore) {
|
|
24788
|
-
const { randomUUID:
|
|
24812
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
24789
24813
|
const known = discussSessions.get(itemKey);
|
|
24790
24814
|
if (known && await chatStore.getSession(known).catch(() => null)) chatSessionId = known;
|
|
24791
24815
|
if (!chatSessionId) {
|
|
24792
|
-
chatSessionId =
|
|
24816
|
+
chatSessionId = randomUUID19();
|
|
24793
24817
|
createdThisCall = true;
|
|
24794
24818
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24795
24819
|
const title = `\u89E3\u51B3\uFF1A${ctx.seed.slice(ctx.seed.indexOf("\uFF1A") + 1, ctx.seed.indexOf("\uFF1A") + 25) || "\u5DE5\u5355\u5361\u70B9"}`;
|
|
@@ -24797,7 +24821,7 @@ async function startOasisServer(opts) {
|
|
|
24797
24821
|
await chatStore.linkWorkOrder(chatSessionId, ctx.workspace).catch(() => void 0);
|
|
24798
24822
|
}
|
|
24799
24823
|
discussSessions.set(itemKey, chatSessionId);
|
|
24800
|
-
await chatStore.appendMessage({ id:
|
|
24824
|
+
await chatStore.appendMessage({ id: randomUUID19(), sessionId: chatSessionId, role: "user", content: ctx.seed, createdAt: (/* @__PURE__ */ new Date()).toISOString() }).catch(() => void 0);
|
|
24801
24825
|
}
|
|
24802
24826
|
let session;
|
|
24803
24827
|
try {
|
|
@@ -24816,9 +24840,9 @@ async function startOasisServer(opts) {
|
|
|
24816
24840
|
reply += chunk;
|
|
24817
24841
|
});
|
|
24818
24842
|
void session.done.then(async () => {
|
|
24819
|
-
const { randomUUID:
|
|
24843
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
24820
24844
|
if (reply || session.runId) {
|
|
24821
|
-
await chatStore.appendMessage({ id:
|
|
24845
|
+
await chatStore.appendMessage({ id: randomUUID19(), sessionId: sid, role: "assistant", content: reply, createdAt: (/* @__PURE__ */ new Date()).toISOString(), ...session.runId ? { runId: session.runId } : {} }).catch(() => void 0);
|
|
24822
24846
|
}
|
|
24823
24847
|
}).catch(() => void 0);
|
|
24824
24848
|
}
|
|
@@ -25151,14 +25175,14 @@ async function startOasisServer(opts) {
|
|
|
25151
25175
|
const persistSession = chatStore && body.chatSessionId ? await chatStore.getSession(body.chatSessionId).catch(() => null) : null;
|
|
25152
25176
|
const persistTarget = persistSession && persistSession.humanActorId === actor ? persistSession : null;
|
|
25153
25177
|
if (chatStore && persistTarget) {
|
|
25154
|
-
const { randomUUID:
|
|
25178
|
+
const { randomUUID: randomUUID20 } = await import("node:crypto");
|
|
25155
25179
|
const persistAttachments = attachments.map((a) => ({
|
|
25156
25180
|
name: a.name,
|
|
25157
25181
|
...a.blobRef !== void 0 ? { blobRef: a.blobRef } : {},
|
|
25158
25182
|
...a.contentType !== void 0 ? { contentType: a.contentType } : {}
|
|
25159
25183
|
}));
|
|
25160
25184
|
await chatStore.appendMessage({
|
|
25161
|
-
id:
|
|
25185
|
+
id: randomUUID20(),
|
|
25162
25186
|
sessionId: persistTarget.id,
|
|
25163
25187
|
role: "user",
|
|
25164
25188
|
content: body.message,
|
|
@@ -25168,8 +25192,8 @@ async function startOasisServer(opts) {
|
|
|
25168
25192
|
}
|
|
25169
25193
|
let assistantMsgId;
|
|
25170
25194
|
if (chatStore && persistTarget) {
|
|
25171
|
-
const { randomUUID:
|
|
25172
|
-
const id =
|
|
25195
|
+
const { randomUUID: randomUUID20 } = await import("node:crypto");
|
|
25196
|
+
const id = randomUUID20();
|
|
25173
25197
|
await chatStore.appendMessage({
|
|
25174
25198
|
id,
|
|
25175
25199
|
sessionId: persistTarget.id,
|
|
@@ -25200,9 +25224,9 @@ async function startOasisServer(opts) {
|
|
|
25200
25224
|
}).catch(() => void 0);
|
|
25201
25225
|
} else {
|
|
25202
25226
|
if (!assistantText && !session.runId && parts.length === 0) return;
|
|
25203
|
-
const { randomUUID:
|
|
25227
|
+
const { randomUUID: randomUUID20 } = await import("node:crypto");
|
|
25204
25228
|
await chatStore.appendMessage({
|
|
25205
|
-
id:
|
|
25229
|
+
id: randomUUID20(),
|
|
25206
25230
|
sessionId: persistTarget.id,
|
|
25207
25231
|
role: "assistant",
|
|
25208
25232
|
content: assistantText,
|
|
@@ -25330,13 +25354,13 @@ async function startOasisServer(opts) {
|
|
|
25330
25354
|
const actorCtx = await opts.resolveActorContext(body.actorId).catch(() => null);
|
|
25331
25355
|
if (actorCtx) {
|
|
25332
25356
|
const { mkdtempSync: mkdtempSync9, mkdirSync: mkdirSync16, writeFileSync: writeFileSync15 } = await import("node:fs");
|
|
25333
|
-
const { join:
|
|
25334
|
-
const { tmpdir:
|
|
25335
|
-
const dir = mkdtempSync9(
|
|
25357
|
+
const { join: join24, dirname: dirname18 } = await import("node:path");
|
|
25358
|
+
const { tmpdir: tmpdir14 } = await import("node:os");
|
|
25359
|
+
const dir = mkdtempSync9(join24(tmpdir14(), "oasis-chat-"));
|
|
25336
25360
|
if (actorCtx.config?.prompt) {
|
|
25337
25361
|
for (const [rel, content] of Object.entries(splitIdentityFiles2(actorCtx.config.prompt))) {
|
|
25338
|
-
const file =
|
|
25339
|
-
mkdirSync16(
|
|
25362
|
+
const file = join24(dir, rel);
|
|
25363
|
+
mkdirSync16(dirname18(file), { recursive: true });
|
|
25340
25364
|
writeFileSync15(file, content);
|
|
25341
25365
|
}
|
|
25342
25366
|
}
|
|
@@ -25347,13 +25371,13 @@ async function startOasisServer(opts) {
|
|
|
25347
25371
|
const s2 = byId.get(id);
|
|
25348
25372
|
return s2 ? `- **${s2.name}** (\`${s2.id}\`): ${s2.description}` : `- \`${id}\`\uFF08\u672A\u5728\u6280\u80FD\u5E93\u4E2D\uFF0C\u53EF\u80FD\u5DF2\u5378\u8F7D\uFF09`;
|
|
25349
25373
|
});
|
|
25350
|
-
writeFileSync15(
|
|
25374
|
+
writeFileSync15(join24(dir, "SKILLS.md"), ["# \u53EF\u7528\u6280\u80FD", "", "\u4EE5\u4E0B\u6280\u80FD\u5DF2\u4E3A\u4F60\u542F\u7528\uFF0C\u53EF\u5728\u672C\u6B21\u4F1A\u8BDD\u4E2D\u76F4\u63A5\u4F7F\u7528\uFF1A", "", ...lines].join("\n"));
|
|
25351
25375
|
}
|
|
25352
25376
|
if (opts.materializeSkills) {
|
|
25353
25377
|
const skillFiles = await opts.materializeSkills(body.actorId, "claude").catch(() => ({}));
|
|
25354
25378
|
for (const [rel, content] of Object.entries(skillFiles)) {
|
|
25355
|
-
const file =
|
|
25356
|
-
mkdirSync16(
|
|
25379
|
+
const file = join24(dir, rel);
|
|
25380
|
+
mkdirSync16(dirname18(file), { recursive: true });
|
|
25357
25381
|
writeFileSync15(file, content);
|
|
25358
25382
|
}
|
|
25359
25383
|
}
|
|
@@ -25366,14 +25390,14 @@ async function startOasisServer(opts) {
|
|
|
25366
25390
|
const modeNote = c.mode === "oauth" ? "OAuth \xB7 \u51ED\u8BC1\u7531\u5E73\u53F0\u7BA1\u7406\uFF0C\u901A\u8FC7\u5BF9\u5E94 CLI wrapper \u8C03\u7528" : "\u76F4\u63A5\u5199\u5165 \xB7 \u51ED\u8BC1\u5DF2\u6CE8\u5165\u73AF\u5883\u53D8\u91CF";
|
|
25367
25391
|
return `- **${c.name}** (\`${c.id}\`): ${statusNote} \xB7 ${modeNote}`;
|
|
25368
25392
|
});
|
|
25369
|
-
writeFileSync15(
|
|
25393
|
+
writeFileSync15(join24(dir, "CONNECTORS.md"), ["# \u53EF\u7528\u8FDE\u63A5\u5668", "", "\u4EE5\u4E0B\u8FDE\u63A5\u5668\u5DF2\u4E3A\u672C\u6B21\u4F1A\u8BDD\u914D\u7F6E\uFF0C\u51ED\u8BC1\u5DF2\u901A\u8FC7\u73AF\u5883\u53D8\u91CF\u6216 CLI wrapper \u6CE8\u5165\uFF0C\u65E0\u9700\u624B\u52A8\u914D\u7F6E\uFF1A", "", ...lines].join("\n"));
|
|
25370
25394
|
}
|
|
25371
25395
|
spawnCwd = dir;
|
|
25372
25396
|
}
|
|
25373
25397
|
}
|
|
25374
25398
|
const { spawn: spawn7 } = await import("node:child_process");
|
|
25375
|
-
const { randomUUID:
|
|
25376
|
-
const sessionId = body.sessionId ??
|
|
25399
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
25400
|
+
const sessionId = body.sessionId ?? randomUUID19();
|
|
25377
25401
|
const args = [
|
|
25378
25402
|
"-p",
|
|
25379
25403
|
body.message,
|
|
@@ -27690,13 +27714,13 @@ var init_service = __esm({
|
|
|
27690
27714
|
async readDocument(contentRef) {
|
|
27691
27715
|
for (const [projectId, space] of this.spaces) {
|
|
27692
27716
|
if (!contentRef.startsWith(`${space.rootRef}/`)) continue;
|
|
27693
|
-
const
|
|
27694
|
-
const content = space.files.get(
|
|
27717
|
+
const path20 = contentRef.slice(space.rootRef.length + 1);
|
|
27718
|
+
const content = space.files.get(path20);
|
|
27695
27719
|
if (content === void 0) return null;
|
|
27696
27720
|
return {
|
|
27697
27721
|
contentRef,
|
|
27698
27722
|
content,
|
|
27699
|
-
url: `https://outline.local/${encodeURIComponent(projectId)}/${
|
|
27723
|
+
url: `https://outline.local/${encodeURIComponent(projectId)}/${path20.split("/").map(encodeURIComponent).join("/")}`
|
|
27700
27724
|
};
|
|
27701
27725
|
}
|
|
27702
27726
|
return null;
|
|
@@ -27780,8 +27804,8 @@ var init_service = __esm({
|
|
|
27780
27804
|
const space = this.requireSpace(state.projectId);
|
|
27781
27805
|
const stored = { ...state, payload: { ...state.payload }, updatedAt: state.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString() };
|
|
27782
27806
|
space.runStates.set(runStateKey(state.workOrderId, state.nodeId), stored);
|
|
27783
|
-
const
|
|
27784
|
-
space.files.set(
|
|
27807
|
+
const path20 = `run_state/${state.workOrderId ?? "project"}/${state.nodeId ?? "default"}.json`;
|
|
27808
|
+
space.files.set(path20, JSON.stringify(stored, null, 2));
|
|
27785
27809
|
return { ...stored, payload: { ...stored.payload } };
|
|
27786
27810
|
}
|
|
27787
27811
|
requireSpace(projectId) {
|
|
@@ -33266,12 +33290,12 @@ var init_daemon_hub = __esm({
|
|
|
33266
33290
|
this.disconnectListeners.add(cb);
|
|
33267
33291
|
return () => this.disconnectListeners.delete(cb);
|
|
33268
33292
|
}
|
|
33269
|
-
constructor(server,
|
|
33293
|
+
constructor(server, path20 = "/daemon/ws", resolveNode, opts = {}) {
|
|
33270
33294
|
this.pingIntervalMs = opts.pingIntervalMs ?? 2e4;
|
|
33271
33295
|
this.silenceTimeoutMs = opts.silenceTimeoutMs ?? 6e4;
|
|
33272
33296
|
this.wss = new import_websocket_server.default({
|
|
33273
33297
|
server,
|
|
33274
|
-
path:
|
|
33298
|
+
path: path20,
|
|
33275
33299
|
...resolveNode ? {
|
|
33276
33300
|
verifyClient: (info, cb) => {
|
|
33277
33301
|
const authHeader = info.req.headers.authorization ?? "";
|
|
@@ -33626,13 +33650,13 @@ var init_skill_fetcher = __esm({
|
|
|
33626
33650
|
files = {};
|
|
33627
33651
|
totalBytes = 0;
|
|
33628
33652
|
fileCount = 0;
|
|
33629
|
-
add(
|
|
33653
|
+
add(path20, content) {
|
|
33630
33654
|
const bytes = new TextEncoder().encode(content).length;
|
|
33631
33655
|
if (this.fileCount >= MAX_FILE_COUNT)
|
|
33632
33656
|
throw new Error(`Import bundle exceeds ${MAX_FILE_COUNT} file limit`);
|
|
33633
33657
|
if (this.totalBytes + bytes > MAX_TOTAL_BYTES)
|
|
33634
33658
|
throw new Error(`Import bundle exceeds ${MAX_TOTAL_BYTES} byte limit`);
|
|
33635
|
-
this.files[
|
|
33659
|
+
this.files[path20] = content;
|
|
33636
33660
|
this.totalBytes += bytes;
|
|
33637
33661
|
this.fileCount++;
|
|
33638
33662
|
}
|
|
@@ -33901,7 +33925,7 @@ ${input.description}
|
|
|
33901
33925
|
};
|
|
33902
33926
|
await this.opts.store.putInstalledSkill(installed);
|
|
33903
33927
|
const skillFiles = Object.entries(fetched.files).map(
|
|
33904
|
-
([
|
|
33928
|
+
([path20, content]) => this.buildSkillFile(id, path20, content, now)
|
|
33905
33929
|
);
|
|
33906
33930
|
await this.opts.store.putSkillFiles(id, skillFiles);
|
|
33907
33931
|
await this.audit({ kind: "skill_install", actorId: by, by, at: now, detail: { skillId: id, source: input.sourceKind, sourceUrl } });
|
|
@@ -33936,7 +33960,7 @@ ${input.description}
|
|
|
33936
33960
|
connectorId
|
|
33937
33961
|
});
|
|
33938
33962
|
const skillFiles = Object.entries(entry.files).map(
|
|
33939
|
-
([
|
|
33963
|
+
([path20, content]) => this.buildSkillFile(id, path20, content, now)
|
|
33940
33964
|
);
|
|
33941
33965
|
await this.opts.store.putSkillFiles(id, skillFiles);
|
|
33942
33966
|
}
|
|
@@ -33954,25 +33978,25 @@ ${input.description}
|
|
|
33954
33978
|
* 构造 SkillFile:正文内联进 content(决策 0036);blobHash/size 计算为 content 的 sha256
|
|
33955
33979
|
* 与字节数,仅作元数据/审计(不再有读取方,正文直接从 content 出)。
|
|
33956
33980
|
*/
|
|
33957
|
-
buildSkillFile(skillId,
|
|
33981
|
+
buildSkillFile(skillId, path20, content, now) {
|
|
33958
33982
|
const bytes = new TextEncoder().encode(content);
|
|
33959
33983
|
const blobHash = (0, import_node_crypto6.createHash)("sha256").update(bytes).digest("hex");
|
|
33960
|
-
return { skillId, path:
|
|
33984
|
+
return { skillId, path: path20, content, blobHash, size: bytes.length, updatedAt: now };
|
|
33961
33985
|
}
|
|
33962
33986
|
/**
|
|
33963
33987
|
* 更新或新建技能的单个文件。
|
|
33964
33988
|
* 正文内联进 skill_files(决策 0036),更新文件索引,但**不**改写技能的 name/description——
|
|
33965
33989
|
* 如果修改的是 SKILL.md,调用方应另外调用 updateInstalledSkill 同步 frontmatter。
|
|
33966
33990
|
*/
|
|
33967
|
-
async putSkillFile(skillId,
|
|
33991
|
+
async putSkillFile(skillId, path20, content) {
|
|
33968
33992
|
const cur = (await this.opts.store.listInstalledSkills()).find((x2) => x2.id === skillId);
|
|
33969
33993
|
if (!cur) throw new Error(`\u672A\u5B89\u88C5\u8BE5\u6280\u80FD\uFF1A${skillId}`);
|
|
33970
33994
|
const now = this.now();
|
|
33971
|
-
const file = this.buildSkillFile(skillId,
|
|
33995
|
+
const file = this.buildSkillFile(skillId, path20, content, now);
|
|
33972
33996
|
const existing = await this.opts.store.listSkillFiles(skillId);
|
|
33973
|
-
const next = [...existing.filter((f2) => f2.path !==
|
|
33997
|
+
const next = [...existing.filter((f2) => f2.path !== path20), file];
|
|
33974
33998
|
await this.opts.store.putSkillFiles(skillId, next);
|
|
33975
|
-
if (
|
|
33999
|
+
if (path20 === "SKILL.md") {
|
|
33976
34000
|
const { name, description } = parseSkillFrontmatter(content);
|
|
33977
34001
|
if (name || description) {
|
|
33978
34002
|
await this.opts.store.putInstalledSkill({
|
|
@@ -33988,11 +34012,11 @@ ${input.description}
|
|
|
33988
34012
|
* 删除技能的单个支撑文件(SKILL.md 主文档受保护,调用方应先拦截)。
|
|
33989
34013
|
* 单文件删除=读现有清单→剔除该 path→整体回写(putSkillFiles 是 replace-all 语义);blob 残留由 GC 回收。
|
|
33990
34014
|
*/
|
|
33991
|
-
async deleteSkillFile(skillId,
|
|
34015
|
+
async deleteSkillFile(skillId, path20) {
|
|
33992
34016
|
const cur = (await this.opts.store.listInstalledSkills()).find((x2) => x2.id === skillId);
|
|
33993
34017
|
if (!cur) throw new Error(`\u672A\u5B89\u88C5\u8BE5\u6280\u80FD\uFF1A${skillId}`);
|
|
33994
34018
|
const existing = await this.opts.store.listSkillFiles(skillId);
|
|
33995
|
-
const next = existing.filter((f2) => f2.path !==
|
|
34019
|
+
const next = existing.filter((f2) => f2.path !== path20);
|
|
33996
34020
|
if (next.length === existing.length) return;
|
|
33997
34021
|
await this.opts.store.putSkillFiles(skillId, next);
|
|
33998
34022
|
}
|
|
@@ -34345,7 +34369,8 @@ function estimateUsageCost(model, usage) {
|
|
|
34345
34369
|
const outputTokens = Math.max(usage.outputTokens ?? 0, 0);
|
|
34346
34370
|
const cacheReadTokens = Math.max(usage.cacheReadTokens ?? 0, 0);
|
|
34347
34371
|
const cacheCreationTokens = Math.max(usage.cacheCreationTokens ?? 0, 0);
|
|
34348
|
-
const
|
|
34372
|
+
const cacheReadPrice = price.cachedInputPerMillion ?? price.inputPerMillion * 0.1;
|
|
34373
|
+
const cost = (inputTokens + cacheCreationTokens) * price.inputPerMillion / 1e6 + outputTokens * price.outputPerMillion / 1e6 + cacheReadTokens * cacheReadPrice / 1e6;
|
|
34349
34374
|
return { currency: price.currency, micros: Math.round(cost * 1e6) };
|
|
34350
34375
|
}
|
|
34351
34376
|
var FOREIGN_MODEL_MARKUP, usd, cny, MODEL_PRICES, PREFIX_PRICES;
|
|
@@ -34530,17 +34555,21 @@ function summarizeWeeklyRuns(runs) {
|
|
|
34530
34555
|
if (!usage) continue;
|
|
34531
34556
|
const input = Math.max(usage.inputTokens ?? 0, 0);
|
|
34532
34557
|
const output = Math.max(usage.outputTokens ?? 0, 0);
|
|
34533
|
-
|
|
34558
|
+
const cacheCreation = Math.max(usage.cacheCreationTokens ?? 0, 0);
|
|
34559
|
+
const cacheRead = Math.max(usage.cacheReadTokens ?? 0, 0);
|
|
34560
|
+
tokenWeek += input + output + cacheCreation + cacheRead;
|
|
34561
|
+
const storedCost = Math.max(usage.costUsdMicros ?? 0, 0);
|
|
34562
|
+
if (storedCost > 0) {
|
|
34563
|
+
costWeekUsdMicros += storedCost;
|
|
34564
|
+
continue;
|
|
34565
|
+
}
|
|
34534
34566
|
const estimated = estimateUsageCost(run.effectiveModel, usage);
|
|
34535
34567
|
if (estimated) {
|
|
34536
34568
|
if (estimated.currency === "USD") costWeekUsdMicros += estimated.micros;
|
|
34537
34569
|
else costWeekCnyMicros += estimated.micros;
|
|
34538
34570
|
continue;
|
|
34539
34571
|
}
|
|
34540
|
-
|
|
34541
|
-
if (storedCost > 0) {
|
|
34542
|
-
costWeekUsdMicros += storedCost;
|
|
34543
|
-
} else if (input + output > 0) {
|
|
34572
|
+
if (input + output + cacheCreation + cacheRead > 0) {
|
|
34544
34573
|
unpriced.add(run.effectiveModel ?? "unknown");
|
|
34545
34574
|
}
|
|
34546
34575
|
}
|
|
@@ -34559,16 +34588,21 @@ function summarizeWeeklyUsage(rows) {
|
|
|
34559
34588
|
for (const row of rows) {
|
|
34560
34589
|
const input = Math.max(row.inputTokens, 0);
|
|
34561
34590
|
const output = Math.max(row.outputTokens, 0);
|
|
34562
|
-
|
|
34591
|
+
const cacheCreation = Math.max(row.cacheCreationTokens, 0);
|
|
34592
|
+
const cacheRead = Math.max(row.cacheReadTokens, 0);
|
|
34593
|
+
tokenWeek += input + output + cacheCreation + cacheRead;
|
|
34594
|
+
const storedCost = Math.max(row.costUsdMicros, 0);
|
|
34595
|
+
if (storedCost > 0) {
|
|
34596
|
+
costWeekUsdMicros += storedCost;
|
|
34597
|
+
continue;
|
|
34598
|
+
}
|
|
34563
34599
|
const estimated = estimateRowCost(row);
|
|
34564
34600
|
if (estimated) {
|
|
34565
34601
|
if (estimated.currency === "USD") costWeekUsdMicros += estimated.micros;
|
|
34566
34602
|
else costWeekCnyMicros += estimated.micros;
|
|
34567
34603
|
continue;
|
|
34568
34604
|
}
|
|
34569
|
-
if (
|
|
34570
|
-
costWeekUsdMicros += row.costUsdMicros;
|
|
34571
|
-
} else if (input + output > 0) {
|
|
34605
|
+
if (input + output + cacheCreation + cacheRead > 0) {
|
|
34572
34606
|
unpriced.add(row.effectiveModel ?? "unknown");
|
|
34573
34607
|
}
|
|
34574
34608
|
}
|
|
@@ -36770,27 +36804,188 @@ var init_sender = __esm({
|
|
|
36770
36804
|
}
|
|
36771
36805
|
});
|
|
36772
36806
|
|
|
36773
|
-
// ../adapters/src/open-design/
|
|
36774
|
-
function numEnv(name, fallback) {
|
|
36775
|
-
const v2 = process.env[name];
|
|
36776
|
-
const n = Number(v2);
|
|
36777
|
-
return v2 !== void 0 && v2 !== "" && Number.isFinite(n) && n > 0 ? n : fallback;
|
|
36778
|
-
}
|
|
36807
|
+
// ../adapters/src/open-design/driver.ts
|
|
36779
36808
|
function deriveBoardKey(artifactId) {
|
|
36780
36809
|
const tail = artifactId.split(":").pop() ?? artifactId;
|
|
36781
36810
|
const ascii = tail.replace(/[^a-zA-Z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 24);
|
|
36782
36811
|
const sha8 = (0, import_node_crypto10.createHash)("sha256").update(artifactId).digest("hex").slice(0, 8);
|
|
36783
36812
|
return ascii ? `od-${ascii}-${sha8}` : `od-${sha8}`;
|
|
36784
36813
|
}
|
|
36785
|
-
|
|
36786
|
-
|
|
36787
|
-
|
|
36814
|
+
async function odApi(base, fetchImpl, method, p2, body) {
|
|
36815
|
+
const res = await fetchImpl(`${base}${p2}`, {
|
|
36816
|
+
method,
|
|
36817
|
+
...body !== void 0 ? { body: JSON.stringify(body), headers: { "content-type": "application/json" } } : {}
|
|
36818
|
+
});
|
|
36819
|
+
if (!res.ok) throw new Error(`od ${method} ${p2} \u2192 ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
36820
|
+
return await res.json();
|
|
36821
|
+
}
|
|
36822
|
+
async function ensureProject(base, fetchImpl, boardKey, title) {
|
|
36823
|
+
let conversationId = null;
|
|
36824
|
+
try {
|
|
36825
|
+
const created = await odApi(base, fetchImpl, "POST", "/api/projects", { id: boardKey, name: title });
|
|
36826
|
+
conversationId = created.conversationId ?? null;
|
|
36827
|
+
} catch {
|
|
36828
|
+
}
|
|
36829
|
+
if (!conversationId) {
|
|
36830
|
+
const c = await odApi(base, fetchImpl, "GET", `/api/projects/${encodeURIComponent(boardKey)}/conversations`);
|
|
36831
|
+
conversationId = c.conversations?.[0]?.id ?? null;
|
|
36832
|
+
}
|
|
36833
|
+
if (!conversationId) throw new Error(`od \u9879\u76EE ${boardKey} \u65E0\u53EF\u7528\u4F1A\u8BDD`);
|
|
36834
|
+
let resolvedDir = null;
|
|
36835
|
+
try {
|
|
36836
|
+
const d = await odApi(base, fetchImpl, "GET", `/api/projects/${encodeURIComponent(boardKey)}`);
|
|
36837
|
+
resolvedDir = d.resolvedDir ?? null;
|
|
36838
|
+
} catch {
|
|
36839
|
+
}
|
|
36840
|
+
return { conversationId, resolvedDir };
|
|
36841
|
+
}
|
|
36842
|
+
function materializeContext(resolvedDir, files) {
|
|
36843
|
+
if (!resolvedDir) return;
|
|
36844
|
+
fs6.mkdirSync(resolvedDir, { recursive: true });
|
|
36845
|
+
const root = path5.join(resolvedDir, "task-context");
|
|
36846
|
+
fs6.rmSync(root, { recursive: true, force: true });
|
|
36847
|
+
for (const [rel, content] of Object.entries(files)) {
|
|
36848
|
+
const f2 = path5.join(root, rel);
|
|
36849
|
+
fs6.mkdirSync(path5.dirname(f2), { recursive: true });
|
|
36850
|
+
fs6.writeFileSync(f2, content);
|
|
36851
|
+
}
|
|
36852
|
+
}
|
|
36853
|
+
async function startDesignRun(base, fetchImpl, args) {
|
|
36854
|
+
const created = await odApi(base, fetchImpl, "POST", "/api/runs", {
|
|
36855
|
+
agentId: args.agentId,
|
|
36856
|
+
projectId: args.boardKey,
|
|
36857
|
+
conversationId: args.conversationId,
|
|
36858
|
+
assistantMessageId: (0, import_node_crypto10.randomUUID)(),
|
|
36859
|
+
clientRequestId: (0, import_node_crypto10.randomUUID)(),
|
|
36860
|
+
message: args.message,
|
|
36861
|
+
systemPrompt: args.systemPrompt
|
|
36862
|
+
});
|
|
36863
|
+
return created.runId;
|
|
36864
|
+
}
|
|
36865
|
+
async function pumpDesignEvents(base, fetchImpl, runId, onLine) {
|
|
36866
|
+
const res = await fetchImpl(`${base}/api/runs/${runId}/events`);
|
|
36867
|
+
if (!res.ok || !res.body) return;
|
|
36868
|
+
const reader = res.body.getReader();
|
|
36869
|
+
const dec2 = new TextDecoder();
|
|
36870
|
+
let buf = "";
|
|
36871
|
+
for (; ; ) {
|
|
36872
|
+
const { done, value } = await reader.read();
|
|
36873
|
+
if (done) break;
|
|
36874
|
+
buf += dec2.decode(value, { stream: true });
|
|
36875
|
+
let nl;
|
|
36876
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
36877
|
+
const line = buf.slice(0, nl).trim();
|
|
36878
|
+
buf = buf.slice(nl + 1);
|
|
36879
|
+
if (line.startsWith("data:")) {
|
|
36880
|
+
const payload = line.slice(5).trim();
|
|
36881
|
+
if (payload) onLine(payload);
|
|
36882
|
+
}
|
|
36883
|
+
}
|
|
36884
|
+
}
|
|
36885
|
+
}
|
|
36886
|
+
async function pollDesignRun(base, fetchImpl, runId, opts = {}) {
|
|
36887
|
+
const interval = opts.intervalMs ?? 5e3;
|
|
36888
|
+
const maxMs = opts.maxMs ?? 30 * 6e4;
|
|
36889
|
+
const started = Date.now();
|
|
36890
|
+
for (; ; ) {
|
|
36891
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
36892
|
+
const s2 = await odApi(base, fetchImpl, "GET", `/api/runs/${runId}`).catch(() => null);
|
|
36893
|
+
if (!s2) {
|
|
36894
|
+
if (Date.now() - started > maxMs) throw new Error(`od run ${runId} \u8F6E\u8BE2\u8D85\u65F6\uFF08${Math.round(maxMs / 6e4)}min \u65E0\u7EC8\u6001\uFF09`);
|
|
36895
|
+
continue;
|
|
36896
|
+
}
|
|
36897
|
+
opts.onPoll?.(s2.status);
|
|
36898
|
+
if (s2.status === "succeeded" || s2.status === "failed" || s2.status === "canceled") return s2.status;
|
|
36899
|
+
if (Date.now() - started > maxMs) throw new Error(`od run ${runId} \u8F6E\u8BE2\u8D85\u65F6\uFF08${Math.round(maxMs / 6e4)}min \u672A\u6536\u5C3E\uFF0C\u672B\u72B6\u6001 ${s2.status}\uFF09`);
|
|
36900
|
+
}
|
|
36901
|
+
}
|
|
36902
|
+
async function harvestBoard(base, fetchImpl, publicBase, workRoot, boardKey, runId) {
|
|
36903
|
+
const listing = await odApi(
|
|
36904
|
+
base,
|
|
36905
|
+
fetchImpl,
|
|
36906
|
+
"GET",
|
|
36907
|
+
`/api/projects/${encodeURIComponent(boardKey)}/files`
|
|
36908
|
+
);
|
|
36909
|
+
const htmls = (listing.files ?? []).filter((f2) => f2.kind === "html" && !f2.path.startsWith("task-context/")).filter((f2) => (f2.artifactManifest?.status ?? "complete") === "complete").sort((a, b2) => (b2.mtime ?? 0) - (a.mtime ?? 0));
|
|
36910
|
+
const entry = htmls[0]?.path;
|
|
36911
|
+
if (!entry) throw new Error("\u753B\u677F\u9879\u76EE\u65E0\u5DF2\u5B8C\u6210\u7684 HTML \u5165\u53E3\u7A3F\u2014\u2014\u8BBE\u8BA1\u4F1A\u8BDD\u672A\u4EA7\u51FA\u53EF\u4EA4\u4ED8\u754C\u9762");
|
|
36912
|
+
const dir = fs6.mkdtempSync(path5.join(workRoot, "od-deliverable-"));
|
|
36913
|
+
const fetchInline = async (rel) => {
|
|
36914
|
+
const res = await fetchImpl(`${base}/api/projects/${encodeURIComponent(boardKey)}/export/${encodeURIComponent(rel)}?inline=1`);
|
|
36915
|
+
if (!res.ok) throw new Error(`od export ${rel} \u2192 ${res.status}`);
|
|
36916
|
+
return await res.text();
|
|
36917
|
+
};
|
|
36918
|
+
fs6.writeFileSync(path5.join(dir, "index.html"), await fetchInline(entry));
|
|
36919
|
+
for (const f2 of listing.files ?? []) {
|
|
36920
|
+
if (f2.path.endsWith(".md") && !f2.path.includes("/")) {
|
|
36921
|
+
try {
|
|
36922
|
+
fs6.writeFileSync(path5.join(dir, f2.path), await fetchInline(f2.path));
|
|
36923
|
+
} catch {
|
|
36924
|
+
}
|
|
36925
|
+
}
|
|
36926
|
+
}
|
|
36927
|
+
fs6.writeFileSync(
|
|
36928
|
+
path5.join(dir, "board.link"),
|
|
36929
|
+
`${publicBase}/projects/${boardKey}
|
|
36930
|
+
\u5165\u53E3\u7A3F\uFF1A${entry}
|
|
36931
|
+
\u5FEB\u7167\u6765\u6E90 run\uFF1A${runId}
|
|
36932
|
+
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
36933
|
+
`
|
|
36934
|
+
);
|
|
36935
|
+
return { dir, entry };
|
|
36936
|
+
}
|
|
36937
|
+
async function runOpenDesignSession(opts) {
|
|
36938
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
36939
|
+
const workRoot = opts.workRoot ?? os.tmpdir();
|
|
36940
|
+
const boardKey = deriveBoardKey(opts.artifactId);
|
|
36941
|
+
const { conversationId, resolvedDir } = await ensureProject(opts.base, fetchImpl, boardKey, opts.title);
|
|
36942
|
+
if (opts.contextFiles) materializeContext(resolvedDir, opts.contextFiles);
|
|
36943
|
+
const runId = await startDesignRun(opts.base, fetchImpl, {
|
|
36944
|
+
agentId: opts.agentId,
|
|
36945
|
+
boardKey,
|
|
36946
|
+
conversationId,
|
|
36947
|
+
message: opts.message,
|
|
36948
|
+
systemPrompt: opts.systemPrompt
|
|
36949
|
+
});
|
|
36950
|
+
if (opts.onLine) void pumpDesignEvents(opts.base, fetchImpl, runId, opts.onLine).catch(() => {
|
|
36951
|
+
});
|
|
36952
|
+
const status = await pollDesignRun(opts.base, fetchImpl, runId, {
|
|
36953
|
+
...opts.pollIntervalMs !== void 0 ? { intervalMs: opts.pollIntervalMs } : {},
|
|
36954
|
+
...opts.pollMaxMs !== void 0 ? { maxMs: opts.pollMaxMs } : {}
|
|
36955
|
+
});
|
|
36956
|
+
if (status === "canceled") throw new Error(`od run ${runId} \u88AB\u53D6\u6D88`);
|
|
36957
|
+
if (status === "failed") throw new Error(`od run ${runId} \u5931\u8D25`);
|
|
36958
|
+
const { dir, entry } = await harvestBoard(opts.base, fetchImpl, opts.publicBase, workRoot, boardKey, runId);
|
|
36959
|
+
return { dir, entry, boardKey, runId };
|
|
36960
|
+
}
|
|
36961
|
+
var import_node_crypto10, fs6, os, path5;
|
|
36962
|
+
var init_driver = __esm({
|
|
36963
|
+
"../adapters/src/open-design/driver.ts"() {
|
|
36788
36964
|
"use strict";
|
|
36789
36965
|
import_node_crypto10 = require("node:crypto");
|
|
36790
|
-
import_node_child_process2 = require("node:child_process");
|
|
36791
36966
|
fs6 = __toESM(require("node:fs"), 1);
|
|
36792
36967
|
os = __toESM(require("node:os"), 1);
|
|
36793
36968
|
path5 = __toESM(require("node:path"), 1);
|
|
36969
|
+
}
|
|
36970
|
+
});
|
|
36971
|
+
|
|
36972
|
+
// ../adapters/src/open-design/index.ts
|
|
36973
|
+
function numEnv(name, fallback) {
|
|
36974
|
+
const v2 = process.env[name];
|
|
36975
|
+
const n = Number(v2);
|
|
36976
|
+
return v2 !== void 0 && v2 !== "" && Number.isFinite(n) && n > 0 ? n : fallback;
|
|
36977
|
+
}
|
|
36978
|
+
var import_node_crypto11, import_node_child_process2, fs7, os2, path6, TOOL_RESULT_SNIPPET, DELTA_FLUSH_MS, TELEMETRY_HEARTBEAT_MS, OdEventTranslator, OpenDesignAdapter;
|
|
36979
|
+
var init_open_design = __esm({
|
|
36980
|
+
"../adapters/src/open-design/index.ts"() {
|
|
36981
|
+
"use strict";
|
|
36982
|
+
import_node_crypto11 = require("node:crypto");
|
|
36983
|
+
import_node_child_process2 = require("node:child_process");
|
|
36984
|
+
fs7 = __toESM(require("node:fs"), 1);
|
|
36985
|
+
os2 = __toESM(require("node:os"), 1);
|
|
36986
|
+
path6 = __toESM(require("node:path"), 1);
|
|
36987
|
+
init_driver();
|
|
36988
|
+
init_driver();
|
|
36794
36989
|
TOOL_RESULT_SNIPPET = 2e3;
|
|
36795
36990
|
DELTA_FLUSH_MS = 2e4;
|
|
36796
36991
|
TELEMETRY_HEARTBEAT_MS = 12e4;
|
|
@@ -36876,7 +37071,7 @@ var init_open_design = __esm({
|
|
|
36876
37071
|
this.publicBase = (opts.publicBaseUrl ?? "https://design.open-friday.com").replace(/\/$/, "");
|
|
36877
37072
|
this.agentId = opts.agentId ?? "claude";
|
|
36878
37073
|
this.oasisBin = opts.oasisBin ?? "oasis";
|
|
36879
|
-
this.workRoot = opts.workRoot ??
|
|
37074
|
+
this.workRoot = opts.workRoot ?? os2.tmpdir();
|
|
36880
37075
|
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
36881
37076
|
this.maxConcurrent = opts.maxConcurrent ?? numEnv("OASIS_OPEN_DESIGN_MAX_CONCURRENT", 2);
|
|
36882
37077
|
this.runPropose = opts.runPropose ?? (async ({ artifactId, dir, reason, serverUrl, token }) => {
|
|
@@ -36909,91 +37104,16 @@ var init_open_design = __esm({
|
|
|
36909
37104
|
this.active--;
|
|
36910
37105
|
this.waiters.shift()?.();
|
|
36911
37106
|
}
|
|
36912
|
-
async api(method, p2, body) {
|
|
36913
|
-
const res = await this.fetchImpl(`${this.base}${p2}`, {
|
|
36914
|
-
method,
|
|
36915
|
-
...body !== void 0 ? { body: JSON.stringify(body), headers: { "content-type": "application/json" } } : {}
|
|
36916
|
-
});
|
|
36917
|
-
if (!res.ok) throw new Error(`od ${method} ${p2} \u2192 ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
36918
|
-
return await res.json();
|
|
36919
|
-
}
|
|
36920
|
-
/** 项目就绪(幂等):不存在则建(显式 id=派生 key);已存在则取既有会话。返回 conversationId + 项目目录。 */
|
|
36921
|
-
async ensureProject(boardKey, title) {
|
|
36922
|
-
let conversationId = null;
|
|
36923
|
-
try {
|
|
36924
|
-
const created = await this.api("POST", "/api/projects", { id: boardKey, name: title });
|
|
36925
|
-
conversationId = created.conversationId ?? null;
|
|
36926
|
-
} catch {
|
|
36927
|
-
}
|
|
36928
|
-
if (!conversationId) {
|
|
36929
|
-
const c = await this.api("GET", `/api/projects/${encodeURIComponent(boardKey)}/conversations`);
|
|
36930
|
-
conversationId = c.conversations?.[0]?.id ?? null;
|
|
36931
|
-
}
|
|
36932
|
-
if (!conversationId) throw new Error(`od \u9879\u76EE ${boardKey} \u65E0\u53EF\u7528\u4F1A\u8BDD`);
|
|
36933
|
-
let resolvedDir = null;
|
|
36934
|
-
try {
|
|
36935
|
-
const d = await this.api("GET", `/api/projects/${encodeURIComponent(boardKey)}`);
|
|
36936
|
-
resolvedDir = d.resolvedDir ?? null;
|
|
36937
|
-
} catch {
|
|
36938
|
-
}
|
|
36939
|
-
return { conversationId, resolvedDir };
|
|
36940
|
-
}
|
|
36941
|
-
/** 把派发 bundle 铺进画板项目的 task-context/(同机直写;TASK.md 里引用的 inputs/ 等由此可读)。 */
|
|
36942
|
-
materializeContext(resolvedDir, files) {
|
|
36943
|
-
if (!resolvedDir) return;
|
|
36944
|
-
fs6.mkdirSync(resolvedDir, { recursive: true });
|
|
36945
|
-
const root = path5.join(resolvedDir, "task-context");
|
|
36946
|
-
fs6.rmSync(root, { recursive: true, force: true });
|
|
36947
|
-
for (const [rel, content] of Object.entries(files)) {
|
|
36948
|
-
const f2 = path5.join(root, rel);
|
|
36949
|
-
fs6.mkdirSync(path5.dirname(f2), { recursive: true });
|
|
36950
|
-
fs6.writeFileSync(f2, content);
|
|
36951
|
-
}
|
|
36952
|
-
}
|
|
36953
|
-
/** 收割:挑最新完成态的 HTML 为入口导出(引用树收拢),连同项目内 .md 文档组装装箱单目录。 */
|
|
36954
|
-
async harvest(boardKey, runId) {
|
|
36955
|
-
const listing = await this.api(
|
|
36956
|
-
"GET",
|
|
36957
|
-
`/api/projects/${encodeURIComponent(boardKey)}/files`
|
|
36958
|
-
);
|
|
36959
|
-
const htmls = (listing.files ?? []).filter((f2) => f2.kind === "html" && !f2.path.startsWith("task-context/")).filter((f2) => (f2.artifactManifest?.status ?? "complete") === "complete").sort((a, b2) => (b2.mtime ?? 0) - (a.mtime ?? 0));
|
|
36960
|
-
const entry = htmls[0]?.path;
|
|
36961
|
-
if (!entry) throw new Error("\u753B\u677F\u9879\u76EE\u65E0\u5DF2\u5B8C\u6210\u7684 HTML \u5165\u53E3\u7A3F\u2014\u2014\u8BBE\u8BA1\u4F1A\u8BDD\u672A\u4EA7\u51FA\u53EF\u4EA4\u4ED8\u754C\u9762");
|
|
36962
|
-
const dir = fs6.mkdtempSync(path5.join(this.workRoot, "od-deliverable-"));
|
|
36963
|
-
const fetchInline = async (rel) => {
|
|
36964
|
-
const res = await this.fetchImpl(`${this.base}/api/projects/${encodeURIComponent(boardKey)}/export/${encodeURIComponent(rel)}?inline=1`);
|
|
36965
|
-
if (!res.ok) throw new Error(`od export ${rel} \u2192 ${res.status}`);
|
|
36966
|
-
return await res.text();
|
|
36967
|
-
};
|
|
36968
|
-
fs6.writeFileSync(path5.join(dir, "index.html"), await fetchInline(entry));
|
|
36969
|
-
for (const f2 of listing.files ?? []) {
|
|
36970
|
-
if (f2.path.endsWith(".md") && !f2.path.includes("/")) {
|
|
36971
|
-
try {
|
|
36972
|
-
fs6.writeFileSync(path5.join(dir, f2.path), await fetchInline(f2.path));
|
|
36973
|
-
} catch {
|
|
36974
|
-
}
|
|
36975
|
-
}
|
|
36976
|
-
}
|
|
36977
|
-
fs6.writeFileSync(
|
|
36978
|
-
path5.join(dir, "board.link"),
|
|
36979
|
-
`${this.publicBase}/projects/${boardKey}
|
|
36980
|
-
\u5165\u53E3\u7A3F\uFF1A${entry}
|
|
36981
|
-
\u5FEB\u7167\u6765\u6E90 run\uFF1A${runId}
|
|
36982
|
-
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
36983
|
-
`
|
|
36984
|
-
);
|
|
36985
|
-
return { dir, entry };
|
|
36986
|
-
}
|
|
36987
37107
|
async spawn(job) {
|
|
36988
37108
|
const boardKey = deriveBoardKey(job.artifactId);
|
|
36989
|
-
const id = `od-${boardKey}-${(0,
|
|
37109
|
+
const id = `od-${boardKey}-${(0, import_node_crypto11.randomUUID)().slice(0, 8)}`;
|
|
36990
37110
|
const exitCbs = [];
|
|
36991
37111
|
const outputCbs = [];
|
|
36992
37112
|
const telemetryCbs = [];
|
|
36993
37113
|
let exited = null;
|
|
36994
37114
|
let killed = false;
|
|
36995
37115
|
let runId = null;
|
|
36996
|
-
const transcriptRef =
|
|
37116
|
+
const transcriptRef = path6.join(this.workRoot, `od-transcript-${id}.ndjson`);
|
|
36997
37117
|
const translator = new OdEventTranslator();
|
|
36998
37118
|
let eventSeq = 0;
|
|
36999
37119
|
let lastTelemetryAt = Date.now();
|
|
@@ -37018,15 +37138,15 @@ var init_open_design = __esm({
|
|
|
37018
37138
|
finish({ code: null, reason: "timeout" });
|
|
37019
37139
|
return;
|
|
37020
37140
|
}
|
|
37021
|
-
const { conversationId, resolvedDir } = await this.
|
|
37022
|
-
|
|
37141
|
+
const { conversationId, resolvedDir } = await ensureProject(this.base, this.fetchImpl, boardKey, job.artifactId);
|
|
37142
|
+
materializeContext(resolvedDir, job.bundle.files);
|
|
37023
37143
|
const task = job.bundle.files["TASK.md"] ?? "";
|
|
37024
|
-
const created = await this.
|
|
37144
|
+
const created = await odApi(this.base, this.fetchImpl, "POST", "/api/runs", {
|
|
37025
37145
|
agentId: this.agentId,
|
|
37026
37146
|
projectId: boardKey,
|
|
37027
37147
|
conversationId,
|
|
37028
|
-
assistantMessageId: (0,
|
|
37029
|
-
clientRequestId: (0,
|
|
37148
|
+
assistantMessageId: (0, import_node_crypto11.randomUUID)(),
|
|
37149
|
+
clientRequestId: (0, import_node_crypto11.randomUUID)(),
|
|
37030
37150
|
message: task,
|
|
37031
37151
|
systemPrompt: "\u4F60\u662F\u8BBE\u8BA1\u5F15\u64CE\u4E2D\u7684\u754C\u9762\u8BBE\u8BA1\u5E08\u3002\u4EFB\u52A1\u4E66\u89C1\u672C\u6761\u6D88\u606F\uFF1B\u4E0A\u6E38\u8F93\u5165\u7B49\u4E0A\u4E0B\u6587\u6587\u4EF6\u5728\u9879\u76EE task-context/ \u76EE\u5F55\u3002\u6309\u4EFB\u52A1\u4E66\u7684\u300C\u600E\u4E48\u63D0\u4EA4\u300D\u534F\u8BAE\u5DE5\u4F5C\uFF1A\u4EA7\u51FA\u81EA\u5305\u542B HTML \u5165\u53E3\u7A3F\u4E0E acceptance.md\uFF0C\u5B8C\u6210\u5373\u7ED3\u675F\u56DE\u590D\uFF0C\u4EA4\u7A3F\u7531\u7CFB\u7EDF\u4EE3\u529E\u3002"
|
|
37032
37152
|
});
|
|
@@ -37039,7 +37159,7 @@ var init_open_design = __esm({
|
|
|
37039
37159
|
let status = "running";
|
|
37040
37160
|
for (; ; ) {
|
|
37041
37161
|
await new Promise((r) => setTimeout(r, 5e3));
|
|
37042
|
-
const s2 = await this.
|
|
37162
|
+
const s2 = await odApi(this.base, this.fetchImpl, "GET", `/api/runs/${runId}`).catch(() => null);
|
|
37043
37163
|
if (!s2) continue;
|
|
37044
37164
|
status = s2.status;
|
|
37045
37165
|
if (status === "succeeded" || status === "failed" || status === "canceled") break;
|
|
@@ -37055,7 +37175,7 @@ var init_open_design = __esm({
|
|
|
37055
37175
|
finish({ code: 1, reason: "error" });
|
|
37056
37176
|
return;
|
|
37057
37177
|
}
|
|
37058
|
-
const { dir, entry } = await this.
|
|
37178
|
+
const { dir, entry } = await harvestBoard(this.base, this.fetchImpl, this.publicBase, this.workRoot, boardKey, runId);
|
|
37059
37179
|
await this.runPropose({
|
|
37060
37180
|
artifactId: job.artifactId,
|
|
37061
37181
|
dir,
|
|
@@ -37066,7 +37186,7 @@ var init_open_design = __esm({
|
|
|
37066
37186
|
finish({ code: 0, reason: "clean" });
|
|
37067
37187
|
} catch (err) {
|
|
37068
37188
|
try {
|
|
37069
|
-
|
|
37189
|
+
fs7.appendFileSync(transcriptRef, JSON.stringify({ kind: "adapter-error", message: String(err) }) + "\n");
|
|
37070
37190
|
} catch {
|
|
37071
37191
|
}
|
|
37072
37192
|
finish({ code: 1, reason: "error" });
|
|
@@ -37076,7 +37196,7 @@ var init_open_design = __esm({
|
|
|
37076
37196
|
})();
|
|
37077
37197
|
const cancel = async () => {
|
|
37078
37198
|
killed = true;
|
|
37079
|
-
if (runId) await this.
|
|
37199
|
+
if (runId) await odApi(this.base, this.fetchImpl, "POST", `/api/runs/${runId}/cancel`).catch(() => {
|
|
37080
37200
|
});
|
|
37081
37201
|
};
|
|
37082
37202
|
return {
|
|
@@ -37112,7 +37232,7 @@ var init_open_design = __esm({
|
|
|
37112
37232
|
const payload = line.slice(5).trim();
|
|
37113
37233
|
if (payload) {
|
|
37114
37234
|
try {
|
|
37115
|
-
|
|
37235
|
+
fs7.appendFileSync(transcriptRef, payload + "\n");
|
|
37116
37236
|
} catch {
|
|
37117
37237
|
}
|
|
37118
37238
|
onLine(payload);
|
|
@@ -37216,26 +37336,26 @@ function classifyExit(result) {
|
|
|
37216
37336
|
return void 0;
|
|
37217
37337
|
}
|
|
37218
37338
|
function conversationExists(sessionId) {
|
|
37219
|
-
const configDir = process.env["CLAUDE_CONFIG_DIR"] ||
|
|
37220
|
-
const projectsDir =
|
|
37339
|
+
const configDir = process.env["CLAUDE_CONFIG_DIR"] || path7.join(os3.homedir(), ".claude");
|
|
37340
|
+
const projectsDir = path7.join(configDir, "projects");
|
|
37221
37341
|
const target = `${sessionId}.jsonl`;
|
|
37222
37342
|
try {
|
|
37223
|
-
for (const proj of
|
|
37224
|
-
if (
|
|
37343
|
+
for (const proj of fs8.readdirSync(projectsDir)) {
|
|
37344
|
+
if (fs8.existsSync(path7.join(projectsDir, proj, target))) return true;
|
|
37225
37345
|
}
|
|
37226
37346
|
} catch {
|
|
37227
37347
|
}
|
|
37228
37348
|
return false;
|
|
37229
37349
|
}
|
|
37230
|
-
var import_node_child_process3,
|
|
37350
|
+
var import_node_child_process3, import_node_crypto12, fs8, os3, path7, readline, ClaudeCodeAdapter;
|
|
37231
37351
|
var init_claude_code = __esm({
|
|
37232
37352
|
"../adapters/src/claude-code/index.ts"() {
|
|
37233
37353
|
"use strict";
|
|
37234
37354
|
import_node_child_process3 = require("node:child_process");
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
|
|
37355
|
+
import_node_crypto12 = require("node:crypto");
|
|
37356
|
+
fs8 = __toESM(require("node:fs"), 1);
|
|
37357
|
+
os3 = __toESM(require("node:os"), 1);
|
|
37358
|
+
path7 = __toESM(require("node:path"), 1);
|
|
37239
37359
|
readline = __toESM(require("node:readline"), 1);
|
|
37240
37360
|
ClaudeCodeAdapter = class {
|
|
37241
37361
|
constructor(opts = {}) {
|
|
@@ -37264,9 +37384,9 @@ var init_claude_code = __esm({
|
|
|
37264
37384
|
}
|
|
37265
37385
|
async spawn(job) {
|
|
37266
37386
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
37267
|
-
const id = `claude-${slug6}-${(0,
|
|
37268
|
-
const dir = job.runtimeSessionId ?
|
|
37269
|
-
|
|
37387
|
+
const id = `claude-${slug6}-${(0, import_node_crypto12.randomUUID)().slice(0, 8)}`;
|
|
37388
|
+
const dir = job.runtimeSessionId ? path7.join(this.opts.workRoot ?? os3.tmpdir(), "oasis-chat-sessions", job.runtimeSessionId.replace(/[^a-zA-Z0-9_-]+/g, "_")) : fs8.mkdtempSync(path7.join(this.opts.workRoot ?? os3.tmpdir(), "oasis-session-"));
|
|
37389
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
37270
37390
|
if (this.opts.syncSkills) {
|
|
37271
37391
|
try {
|
|
37272
37392
|
await this.opts.syncSkills({
|
|
@@ -37281,14 +37401,14 @@ var init_claude_code = __esm({
|
|
|
37281
37401
|
}
|
|
37282
37402
|
}
|
|
37283
37403
|
for (const [rel, content] of Object.entries(job.bundle.files)) {
|
|
37284
|
-
const file =
|
|
37285
|
-
|
|
37286
|
-
|
|
37404
|
+
const file = path7.join(dir, rel);
|
|
37405
|
+
fs8.mkdirSync(path7.dirname(file), { recursive: true });
|
|
37406
|
+
fs8.writeFileSync(file, content);
|
|
37287
37407
|
}
|
|
37288
37408
|
for (const [rel, b64] of Object.entries(job.bundle.binaryFiles ?? {})) {
|
|
37289
|
-
const file =
|
|
37290
|
-
|
|
37291
|
-
|
|
37409
|
+
const file = path7.join(dir, rel);
|
|
37410
|
+
fs8.mkdirSync(path7.dirname(file), { recursive: true });
|
|
37411
|
+
fs8.writeFileSync(file, Buffer.from(b64, "base64"));
|
|
37292
37412
|
}
|
|
37293
37413
|
const prompt = job.bundle.files["TASK.md"];
|
|
37294
37414
|
if (!prompt) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
@@ -37320,7 +37440,7 @@ var init_claude_code = __esm({
|
|
|
37320
37440
|
...job.env,
|
|
37321
37441
|
// BUG-4 缓冲:抬高单响应输出 token 上限(临时缓冲,根治靠分解)
|
|
37322
37442
|
...this.opts.maxOutputTokens ? { CLAUDE_CODE_MAX_OUTPUT_TOKENS: String(this.opts.maxOutputTokens) } : {},
|
|
37323
|
-
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) =>
|
|
37443
|
+
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) => path7.dirname(p2)).join(path7.delimiter)}${path7.delimiter}${job.env?.["PATH"] ?? process.env["PATH"] ?? ""}` } : {},
|
|
37324
37444
|
OASIS_SERVER: job.server.url,
|
|
37325
37445
|
OASIS_TOKEN: job.actorToken,
|
|
37326
37446
|
// OTel 遥测(默认关;resolveOtelEnv 决定开不开,runId 进 resource 属性自然归位到本次 run)。
|
|
@@ -37332,8 +37452,8 @@ var init_claude_code = __esm({
|
|
|
37332
37452
|
});
|
|
37333
37453
|
if (promptViaStdin) child.stdin.write(prompt);
|
|
37334
37454
|
child.stdin.end();
|
|
37335
|
-
let transcriptRef =
|
|
37336
|
-
const out =
|
|
37455
|
+
let transcriptRef = path7.join(dir, "transcript.txt");
|
|
37456
|
+
const out = fs8.createWriteStream(transcriptRef);
|
|
37337
37457
|
const telemetryCbs = [];
|
|
37338
37458
|
let eventSeq = 0;
|
|
37339
37459
|
let lastResult;
|
|
@@ -37403,14 +37523,14 @@ var init_claude_code = __esm({
|
|
|
37403
37523
|
const reason = killedByUs ? "timeout" : classifyExit(lastResult);
|
|
37404
37524
|
if (this.opts.cleanupWorkdir && !job.runtimeSessionId) {
|
|
37405
37525
|
try {
|
|
37406
|
-
const keepDir =
|
|
37407
|
-
|
|
37408
|
-
const kept =
|
|
37526
|
+
const keepDir = path7.join(this.opts.workRoot ?? os3.tmpdir(), "oasis-transcripts");
|
|
37527
|
+
fs8.mkdirSync(keepDir, { recursive: true });
|
|
37528
|
+
const kept = path7.join(keepDir, `${id}.txt`);
|
|
37409
37529
|
const src = transcriptRef;
|
|
37410
37530
|
out.end(() => {
|
|
37411
37531
|
try {
|
|
37412
|
-
|
|
37413
|
-
|
|
37532
|
+
fs8.renameSync(src, kept);
|
|
37533
|
+
fs8.rmSync(dir, { recursive: true, force: true });
|
|
37414
37534
|
} catch {
|
|
37415
37535
|
}
|
|
37416
37536
|
});
|
|
@@ -37589,7 +37709,7 @@ var init_resilient = __esm({
|
|
|
37589
37709
|
|
|
37590
37710
|
// ../adapters/src/_core/skill-cache.ts
|
|
37591
37711
|
function defaultCacheRoot() {
|
|
37592
|
-
return
|
|
37712
|
+
return path8.join(os4.homedir(), ".oasis", "skill-cache");
|
|
37593
37713
|
}
|
|
37594
37714
|
function sessionSkillsSubdir(runtimeKind) {
|
|
37595
37715
|
return runtimeKind === "claude" || runtimeKind === "claude-code" ? ".claude/skills" : ".agent_context/skills";
|
|
@@ -37600,7 +37720,7 @@ async function syncActorSkills(opts) {
|
|
|
37600
37720
|
});
|
|
37601
37721
|
const now = opts.now ?? (() => /* @__PURE__ */ new Date());
|
|
37602
37722
|
const actorDir = pathForActor(cacheRoot, opts.actorId);
|
|
37603
|
-
const manifestPath =
|
|
37723
|
+
const manifestPath = path8.join(actorDir, "manifest.json");
|
|
37604
37724
|
await fsp.mkdir(actorDir, { recursive: true, mode: 493 });
|
|
37605
37725
|
const release = await acquireLock(cacheRoot, opts.actorId, now, log3);
|
|
37606
37726
|
try {
|
|
@@ -37618,7 +37738,7 @@ async function syncActorSkills(opts) {
|
|
|
37618
37738
|
const cloudIds = new Set(cloudMetadata.map((s2) => s2.id));
|
|
37619
37739
|
for (const cloud of cloudMetadata) {
|
|
37620
37740
|
const cached2 = manifest.skills[cloud.id];
|
|
37621
|
-
const skillDir =
|
|
37741
|
+
const skillDir = path8.join(actorDir, cloud.dir);
|
|
37622
37742
|
const inSync = cached2 && cached2.dir === cloud.dir && cached2.contentHash === cloud.contentHash && cached2.cloudUpdatedAt === cloud.updatedAt && await dirLooksValid(skillDir, cached2.fileList);
|
|
37623
37743
|
if (inSync) {
|
|
37624
37744
|
skipped += 1;
|
|
@@ -37646,7 +37766,7 @@ async function syncActorSkills(opts) {
|
|
|
37646
37766
|
for (const [id, entry] of Object.entries(manifest.skills)) {
|
|
37647
37767
|
if (cloudIds.has(id)) continue;
|
|
37648
37768
|
try {
|
|
37649
|
-
await fsp.rm(
|
|
37769
|
+
await fsp.rm(path8.join(actorDir, entry.dir), { recursive: true, force: true });
|
|
37650
37770
|
} catch (err) {
|
|
37651
37771
|
log3("warn", `\u5220\u9664\u5B64\u513F\u6280\u80FD\u76EE\u5F55\u5931\u8D25 ${entry.dir}`, err);
|
|
37652
37772
|
}
|
|
@@ -37663,14 +37783,14 @@ async function syncActorSkills(opts) {
|
|
|
37663
37783
|
}
|
|
37664
37784
|
}
|
|
37665
37785
|
function pathForActor(cacheRoot, actorId) {
|
|
37666
|
-
return
|
|
37786
|
+
return path8.join(cacheRoot, "actors", encodeURIComponent(actorId));
|
|
37667
37787
|
}
|
|
37668
37788
|
function lockPathFor(cacheRoot, actorId) {
|
|
37669
|
-
return
|
|
37789
|
+
return path8.join(cacheRoot, "locks", `${encodeURIComponent(actorId)}.lock`);
|
|
37670
37790
|
}
|
|
37671
37791
|
async function acquireLock(cacheRoot, actorId, now, log3) {
|
|
37672
37792
|
const lockPath = lockPathFor(cacheRoot, actorId);
|
|
37673
|
-
await fsp.mkdir(
|
|
37793
|
+
await fsp.mkdir(path8.dirname(lockPath), { recursive: true, mode: 493 });
|
|
37674
37794
|
const started = now().getTime();
|
|
37675
37795
|
while (true) {
|
|
37676
37796
|
try {
|
|
@@ -37736,26 +37856,26 @@ async function readManifest2(manifestPath, actorId, log3) {
|
|
|
37736
37856
|
};
|
|
37737
37857
|
}
|
|
37738
37858
|
async function writeManifest(manifestPath, manifest) {
|
|
37739
|
-
const dir =
|
|
37859
|
+
const dir = path8.dirname(manifestPath);
|
|
37740
37860
|
await fsp.mkdir(dir, { recursive: true });
|
|
37741
37861
|
const tmp = `${manifestPath}.${process.pid}.${Date.now()}.tmp`;
|
|
37742
37862
|
await fsp.writeFile(tmp, JSON.stringify(manifest, null, 2), { mode: 420 });
|
|
37743
37863
|
await fsp.rename(tmp, manifestPath);
|
|
37744
37864
|
}
|
|
37745
37865
|
async function materializeSkillDir(actorDir, targetDir, files, previousDir) {
|
|
37746
|
-
const targetPath =
|
|
37747
|
-
const tmpPath =
|
|
37748
|
-
const oldBackup =
|
|
37866
|
+
const targetPath = path8.join(actorDir, targetDir);
|
|
37867
|
+
const tmpPath = path8.join(actorDir, `${targetDir}.new.${process.pid}.${Date.now()}`);
|
|
37868
|
+
const oldBackup = path8.join(actorDir, `${targetDir}.old.${process.pid}.${Date.now()}`);
|
|
37749
37869
|
await fsp.rm(tmpPath, { recursive: true, force: true });
|
|
37750
37870
|
await fsp.mkdir(tmpPath, { recursive: true, mode: 493 });
|
|
37751
37871
|
for (const f2 of files) {
|
|
37752
37872
|
if (!f2.content) continue;
|
|
37753
|
-
const dest =
|
|
37754
|
-
const rel =
|
|
37755
|
-
if (rel.startsWith("..") ||
|
|
37873
|
+
const dest = path8.join(tmpPath, f2.path);
|
|
37874
|
+
const rel = path8.relative(tmpPath, dest);
|
|
37875
|
+
if (rel.startsWith("..") || path8.isAbsolute(rel)) {
|
|
37756
37876
|
throw new Error(`SkillFile.path \u4E0D\u5408\u6CD5: ${f2.path}`);
|
|
37757
37877
|
}
|
|
37758
|
-
await fsp.mkdir(
|
|
37878
|
+
await fsp.mkdir(path8.dirname(dest), { recursive: true });
|
|
37759
37879
|
await fsp.writeFile(dest, f2.content, { mode: 420 });
|
|
37760
37880
|
}
|
|
37761
37881
|
let hadOld = false;
|
|
@@ -37769,14 +37889,14 @@ async function materializeSkillDir(actorDir, targetDir, files, previousDir) {
|
|
|
37769
37889
|
await fsp.rename(tmpPath, targetPath);
|
|
37770
37890
|
if (hadOld) await fsp.rm(oldBackup, { recursive: true, force: true });
|
|
37771
37891
|
if (previousDir && previousDir !== targetDir) {
|
|
37772
|
-
await fsp.rm(
|
|
37892
|
+
await fsp.rm(path8.join(actorDir, previousDir), { recursive: true, force: true });
|
|
37773
37893
|
}
|
|
37774
37894
|
}
|
|
37775
37895
|
async function dirLooksValid(dir, expectFileList) {
|
|
37776
37896
|
if (expectFileList.length === 0) return false;
|
|
37777
37897
|
try {
|
|
37778
37898
|
for (const rel of expectFileList) {
|
|
37779
|
-
await fsp.stat(
|
|
37899
|
+
await fsp.stat(path8.join(dir, rel));
|
|
37780
37900
|
}
|
|
37781
37901
|
return true;
|
|
37782
37902
|
} catch {
|
|
@@ -37785,18 +37905,18 @@ async function dirLooksValid(dir, expectFileList) {
|
|
|
37785
37905
|
}
|
|
37786
37906
|
async function syncSessionSymlinks(sessionDir, runtimeKind, actorDir, manifest, log3) {
|
|
37787
37907
|
const subdir = sessionSkillsSubdir(runtimeKind);
|
|
37788
|
-
const skillsDir =
|
|
37908
|
+
const skillsDir = path8.join(sessionDir, subdir);
|
|
37789
37909
|
await fsp.mkdir(skillsDir, { recursive: true, mode: 493 });
|
|
37790
37910
|
const desired = /* @__PURE__ */ new Map();
|
|
37791
37911
|
for (const entry of Object.values(manifest.skills)) {
|
|
37792
|
-
desired.set(entry.dir,
|
|
37912
|
+
desired.set(entry.dir, path8.join(actorDir, entry.dir));
|
|
37793
37913
|
}
|
|
37794
37914
|
for (const [name, target] of desired) {
|
|
37795
|
-
const link =
|
|
37915
|
+
const link = path8.join(skillsDir, name);
|
|
37796
37916
|
let ok = false;
|
|
37797
37917
|
try {
|
|
37798
37918
|
const current = await fsp.readlink(link);
|
|
37799
|
-
ok =
|
|
37919
|
+
ok = path8.resolve(skillsDir, current) === target;
|
|
37800
37920
|
} catch {
|
|
37801
37921
|
}
|
|
37802
37922
|
if (!ok) {
|
|
@@ -37816,19 +37936,19 @@ async function syncSessionSymlinks(sessionDir, runtimeKind, actorDir, manifest,
|
|
|
37816
37936
|
for (const name of entries) {
|
|
37817
37937
|
if (desired.has(name)) continue;
|
|
37818
37938
|
try {
|
|
37819
|
-
await fsp.rm(
|
|
37939
|
+
await fsp.rm(path8.join(skillsDir, name), { recursive: true, force: true });
|
|
37820
37940
|
} catch (err) {
|
|
37821
37941
|
log3("warn", `\u6E05\u5B64\u513F\u5931\u8D25 ${name}`, err);
|
|
37822
37942
|
}
|
|
37823
37943
|
}
|
|
37824
37944
|
}
|
|
37825
|
-
var fsp,
|
|
37945
|
+
var fsp, os4, path8, MANIFEST_SCHEMA_VERSION, STALE_LOCK_MS, LOCK_ACQUIRE_TIMEOUT_MS, LOCK_POLL_MS;
|
|
37826
37946
|
var init_skill_cache = __esm({
|
|
37827
37947
|
"../adapters/src/_core/skill-cache.ts"() {
|
|
37828
37948
|
"use strict";
|
|
37829
37949
|
fsp = __toESM(require("node:fs/promises"), 1);
|
|
37830
|
-
|
|
37831
|
-
|
|
37950
|
+
os4 = __toESM(require("node:os"), 1);
|
|
37951
|
+
path8 = __toESM(require("node:path"), 1);
|
|
37832
37952
|
MANIFEST_SCHEMA_VERSION = 1;
|
|
37833
37953
|
STALE_LOCK_MS = 6e4;
|
|
37834
37954
|
LOCK_ACQUIRE_TIMEOUT_MS = 3e4;
|
|
@@ -38197,12 +38317,12 @@ function parseCodexModel(lines) {
|
|
|
38197
38317
|
function codexSessionsRoot() {
|
|
38198
38318
|
const candidates = [];
|
|
38199
38319
|
const ch = process.env["CODEX_HOME"];
|
|
38200
|
-
if (ch) candidates.push(
|
|
38201
|
-
const home = process.env["HOME"] ||
|
|
38202
|
-
if (home) candidates.push(
|
|
38320
|
+
if (ch) candidates.push(path9.join(ch, "sessions"));
|
|
38321
|
+
const home = process.env["HOME"] || os5.homedir();
|
|
38322
|
+
if (home) candidates.push(path9.join(home, ".codex", "sessions"));
|
|
38203
38323
|
for (const c of candidates) {
|
|
38204
38324
|
try {
|
|
38205
|
-
if (
|
|
38325
|
+
if (fs9.statSync(c).isDirectory()) return c;
|
|
38206
38326
|
} catch {
|
|
38207
38327
|
}
|
|
38208
38328
|
}
|
|
@@ -38216,13 +38336,13 @@ function codexRolloutExists(sessionId, root = codexSessionsRoot()) {
|
|
|
38216
38336
|
if (hit) return;
|
|
38217
38337
|
let ents;
|
|
38218
38338
|
try {
|
|
38219
|
-
ents =
|
|
38339
|
+
ents = fs9.readdirSync(d, { withFileTypes: true });
|
|
38220
38340
|
} catch {
|
|
38221
38341
|
return;
|
|
38222
38342
|
}
|
|
38223
38343
|
for (const ent of ents) {
|
|
38224
38344
|
if (hit) return;
|
|
38225
|
-
const p2 =
|
|
38345
|
+
const p2 = path9.join(d, ent.name);
|
|
38226
38346
|
if (ent.isDirectory()) walk(p2);
|
|
38227
38347
|
else if (ent.isFile() && ent.name.startsWith("rollout-") && ent.name.endsWith(suffix)) {
|
|
38228
38348
|
hit = true;
|
|
@@ -38239,17 +38359,17 @@ function listRecentRollouts(root, sinceMs) {
|
|
|
38239
38359
|
const walk = (d) => {
|
|
38240
38360
|
let ents;
|
|
38241
38361
|
try {
|
|
38242
|
-
ents =
|
|
38362
|
+
ents = fs9.readdirSync(d, { withFileTypes: true });
|
|
38243
38363
|
} catch {
|
|
38244
38364
|
return;
|
|
38245
38365
|
}
|
|
38246
38366
|
for (const ent of ents) {
|
|
38247
|
-
const p2 =
|
|
38367
|
+
const p2 = path9.join(d, ent.name);
|
|
38248
38368
|
if (ent.isDirectory()) walk(p2);
|
|
38249
38369
|
else if (ent.isFile() && ent.name.startsWith("rollout-") && ent.name.endsWith(".jsonl")) {
|
|
38250
38370
|
let m2 = 0;
|
|
38251
38371
|
try {
|
|
38252
|
-
m2 =
|
|
38372
|
+
m2 = fs9.statSync(p2).mtimeMs;
|
|
38253
38373
|
} catch {
|
|
38254
38374
|
}
|
|
38255
38375
|
if (m2 >= margin) found.push({ f: p2, m: m2 });
|
|
@@ -38264,7 +38384,7 @@ function scanCodexTelemetry(workdir, sinceMs, sessionsRoot = codexSessionsRoot()
|
|
|
38264
38384
|
for (const f2 of listRecentRollouts(sessionsRoot, sinceMs)) {
|
|
38265
38385
|
let lines;
|
|
38266
38386
|
try {
|
|
38267
|
-
lines =
|
|
38387
|
+
lines = fs9.readFileSync(f2, "utf8").split("\n");
|
|
38268
38388
|
} catch {
|
|
38269
38389
|
continue;
|
|
38270
38390
|
}
|
|
@@ -38455,15 +38575,15 @@ function normalizeCodexConsoleLine(line, state = createCodexNormalizeState()) {
|
|
|
38455
38575
|
tool.output.push(line);
|
|
38456
38576
|
return [];
|
|
38457
38577
|
}
|
|
38458
|
-
var import_node_child_process5,
|
|
38578
|
+
var import_node_child_process5, import_node_crypto13, fs9, os5, path9, readline2, CodexAdapter;
|
|
38459
38579
|
var init_codex = __esm({
|
|
38460
38580
|
"../adapters/src/codex/index.ts"() {
|
|
38461
38581
|
"use strict";
|
|
38462
38582
|
import_node_child_process5 = require("node:child_process");
|
|
38463
|
-
|
|
38464
|
-
|
|
38465
|
-
|
|
38466
|
-
|
|
38583
|
+
import_node_crypto13 = require("node:crypto");
|
|
38584
|
+
fs9 = __toESM(require("node:fs"), 1);
|
|
38585
|
+
os5 = __toESM(require("node:os"), 1);
|
|
38586
|
+
path9 = __toESM(require("node:path"), 1);
|
|
38467
38587
|
readline2 = __toESM(require("node:readline"), 1);
|
|
38468
38588
|
init_claude_code();
|
|
38469
38589
|
CodexAdapter = class {
|
|
@@ -38472,13 +38592,13 @@ var init_codex = __esm({
|
|
|
38472
38592
|
}
|
|
38473
38593
|
async spawn(job) {
|
|
38474
38594
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
38475
|
-
const id = `codex-${slug6}-${(0,
|
|
38595
|
+
const id = `codex-${slug6}-${(0, import_node_crypto13.randomUUID)().slice(0, 8)}`;
|
|
38476
38596
|
const startedAtMs = Date.now();
|
|
38477
|
-
const dir =
|
|
38597
|
+
const dir = fs9.mkdtempSync(path9.join(this.opts.workRoot ?? os5.tmpdir(), "oasis-session-"));
|
|
38478
38598
|
for (const [rel, content] of Object.entries(job.bundle.files)) {
|
|
38479
|
-
const file =
|
|
38480
|
-
|
|
38481
|
-
|
|
38599
|
+
const file = path9.join(dir, rel);
|
|
38600
|
+
fs9.mkdirSync(path9.dirname(file), { recursive: true });
|
|
38601
|
+
fs9.writeFileSync(file, content);
|
|
38482
38602
|
}
|
|
38483
38603
|
const task = job.bundle.files["TASK.md"];
|
|
38484
38604
|
if (!task) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
@@ -38507,14 +38627,14 @@ var init_codex = __esm({
|
|
|
38507
38627
|
...scrubLeakyEnv(process.env),
|
|
38508
38628
|
...this.opts.env,
|
|
38509
38629
|
...job.env,
|
|
38510
|
-
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) =>
|
|
38630
|
+
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) => path9.dirname(p2)).join(path9.delimiter)}${path9.delimiter}${job.env?.["PATH"] ?? process.env["PATH"] ?? ""}` } : {},
|
|
38511
38631
|
OASIS_SERVER: job.server.url,
|
|
38512
38632
|
OASIS_TOKEN: job.actorToken
|
|
38513
38633
|
},
|
|
38514
38634
|
stdio: ["ignore", "pipe", "pipe"]
|
|
38515
38635
|
});
|
|
38516
|
-
let transcriptRef =
|
|
38517
|
-
const out =
|
|
38636
|
+
let transcriptRef = path9.join(dir, "transcript.txt");
|
|
38637
|
+
const out = fs9.createWriteStream(transcriptRef);
|
|
38518
38638
|
const outputCbs = [];
|
|
38519
38639
|
const telemetryCbs = [];
|
|
38520
38640
|
const normalizeState = createCodexNormalizeState();
|
|
@@ -38527,14 +38647,34 @@ var init_codex = __esm({
|
|
|
38527
38647
|
for (const cb of telemetryCbs) cb(full);
|
|
38528
38648
|
}
|
|
38529
38649
|
};
|
|
38650
|
+
const stderrTail = [];
|
|
38651
|
+
const STDERR_MAX_LINES = 40;
|
|
38652
|
+
const STDERR_MAX_BYTES = 4e3;
|
|
38653
|
+
const pushStderrTail = (line) => {
|
|
38654
|
+
stderrTail.push(line);
|
|
38655
|
+
while (stderrTail.length > STDERR_MAX_LINES) stderrTail.shift();
|
|
38656
|
+
let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
|
|
38657
|
+
while (total > STDERR_MAX_BYTES && stderrTail.length > 1) {
|
|
38658
|
+
total -= stderrTail.shift().length + 1;
|
|
38659
|
+
}
|
|
38660
|
+
};
|
|
38661
|
+
const stdoutErrorLines = [];
|
|
38662
|
+
const pushStdoutErrorLine = (line) => {
|
|
38663
|
+
if (/^\s*(Error|error):/i.test(line) || /"error"\s*:/.test(line)) {
|
|
38664
|
+
stdoutErrorLines.push(line);
|
|
38665
|
+
if (stdoutErrorLines.length > 10) stdoutErrorLines.shift();
|
|
38666
|
+
}
|
|
38667
|
+
};
|
|
38530
38668
|
const rl = readline2.createInterface({ input: child.stdout });
|
|
38531
38669
|
rl.on("line", (line) => {
|
|
38532
38670
|
out.write(line + "\n");
|
|
38671
|
+
pushStdoutErrorLine(line);
|
|
38533
38672
|
emitNormalized(normalizeCodexStreamLine(line, normalizeState));
|
|
38534
38673
|
});
|
|
38535
38674
|
const errRl = readline2.createInterface({ input: child.stderr });
|
|
38536
38675
|
errRl.on("line", (line) => {
|
|
38537
38676
|
out.write(line + "\n");
|
|
38677
|
+
pushStderrTail(line);
|
|
38538
38678
|
emitNormalized(normalizeCodexConsoleLine(line, consoleNormalizeState));
|
|
38539
38679
|
});
|
|
38540
38680
|
const callbacks = [];
|
|
@@ -38544,14 +38684,14 @@ var init_codex = __esm({
|
|
|
38544
38684
|
if (exited) return;
|
|
38545
38685
|
if (this.opts.cleanupWorkdir) {
|
|
38546
38686
|
try {
|
|
38547
|
-
const keepDir =
|
|
38548
|
-
|
|
38549
|
-
const kept =
|
|
38687
|
+
const keepDir = path9.join(this.opts.workRoot ?? os5.tmpdir(), "oasis-transcripts");
|
|
38688
|
+
fs9.mkdirSync(keepDir, { recursive: true });
|
|
38689
|
+
const kept = path9.join(keepDir, `${id}.txt`);
|
|
38550
38690
|
const src = transcriptRef;
|
|
38551
38691
|
out.end(() => {
|
|
38552
38692
|
try {
|
|
38553
|
-
|
|
38554
|
-
|
|
38693
|
+
fs9.renameSync(src, kept);
|
|
38694
|
+
fs9.rmSync(dir, { recursive: true, force: true });
|
|
38555
38695
|
} catch {
|
|
38556
38696
|
}
|
|
38557
38697
|
});
|
|
@@ -38576,13 +38716,16 @@ var init_codex = __esm({
|
|
|
38576
38716
|
const telemetry = scanCodexTelemetry(dir, startedAtMs);
|
|
38577
38717
|
const model = telemetry.model ?? job.model ?? this.opts.model;
|
|
38578
38718
|
const runtimeSessionId = telemetry.sessionId ?? (job.resumeRuntimeSession ? job.runtimeSessionId : void 0);
|
|
38719
|
+
const isError = !killedByUs && typeof code === "number" && code !== 0;
|
|
38720
|
+
const errorMessage = isError ? [...stdoutErrorLines, ...stderrTail].join("\n").trim().slice(-4e3) || void 0 : void 0;
|
|
38579
38721
|
finish({
|
|
38580
38722
|
code: killedByUs ? null : code,
|
|
38581
38723
|
reason: killedByUs ? "timeout" : code === 0 ? "clean" : "error",
|
|
38582
38724
|
transcriptRef,
|
|
38583
38725
|
...telemetry.usage ? { usage: telemetry.usage } : {},
|
|
38584
38726
|
...model ? { model } : {},
|
|
38585
|
-
...runtimeSessionId ? { runtimeSessionId } : {}
|
|
38727
|
+
...runtimeSessionId ? { runtimeSessionId } : {},
|
|
38728
|
+
...errorMessage ? { errorMessage } : {}
|
|
38586
38729
|
});
|
|
38587
38730
|
});
|
|
38588
38731
|
return {
|
|
@@ -39096,6 +39239,13 @@ function parseArgsJSON(argsText) {
|
|
|
39096
39239
|
return { text: t };
|
|
39097
39240
|
}
|
|
39098
39241
|
}
|
|
39242
|
+
function composeAcpErrorMessage(rpcError, stderrTail) {
|
|
39243
|
+
const parts = [];
|
|
39244
|
+
if (rpcError && rpcError.trim()) parts.push(rpcError.trim());
|
|
39245
|
+
if (stderrTail.length) parts.push(stderrTail.join("\n").trim());
|
|
39246
|
+
const combined = parts.filter(Boolean).join("\n---\n").slice(-4e3).trim();
|
|
39247
|
+
return combined || void 0;
|
|
39248
|
+
}
|
|
39099
39249
|
function extractSessionID(result) {
|
|
39100
39250
|
return result?.sessionId ?? "";
|
|
39101
39251
|
}
|
|
@@ -39117,13 +39267,13 @@ function extractStopReason(result) {
|
|
|
39117
39267
|
}
|
|
39118
39268
|
async function runACPSession(job, cfg) {
|
|
39119
39269
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
39120
|
-
const binTag =
|
|
39121
|
-
const id = `${binTag}-${slug6}-${(0,
|
|
39122
|
-
const dir =
|
|
39270
|
+
const binTag = path10.basename(cfg.bin).replace(/[^a-zA-Z0-9]/g, "").slice(0, 12) || "acp";
|
|
39271
|
+
const id = `${binTag}-${slug6}-${(0, import_node_crypto14.randomUUID)().slice(0, 8)}`;
|
|
39272
|
+
const dir = fs10.mkdtempSync(path10.join(cfg.workRoot ?? os6.tmpdir(), "oasis-session-"));
|
|
39123
39273
|
for (const [rel, content] of Object.entries(job.bundle.files)) {
|
|
39124
|
-
const file =
|
|
39125
|
-
|
|
39126
|
-
|
|
39274
|
+
const file = path10.join(dir, rel);
|
|
39275
|
+
fs10.mkdirSync(path10.dirname(file), { recursive: true });
|
|
39276
|
+
fs10.writeFileSync(file, content);
|
|
39127
39277
|
}
|
|
39128
39278
|
const task = job.bundle.files["TASK.md"];
|
|
39129
39279
|
if (!task) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
@@ -39134,14 +39284,14 @@ async function runACPSession(job, cfg) {
|
|
|
39134
39284
|
...cfg.env,
|
|
39135
39285
|
...job.env,
|
|
39136
39286
|
...cfg.yoloEnv ?? {},
|
|
39137
|
-
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) =>
|
|
39287
|
+
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) => path10.dirname(p2)).join(path10.delimiter)}${path10.delimiter}${job.env?.["PATH"] ?? process.env["PATH"] ?? ""}` } : {},
|
|
39138
39288
|
OASIS_SERVER: job.server.url,
|
|
39139
39289
|
OASIS_TOKEN: job.actorToken
|
|
39140
39290
|
},
|
|
39141
39291
|
stdio: ["pipe", "pipe", "pipe"]
|
|
39142
39292
|
});
|
|
39143
|
-
let transcriptRef =
|
|
39144
|
-
const transcriptOut =
|
|
39293
|
+
let transcriptRef = path10.join(dir, "transcript.txt");
|
|
39294
|
+
const transcriptOut = fs10.createWriteStream(transcriptRef);
|
|
39145
39295
|
const outputCbs = [];
|
|
39146
39296
|
const telemetryCbs = [];
|
|
39147
39297
|
const exitCbs = [];
|
|
@@ -39158,14 +39308,14 @@ async function runACPSession(job, cfg) {
|
|
|
39158
39308
|
if (capturedSessionId && !info.runtimeSessionId) info = { ...info, runtimeSessionId: capturedSessionId };
|
|
39159
39309
|
if (cfg.cleanupWorkdir) {
|
|
39160
39310
|
try {
|
|
39161
|
-
const keepDir =
|
|
39162
|
-
|
|
39163
|
-
const kept =
|
|
39311
|
+
const keepDir = path10.join(cfg.workRoot ?? os6.tmpdir(), "oasis-transcripts");
|
|
39312
|
+
fs10.mkdirSync(keepDir, { recursive: true });
|
|
39313
|
+
const kept = path10.join(keepDir, `${id}.txt`);
|
|
39164
39314
|
const src = transcriptRef;
|
|
39165
39315
|
transcriptOut.end(() => {
|
|
39166
39316
|
try {
|
|
39167
|
-
|
|
39168
|
-
|
|
39317
|
+
fs10.renameSync(src, kept);
|
|
39318
|
+
fs10.rmSync(dir, { recursive: true, force: true });
|
|
39169
39319
|
} catch {
|
|
39170
39320
|
}
|
|
39171
39321
|
});
|
|
@@ -39181,7 +39331,23 @@ async function runACPSession(job, cfg) {
|
|
|
39181
39331
|
killedByUs = true;
|
|
39182
39332
|
child.kill("SIGKILL");
|
|
39183
39333
|
}, job.limits.wallClockMs);
|
|
39184
|
-
|
|
39334
|
+
const stderrTail = [];
|
|
39335
|
+
const STDERR_MAX_LINES = 40;
|
|
39336
|
+
const STDERR_MAX_BYTES = 4e3;
|
|
39337
|
+
const stderrRl = readline3.createInterface({ input: child.stderr });
|
|
39338
|
+
stderrRl.on("line", (line) => {
|
|
39339
|
+
try {
|
|
39340
|
+
transcriptOut.write(line + "\n");
|
|
39341
|
+
} catch {
|
|
39342
|
+
}
|
|
39343
|
+
stderrTail.push(line);
|
|
39344
|
+
while (stderrTail.length > STDERR_MAX_LINES) stderrTail.shift();
|
|
39345
|
+
let total = stderrTail.reduce((n, l) => n + l.length + 1, 0);
|
|
39346
|
+
while (total > STDERR_MAX_BYTES && stderrTail.length > 1) {
|
|
39347
|
+
total -= stderrTail.shift().length + 1;
|
|
39348
|
+
}
|
|
39349
|
+
});
|
|
39350
|
+
let lastRpcError;
|
|
39185
39351
|
let streamingCurrentTurn = false;
|
|
39186
39352
|
const client = new ACPClient(
|
|
39187
39353
|
(line) => {
|
|
@@ -39213,14 +39379,20 @@ async function runACPSession(job, cfg) {
|
|
|
39213
39379
|
resolve4();
|
|
39214
39380
|
});
|
|
39215
39381
|
});
|
|
39216
|
-
child.on("error", () => {
|
|
39382
|
+
child.on("error", (err) => {
|
|
39217
39383
|
clearTimeout(timer);
|
|
39218
|
-
finish({ code: null, reason: "error", transcriptRef });
|
|
39384
|
+
finish({ code: null, reason: "error", transcriptRef, errorMessage: composeAcpErrorMessage(err instanceof Error ? err.message : String(err), stderrTail) });
|
|
39219
39385
|
});
|
|
39220
39386
|
child.on("exit", (code) => {
|
|
39221
39387
|
clearTimeout(timer);
|
|
39222
39388
|
void readerDone.then(() => {
|
|
39223
|
-
|
|
39389
|
+
const isError = !killedByUs && typeof code === "number" && code !== 0;
|
|
39390
|
+
finish({
|
|
39391
|
+
code: killedByUs ? null : code,
|
|
39392
|
+
reason: killedByUs ? "timeout" : code === 0 ? "clean" : "error",
|
|
39393
|
+
transcriptRef,
|
|
39394
|
+
...isError ? { errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail) } : {}
|
|
39395
|
+
});
|
|
39224
39396
|
});
|
|
39225
39397
|
});
|
|
39226
39398
|
void (async () => {
|
|
@@ -39311,10 +39483,11 @@ ${task}` : task;
|
|
|
39311
39483
|
if (!exited) finish({ code: 0, reason: "clean", transcriptRef, usage, model: actualModel });
|
|
39312
39484
|
child.kill("SIGTERM");
|
|
39313
39485
|
} catch (err) {
|
|
39486
|
+
lastRpcError = err instanceof Error ? err.message : String(err);
|
|
39314
39487
|
if (!exited) {
|
|
39315
39488
|
const reason = killedByUs ? "timeout" : "error";
|
|
39316
39489
|
const usage = buildUsage(client.usage, estimateCost(client.usage, actualModel));
|
|
39317
|
-
finish({ code: null, reason, transcriptRef, usage, model: actualModel });
|
|
39490
|
+
finish({ code: null, reason, transcriptRef, usage, model: actualModel, errorMessage: composeAcpErrorMessage(lastRpcError, stderrTail) });
|
|
39318
39491
|
}
|
|
39319
39492
|
} finally {
|
|
39320
39493
|
await readerDone;
|
|
@@ -39342,15 +39515,15 @@ ${task}` : task;
|
|
|
39342
39515
|
}
|
|
39343
39516
|
};
|
|
39344
39517
|
}
|
|
39345
|
-
var import_node_child_process6,
|
|
39518
|
+
var import_node_child_process6, import_node_crypto14, fs10, os6, path10, readline3, ACPClient;
|
|
39346
39519
|
var init_acp = __esm({
|
|
39347
39520
|
"../adapters/src/_core/acp.ts"() {
|
|
39348
39521
|
"use strict";
|
|
39349
39522
|
import_node_child_process6 = require("node:child_process");
|
|
39350
|
-
|
|
39351
|
-
|
|
39352
|
-
|
|
39353
|
-
|
|
39523
|
+
import_node_crypto14 = require("node:crypto");
|
|
39524
|
+
fs10 = __toESM(require("node:fs"), 1);
|
|
39525
|
+
os6 = __toESM(require("node:os"), 1);
|
|
39526
|
+
path10 = __toESM(require("node:path"), 1);
|
|
39354
39527
|
readline3 = __toESM(require("node:readline"), 1);
|
|
39355
39528
|
init_claude_code();
|
|
39356
39529
|
init_usage();
|
|
@@ -39668,12 +39841,12 @@ var init_kiro = __esm({
|
|
|
39668
39841
|
// ../adapters/src/_core/subprocess.ts
|
|
39669
39842
|
function materialize(job, workRoot) {
|
|
39670
39843
|
const slug6 = job.artifactId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32);
|
|
39671
|
-
const id = `${slug6}-${(0,
|
|
39672
|
-
const dir =
|
|
39844
|
+
const id = `${slug6}-${(0, import_node_crypto15.randomUUID)().slice(0, 8)}`;
|
|
39845
|
+
const dir = fs11.mkdtempSync(path11.join(workRoot ?? os7.tmpdir(), "oasis-session-"));
|
|
39673
39846
|
for (const [rel, content] of Object.entries(job.bundle.files)) {
|
|
39674
|
-
const file =
|
|
39675
|
-
|
|
39676
|
-
|
|
39847
|
+
const file = path11.join(dir, rel);
|
|
39848
|
+
fs11.mkdirSync(path11.dirname(file), { recursive: true });
|
|
39849
|
+
fs11.writeFileSync(file, content);
|
|
39677
39850
|
}
|
|
39678
39851
|
const task = job.bundle.files["TASK.md"];
|
|
39679
39852
|
if (!task) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
@@ -39684,7 +39857,7 @@ function buildEnv(job, extra) {
|
|
|
39684
39857
|
...scrubLeakyEnv(process.env),
|
|
39685
39858
|
...extra,
|
|
39686
39859
|
...job.env,
|
|
39687
|
-
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) =>
|
|
39860
|
+
...job.wrapperPaths?.length ? { PATH: `${job.wrapperPaths.map((p2) => path11.dirname(p2)).join(path11.delimiter)}${path11.delimiter}${job.env?.["PATH"] ?? process.env["PATH"] ?? ""}` } : {},
|
|
39688
39861
|
OASIS_SERVER: job.server.url,
|
|
39689
39862
|
OASIS_TOKEN: job.actorToken
|
|
39690
39863
|
};
|
|
@@ -39696,14 +39869,14 @@ function makeFinish(id, cfg, transcriptRefPtr, transcriptOut, dir, exitCbs) {
|
|
|
39696
39869
|
if (cfg.model && !info.model) info = { ...info, model: cfg.model };
|
|
39697
39870
|
if (cfg.cleanupWorkdir) {
|
|
39698
39871
|
try {
|
|
39699
|
-
const keepDir =
|
|
39700
|
-
|
|
39701
|
-
const kept =
|
|
39872
|
+
const keepDir = path11.join(cfg.workRoot ?? os7.tmpdir(), "oasis-transcripts");
|
|
39873
|
+
fs11.mkdirSync(keepDir, { recursive: true });
|
|
39874
|
+
const kept = path11.join(keepDir, `${id}.txt`);
|
|
39702
39875
|
const src = transcriptRefPtr.value;
|
|
39703
39876
|
transcriptOut.end(() => {
|
|
39704
39877
|
try {
|
|
39705
|
-
|
|
39706
|
-
|
|
39878
|
+
fs11.renameSync(src, kept);
|
|
39879
|
+
fs11.rmSync(dir, { recursive: true, force: true });
|
|
39707
39880
|
} catch {
|
|
39708
39881
|
}
|
|
39709
39882
|
});
|
|
@@ -39725,8 +39898,8 @@ function runStreamJson(job, cfg) {
|
|
|
39725
39898
|
env: buildEnv(job, cfg.env),
|
|
39726
39899
|
stdio: ["ignore", "pipe", "pipe"]
|
|
39727
39900
|
});
|
|
39728
|
-
const transcriptRefPtr = { value:
|
|
39729
|
-
const transcriptOut =
|
|
39901
|
+
const transcriptRefPtr = { value: path11.join(dir, "transcript.txt") };
|
|
39902
|
+
const transcriptOut = fs11.createWriteStream(transcriptRefPtr.value);
|
|
39730
39903
|
const outputCbs = [];
|
|
39731
39904
|
const telemetryCbs = [];
|
|
39732
39905
|
const exitCbs = [];
|
|
@@ -39783,8 +39956,8 @@ function runOneShotText(job, cfg) {
|
|
|
39783
39956
|
env: buildEnv(job, cfg.env),
|
|
39784
39957
|
stdio: ["ignore", "pipe", "pipe"]
|
|
39785
39958
|
});
|
|
39786
|
-
const transcriptRefPtr = { value:
|
|
39787
|
-
const transcriptOut =
|
|
39959
|
+
const transcriptRefPtr = { value: path11.join(dir, "transcript.txt") };
|
|
39960
|
+
const transcriptOut = fs11.createWriteStream(transcriptRefPtr.value);
|
|
39788
39961
|
const outputCbs = [];
|
|
39789
39962
|
const exitCbs = [];
|
|
39790
39963
|
const { finish, exited } = makeFinish(id, cfg, transcriptRefPtr, transcriptOut, dir, exitCbs);
|
|
@@ -39823,15 +39996,15 @@ function runOneShotText(job, cfg) {
|
|
|
39823
39996
|
}
|
|
39824
39997
|
});
|
|
39825
39998
|
}
|
|
39826
|
-
var import_node_child_process7,
|
|
39999
|
+
var import_node_child_process7, import_node_crypto15, fs11, os7, path11, readline4;
|
|
39827
40000
|
var init_subprocess = __esm({
|
|
39828
40001
|
"../adapters/src/_core/subprocess.ts"() {
|
|
39829
40002
|
"use strict";
|
|
39830
40003
|
import_node_child_process7 = require("node:child_process");
|
|
39831
|
-
|
|
39832
|
-
|
|
39833
|
-
|
|
39834
|
-
|
|
40004
|
+
import_node_crypto15 = require("node:crypto");
|
|
40005
|
+
fs11 = __toESM(require("node:fs"), 1);
|
|
40006
|
+
os7 = __toESM(require("node:os"), 1);
|
|
40007
|
+
path11 = __toESM(require("node:path"), 1);
|
|
39835
40008
|
readline4 = __toESM(require("node:readline"), 1);
|
|
39836
40009
|
init_claude_code();
|
|
39837
40010
|
}
|
|
@@ -40235,11 +40408,11 @@ function normalizeOpenClaw(line) {
|
|
|
40235
40408
|
}
|
|
40236
40409
|
return [];
|
|
40237
40410
|
}
|
|
40238
|
-
var
|
|
40411
|
+
var import_node_crypto16, OpenClawAdapter;
|
|
40239
40412
|
var init_openclaw = __esm({
|
|
40240
40413
|
"../adapters/src/openclaw/index.ts"() {
|
|
40241
40414
|
"use strict";
|
|
40242
|
-
|
|
40415
|
+
import_node_crypto16 = require("node:crypto");
|
|
40243
40416
|
init_subprocess();
|
|
40244
40417
|
OpenClawAdapter = class {
|
|
40245
40418
|
constructor(opts = {}) {
|
|
@@ -40257,7 +40430,7 @@ var init_openclaw = __esm({
|
|
|
40257
40430
|
---
|
|
40258
40431
|
|
|
40259
40432
|
${task}` : task;
|
|
40260
|
-
const sessionId = job2.runtimeSessionId ?? `oasis-${(0,
|
|
40433
|
+
const sessionId = job2.runtimeSessionId ?? `oasis-${(0, import_node_crypto16.randomUUID)().slice(0, 8)}`;
|
|
40261
40434
|
return [
|
|
40262
40435
|
"agent",
|
|
40263
40436
|
...opts.mode !== "gateway" ? ["--local"] : [],
|
|
@@ -40728,7 +40901,7 @@ function nodesDomain(deps) {
|
|
|
40728
40901
|
nodeId = incomingNodeId;
|
|
40729
40902
|
deps.enrollTokens.setIssuedNodeId(enrollToken, nodeId);
|
|
40730
40903
|
} else {
|
|
40731
|
-
nodeId = `node-${(0,
|
|
40904
|
+
nodeId = `node-${(0, import_node_crypto17.randomUUID)().slice(0, 8)}`;
|
|
40732
40905
|
deps.enrollTokens.setIssuedNodeId(enrollToken, nodeId);
|
|
40733
40906
|
}
|
|
40734
40907
|
const existingNode = await deps.nodeStore.getNode(nodeId);
|
|
@@ -40768,6 +40941,23 @@ function nodesDomain(deps) {
|
|
|
40768
40941
|
await deps.nodeStore.deleteNode(nodeId);
|
|
40769
40942
|
return { status: 200, body: { ok: true } };
|
|
40770
40943
|
});
|
|
40944
|
+
router.get("/api/nodes/expected-daemon-version", async () => {
|
|
40945
|
+
const envVer = (process.env["OASIS_LATEST_NODE_DAEMON_VERSION"] ?? "").trim();
|
|
40946
|
+
if (envVer) return { status: 200, body: { version: envVer, source: "env" } };
|
|
40947
|
+
try {
|
|
40948
|
+
const here = (0, import_node_path2.dirname)((0, import_node_url.fileURLToPath)(__esm_import_meta_url));
|
|
40949
|
+
for (const rel of ["../../../../node-daemon/package.json", "../../../../../node-daemon/package.json"]) {
|
|
40950
|
+
try {
|
|
40951
|
+
const raw = (0, import_node_fs3.readFileSync)((0, import_node_path2.resolve)(here, rel), "utf8");
|
|
40952
|
+
const pkg = JSON.parse(raw);
|
|
40953
|
+
if (pkg.version) return { status: 200, body: { version: pkg.version, source: "monorepo" } };
|
|
40954
|
+
} catch {
|
|
40955
|
+
}
|
|
40956
|
+
}
|
|
40957
|
+
} catch {
|
|
40958
|
+
}
|
|
40959
|
+
return { status: 200, body: { version: null, source: null } };
|
|
40960
|
+
});
|
|
40771
40961
|
router.post("/api/nodes/:nodeId/update", async (req) => {
|
|
40772
40962
|
const nodeId = req.params["nodeId"];
|
|
40773
40963
|
if (!nodeId) return { status: 400, body: { error: "missing nodeId" } };
|
|
@@ -40851,11 +41041,14 @@ function nodesDomain(deps) {
|
|
|
40851
41041
|
});
|
|
40852
41042
|
};
|
|
40853
41043
|
}
|
|
40854
|
-
var
|
|
41044
|
+
var import_node_crypto17, import_node_fs3, import_node_url, import_node_path2;
|
|
40855
41045
|
var init_routes4 = __esm({
|
|
40856
41046
|
"../server/src/domains/nodes/routes.ts"() {
|
|
40857
41047
|
"use strict";
|
|
40858
|
-
|
|
41048
|
+
import_node_crypto17 = require("node:crypto");
|
|
41049
|
+
import_node_fs3 = require("node:fs");
|
|
41050
|
+
import_node_url = require("node:url");
|
|
41051
|
+
import_node_path2 = require("node:path");
|
|
40859
41052
|
init_src4();
|
|
40860
41053
|
init_connect_script();
|
|
40861
41054
|
}
|
|
@@ -40914,11 +41107,11 @@ var init_types3 = __esm({
|
|
|
40914
41107
|
});
|
|
40915
41108
|
|
|
40916
41109
|
// ../server/src/node-store.ts
|
|
40917
|
-
var
|
|
41110
|
+
var fs12, MemoryNodeStore, FileNodeStore;
|
|
40918
41111
|
var init_node_store = __esm({
|
|
40919
41112
|
"../server/src/node-store.ts"() {
|
|
40920
41113
|
"use strict";
|
|
40921
|
-
|
|
41114
|
+
fs12 = __toESM(require("node:fs"), 1);
|
|
40922
41115
|
MemoryNodeStore = class {
|
|
40923
41116
|
nodes = /* @__PURE__ */ new Map();
|
|
40924
41117
|
runtimes = /* @__PURE__ */ new Map();
|
|
@@ -41003,16 +41196,16 @@ var init_node_store = __esm({
|
|
|
41003
41196
|
static async open(file) {
|
|
41004
41197
|
const s2 = new _FileNodeStore(file);
|
|
41005
41198
|
try {
|
|
41006
|
-
const snap = JSON.parse(
|
|
41199
|
+
const snap = JSON.parse(fs12.readFileSync(file, "utf8"));
|
|
41007
41200
|
for (const n of snap.nodes ?? []) s2.nodes.set(n.id, n);
|
|
41008
41201
|
for (const r of snap.runtimes ?? []) s2.runtimes.set(r.id, r);
|
|
41009
41202
|
} catch {
|
|
41010
|
-
|
|
41203
|
+
fs12.writeFileSync(file, JSON.stringify({ nodes: [], runtimes: [] }, null, 2));
|
|
41011
41204
|
}
|
|
41012
41205
|
return s2;
|
|
41013
41206
|
}
|
|
41014
41207
|
flush() {
|
|
41015
|
-
|
|
41208
|
+
fs12.writeFileSync(this.file, JSON.stringify({
|
|
41016
41209
|
nodes: [...this.nodes.values()],
|
|
41017
41210
|
runtimes: [...this.runtimes.values()]
|
|
41018
41211
|
}, null, 2));
|
|
@@ -41556,7 +41749,7 @@ var init_collab = __esm({
|
|
|
41556
41749
|
|
|
41557
41750
|
// ../server/src/domains/collab/create-seeded-workorder.ts
|
|
41558
41751
|
function makeSeededWorkorderCreator(deps) {
|
|
41559
|
-
const genWorkspace = deps.genWorkspace ?? (() => `ws:wo-${(0,
|
|
41752
|
+
const genWorkspace = deps.genWorkspace ?? (() => `ws:wo-${(0, import_node_crypto18.randomUUID)().slice(0, 8)}`);
|
|
41560
41753
|
return async (input) => {
|
|
41561
41754
|
const workspace = genWorkspace();
|
|
41562
41755
|
if (input.projectId && deps.artifactState) {
|
|
@@ -41593,11 +41786,11 @@ function makeSeededWorkorderCreator(deps) {
|
|
|
41593
41786
|
return { workspace, rootArtifactId: briefId, spawned: planned.spawned };
|
|
41594
41787
|
};
|
|
41595
41788
|
}
|
|
41596
|
-
var
|
|
41789
|
+
var import_node_crypto18, enc2;
|
|
41597
41790
|
var init_create_seeded_workorder = __esm({
|
|
41598
41791
|
"../server/src/domains/collab/create-seeded-workorder.ts"() {
|
|
41599
41792
|
"use strict";
|
|
41600
|
-
|
|
41793
|
+
import_node_crypto18 = require("node:crypto");
|
|
41601
41794
|
init_planner();
|
|
41602
41795
|
enc2 = (s2) => new TextEncoder().encode(s2);
|
|
41603
41796
|
}
|
|
@@ -42623,7 +42816,7 @@ function createChatSessionsDomain(opts) {
|
|
|
42623
42816
|
const runtimeId = await currentRuntimeId(body.aiActorId) ?? "unknown";
|
|
42624
42817
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
42625
42818
|
const session = {
|
|
42626
|
-
id: (0,
|
|
42819
|
+
id: (0, import_node_crypto19.randomUUID)(),
|
|
42627
42820
|
humanActorId: req.auth.actor,
|
|
42628
42821
|
aiActorId: body.aiActorId,
|
|
42629
42822
|
runtimeId,
|
|
@@ -42674,7 +42867,7 @@ function createChatSessionsDomain(opts) {
|
|
|
42674
42867
|
if (!body?.role || !body?.content) throw new ApiError(400, "BAD_REQUEST", "role and content required");
|
|
42675
42868
|
if (body.role !== "user" && body.role !== "assistant") throw new ApiError(400, "BAD_REQUEST", "role must be user or assistant");
|
|
42676
42869
|
const msg = await store.appendMessage({
|
|
42677
|
-
id: (0,
|
|
42870
|
+
id: (0, import_node_crypto19.randomUUID)(),
|
|
42678
42871
|
sessionId: req.params.id,
|
|
42679
42872
|
role: body.role,
|
|
42680
42873
|
content: body.content,
|
|
@@ -42711,11 +42904,11 @@ function createChatSessionsDomain(opts) {
|
|
|
42711
42904
|
});
|
|
42712
42905
|
};
|
|
42713
42906
|
}
|
|
42714
|
-
var
|
|
42907
|
+
var import_node_crypto19;
|
|
42715
42908
|
var init_chat_sessions = __esm({
|
|
42716
42909
|
"../server/src/domains/chat-sessions/index.ts"() {
|
|
42717
42910
|
"use strict";
|
|
42718
|
-
|
|
42911
|
+
import_node_crypto19 = require("node:crypto");
|
|
42719
42912
|
init_router();
|
|
42720
42913
|
init_workorders();
|
|
42721
42914
|
init_chat_parts();
|
|
@@ -44081,11 +44274,11 @@ function ackMsFromEnv(fallback) {
|
|
|
44081
44274
|
const n = Number(v2);
|
|
44082
44275
|
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
44083
44276
|
}
|
|
44084
|
-
var
|
|
44277
|
+
var import_node_crypto20, DaemonHubAdapter, BindingRouterAdapter;
|
|
44085
44278
|
var init_daemon_adapter = __esm({
|
|
44086
44279
|
"../server/src/daemon-adapter.ts"() {
|
|
44087
44280
|
"use strict";
|
|
44088
|
-
|
|
44281
|
+
import_node_crypto20 = require("node:crypto");
|
|
44089
44282
|
DaemonHubAdapter = class {
|
|
44090
44283
|
constructor(hub, opts = {}) {
|
|
44091
44284
|
this.hub = hub;
|
|
@@ -44172,7 +44365,7 @@ var init_daemon_adapter = __esm({
|
|
|
44172
44365
|
async spawn(job) {
|
|
44173
44366
|
const nodeId = job.binding?.nodeId;
|
|
44174
44367
|
if (!nodeId) throw new Error("DaemonHubAdapter \u9700\u8981 job.binding.nodeId\uFF08\u8DEF\u7531\u9519\u8BEF\uFF09");
|
|
44175
|
-
const dispatchId = `dispatch:${(0,
|
|
44368
|
+
const dispatchId = `dispatch:${(0, import_node_crypto20.randomUUID)()}`;
|
|
44176
44369
|
const entry = {
|
|
44177
44370
|
nodeId,
|
|
44178
44371
|
exitCbs: [],
|
|
@@ -44270,17 +44463,17 @@ var init_daemon_adapter = __esm({
|
|
|
44270
44463
|
});
|
|
44271
44464
|
|
|
44272
44465
|
// ../server/src/side-map.ts
|
|
44273
|
-
var
|
|
44466
|
+
var import_node_fs4, import_node_path3, FileSideMap;
|
|
44274
44467
|
var init_side_map = __esm({
|
|
44275
44468
|
"../server/src/side-map.ts"() {
|
|
44276
44469
|
"use strict";
|
|
44277
|
-
|
|
44278
|
-
|
|
44470
|
+
import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
44471
|
+
import_node_path3 = __toESM(require("node:path"), 1);
|
|
44279
44472
|
FileSideMap = class {
|
|
44280
44473
|
constructor(file) {
|
|
44281
44474
|
this.file = file;
|
|
44282
44475
|
try {
|
|
44283
|
-
const raw = JSON.parse(
|
|
44476
|
+
const raw = JSON.parse(import_node_fs4.default.readFileSync(file, "utf8"));
|
|
44284
44477
|
for (const [k2, v2] of Object.entries(raw)) if (typeof v2 === "string") this.map.set(k2, v2);
|
|
44285
44478
|
} catch {
|
|
44286
44479
|
}
|
|
@@ -44298,10 +44491,10 @@ var init_side_map = __esm({
|
|
|
44298
44491
|
}
|
|
44299
44492
|
persist() {
|
|
44300
44493
|
try {
|
|
44301
|
-
|
|
44494
|
+
import_node_fs4.default.mkdirSync(import_node_path3.default.dirname(this.file), { recursive: true });
|
|
44302
44495
|
const tmp = `${this.file}.tmp`;
|
|
44303
|
-
|
|
44304
|
-
|
|
44496
|
+
import_node_fs4.default.writeFileSync(tmp, JSON.stringify(Object.fromEntries(this.map), null, 2));
|
|
44497
|
+
import_node_fs4.default.renameSync(tmp, this.file);
|
|
44305
44498
|
} catch {
|
|
44306
44499
|
}
|
|
44307
44500
|
}
|
|
@@ -44316,13 +44509,13 @@ function classifyPage(page, lastPushedHash, serviceAccount) {
|
|
|
44316
44509
|
if (sha(body) === lastPushedHash) return { kind: "echo" };
|
|
44317
44510
|
return { kind: "human-edit", content: body, updatedBy: page.updatedBy };
|
|
44318
44511
|
}
|
|
44319
|
-
var
|
|
44512
|
+
var import_node_crypto21, sha, enc3, dec, MirrorEngine, MapMirrorIdentities;
|
|
44320
44513
|
var init_engine = __esm({
|
|
44321
44514
|
"../server/src/mirror/engine.ts"() {
|
|
44322
44515
|
"use strict";
|
|
44323
|
-
|
|
44516
|
+
import_node_crypto21 = require("node:crypto");
|
|
44324
44517
|
init_src();
|
|
44325
|
-
sha = (s2) => (0,
|
|
44518
|
+
sha = (s2) => (0, import_node_crypto21.createHash)("sha256").update(s2, "utf8").digest("hex");
|
|
44326
44519
|
enc3 = (s2) => new TextEncoder().encode(s2);
|
|
44327
44520
|
dec = (b2) => new TextDecoder().decode(b2);
|
|
44328
44521
|
MirrorEngine = class {
|
|
@@ -44435,22 +44628,22 @@ var init_engine = __esm({
|
|
|
44435
44628
|
});
|
|
44436
44629
|
|
|
44437
44630
|
// ../server/src/mirror/fs-state.ts
|
|
44438
|
-
var
|
|
44631
|
+
var fs14, FsMirrorStateStore;
|
|
44439
44632
|
var init_fs_state = __esm({
|
|
44440
44633
|
"../server/src/mirror/fs-state.ts"() {
|
|
44441
44634
|
"use strict";
|
|
44442
|
-
|
|
44635
|
+
fs14 = __toESM(require("node:fs"), 1);
|
|
44443
44636
|
FsMirrorStateStore = class {
|
|
44444
44637
|
constructor(file) {
|
|
44445
44638
|
this.file = file;
|
|
44446
|
-
if (
|
|
44447
|
-
const obj = JSON.parse(
|
|
44639
|
+
if (fs14.existsSync(file)) {
|
|
44640
|
+
const obj = JSON.parse(fs14.readFileSync(file, "utf8"));
|
|
44448
44641
|
for (const [k2, v2] of Object.entries(obj)) this.map.set(k2, v2);
|
|
44449
44642
|
}
|
|
44450
44643
|
}
|
|
44451
44644
|
map = /* @__PURE__ */ new Map();
|
|
44452
44645
|
flush() {
|
|
44453
|
-
|
|
44646
|
+
fs14.writeFileSync(this.file, JSON.stringify(Object.fromEntries(this.map), null, 2));
|
|
44454
44647
|
}
|
|
44455
44648
|
async get(artifactId) {
|
|
44456
44649
|
return this.map.get(artifactId) ?? null;
|
|
@@ -44467,13 +44660,13 @@ var init_fs_state = __esm({
|
|
|
44467
44660
|
});
|
|
44468
44661
|
|
|
44469
44662
|
// ../server/src/git/integrate.ts
|
|
44470
|
-
var import_node_child_process8,
|
|
44663
|
+
var import_node_child_process8, fs15, path13, GitRemoteIntegrator;
|
|
44471
44664
|
var init_integrate = __esm({
|
|
44472
44665
|
"../server/src/git/integrate.ts"() {
|
|
44473
44666
|
"use strict";
|
|
44474
44667
|
import_node_child_process8 = require("node:child_process");
|
|
44475
|
-
|
|
44476
|
-
|
|
44668
|
+
fs15 = __toESM(require("node:fs"), 1);
|
|
44669
|
+
path13 = __toESM(require("node:path"), 1);
|
|
44477
44670
|
GitRemoteIntegrator = class {
|
|
44478
44671
|
constructor(remote, cloneDir, develop = "develop") {
|
|
44479
44672
|
this.remote = remote;
|
|
@@ -44490,8 +44683,8 @@ var init_integrate = __esm({
|
|
|
44490
44683
|
}
|
|
44491
44684
|
/** 确保本地工作克隆存在并拉到最新远程态。幂等。 */
|
|
44492
44685
|
sync() {
|
|
44493
|
-
if (!
|
|
44494
|
-
|
|
44686
|
+
if (!fs15.existsSync(path13.join(this.cloneDir, ".git"))) {
|
|
44687
|
+
fs15.mkdirSync(path13.dirname(this.cloneDir), { recursive: true });
|
|
44495
44688
|
(0, import_node_child_process8.execFileSync)("git", ["clone", "--quiet", this.remote, this.cloneDir], { env: this.env, maxBuffer: 256 * 1024 * 1024 });
|
|
44496
44689
|
this.git(["config", "user.email", "oasis@local"]);
|
|
44497
44690
|
this.git(["config", "user.name", "oasis"]);
|
|
@@ -44542,12 +44735,12 @@ var init_integrate = __esm({
|
|
|
44542
44735
|
});
|
|
44543
44736
|
|
|
44544
44737
|
// ../server/src/git/sync.ts
|
|
44545
|
-
var
|
|
44738
|
+
var os8, path14, slug3, GitSyncWorker;
|
|
44546
44739
|
var init_sync = __esm({
|
|
44547
44740
|
"../server/src/git/sync.ts"() {
|
|
44548
44741
|
"use strict";
|
|
44549
|
-
|
|
44550
|
-
|
|
44742
|
+
os8 = __toESM(require("node:os"), 1);
|
|
44743
|
+
path14 = __toESM(require("node:path"), 1);
|
|
44551
44744
|
init_src2();
|
|
44552
44745
|
init_integrate();
|
|
44553
44746
|
init_collect();
|
|
@@ -44563,8 +44756,8 @@ var init_sync = __esm({
|
|
|
44563
44756
|
const key = repo.remote;
|
|
44564
44757
|
let g2 = this.integrators.get(key);
|
|
44565
44758
|
if (!g2) {
|
|
44566
|
-
const root = this.deps.mirrorRoot ??
|
|
44567
|
-
const cloneDir = repo.repoDir ??
|
|
44759
|
+
const root = this.deps.mirrorRoot ?? path14.join(os8.tmpdir(), "oasis-git-mirrors");
|
|
44760
|
+
const cloneDir = repo.repoDir ?? path14.join(root, slug3(repo.id));
|
|
44568
44761
|
g2 = new GitRemoteIntegrator(repo.remote, cloneDir, repo.develop);
|
|
44569
44762
|
this.integrators.set(key, g2);
|
|
44570
44763
|
}
|
|
@@ -44605,13 +44798,13 @@ var init_sync = __esm({
|
|
|
44605
44798
|
});
|
|
44606
44799
|
|
|
44607
44800
|
// ../server/src/git/ci-provider.ts
|
|
44608
|
-
var import_node_child_process9,
|
|
44801
|
+
var import_node_child_process9, fs16, path15, import_node_util, execFile, slug4, GhCiProvider;
|
|
44609
44802
|
var init_ci_provider = __esm({
|
|
44610
44803
|
"../server/src/git/ci-provider.ts"() {
|
|
44611
44804
|
"use strict";
|
|
44612
44805
|
import_node_child_process9 = require("node:child_process");
|
|
44613
|
-
|
|
44614
|
-
|
|
44806
|
+
fs16 = __toESM(require("node:fs"), 1);
|
|
44807
|
+
path15 = __toESM(require("node:path"), 1);
|
|
44615
44808
|
import_node_util = require("node:util");
|
|
44616
44809
|
execFile = (0, import_node_util.promisify)(import_node_child_process9.execFile);
|
|
44617
44810
|
slug4 = (id) => id.replace(/[^a-zA-Z0-9_-]+/g, "_");
|
|
@@ -44625,9 +44818,9 @@ var init_ci_provider = __esm({
|
|
|
44625
44818
|
/** 缺则 clone(首次使用/进程重启后本地镜像不存在)——否则 git fetch 会"not a git repo"报错。同 GitRemoteIntegrator。 */
|
|
44626
44819
|
ensureClone(repo) {
|
|
44627
44820
|
const dir = this.repoDir(repo);
|
|
44628
|
-
if (
|
|
44821
|
+
if (fs16.existsSync(path15.join(dir, ".git"))) return;
|
|
44629
44822
|
if (!repo.remote) throw new Error(`repo ${repo.id} \u65E0 remote\uFF0C\u65E0\u6CD5 clone`);
|
|
44630
|
-
|
|
44823
|
+
fs16.mkdirSync(path15.dirname(dir), { recursive: true });
|
|
44631
44824
|
(0, import_node_child_process9.execFileSync)("git", ["clone", "--quiet", repo.remote, dir], { env: process.env });
|
|
44632
44825
|
this.opts.log?.(`[ci] cloned ${repo.id} \u2192 ${dir}`);
|
|
44633
44826
|
}
|
|
@@ -44890,11 +45083,11 @@ var init_resolve = __esm({
|
|
|
44890
45083
|
});
|
|
44891
45084
|
|
|
44892
45085
|
// ../server/src/coordinator/worker.ts
|
|
44893
|
-
var
|
|
45086
|
+
var import_node_crypto22, AUTONOMOUS_ETHOS, CONVERSATIONAL_ETHOS, SHARED_GRAPH_BODY, COORDINATOR_SYSTEM_PROMPT, CONVERSATIONAL_MANAGER_BODY, CoordinatorWorker;
|
|
44894
45087
|
var init_worker = __esm({
|
|
44895
45088
|
"../server/src/coordinator/worker.ts"() {
|
|
44896
45089
|
"use strict";
|
|
44897
|
-
|
|
45090
|
+
import_node_crypto22 = require("node:crypto");
|
|
44898
45091
|
init_src2();
|
|
44899
45092
|
init_identity();
|
|
44900
45093
|
AUTONOMOUS_ETHOS = `\u4F60\u662F\u8FD9\u4E2A\u5DE5\u5355\u7684**\u7BA1\u7406\u8005**\u2014\u2014\u804C\u8D23\u662F\u8BA9\u5B83\u987A\u7545\u8DD1\u5B8C\u3002\u7CFB\u7EDF\u5728\u67D0\u4E2A\u8282\u70B9\u5361\u4F4F\u3001\u673A\u68B0\u5206\u8BCA\u786E\u8BA4"\u9700\u8981\u4F60"\u65F6\u5524\u8D77\u4F60\uFF08\u65E0\u4EBA\u5728\u573A\uFF0C\u4F60\u8FD9\u4E00\u8F6E\u628A\u80FD\u505A\u7684\u505A\u6389\uFF09\u3002\u4F60\u7684\u624B\u6BB5\u5F88\u5BBD\uFF1A
|
|
@@ -45070,7 +45263,7 @@ ${SHARED_GRAPH_BODY}`;
|
|
|
45070
45263
|
return this.deps.kernel.model.lastSeq.get(artifactId) ?? 0;
|
|
45071
45264
|
}
|
|
45072
45265
|
evaluationKey(kind, artifactId, evidence) {
|
|
45073
|
-
const fingerprint = (0,
|
|
45266
|
+
const fingerprint = (0, import_node_crypto22.createHash)("sha256").update(JSON.stringify(evidence)).digest("hex");
|
|
45074
45267
|
return `${kind}:${artifactId}:${fingerprint}`;
|
|
45075
45268
|
}
|
|
45076
45269
|
artifactEvidence(id) {
|
|
@@ -45310,7 +45503,7 @@ ${SHARED_GRAPH_BODY}`;
|
|
|
45310
45503
|
const token = this.deps.tokenFor(actorId, ctx);
|
|
45311
45504
|
const serverUrl = this.deps.serverUrlFor ? await this.deps.serverUrlFor(ctx) : this.deps.serverUrl;
|
|
45312
45505
|
const workspace = this.deps.kernel.model.artifacts.get(artifactId)?.workspace;
|
|
45313
|
-
const runtimeSessionId = opts?.resumeSessionId ?? (0,
|
|
45506
|
+
const runtimeSessionId = opts?.resumeSessionId ?? (0, import_node_crypto22.randomUUID)();
|
|
45314
45507
|
const job = {
|
|
45315
45508
|
actor: actorId,
|
|
45316
45509
|
actorToken: token,
|
|
@@ -45382,7 +45575,7 @@ ${SHARED_GRAPH_BODY}`;
|
|
|
45382
45575
|
async function collectDir(root, dir, out) {
|
|
45383
45576
|
const entries = await (0, import_promises.readdir)(dir, { withFileTypes: true });
|
|
45384
45577
|
for (const e of entries) {
|
|
45385
|
-
const abs = (0,
|
|
45578
|
+
const abs = (0, import_node_path4.join)(dir, e.name);
|
|
45386
45579
|
if (e.isDirectory()) {
|
|
45387
45580
|
await collectDir(root, abs, out);
|
|
45388
45581
|
} else if (e.isFile()) {
|
|
@@ -45391,7 +45584,7 @@ async function collectDir(root, dir, out) {
|
|
|
45391
45584
|
console.warn(`[builtin-skills] skip oversized file (${info.size}B): ${abs}`);
|
|
45392
45585
|
continue;
|
|
45393
45586
|
}
|
|
45394
|
-
const rel = (0,
|
|
45587
|
+
const rel = (0, import_node_path4.relative)(root, abs).split(/[\\/]/).join("/");
|
|
45395
45588
|
out[rel] = await (0, import_promises.readFile)(abs, "utf8");
|
|
45396
45589
|
}
|
|
45397
45590
|
}
|
|
@@ -45407,7 +45600,7 @@ async function loadBuiltinSkills(skillsDir) {
|
|
|
45407
45600
|
for (const d of dirents) {
|
|
45408
45601
|
if (!d.isDirectory()) continue;
|
|
45409
45602
|
const slug6 = d.name;
|
|
45410
|
-
const skillDir = (0,
|
|
45603
|
+
const skillDir = (0, import_node_path4.join)(skillsDir, slug6);
|
|
45411
45604
|
const files = {};
|
|
45412
45605
|
try {
|
|
45413
45606
|
await collectDir(skillDir, skillDir, files);
|
|
@@ -45439,12 +45632,12 @@ function sanitize(name) {
|
|
|
45439
45632
|
const s2 = name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
45440
45633
|
return s2 || "skill";
|
|
45441
45634
|
}
|
|
45442
|
-
var import_promises,
|
|
45635
|
+
var import_promises, import_node_path4, MAX_FILE_BYTES2;
|
|
45443
45636
|
var init_builtin_skills = __esm({
|
|
45444
45637
|
"../server/src/governance/builtin-skills.ts"() {
|
|
45445
45638
|
"use strict";
|
|
45446
45639
|
import_promises = require("node:fs/promises");
|
|
45447
|
-
|
|
45640
|
+
import_node_path4 = require("node:path");
|
|
45448
45641
|
init_skill_fetcher();
|
|
45449
45642
|
MAX_FILE_BYTES2 = 1 << 20;
|
|
45450
45643
|
}
|
|
@@ -47099,15 +47292,15 @@ var require_pg_connection_string = __commonJS({
|
|
|
47099
47292
|
if (config2.sslcert || config2.sslkey || config2.sslrootcert || config2.sslmode) {
|
|
47100
47293
|
config2.ssl = {};
|
|
47101
47294
|
}
|
|
47102
|
-
const
|
|
47295
|
+
const fs21 = config2.sslcert || config2.sslkey || config2.sslrootcert ? require("fs") : null;
|
|
47103
47296
|
if (config2.sslcert) {
|
|
47104
|
-
config2.ssl.cert =
|
|
47297
|
+
config2.ssl.cert = fs21.readFileSync(config2.sslcert).toString();
|
|
47105
47298
|
}
|
|
47106
47299
|
if (config2.sslkey) {
|
|
47107
|
-
config2.ssl.key =
|
|
47300
|
+
config2.ssl.key = fs21.readFileSync(config2.sslkey).toString();
|
|
47108
47301
|
}
|
|
47109
47302
|
if (config2.sslrootcert) {
|
|
47110
|
-
config2.ssl.ca =
|
|
47303
|
+
config2.ssl.ca = fs21.readFileSync(config2.sslrootcert).toString();
|
|
47111
47304
|
}
|
|
47112
47305
|
if (options.useLibpqCompat && config2.uselibpqcompat) {
|
|
47113
47306
|
throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
|
|
@@ -48872,7 +49065,7 @@ var require_split2 = __commonJS({
|
|
|
48872
49065
|
var require_helper = __commonJS({
|
|
48873
49066
|
"../../node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/helper.js"(exports2, module2) {
|
|
48874
49067
|
"use strict";
|
|
48875
|
-
var
|
|
49068
|
+
var path20 = require("path");
|
|
48876
49069
|
var Stream = require("stream").Stream;
|
|
48877
49070
|
var split = require_split2();
|
|
48878
49071
|
var util2 = require("util");
|
|
@@ -48911,7 +49104,7 @@ var require_helper = __commonJS({
|
|
|
48911
49104
|
};
|
|
48912
49105
|
module2.exports.getFileName = function(rawEnv) {
|
|
48913
49106
|
var env = rawEnv || process.env;
|
|
48914
|
-
var file = env.PGPASSFILE || (isWin ?
|
|
49107
|
+
var file = env.PGPASSFILE || (isWin ? path20.join(env.APPDATA || "./", "postgresql", "pgpass.conf") : path20.join(env.HOME || "./", ".pgpass"));
|
|
48915
49108
|
return file;
|
|
48916
49109
|
};
|
|
48917
49110
|
module2.exports.usePgPass = function(stats, fname) {
|
|
@@ -49043,16 +49236,16 @@ var require_helper = __commonJS({
|
|
|
49043
49236
|
var require_lib = __commonJS({
|
|
49044
49237
|
"../../node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/index.js"(exports2, module2) {
|
|
49045
49238
|
"use strict";
|
|
49046
|
-
var
|
|
49047
|
-
var
|
|
49239
|
+
var path20 = require("path");
|
|
49240
|
+
var fs21 = require("fs");
|
|
49048
49241
|
var helper = require_helper();
|
|
49049
49242
|
module2.exports = function(connInfo, cb) {
|
|
49050
49243
|
var file = helper.getFileName();
|
|
49051
|
-
|
|
49244
|
+
fs21.stat(file, function(err, stat3) {
|
|
49052
49245
|
if (err || !helper.usePgPass(stat3, file)) {
|
|
49053
49246
|
return cb(void 0);
|
|
49054
49247
|
}
|
|
49055
|
-
var st =
|
|
49248
|
+
var st = fs21.createReadStream(file);
|
|
49056
49249
|
helper.getPassword(connInfo, st, cb);
|
|
49057
49250
|
});
|
|
49058
49251
|
};
|
|
@@ -50605,38 +50798,38 @@ __export(trajectory_exports, {
|
|
|
50605
50798
|
exportTrajectories: () => exportTrajectories
|
|
50606
50799
|
});
|
|
50607
50800
|
async function exportTrajectories(dataDir) {
|
|
50608
|
-
const root =
|
|
50609
|
-
if (!
|
|
50801
|
+
const root = path16.join(dataDir, "trajectories");
|
|
50802
|
+
if (!fs17.existsSync(root)) return [];
|
|
50610
50803
|
const model = emptyReadModel();
|
|
50611
|
-
const oplogFile =
|
|
50612
|
-
if (
|
|
50804
|
+
const oplogFile = path16.join(dataDir, "oplog.ndjson");
|
|
50805
|
+
if (fs17.existsSync(oplogFile)) {
|
|
50613
50806
|
const oplog = await NdjsonOplogStore.open(oplogFile);
|
|
50614
50807
|
for await (const entry of oplog.readAll()) fold(model, entry.op);
|
|
50615
50808
|
}
|
|
50616
50809
|
const samples = [];
|
|
50617
|
-
for (const sessionId of
|
|
50618
|
-
const dir =
|
|
50619
|
-
const sessionFile =
|
|
50620
|
-
if (!
|
|
50621
|
-
const session = JSON.parse(
|
|
50810
|
+
for (const sessionId of fs17.readdirSync(root).sort()) {
|
|
50811
|
+
const dir = path16.join(root, sessionId);
|
|
50812
|
+
const sessionFile = path16.join(dir, "session.json");
|
|
50813
|
+
if (!fs17.existsSync(sessionFile)) continue;
|
|
50814
|
+
const session = JSON.parse(fs17.readFileSync(sessionFile, "utf8"));
|
|
50622
50815
|
const events = [];
|
|
50623
|
-
const eventsFile =
|
|
50624
|
-
if (
|
|
50625
|
-
for (const line of
|
|
50816
|
+
const eventsFile = path16.join(dir, "events.ndjson");
|
|
50817
|
+
if (fs17.existsSync(eventsFile)) {
|
|
50818
|
+
for (const line of fs17.readFileSync(eventsFile, "utf8").split("\n")) {
|
|
50626
50819
|
if (line.trim()) events.push(JSON.parse(line));
|
|
50627
50820
|
}
|
|
50628
50821
|
}
|
|
50629
50822
|
const bundle = {};
|
|
50630
|
-
const bundleDir =
|
|
50823
|
+
const bundleDir = path16.join(dir, "bundle");
|
|
50631
50824
|
const walk = (sub) => {
|
|
50632
|
-
for (const name of
|
|
50825
|
+
for (const name of fs17.readdirSync(path16.join(bundleDir, sub))) {
|
|
50633
50826
|
const rel = sub ? `${sub}/${name}` : name;
|
|
50634
|
-
const full =
|
|
50635
|
-
if (
|
|
50636
|
-
else bundle[rel] =
|
|
50827
|
+
const full = path16.join(bundleDir, rel);
|
|
50828
|
+
if (fs17.statSync(full).isDirectory()) walk(rel);
|
|
50829
|
+
else bundle[rel] = fs17.readFileSync(full, "utf8");
|
|
50637
50830
|
}
|
|
50638
50831
|
};
|
|
50639
|
-
if (
|
|
50832
|
+
if (fs17.existsSync(bundleDir)) walk("");
|
|
50640
50833
|
const proposed = (session.opRefs ?? []).filter((r) => r.kind === "propose_revision").map((r) => r.target);
|
|
50641
50834
|
const verdicts = proposed.flatMap(
|
|
50642
50835
|
(rev) => (model.reviews.get(rev) ?? []).map((v2) => ({ author: v2.author, verdict: v2.verdict, ...v2.note !== void 0 ? { note: v2.note } : {} }))
|
|
@@ -50648,51 +50841,51 @@ async function exportTrajectories(dataDir) {
|
|
|
50648
50841
|
}
|
|
50649
50842
|
return samples;
|
|
50650
50843
|
}
|
|
50651
|
-
var
|
|
50844
|
+
var fs17, path16, FsTrajectorySink;
|
|
50652
50845
|
var init_trajectory = __esm({
|
|
50653
50846
|
"../cli/src/trajectory.ts"() {
|
|
50654
50847
|
"use strict";
|
|
50655
|
-
|
|
50656
|
-
|
|
50848
|
+
fs17 = __toESM(require("node:fs"), 1);
|
|
50849
|
+
path16 = __toESM(require("node:path"), 1);
|
|
50657
50850
|
init_src2();
|
|
50658
50851
|
init_src5();
|
|
50659
50852
|
FsTrajectorySink = class {
|
|
50660
50853
|
constructor(dataDir, broadcast) {
|
|
50661
50854
|
this.broadcast = broadcast;
|
|
50662
|
-
this.root =
|
|
50855
|
+
this.root = path16.join(dataDir, "trajectories");
|
|
50663
50856
|
}
|
|
50664
50857
|
root;
|
|
50665
50858
|
dir(sessionId) {
|
|
50666
|
-
return
|
|
50859
|
+
return path16.join(this.root, sessionId);
|
|
50667
50860
|
}
|
|
50668
50861
|
begin(session, bundleFiles) {
|
|
50669
50862
|
const dir = this.dir(session.sessionId);
|
|
50670
|
-
|
|
50671
|
-
|
|
50863
|
+
fs17.mkdirSync(path16.join(dir, "bundle"), { recursive: true });
|
|
50864
|
+
fs17.writeFileSync(path16.join(dir, "session.json"), JSON.stringify(session, null, 2));
|
|
50672
50865
|
for (const [rel, content] of Object.entries(bundleFiles)) {
|
|
50673
|
-
const file =
|
|
50674
|
-
|
|
50675
|
-
|
|
50866
|
+
const file = path16.join(dir, "bundle", rel);
|
|
50867
|
+
fs17.mkdirSync(path16.dirname(file), { recursive: true });
|
|
50868
|
+
fs17.writeFileSync(file, content);
|
|
50676
50869
|
}
|
|
50677
50870
|
this.broadcast?.({ type: "begin", sessionId: session.sessionId, data: session });
|
|
50678
50871
|
}
|
|
50679
50872
|
recover(session) {
|
|
50680
|
-
|
|
50681
|
-
const file =
|
|
50682
|
-
if (!
|
|
50873
|
+
fs17.mkdirSync(this.dir(session.sessionId), { recursive: true });
|
|
50874
|
+
const file = path16.join(this.dir(session.sessionId), "session.json");
|
|
50875
|
+
if (!fs17.existsSync(file)) fs17.writeFileSync(file, JSON.stringify(session, null, 2));
|
|
50683
50876
|
this.broadcast?.({ type: "begin", sessionId: session.sessionId, data: { ...session, recovered: true } });
|
|
50684
50877
|
}
|
|
50685
50878
|
event(sessionId, event) {
|
|
50686
|
-
|
|
50687
|
-
|
|
50879
|
+
fs17.mkdirSync(this.dir(sessionId), { recursive: true });
|
|
50880
|
+
fs17.appendFileSync(path16.join(this.dir(sessionId), "events.ndjson"), JSON.stringify(event) + "\n");
|
|
50688
50881
|
this.broadcast?.({ type: "event", sessionId, data: event });
|
|
50689
50882
|
}
|
|
50690
50883
|
end(sessionId, update) {
|
|
50691
|
-
const file =
|
|
50692
|
-
const session = JSON.parse(
|
|
50884
|
+
const file = path16.join(this.dir(sessionId), "session.json");
|
|
50885
|
+
const session = JSON.parse(fs17.readFileSync(file, "utf8"));
|
|
50693
50886
|
session.exit = update.exit;
|
|
50694
50887
|
session.opRefs = update.opRefs;
|
|
50695
|
-
|
|
50888
|
+
fs17.writeFileSync(file, JSON.stringify(session, null, 2));
|
|
50696
50889
|
this.broadcast?.({ type: "end", sessionId, data: session });
|
|
50697
50890
|
}
|
|
50698
50891
|
};
|
|
@@ -50700,30 +50893,30 @@ var init_trajectory = __esm({
|
|
|
50700
50893
|
});
|
|
50701
50894
|
|
|
50702
50895
|
// src/index.ts
|
|
50703
|
-
var
|
|
50704
|
-
var
|
|
50705
|
-
var
|
|
50896
|
+
var fs20 = __toESM(require("node:fs"));
|
|
50897
|
+
var os11 = __toESM(require("node:os"));
|
|
50898
|
+
var path19 = __toESM(require("node:path"));
|
|
50706
50899
|
var import_node_child_process15 = require("node:child_process");
|
|
50707
50900
|
|
|
50708
50901
|
// ../cli/src/cli.ts
|
|
50902
|
+
var fs19 = __toESM(require("node:fs"), 1);
|
|
50903
|
+
var os10 = __toESM(require("node:os"), 1);
|
|
50904
|
+
var path18 = __toESM(require("node:path"), 1);
|
|
50905
|
+
var import_node_crypto27 = require("node:crypto");
|
|
50906
|
+
|
|
50907
|
+
// ../cli/src/serve.ts
|
|
50709
50908
|
var fs18 = __toESM(require("node:fs"), 1);
|
|
50710
50909
|
var os9 = __toESM(require("node:os"), 1);
|
|
50711
50910
|
var path17 = __toESM(require("node:path"), 1);
|
|
50712
|
-
var
|
|
50713
|
-
|
|
50714
|
-
// ../cli/src/serve.ts
|
|
50715
|
-
var fs17 = __toESM(require("node:fs"), 1);
|
|
50716
|
-
var os8 = __toESM(require("node:os"), 1);
|
|
50717
|
-
var path16 = __toESM(require("node:path"), 1);
|
|
50718
|
-
var import_node_crypto24 = require("node:crypto");
|
|
50719
|
-
var import_node_url3 = require("node:url");
|
|
50911
|
+
var import_node_crypto25 = require("node:crypto");
|
|
50912
|
+
var import_node_url4 = require("node:url");
|
|
50720
50913
|
init_src2();
|
|
50721
50914
|
init_src5();
|
|
50722
50915
|
|
|
50723
50916
|
// ../connectors/src/_base/stage.ts
|
|
50724
|
-
var
|
|
50917
|
+
var import_node_fs5 = require("node:fs");
|
|
50725
50918
|
var import_node_os2 = require("node:os");
|
|
50726
|
-
var
|
|
50919
|
+
var import_node_path5 = require("node:path");
|
|
50727
50920
|
var stagedBinDirs = /* @__PURE__ */ new Map();
|
|
50728
50921
|
function stageConnectorWrapper(connector) {
|
|
50729
50922
|
const scriptPath = connector.wrapperScriptPath();
|
|
@@ -50734,10 +50927,10 @@ function stageConnectorWrapper(connector) {
|
|
|
50734
50927
|
}
|
|
50735
50928
|
const cacheKey = `${commandName}\0${scriptPath}`;
|
|
50736
50929
|
const cached2 = stagedBinDirs.get(cacheKey);
|
|
50737
|
-
if (cached2 && (0,
|
|
50738
|
-
const binDir = (0,
|
|
50739
|
-
const link = (0,
|
|
50740
|
-
(0,
|
|
50930
|
+
if (cached2 && (0, import_node_fs5.existsSync)((0, import_node_path5.join)(cached2, commandName))) return (0, import_node_path5.join)(cached2, commandName);
|
|
50931
|
+
const binDir = (0, import_node_fs5.mkdtempSync)((0, import_node_path5.join)((0, import_node_os2.tmpdir)(), `oasis-conn-${connector.config.slug}-`));
|
|
50932
|
+
const link = (0, import_node_path5.join)(binDir, commandName);
|
|
50933
|
+
(0, import_node_fs5.symlinkSync)(scriptPath, link);
|
|
50741
50934
|
stagedBinDirs.set(cacheKey, binDir);
|
|
50742
50935
|
return link;
|
|
50743
50936
|
}
|
|
@@ -50831,7 +51024,7 @@ async function ensureConnectorTools(tools, deps = {}) {
|
|
|
50831
51024
|
// ../connectors/src/_base/cli-connector.ts
|
|
50832
51025
|
var import_node_child_process11 = require("node:child_process");
|
|
50833
51026
|
var import_node_util3 = require("node:util");
|
|
50834
|
-
var
|
|
51027
|
+
var import_node_path6 = require("node:path");
|
|
50835
51028
|
var execFile3 = (0, import_node_util3.promisify)(import_node_child_process11.execFile);
|
|
50836
51029
|
var CliConnector = class {
|
|
50837
51030
|
constructor(wrapperDir) {
|
|
@@ -50843,7 +51036,7 @@ var CliConnector = class {
|
|
|
50843
51036
|
* The wrapper is a bash script that shadows the real CLI on PATH.
|
|
50844
51037
|
*/
|
|
50845
51038
|
wrapperScriptPath() {
|
|
50846
|
-
return (0,
|
|
51039
|
+
return (0, import_node_path6.join)(this.wrapperDir, "wrapper.sh");
|
|
50847
51040
|
}
|
|
50848
51041
|
/**
|
|
50849
51042
|
* Resolve the absolute path to a CLI binary using `which`.
|
|
@@ -50878,15 +51071,15 @@ var CliConnector = class {
|
|
|
50878
51071
|
// ../connectors/src/feishu/index.ts
|
|
50879
51072
|
var import_node_child_process12 = require("node:child_process");
|
|
50880
51073
|
var import_node_util4 = require("node:util");
|
|
50881
|
-
var
|
|
50882
|
-
var
|
|
51074
|
+
var import_node_path7 = require("node:path");
|
|
51075
|
+
var import_node_url2 = require("node:url");
|
|
50883
51076
|
var import_promises2 = require("node:fs/promises");
|
|
50884
51077
|
var import_node_os3 = require("node:os");
|
|
50885
51078
|
function shSingleQuote(v2) {
|
|
50886
51079
|
return `'${v2.replace(/'/g, `'\\''`)}'`;
|
|
50887
51080
|
}
|
|
50888
51081
|
var execFileAsync2 = (0, import_node_util4.promisify)(import_node_child_process12.execFile);
|
|
50889
|
-
var __dirname = (0,
|
|
51082
|
+
var __dirname = (0, import_node_path7.dirname)((0, import_node_url2.fileURLToPath)(__esm_import_meta_url));
|
|
50890
51083
|
var FeishuConnector = class extends CliConnector {
|
|
50891
51084
|
config = {
|
|
50892
51085
|
slug: "feishu",
|
|
@@ -50926,8 +51119,8 @@ var FeishuConnector = class extends CliConnector {
|
|
|
50926
51119
|
if (!appId) throw new Error("feishu inject: missing app_id");
|
|
50927
51120
|
if (!appSecret) throw new Error("feishu inject: missing app_secret");
|
|
50928
51121
|
const userAccessToken = credentials["user_access_token"] ?? credentials["FEISHU_USER_ACCESS_TOKEN"];
|
|
50929
|
-
const dir = await (0, import_promises2.mkdtemp)((0,
|
|
50930
|
-
const credsFile = (0,
|
|
51122
|
+
const dir = await (0, import_promises2.mkdtemp)((0, import_node_path7.join)((0, import_node_os3.tmpdir)(), "oasis-feishu-"));
|
|
51123
|
+
const credsFile = (0, import_node_path7.join)(dir, "creds.env");
|
|
50931
51124
|
const lines = [
|
|
50932
51125
|
`export LARKSUITE_CLI_APP_ID=${shSingleQuote(appId)}`,
|
|
50933
51126
|
`export LARKSUITE_CLI_APP_SECRET=${shSingleQuote(appSecret)}`
|
|
@@ -50982,11 +51175,11 @@ var FeishuConnector = class extends CliConnector {
|
|
|
50982
51175
|
};
|
|
50983
51176
|
|
|
50984
51177
|
// ../connectors/src/github/index.ts
|
|
50985
|
-
var
|
|
50986
|
-
var
|
|
51178
|
+
var import_node_path8 = require("node:path");
|
|
51179
|
+
var import_node_url3 = require("node:url");
|
|
50987
51180
|
var import_promises3 = require("node:fs/promises");
|
|
50988
51181
|
var import_node_os4 = require("node:os");
|
|
50989
|
-
var __dirname2 = (0,
|
|
51182
|
+
var __dirname2 = (0, import_node_path8.dirname)((0, import_node_url3.fileURLToPath)(__esm_import_meta_url));
|
|
50990
51183
|
function shSingleQuote2(v2) {
|
|
50991
51184
|
return `'${v2.replace(/'/g, `'\\''`)}'`;
|
|
50992
51185
|
}
|
|
@@ -51024,8 +51217,8 @@ var GithubConnector = class extends CliConnector {
|
|
|
51024
51217
|
const token = credentials["access_token"];
|
|
51025
51218
|
if (!token) throw new Error("github inject: missing access_token");
|
|
51026
51219
|
const name = credentials["actor_name"] ?? "oasis-agent";
|
|
51027
|
-
const dir = await (0, import_promises3.mkdtemp)((0,
|
|
51028
|
-
const credsFile = (0,
|
|
51220
|
+
const dir = await (0, import_promises3.mkdtemp)((0, import_node_path8.join)((0, import_node_os4.tmpdir)(), "oasis-github-"));
|
|
51221
|
+
const credsFile = (0, import_node_path8.join)(dir, "creds.env");
|
|
51029
51222
|
await (0, import_promises3.writeFile)(
|
|
51030
51223
|
credsFile,
|
|
51031
51224
|
`export GH_TOKEN=${shSingleQuote2(token)}
|
|
@@ -51065,7 +51258,7 @@ export GITHUB_TOKEN=${shSingleQuote2(token)}
|
|
|
51065
51258
|
// ../connectors/src/connector-adapter.ts
|
|
51066
51259
|
var import_promises4 = require("node:fs/promises");
|
|
51067
51260
|
var import_node_os5 = require("node:os");
|
|
51068
|
-
var
|
|
51261
|
+
var import_node_path9 = require("node:path");
|
|
51069
51262
|
init_src4();
|
|
51070
51263
|
|
|
51071
51264
|
// ../connectors/src/logger.ts
|
|
@@ -51095,11 +51288,11 @@ var ConnectorAwareAdapter = class {
|
|
|
51095
51288
|
);
|
|
51096
51289
|
let extraEnv = { ...strippedEnv };
|
|
51097
51290
|
if (wrapperPaths.length > 0) {
|
|
51098
|
-
const wrapperBinDir = await (0, import_promises4.mkdtemp)((0,
|
|
51291
|
+
const wrapperBinDir = await (0, import_promises4.mkdtemp)((0, import_node_path9.join)((0, import_node_os5.tmpdir)(), "oasis-wrappers-"));
|
|
51099
51292
|
await (0, import_promises4.mkdir)(wrapperBinDir, { recursive: true });
|
|
51100
51293
|
for (const wp of wrapperPaths) {
|
|
51101
|
-
const linkName = (0,
|
|
51102
|
-
await (0, import_promises4.symlink)(wp, (0,
|
|
51294
|
+
const linkName = (0, import_node_path9.basename)(wp).replace(/\.sh$/, "");
|
|
51295
|
+
await (0, import_promises4.symlink)(wp, (0, import_node_path9.join)(wrapperBinDir, linkName));
|
|
51103
51296
|
}
|
|
51104
51297
|
extraEnv = { ...extraEnv, PATH: `${wrapperBinDir}:${process.env["PATH"] ?? ""}` };
|
|
51105
51298
|
log("[adapter]", ` connectors injected +${Date.now() - t0}ms wrappers=${wrapperPaths.length} env_keys=${Object.keys(job.env ?? {}).join(",")}`);
|
|
@@ -51632,7 +51825,7 @@ function defaultDocumentPath2(input) {
|
|
|
51632
51825
|
init_src4();
|
|
51633
51826
|
|
|
51634
51827
|
// ../storage/src/postgres.ts
|
|
51635
|
-
var
|
|
51828
|
+
var import_node_crypto23 = require("node:crypto");
|
|
51636
51829
|
|
|
51637
51830
|
// ../../node_modules/.pnpm/pg@8.21.0/node_modules/pg/esm/index.mjs
|
|
51638
51831
|
var import_lib = __toESM(require_lib2(), 1);
|
|
@@ -51767,7 +51960,7 @@ var PostgresBlobStore = class _PostgresBlobStore {
|
|
|
51767
51960
|
return new _PostgresBlobStore(pool, schema);
|
|
51768
51961
|
}
|
|
51769
51962
|
async put(bytes) {
|
|
51770
|
-
const hash = (0,
|
|
51963
|
+
const hash = (0, import_node_crypto23.createHash)("sha256").update(bytes).digest("hex");
|
|
51771
51964
|
await this.pool.query(
|
|
51772
51965
|
`INSERT INTO ${this.t} (hash, bytes, size, content_type) VALUES ($1, $2, $3, $4) ON CONFLICT (hash) DO NOTHING`,
|
|
51773
51966
|
[hash, Buffer.from(bytes), bytes.byteLength, sniffContentType(bytes) ?? null]
|
|
@@ -54760,7 +54953,7 @@ var rowToMessage = (row) => ({
|
|
|
54760
54953
|
});
|
|
54761
54954
|
|
|
54762
54955
|
// ../storage/src/postgres-nodes.ts
|
|
54763
|
-
var
|
|
54956
|
+
var import_node_crypto24 = require("node:crypto");
|
|
54764
54957
|
var ident8 = (s2) => {
|
|
54765
54958
|
if (!/^[a-z_][a-z0-9_]*$/.test(s2)) throw new Error(`invalid schema name: ${s2}`);
|
|
54766
54959
|
return s2;
|
|
@@ -54898,7 +55091,7 @@ var PostgresNodeTokenStore = class _PostgresNodeTokenStore {
|
|
|
54898
55091
|
return store;
|
|
54899
55092
|
}
|
|
54900
55093
|
issue(nodeId) {
|
|
54901
|
-
const token = `ont_${(0,
|
|
55094
|
+
const token = `ont_${(0, import_node_crypto24.randomBytes)(24).toString("base64url")}`;
|
|
54902
55095
|
this.cache.set(token, nodeId);
|
|
54903
55096
|
void this.pool.query(`INSERT INTO ${this.s}.node_tokens (token,node_id) VALUES ($1,$2)`, [token, nodeId]);
|
|
54904
55097
|
return token;
|
|
@@ -54940,8 +55133,8 @@ init_trajectory();
|
|
|
54940
55133
|
function builtinSkillsDir() {
|
|
54941
55134
|
const override = process.env["OASIS_BUILTIN_SKILLS_DIR"]?.trim();
|
|
54942
55135
|
if (override) return override;
|
|
54943
|
-
const repoRoot = (0,
|
|
54944
|
-
return
|
|
55136
|
+
const repoRoot = (0, import_node_url4.fileURLToPath)(new URL("../../../", __esm_import_meta_url));
|
|
55137
|
+
return path17.join(repoRoot, "skills");
|
|
54945
55138
|
}
|
|
54946
55139
|
function materializeBuiltins(builtins, runtimeKind) {
|
|
54947
55140
|
if (builtins.length === 0) return {};
|
|
@@ -54973,16 +55166,16 @@ function apiUrlFromGatewayUrl(raw) {
|
|
|
54973
55166
|
}
|
|
54974
55167
|
var oasisWrapperCache;
|
|
54975
55168
|
function oasisWrapperScript() {
|
|
54976
|
-
if (oasisWrapperCache &&
|
|
54977
|
-
const repoRoot = (0,
|
|
54978
|
-
const tsx =
|
|
54979
|
-
const main =
|
|
54980
|
-
const dir =
|
|
54981
|
-
const wrapper =
|
|
54982
|
-
|
|
55169
|
+
if (oasisWrapperCache && fs18.existsSync(oasisWrapperCache)) return oasisWrapperCache;
|
|
55170
|
+
const repoRoot = (0, import_node_url4.fileURLToPath)(new URL("../../../", __esm_import_meta_url));
|
|
55171
|
+
const tsx = path17.join(repoRoot, "node_modules/.bin/tsx");
|
|
55172
|
+
const main = path17.join(repoRoot, "packages/cli/src/main.ts");
|
|
55173
|
+
const dir = fs18.mkdtempSync(path17.join(os9.tmpdir(), "oasis-cli-"));
|
|
55174
|
+
const wrapper = path17.join(dir, "oasis");
|
|
55175
|
+
fs18.writeFileSync(wrapper, `#!/usr/bin/env bash
|
|
54983
55176
|
exec ${JSON.stringify(tsx)} ${JSON.stringify(main)} "$@"
|
|
54984
55177
|
`);
|
|
54985
|
-
|
|
55178
|
+
fs18.chmodSync(wrapper, 493);
|
|
54986
55179
|
oasisWrapperCache = wrapper;
|
|
54987
55180
|
return wrapper;
|
|
54988
55181
|
}
|
|
@@ -55069,26 +55262,26 @@ function traceRuntimeKind(runtimeKind) {
|
|
|
55069
55262
|
}
|
|
55070
55263
|
async function startServe(opts) {
|
|
55071
55264
|
const serverStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55072
|
-
|
|
55073
|
-
const serverHeartbeatFile =
|
|
55265
|
+
fs18.mkdirSync(opts.dir, { recursive: true });
|
|
55266
|
+
const serverHeartbeatFile = path17.join(opts.dir, "serve-heartbeat.json");
|
|
55074
55267
|
let previousServerHeartbeatAt;
|
|
55075
|
-
if (
|
|
55268
|
+
if (fs18.existsSync(serverHeartbeatFile)) {
|
|
55076
55269
|
try {
|
|
55077
|
-
const raw = JSON.parse(
|
|
55270
|
+
const raw = JSON.parse(fs18.readFileSync(serverHeartbeatFile, "utf8"));
|
|
55078
55271
|
if (raw.at && Number.isFinite(Date.parse(raw.at))) previousServerHeartbeatAt = raw.at;
|
|
55079
55272
|
} catch {
|
|
55080
55273
|
}
|
|
55081
55274
|
}
|
|
55082
55275
|
const writeServerHeartbeat = () => {
|
|
55083
|
-
|
|
55276
|
+
fs18.writeFile(serverHeartbeatFile, JSON.stringify({ at: (/* @__PURE__ */ new Date()).toISOString(), pid: process.pid }) + "\n", () => {
|
|
55084
55277
|
});
|
|
55085
55278
|
};
|
|
55086
55279
|
writeServerHeartbeat();
|
|
55087
55280
|
const serverHeartbeatTimer = setInterval(writeServerHeartbeat, 5e3);
|
|
55088
55281
|
serverHeartbeatTimer.unref?.();
|
|
55089
|
-
const lock =
|
|
55090
|
-
if (
|
|
55091
|
-
const pid = Number(
|
|
55282
|
+
const lock = path17.join(opts.dir, "serve.lock");
|
|
55283
|
+
if (fs18.existsSync(lock)) {
|
|
55284
|
+
const pid = Number(fs18.readFileSync(lock, "utf8"));
|
|
55092
55285
|
let alive = false;
|
|
55093
55286
|
try {
|
|
55094
55287
|
process.kill(pid, 0);
|
|
@@ -55096,19 +55289,19 @@ async function startServe(opts) {
|
|
|
55096
55289
|
} catch {
|
|
55097
55290
|
}
|
|
55098
55291
|
if (alive) throw new Error(`\u8BE5\u6570\u636E\u76EE\u5F55\u5DF2\u6709 serve \u5728\u8DD1\uFF08pid=${pid}\uFF09\u2014\u2014\u5355\u5199\u8005\u8FDB\u7A0B\uFF0C\u4E0D\u80FD\u53CC\u5F00`);
|
|
55099
|
-
|
|
55292
|
+
fs18.unlinkSync(lock);
|
|
55100
55293
|
}
|
|
55101
|
-
|
|
55294
|
+
fs18.writeFileSync(lock, String(process.pid));
|
|
55102
55295
|
const loadJson = (name) => {
|
|
55103
|
-
const file =
|
|
55104
|
-
return
|
|
55296
|
+
const file = path17.join(opts.dir, name);
|
|
55297
|
+
return fs18.existsSync(file) ? JSON.parse(fs18.readFileSync(file, "utf8")) : void 0;
|
|
55105
55298
|
};
|
|
55106
55299
|
const pgDsn = process.env["OASIS_PG_DSN"] ?? process.env["DATABASE_URL"];
|
|
55107
55300
|
const pgSchema = process.env["OASIS_PG_SCHEMA"] ?? "public";
|
|
55108
55301
|
const pgPool = pgDsn ? createPgPool(pgDsn) : void 0;
|
|
55109
|
-
const oplog = pgDsn && pgPool ? await PostgresOplogStore.open(pgPool, pgSchema) : await NdjsonOplogStore.open(
|
|
55110
|
-
const blobs = pgDsn && pgPool ? await PostgresBlobStore.open(pgPool, pgSchema) : new DirBlobStore(
|
|
55111
|
-
const assets = new DirBlobStore(
|
|
55302
|
+
const oplog = pgDsn && pgPool ? await PostgresOplogStore.open(pgPool, pgSchema) : await NdjsonOplogStore.open(path17.join(opts.dir, "oplog.ndjson"));
|
|
55303
|
+
const blobs = pgDsn && pgPool ? await PostgresBlobStore.open(pgPool, pgSchema) : new DirBlobStore(path17.join(opts.dir, "blobs"));
|
|
55304
|
+
const assets = new DirBlobStore(path17.join(opts.dir, "assets"));
|
|
55112
55305
|
const defaultRootSchema = [
|
|
55113
55306
|
{ name: "brief", description: "\u5DE5\u5355\u603B\u7EB2\uFF1A\u53D1\u8D77\u65B9\u5BF9\u9F50\u7684\u603B\u76EE\u6807\u4E0E\u8303\u56F4\uFF0C\u6574\u5F20\u534F\u4F5C\u56FE\u7684\u6839\u3002", contentType: "text", ownerRole: "founder" },
|
|
55114
55307
|
{
|
|
@@ -55126,7 +55319,7 @@ async function startServe(opts) {
|
|
|
55126
55319
|
if (!schema.some((d) => d.name === "document")) {
|
|
55127
55320
|
schema.push({ name: "document", description: "\u901A\u7528\u6587\u6863\uFF1A\u672A\u7EC6\u5206\u7684\u6587\u5B57\u4EA7\u7269\uFF08\u5177\u4F53\u7C7B\u578B\u89C1 docType\uFF09\u3002", contentType: "text", ownerRole: "writer" });
|
|
55128
55321
|
}
|
|
55129
|
-
const typeStore = await FileTypeRegistryStore.open(
|
|
55322
|
+
const typeStore = await FileTypeRegistryStore.open(path17.join(opts.dir, "type-registry.json"));
|
|
55130
55323
|
if ((await typeStore.list()).length === 0) for (const d of schema) await typeStore.put(d);
|
|
55131
55324
|
{
|
|
55132
55325
|
const live = await typeStore.list();
|
|
@@ -55134,7 +55327,7 @@ async function startServe(opts) {
|
|
|
55134
55327
|
schema.length = 0;
|
|
55135
55328
|
schema.push(...live);
|
|
55136
55329
|
}
|
|
55137
|
-
const registryStore = pgDsn && pgPool ? await PostgresRegistryStore.open(pgPool, pgSchema) : await FileRegistryStore.open(
|
|
55330
|
+
const registryStore = pgDsn && pgPool ? await PostgresRegistryStore.open(pgPool, pgSchema) : await FileRegistryStore.open(path17.join(opts.dir, "registry-store.json"));
|
|
55138
55331
|
try {
|
|
55139
55332
|
await backfillSkillContentFromAssets(registryStore, assets);
|
|
55140
55333
|
} catch (err) {
|
|
@@ -55158,17 +55351,17 @@ async function startServe(opts) {
|
|
|
55158
55351
|
// per-contentType merge facet(§5.6):text=expensive→group-commit、code/structured=cheap→顺序 rebase
|
|
55159
55352
|
handlers: defaultHandlersByContentType()
|
|
55160
55353
|
});
|
|
55161
|
-
const issuer = createTokenIssuer({ secretFile:
|
|
55162
|
-
const operatorActor = `actor:human:${
|
|
55354
|
+
const issuer = createTokenIssuer({ secretFile: path17.join(opts.dir, "session-token-secret") });
|
|
55355
|
+
const operatorActor = `actor:human:${os9.userInfo().username}`;
|
|
55163
55356
|
const operatorToken = issuer.issue(operatorActor);
|
|
55164
|
-
|
|
55165
|
-
let nodeTokens = createNodeTokenStore(
|
|
55166
|
-
const enrollTokens = createEnrollTokenStore(30 * 60 * 1e3,
|
|
55167
|
-
let nodeStore = await FileNodeStore.open(
|
|
55168
|
-
const registryAuditFile =
|
|
55357
|
+
fs18.writeFileSync(path17.join(opts.dir, "operator-token"), operatorToken, { mode: 384 });
|
|
55358
|
+
let nodeTokens = createNodeTokenStore(path17.join(opts.dir, "node-tokens.json"));
|
|
55359
|
+
const enrollTokens = createEnrollTokenStore(30 * 60 * 1e3, path17.join(opts.dir, "enroll-tokens.json"));
|
|
55360
|
+
let nodeStore = await FileNodeStore.open(path17.join(opts.dir, "nodes.json"));
|
|
55361
|
+
const registryAuditFile = path17.join(opts.dir, "registry-audit.ndjson");
|
|
55169
55362
|
const registryListeners = /* @__PURE__ */ new Set();
|
|
55170
55363
|
const registryAudit = (record5) => {
|
|
55171
|
-
|
|
55364
|
+
fs18.appendFile(registryAuditFile, JSON.stringify(record5) + "\n", () => {
|
|
55172
55365
|
});
|
|
55173
55366
|
for (const l of registryListeners) l({ kind: record5.kind, actor: record5.actor, target: record5.target, timestamp: record5.timestamp });
|
|
55174
55367
|
};
|
|
@@ -55205,9 +55398,9 @@ async function startServe(opts) {
|
|
|
55205
55398
|
nodeTokens = await PostgresNodeTokenStore.open(pgPool, pgSchema);
|
|
55206
55399
|
console.log(`[serve] \u4E8B\u5B9E/\u72B6\u6001\u4F53\u7CFB\uFF1APostgres schema=${pgSchema}\uFF08oplog / registry / blobs / artifacts / chat\uFF09`);
|
|
55207
55400
|
} else {
|
|
55208
|
-
projectStateStore = await FileProjectStateStore.open(
|
|
55209
|
-
artifactStateStore = await FileArtifactStateStore.open(
|
|
55210
|
-
chatSessionStore = await FileChatSessionStore.open(
|
|
55401
|
+
projectStateStore = await FileProjectStateStore.open(path17.join(opts.dir, "artifact-document-projects.json"));
|
|
55402
|
+
artifactStateStore = await FileArtifactStateStore.open(path17.join(opts.dir, "artifact-document-state.json"));
|
|
55403
|
+
chatSessionStore = await FileChatSessionStore.open(path17.join(opts.dir, "chat-sessions.json"));
|
|
55211
55404
|
console.log("[serve] \u4EA4\u4ED8\u7269\u72B6\u6001\u4F53\u7CFB\uFF1A\u672C\u5730 JSON dev store");
|
|
55212
55405
|
console.log("[serve] \u8282\u70B9/\u8FD0\u884C\u65F6\u4F53\u7CFB\uFF1A\u672C\u5730 JSON dev store");
|
|
55213
55406
|
}
|
|
@@ -55226,7 +55419,7 @@ async function startServe(opts) {
|
|
|
55226
55419
|
});
|
|
55227
55420
|
console.log(`[serve] \u9879\u76EE\u6587\u6863\u4F53\u7CFB\uFF1AOutline ${outlineUrl}\uFF08\u6302\u5728 Team Workspace\u300C\u9879\u76EE\u300D\u4E0B\uFF09`);
|
|
55228
55421
|
} else {
|
|
55229
|
-
projectDocumentStore = await FileProjectDocumentStore.open(
|
|
55422
|
+
projectDocumentStore = await FileProjectDocumentStore.open(path17.join(opts.dir, "project-document-spaces.json"));
|
|
55230
55423
|
console.log("[serve] \u9879\u76EE\u6587\u6863\u4F53\u7CFB\uFF1A\u672C\u5730\u5185\u5B58/\u6587\u4EF6 dev store");
|
|
55231
55424
|
}
|
|
55232
55425
|
const registryActorNames = /* @__PURE__ */ new Map();
|
|
@@ -55260,7 +55453,7 @@ async function startServe(opts) {
|
|
|
55260
55453
|
traceStore = await PostgresTraceStore.open(tracePool, pgSchema);
|
|
55261
55454
|
console.log(`[serve] \u8FD0\u884C\u8F68\u8FF9\u4F53\u7CFB\uFF1APostgres schema=${pgSchema}${traceDsn === pgDsn ? "" : "\uFF08\u72EC\u7ACB trace \u5E93\uFF09"}`);
|
|
55262
55455
|
} else {
|
|
55263
|
-
traceStore = await FileTraceStore.open(
|
|
55456
|
+
traceStore = await FileTraceStore.open(path17.join(opts.dir, "trace"));
|
|
55264
55457
|
console.log("[serve] \u8FD0\u884C\u8F68\u8FF9\u4F53\u7CFB\uFF1A\u672C\u5730 ndjson dev store");
|
|
55265
55458
|
}
|
|
55266
55459
|
traceStoreForActors = traceStore;
|
|
@@ -55280,7 +55473,7 @@ async function startServe(opts) {
|
|
|
55280
55473
|
create: createSeededWorkorder,
|
|
55281
55474
|
projectExists: async (id) => Boolean(await projectStateStore.getProject(id))
|
|
55282
55475
|
});
|
|
55283
|
-
const controlPlaneStore = pgDsn && pgPool ? await PostgresControlPlaneStore.open(pgPool, pgSchema) : await FileControlPlaneStore.open(
|
|
55476
|
+
const controlPlaneStore = pgDsn && pgPool ? await PostgresControlPlaneStore.open(pgPool, pgSchema) : await FileControlPlaneStore.open(path17.join(opts.dir, "control-plane.json"));
|
|
55284
55477
|
const resendKey = process.env["RESEND_API_KEY"];
|
|
55285
55478
|
const mailFrom = process.env["RESEND_FROM_EMAIL"] ?? process.env["OASIS_MAIL_FROM"] ?? "noreply@open-friday.com";
|
|
55286
55479
|
if (!resendKey) console.warn("[serve] RESEND_API_KEY \u672A\u8BBE\u2014\u2014\u9A8C\u8BC1\u7801/\u9080\u8BF7\u6253\u5370\u5230\u65E5\u5FD7\uFF08dev\uFF09\uFF1B\u751F\u4EA7\u8BF7\u914D RESEND_API_KEY + RESEND_FROM_EMAIL\uFF08Resend \u5DF2\u9A8C\u8BC1\u57DF\u540D\uFF09");
|
|
@@ -55350,12 +55543,12 @@ async function startServe(opts) {
|
|
|
55350
55543
|
}
|
|
55351
55544
|
return auth.sessionAccountId(headers);
|
|
55352
55545
|
};
|
|
55353
|
-
const workorderDrafts = new WorkorderDraftStore(
|
|
55354
|
-
const journalFile =
|
|
55546
|
+
const workorderDrafts = new WorkorderDraftStore(path17.join(opts.dir, "workorder-drafts.json"));
|
|
55547
|
+
const journalFile = path17.join(opts.dir, "dispatch-journal.ndjson");
|
|
55355
55548
|
const journalRing = [];
|
|
55356
|
-
if (
|
|
55549
|
+
if (fs18.existsSync(journalFile)) {
|
|
55357
55550
|
try {
|
|
55358
|
-
const lines =
|
|
55551
|
+
const lines = fs18.readFileSync(journalFile, "utf8").split(/\r?\n/).filter(Boolean);
|
|
55359
55552
|
for (const line of lines.slice(-500)) {
|
|
55360
55553
|
try {
|
|
55361
55554
|
journalRing.push(JSON.parse(line));
|
|
@@ -55368,7 +55561,7 @@ async function startServe(opts) {
|
|
|
55368
55561
|
const journal = (entry) => {
|
|
55369
55562
|
journalRing.push(entry);
|
|
55370
55563
|
if (journalRing.length > 500) journalRing.shift();
|
|
55371
|
-
|
|
55564
|
+
fs18.appendFile(journalFile, JSON.stringify(entry) + "\n", () => {
|
|
55372
55565
|
});
|
|
55373
55566
|
};
|
|
55374
55567
|
const closeOrphanedDispatches = () => {
|
|
@@ -55395,7 +55588,7 @@ async function startServe(opts) {
|
|
|
55395
55588
|
defaultEngine: { kernel, oplog, blobs, registry: registryStore, assets },
|
|
55396
55589
|
defaultCompanyId,
|
|
55397
55590
|
buildEngine: async (companyId) => {
|
|
55398
|
-
const engine2 = await openFileEngine(
|
|
55591
|
+
const engine2 = await openFileEngine(path17.join(opts.dir, "companies", companyEngineDirName(companyId)), { schema });
|
|
55399
55592
|
await ensureCompanyActors(controlPlaneStore, companyId, engine2.registry);
|
|
55400
55593
|
await syncRegistryRolesToKernel(engine2.registry, engine2.kernel);
|
|
55401
55594
|
return engine2;
|
|
@@ -55512,7 +55705,7 @@ async function startServe(opts) {
|
|
|
55512
55705
|
return {};
|
|
55513
55706
|
}));
|
|
55514
55707
|
const limits = { wallClockMs: SESSION_WALL_CLOCK_MS.planner };
|
|
55515
|
-
const artifactId = `artifact:planner:${(0,
|
|
55708
|
+
const artifactId = `artifact:planner:${(0, import_node_crypto25.randomUUID)()}`;
|
|
55516
55709
|
const handle = await chatRemoteAdapter.spawn({
|
|
55517
55710
|
actor: planner.id,
|
|
55518
55711
|
actorToken: issueSessionToken(planner.id, { artifactId, action: "plan-workorder", limits, binding }),
|
|
@@ -55620,7 +55813,7 @@ async function startServe(opts) {
|
|
|
55620
55813
|
},
|
|
55621
55814
|
retainedSession: (key) => key.annotationId && key.artifactId ? allDispatchers().map((d) => d.retainedProduceSessionFor(key.artifactId)).find(Boolean) : coordinatorRef?.retainedSessionFor(key),
|
|
55622
55815
|
// 0030 D3/D7 落盘:discuss 按项表写文件,serve 重启后同一卡点续同一段、不再新开。
|
|
55623
|
-
discussSessions: new FileSideMap(
|
|
55816
|
+
discussSessions: new FileSideMap(path17.join(opts.dir, "discuss-sessions.json")),
|
|
55624
55817
|
dispatchChat: async ({ actorId, message, sessionId, chatSessionId, attachments, workspace, companyId }) => {
|
|
55625
55818
|
const runCompanyId = companyId ?? defaultCompanyId;
|
|
55626
55819
|
const actorCtxForCompany = await actors.resolveCtx(runCompanyId);
|
|
@@ -55642,10 +55835,10 @@ async function startServe(opts) {
|
|
|
55642
55835
|
if (!localUrl) {
|
|
55643
55836
|
throw new ApiError(503, "SERVER_URL_NOT_READY", "server URL \u5C1A\u672A\u5C31\u7EEA");
|
|
55644
55837
|
}
|
|
55645
|
-
const runtimeSessionId = sessionId ?? (0,
|
|
55838
|
+
const runtimeSessionId = sessionId ?? (0, import_node_crypto25.randomUUID)();
|
|
55646
55839
|
const resumeRuntimeSession = Boolean(sessionId);
|
|
55647
|
-
const traceRunId = `chat-run:${(0,
|
|
55648
|
-
const artifactId = `artifact:chat:${(0,
|
|
55840
|
+
const traceRunId = `chat-run:${(0, import_node_crypto25.randomUUID)()}`;
|
|
55841
|
+
const artifactId = `artifact:chat:${(0, import_node_crypto25.randomUUID)()}`;
|
|
55649
55842
|
const traceStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55650
55843
|
let traceSeq = 0;
|
|
55651
55844
|
let traceEnabled = true;
|
|
@@ -55846,7 +56039,13 @@ async function startServe(opts) {
|
|
|
55846
56039
|
}
|
|
55847
56040
|
});
|
|
55848
56041
|
if (info.code === 0) resolve4();
|
|
55849
|
-
else
|
|
56042
|
+
else {
|
|
56043
|
+
const detail = info.errorMessage?.trim();
|
|
56044
|
+
const generic = `runtime exited with code ${info.code ?? "null"}${info.reason ? ` (${info.reason})` : ""}`;
|
|
56045
|
+
reject(new Error(detail ? `${generic}
|
|
56046
|
+
|
|
56047
|
+
${detail}` : generic));
|
|
56048
|
+
}
|
|
55850
56049
|
});
|
|
55851
56050
|
});
|
|
55852
56051
|
return {
|
|
@@ -55890,7 +56089,7 @@ async function startServe(opts) {
|
|
|
55890
56089
|
console.log(`[serve] \u8FDC\u7A0B agent API URL\uFF1A${remoteApiUrl ?? "\u672A\u914D\u7F6E\uFF08\u4EC5\u652F\u6301\u672C\u673A runtime\uFF09"}`);
|
|
55891
56090
|
const projectsCfg = loadJson("projects.json");
|
|
55892
56091
|
const seedProjects = (projectsCfg?.projects ?? []).map(
|
|
55893
|
-
(p2) => p2.repos?.length ? { ...p2, repos: p2.repos.map((r) => r.repoDir ? { ...r, repoDir:
|
|
56092
|
+
(p2) => p2.repos?.length ? { ...p2, repos: p2.repos.map((r) => r.repoDir ? { ...r, repoDir: path17.resolve(opts.dir, r.repoDir) } : r) } : p2
|
|
55894
56093
|
);
|
|
55895
56094
|
for (const sp of seedProjects) {
|
|
55896
56095
|
const existing = await projectStateStore.getProject(sp.id);
|
|
@@ -56021,8 +56220,8 @@ async function startServe(opts) {
|
|
|
56021
56220
|
// 每 agent 并发产出上限默认 5(工单数 / 全局总量默认不限);--max-produce-per-agent N 覆盖。
|
|
56022
56221
|
maxConcurrentProducePerActor: opts.maxConcurrentProducePerActor ?? 5,
|
|
56023
56222
|
// 提案 uniform-annotation-resolve ③/④ 落盘:容错计数 + produce 会话号(重启不丢;丢了也只是降级/多容错一轮)
|
|
56024
|
-
annotationRescue: new FileSideMap(
|
|
56025
|
-
produceSessions: new FileSideMap(
|
|
56223
|
+
annotationRescue: new FileSideMap(path17.join(opts.dir, `annotation-rescue.${companyId}.json`)),
|
|
56224
|
+
produceSessions: new FileSideMap(path17.join(opts.dir, `produce-sessions.${companyId}.json`))
|
|
56026
56225
|
});
|
|
56027
56226
|
const slot = { dispatcher: d, logged: 0, ticking: false };
|
|
56028
56227
|
dispatchers.set(companyId, slot);
|
|
@@ -56208,7 +56407,7 @@ async function startServe(opts) {
|
|
|
56208
56407
|
schema: schemaMap,
|
|
56209
56408
|
mirrors: new Map(opts.mirror.connectors.map((c) => [c.platform, c])),
|
|
56210
56409
|
identities: opts.mirror.identities ?? new MapMirrorIdentities(),
|
|
56211
|
-
state: new FsMirrorStateStore(
|
|
56410
|
+
state: new FsMirrorStateStore(path17.join(opts.dir, "mirror-state.json")),
|
|
56212
56411
|
...opts.mirror.debounceMs !== void 0 ? { debounceMs: opts.mirror.debounceMs } : {},
|
|
56213
56412
|
log: (m2) => console.log(m2)
|
|
56214
56413
|
});
|
|
@@ -56220,7 +56419,7 @@ async function startServe(opts) {
|
|
|
56220
56419
|
if (opts.dispatch) {
|
|
56221
56420
|
if (ciGateEnabled) {
|
|
56222
56421
|
const ci = new GhCiProvider({
|
|
56223
|
-
mirrorRoot:
|
|
56422
|
+
mirrorRoot: path17.join(opts.dir, "git-mirrors"),
|
|
56224
56423
|
failClosedWhenNoChecks: process.env["OASIS_CI_FAIL_CLOSED"] === "1",
|
|
56225
56424
|
log: (m2) => console.log(m2)
|
|
56226
56425
|
});
|
|
@@ -56232,7 +56431,7 @@ async function startServe(opts) {
|
|
|
56232
56431
|
const gitSync = new GitSyncWorker({
|
|
56233
56432
|
kernel,
|
|
56234
56433
|
resolveProject,
|
|
56235
|
-
mirrorRoot:
|
|
56434
|
+
mirrorRoot: path17.join(opts.dir, "git-mirrors"),
|
|
56236
56435
|
log: (m2) => console.log(m2)
|
|
56237
56436
|
});
|
|
56238
56437
|
gitTimer = setInterval(() => {
|
|
@@ -56295,7 +56494,7 @@ async function startServe(opts) {
|
|
|
56295
56494
|
// 病历里展示节点的"在跑会话情况"(runId + 跑了多久):从派发器在途会话按 artifactId 过滤。
|
|
56296
56495
|
sessionsOf: (id) => allDispatchers().flatMap((d) => d.inFlightSessions()).filter((s2) => s2.artifactId === id).map((s2) => ({ runId: s2.sessionId, action: s2.action, startedAt: s2.startedAt })),
|
|
56297
56496
|
log: (m2) => console.log(m2),
|
|
56298
|
-
retention: new FileSideMap(
|
|
56497
|
+
retention: new FileSideMap(path17.join(opts.dir, "retained-sessions.json"))
|
|
56299
56498
|
// 0030 D7 落盘
|
|
56300
56499
|
});
|
|
56301
56500
|
coordinatorRef = coordinator;
|
|
@@ -56406,7 +56605,7 @@ async function startServe(opts) {
|
|
|
56406
56605
|
await server.close();
|
|
56407
56606
|
if (pgPool) await pgPool.end().catch(() => {
|
|
56408
56607
|
});
|
|
56409
|
-
|
|
56608
|
+
fs18.rmSync(lock, { force: true });
|
|
56410
56609
|
}
|
|
56411
56610
|
};
|
|
56412
56611
|
}
|
|
@@ -56842,13 +57041,13 @@ async function startNode(opts) {
|
|
|
56842
57041
|
|
|
56843
57042
|
// ../cli/src/daemon/machine-id.ts
|
|
56844
57043
|
var import_node_child_process14 = require("node:child_process");
|
|
56845
|
-
var
|
|
56846
|
-
var
|
|
57044
|
+
var import_node_fs6 = require("node:fs");
|
|
57045
|
+
var import_node_crypto26 = require("node:crypto");
|
|
56847
57046
|
var import_node_os7 = require("node:os");
|
|
56848
57047
|
function linuxMachineId() {
|
|
56849
57048
|
for (const p2 of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
56850
57049
|
try {
|
|
56851
|
-
const v2 = (0,
|
|
57050
|
+
const v2 = (0, import_node_fs6.readFileSync)(p2, "utf8").trim();
|
|
56852
57051
|
if (v2) return v2;
|
|
56853
57052
|
} catch {
|
|
56854
57053
|
}
|
|
@@ -56909,13 +57108,14 @@ var defaultSources = {
|
|
|
56909
57108
|
function resolveNodeId(sources = {}) {
|
|
56910
57109
|
const s2 = { ...defaultSources, ...sources };
|
|
56911
57110
|
const material = `${s2.machineFingerprint()}:${s2.osUser()}`;
|
|
56912
|
-
const digest = (0,
|
|
57111
|
+
const digest = (0, import_node_crypto26.createHash)("sha256").update(material).digest("hex").slice(0, 12);
|
|
56913
57112
|
return `node-${digest}`;
|
|
56914
57113
|
}
|
|
56915
57114
|
|
|
56916
57115
|
// ../cli/src/cli.ts
|
|
56917
57116
|
init_src5();
|
|
56918
57117
|
init_src();
|
|
57118
|
+
init_src4();
|
|
56919
57119
|
var USAGE = `oasis \u2014\u2014 artifact-centric \u534F\u4F5C\u5185\u6838 CLI\uFF08\u670D\u52A1\u7AEF\u7626\u5BA2\u6237\u7AEF\uFF09
|
|
56920
57120
|
|
|
56921
57121
|
oasis serve [--dir .oasis] [--port 7320] [--dispatch true [--model haiku] [--max-produce-per-agent 5] [--max-concurrent-produce N]] [--allow-simple-tokens true] [--public-url https://host/oasis-api] [--gateway-url wss://host/oasis-api/node-gateway]
|
|
@@ -56952,6 +57152,9 @@ var USAGE = `oasis \u2014\u2014 artifact-centric \u534F\u4F5C\u5185\u6838 CLI\uF
|
|
|
56952
57152
|
reject <artifactId> <revisionId> --reason <text>
|
|
56953
57153
|
conclude <artifactId> [--note <text>] # \u673A\u68B0 grounding \u786C\u62E6\uFF1B\u6709 gate \u5219\u8FDB\u5165\u5F85\u5BA1
|
|
56954
57154
|
review <artifactId> --verdict approve|request_changes [--note <t>]
|
|
57155
|
+
design run <artifactId> [--brief <t>] [--reason <t>] [--od-url <url>] [--title <t>] [--agent <id>]
|
|
57156
|
+
# design \u4EA7\u7269\uFF1A\u5728\u901A\u7528 runtime \u4E0A\u9A71\u52A8 open-design \u753B\u677F\u5F15\u64CE\u4EA7\u754C\u9762\u7A3F\u5E76\u4EA4\u7A3F\uFF08\u63D0\u6848 design-node-runtime-to-cli-tool\uFF09\u3002
|
|
57157
|
+
# --brief \u7F3A\u7701\u8BFB\u5F53\u524D\u76EE\u5F55 TASK.md\uFF1B\u4E0A\u4E0B\u6587\u53D6\u5F53\u524D\u76EE\u5F55 inputs/\uFF1Bod \u5730\u5740\u7F3A\u7701 $OASIS_OPEN_DESIGN_URL \u6216\u672C\u673A 7457\u3002
|
|
56955
57158
|
|
|
56956
57159
|
\u56FE\u673A\u5236\uFF08\xA76/\xA77\uFF09
|
|
56957
57160
|
annotate <artifactId> --body <text> [--from <\u4E0B\u6E38> --blocks true]
|
|
@@ -57075,8 +57278,8 @@ function makeClient(base, token) {
|
|
|
57075
57278
|
if (!res.ok) await fail(res);
|
|
57076
57279
|
return (await res.json()).data;
|
|
57077
57280
|
},
|
|
57078
|
-
async request(method,
|
|
57079
|
-
const res = await fetch(`${base}${
|
|
57281
|
+
async request(method, path20, body) {
|
|
57282
|
+
const res = await fetch(`${base}${path20}`, {
|
|
57080
57283
|
method,
|
|
57081
57284
|
headers,
|
|
57082
57285
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
@@ -57084,8 +57287,8 @@ function makeClient(base, token) {
|
|
|
57084
57287
|
if (!res.ok) await fail(res);
|
|
57085
57288
|
return await res.json();
|
|
57086
57289
|
},
|
|
57087
|
-
async post(
|
|
57088
|
-
const res = await fetch(`${base}${
|
|
57290
|
+
async post(path20, body) {
|
|
57291
|
+
const res = await fetch(`${base}${path20}`, { method: "POST", headers, body: JSON.stringify(body) });
|
|
57089
57292
|
if (!res.ok) await fail(res);
|
|
57090
57293
|
return await res.json();
|
|
57091
57294
|
}
|
|
@@ -57098,62 +57301,62 @@ async function runCli(argv, println = console.log) {
|
|
|
57098
57301
|
return;
|
|
57099
57302
|
}
|
|
57100
57303
|
const { positional, flags } = parseArgs(rest);
|
|
57101
|
-
const dir = flags.get("dir") ?? process.env["OASIS_DIR"] ??
|
|
57304
|
+
const dir = flags.get("dir") ?? process.env["OASIS_DIR"] ?? path18.resolve(".oasis");
|
|
57102
57305
|
if (command === "node" && positional[0] !== "output") {
|
|
57103
57306
|
const serverUrl = flags.get("server-ws") ?? process.env["OASIS_SERVER_WS"] ?? "ws://127.0.0.1:7320/node-gateway";
|
|
57104
57307
|
const nodeName = flags.get("name") ?? process.env["OASIS_NODE_NAME"];
|
|
57105
|
-
const nodeIdFile =
|
|
57106
|
-
const nodeTokenFile =
|
|
57107
|
-
const enrollTokenFile =
|
|
57108
|
-
const reportMarkerFile =
|
|
57109
|
-
const persistedNodeId =
|
|
57308
|
+
const nodeIdFile = path18.join(dir, "node-id");
|
|
57309
|
+
const nodeTokenFile = path18.join(dir, "node-token");
|
|
57310
|
+
const enrollTokenFile = path18.join(dir, "enroll-token");
|
|
57311
|
+
const reportMarkerFile = path18.join(dir, "report-runtimes");
|
|
57312
|
+
const persistedNodeId = fs19.existsSync(nodeIdFile) ? fs19.readFileSync(nodeIdFile, "utf8").trim() : null;
|
|
57110
57313
|
let nodeId = persistedNodeId || resolveNodeId();
|
|
57111
|
-
let token2 = flags.get("token") ?? process.env["OASIS_NODE_TOKEN"] ?? (
|
|
57112
|
-
const enrollToken = flags.get("enroll-token") ?? process.env["OASIS_ENROLL_TOKEN"] ?? (
|
|
57314
|
+
let token2 = flags.get("token") ?? process.env["OASIS_NODE_TOKEN"] ?? (fs19.existsSync(nodeTokenFile) ? fs19.readFileSync(nodeTokenFile, "utf8").trim() : void 0);
|
|
57315
|
+
const enrollToken = flags.get("enroll-token") ?? process.env["OASIS_ENROLL_TOKEN"] ?? (fs19.existsSync(enrollTokenFile) ? fs19.readFileSync(enrollTokenFile, "utf8").trim() : void 0);
|
|
57113
57316
|
let freshEnrollment = false;
|
|
57114
57317
|
if (!token2 && enrollToken) {
|
|
57115
57318
|
const httpBase2 = serverUrl.replace(/^ws(s?):\/\//, "http$1://").replace(/\/node-gateway.*$/, "");
|
|
57116
57319
|
const res = await fetch(`${httpBase2}/api/nodes/exchange`, {
|
|
57117
57320
|
method: "POST",
|
|
57118
57321
|
headers: { "content-type": "application/json" },
|
|
57119
|
-
body: JSON.stringify({ enrollToken, nodeId, hostname:
|
|
57322
|
+
body: JSON.stringify({ enrollToken, nodeId, hostname: os10.hostname() })
|
|
57120
57323
|
});
|
|
57121
57324
|
if (!res.ok) throw new Error(`enroll token exchange failed: HTTP ${res.status}`);
|
|
57122
57325
|
const body = await res.json();
|
|
57123
57326
|
nodeId = body.nodeId;
|
|
57124
57327
|
token2 = body.token;
|
|
57125
|
-
|
|
57126
|
-
|
|
57127
|
-
|
|
57328
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
57329
|
+
fs19.writeFileSync(nodeIdFile, nodeId);
|
|
57330
|
+
fs19.writeFileSync(nodeTokenFile, token2, { mode: 384 });
|
|
57128
57331
|
try {
|
|
57129
|
-
|
|
57332
|
+
fs19.unlinkSync(enrollTokenFile);
|
|
57130
57333
|
} catch {
|
|
57131
57334
|
}
|
|
57132
57335
|
freshEnrollment = true;
|
|
57133
57336
|
}
|
|
57134
57337
|
if (!nodeId) throw new Error("no nodeId \u2014 provide --enroll-token <ent_...> on first run");
|
|
57135
|
-
const scriptRun = freshEnrollment ||
|
|
57338
|
+
const scriptRun = freshEnrollment || fs19.existsSync(reportMarkerFile);
|
|
57136
57339
|
if (flags.has("service")) {
|
|
57137
57340
|
const { spawnSync, execSync: execSync2 } = await import("node:child_process");
|
|
57138
57341
|
if (token2) {
|
|
57139
|
-
|
|
57140
|
-
|
|
57342
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
57343
|
+
fs19.writeFileSync(nodeTokenFile, token2, { mode: 384 });
|
|
57141
57344
|
}
|
|
57142
57345
|
if (scriptRun) {
|
|
57143
|
-
|
|
57144
|
-
|
|
57346
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
57347
|
+
fs19.writeFileSync(reportMarkerFile, "");
|
|
57145
57348
|
}
|
|
57146
57349
|
println("\u2192 Installing oasis_test globally...");
|
|
57147
57350
|
spawnSync("npm", ["install", "-g", "oasis_test@latest"], { stdio: "inherit" });
|
|
57148
57351
|
const prefix = execSync2("npm prefix -g").toString().trim();
|
|
57149
|
-
const binPath =
|
|
57352
|
+
const binPath = path18.join(prefix, "bin", "oasis_test");
|
|
57150
57353
|
const svcArgs = `node --server-ws ${serverUrl} --dir ${dir}${nodeName ? ` --name ${nodeName}` : ""}`;
|
|
57151
57354
|
if (process.platform === "linux") {
|
|
57152
|
-
const svcFile =
|
|
57153
|
-
|
|
57355
|
+
const svcFile = path18.join(os10.homedir(), ".config/systemd/user/oasis-node.service");
|
|
57356
|
+
fs19.mkdirSync(path18.dirname(svcFile), { recursive: true });
|
|
57154
57357
|
if (spawnSync("systemctl", ["--user", "is-active", "--quiet", "oasis-node"], {}).status === 0)
|
|
57155
57358
|
spawnSync("systemctl", ["--user", "stop", "oasis-node"], { stdio: "inherit" });
|
|
57156
|
-
|
|
57359
|
+
fs19.writeFileSync(svcFile, [
|
|
57157
57360
|
"[Unit]",
|
|
57158
57361
|
"Description=Oasis Node Daemon",
|
|
57159
57362
|
"After=network.target",
|
|
@@ -57162,7 +57365,7 @@ async function runCli(argv, println = console.log) {
|
|
|
57162
57365
|
`ExecStart=${binPath} ${svcArgs}`,
|
|
57163
57366
|
// Carry the install-time PATH so the detached daemon detects CLIs in user dirs
|
|
57164
57367
|
// (~/.npm-global/bin, ~/.local/bin) — systemd --user otherwise gives a minimal PATH.
|
|
57165
|
-
`Environment=PATH=${process.env["PATH"] ?? ""}:${
|
|
57368
|
+
`Environment=PATH=${process.env["PATH"] ?? ""}:${path18.join(os10.homedir(), ".npm-global/bin")}:${path18.join(os10.homedir(), ".local/bin")}:/usr/local/bin`,
|
|
57166
57369
|
"Restart=on-failure",
|
|
57167
57370
|
"RestartSec=5",
|
|
57168
57371
|
"StandardOutput=journal",
|
|
@@ -57174,31 +57377,31 @@ async function runCli(argv, println = console.log) {
|
|
|
57174
57377
|
].join("\n"));
|
|
57175
57378
|
spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "inherit" });
|
|
57176
57379
|
spawnSync("systemctl", ["--user", "enable", "--now", "oasis-node"], { stdio: "inherit" });
|
|
57177
|
-
spawnSync("loginctl", ["enable-linger",
|
|
57380
|
+
spawnSync("loginctl", ["enable-linger", os10.userInfo().username], { stdio: "ignore" });
|
|
57178
57381
|
println("\u2713 Oasis node service started (systemd --user oasis-node)");
|
|
57179
57382
|
println(" Status : systemctl --user status oasis-node");
|
|
57180
57383
|
println(" Logs : journalctl --user -u oasis-node -f");
|
|
57181
57384
|
println(" Stop : systemctl --user stop oasis-node");
|
|
57182
57385
|
} else if (process.platform === "darwin") {
|
|
57183
|
-
const plist =
|
|
57184
|
-
|
|
57386
|
+
const plist = path18.join(os10.homedir(), "Library/LaunchAgents/com.oasis.node.plist");
|
|
57387
|
+
fs19.mkdirSync(path18.dirname(plist), { recursive: true });
|
|
57185
57388
|
spawnSync("launchctl", ["unload", plist], { stdio: "ignore" });
|
|
57186
57389
|
const argXml = [binPath, "node", "--server-ws", serverUrl, "--dir", dir, ...nodeName ? ["--name", nodeName] : []].map((a) => `<string>${a}</string>`).join("");
|
|
57187
|
-
|
|
57390
|
+
fs19.writeFileSync(plist, `<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>Label</key><string>com.oasis.node</string><key>ProgramArguments</key><array>${argXml}</array><key>RunAtLoad</key><true/><key>KeepAlive</key><true/><key>StandardOutPath</key><string>${os10.homedir()}/.oasis-node.log</string><key>StandardErrorPath</key><string>${os10.homedir()}/.oasis-node.err</string></dict></plist>`);
|
|
57188
57391
|
spawnSync("launchctl", ["load", plist], { stdio: "inherit" });
|
|
57189
57392
|
println("\u2713 Oasis node service started (macOS LaunchAgent com.oasis.node)");
|
|
57190
|
-
println(` Logs : tail -f ${
|
|
57393
|
+
println(` Logs : tail -f ${os10.homedir()}/.oasis-node.log`);
|
|
57191
57394
|
println(` Stop : launchctl unload ${plist}`);
|
|
57192
57395
|
} else {
|
|
57193
|
-
spawnSync("sh", ["-c", `nohup ${binPath} ${svcArgs} > ${
|
|
57396
|
+
spawnSync("sh", ["-c", `nohup ${binPath} ${svcArgs} > ${path18.join(os10.homedir(), ".oasis-node.log")} 2>&1 &`], { stdio: "inherit" });
|
|
57194
57397
|
println(`\u2713 Oasis node started in background (nohup). Logs: ~/.oasis-node.log`);
|
|
57195
57398
|
println(" Note: no automatic restart on reboot in this environment.");
|
|
57196
57399
|
}
|
|
57197
57400
|
return;
|
|
57198
57401
|
}
|
|
57199
|
-
if (
|
|
57402
|
+
if (fs19.existsSync(reportMarkerFile)) {
|
|
57200
57403
|
try {
|
|
57201
|
-
|
|
57404
|
+
fs19.unlinkSync(reportMarkerFile);
|
|
57202
57405
|
} catch {
|
|
57203
57406
|
}
|
|
57204
57407
|
}
|
|
@@ -57206,14 +57409,14 @@ async function runCli(argv, println = console.log) {
|
|
|
57206
57409
|
return;
|
|
57207
57410
|
}
|
|
57208
57411
|
if (command === "node-token") {
|
|
57209
|
-
const store = createNodeTokenStore(
|
|
57412
|
+
const store = createNodeTokenStore(path18.join(dir, "node-tokens.json"));
|
|
57210
57413
|
const sub = positional[0];
|
|
57211
57414
|
if (sub === "issue") {
|
|
57212
|
-
const id = flags.get("id") ?? `node-${(0,
|
|
57415
|
+
const id = flags.get("id") ?? `node-${(0, import_node_crypto27.randomUUID)()}`;
|
|
57213
57416
|
const token2 = store.issue(id);
|
|
57214
57417
|
println(token2);
|
|
57215
57418
|
process.stderr.write(
|
|
57216
|
-
`\u5DF2\u4E3A ${id} \u7B7E\u53D1 node-token\uFF08\u5199\u5165 ${
|
|
57419
|
+
`\u5DF2\u4E3A ${id} \u7B7E\u53D1 node-token\uFF08\u5199\u5165 ${path18.join(dir, "node-tokens.json")}\uFF09\u3002
|
|
57217
57420
|
\u628A\u4E0A\u9762\u8FD9\u4E32\u653E\u5230\u8282\u70B9\u673A\uFF1A--token <t> / $OASIS_NODE_TOKEN / <\u8282\u70B9dir>/node-token
|
|
57218
57421
|
`
|
|
57219
57422
|
);
|
|
@@ -57234,7 +57437,7 @@ async function runCli(argv, println = console.log) {
|
|
|
57234
57437
|
}
|
|
57235
57438
|
if (command === "admin" && positional[0] === "grant-owner") {
|
|
57236
57439
|
const email2 = need(flags, "email");
|
|
57237
|
-
const store = await FileControlPlaneStore.open(
|
|
57440
|
+
const store = await FileControlPlaneStore.open(path18.join(dir, "control-plane.json"));
|
|
57238
57441
|
const activeCompanies = (await store.listCompanies()).filter((c) => c.status === "active");
|
|
57239
57442
|
const companyId = flags.get("company") ?? activeCompanies[0]?.id ?? resolveDefaultCompanyConfig().id;
|
|
57240
57443
|
const name = flags.get("name");
|
|
@@ -57247,11 +57450,11 @@ async function runCli(argv, println = console.log) {
|
|
|
57247
57450
|
}
|
|
57248
57451
|
if (command === "export-trajectories") {
|
|
57249
57452
|
const { exportTrajectories: exportTrajectories2 } = await Promise.resolve().then(() => (init_trajectory(), trajectory_exports));
|
|
57250
|
-
const samples = await exportTrajectories2(
|
|
57453
|
+
const samples = await exportTrajectories2(path18.resolve(dir));
|
|
57251
57454
|
const outFile = flags.get("out");
|
|
57252
57455
|
const lines = samples.map((sample) => JSON.stringify(sample)).join("\n");
|
|
57253
57456
|
if (outFile !== void 0) {
|
|
57254
|
-
|
|
57457
|
+
fs19.writeFileSync(outFile, lines + (lines ? "\n" : ""));
|
|
57255
57458
|
println(`\u5DF2\u5BFC\u51FA ${samples.length} \u6761\u8F68\u8FF9\u6837\u672C \u2192 ${outFile}\uFF08approved/rejected \u6210\u5BF9\u5373\u504F\u597D\u5BF9\uFF09`);
|
|
57256
57459
|
} else {
|
|
57257
57460
|
println(lines);
|
|
@@ -57259,10 +57462,10 @@ async function runCli(argv, println = console.log) {
|
|
|
57259
57462
|
return;
|
|
57260
57463
|
}
|
|
57261
57464
|
if (command === "serve" && positional[0] === "install") {
|
|
57262
|
-
const absDir =
|
|
57263
|
-
const name = `oasis-serve-${
|
|
57264
|
-
const unitDir = flags.get("unit-dir") ??
|
|
57265
|
-
const bin = flags.get("bin") ??
|
|
57465
|
+
const absDir = path18.resolve(dir);
|
|
57466
|
+
const name = `oasis-serve-${path18.basename(absDir)}`;
|
|
57467
|
+
const unitDir = flags.get("unit-dir") ?? path18.join(os10.homedir(), ".config", "systemd", "user");
|
|
57468
|
+
const bin = flags.get("bin") ?? path18.join(os10.homedir(), ".local", "bin", "oasis");
|
|
57266
57469
|
const port = flags.get("port") ?? "7320";
|
|
57267
57470
|
const extra = (flags.get("dispatch") === "true" ? ` --dispatch true` : "") + (flags.has("model") ? ` --model ${flags.get("model")}` : "");
|
|
57268
57471
|
const unit = [
|
|
@@ -57279,9 +57482,9 @@ async function runCli(argv, println = console.log) {
|
|
|
57279
57482
|
`WantedBy=default.target`,
|
|
57280
57483
|
``
|
|
57281
57484
|
].join("\n");
|
|
57282
|
-
|
|
57283
|
-
const unitPath =
|
|
57284
|
-
|
|
57485
|
+
fs19.mkdirSync(unitDir, { recursive: true });
|
|
57486
|
+
const unitPath = path18.join(unitDir, `${name}.service`);
|
|
57487
|
+
fs19.writeFileSync(unitPath, unit);
|
|
57285
57488
|
println(`\u5DF2\u5199\u5165 ${unitPath}`);
|
|
57286
57489
|
println(`\u542F\u7528\uFF1Asystemctl --user daemon-reload && systemctl --user enable --now ${name}`);
|
|
57287
57490
|
println(`\u5F00\u673A\u81EA\u542F\uFF08\u542B\u672A\u767B\u5F55\uFF09\uFF1Aloginctl enable-linger $USER`);
|
|
@@ -57303,20 +57506,20 @@ async function runCli(argv, println = console.log) {
|
|
|
57303
57506
|
});
|
|
57304
57507
|
const port2 = new URL(handle.baseUrl).port;
|
|
57305
57508
|
println(`oasis serve \u5C31\u7EEA\uFF1Ahttp://0.0.0.0:${port2}\uFF08\u672C\u673A\u8BBF\u95EE\u7528 http://127.0.0.1:${port2}\uFF09`);
|
|
57306
|
-
println(`operator token \u5DF2\u5199\u5165 ${
|
|
57509
|
+
println(`operator token \u5DF2\u5199\u5165 ${path18.join(dir, "operator-token")}\uFF08\u672C\u673A CLI \u81EA\u52A8\u8BFB\u53D6\uFF09`);
|
|
57307
57510
|
if (flags.get("dispatch") === "true") println(`\u8C03\u5EA6\u5FAA\u73AF\u5DF2\u542F\u52A8\uFF08claude-code adapter\uFF09`);
|
|
57308
57511
|
await new Promise(() => {
|
|
57309
57512
|
});
|
|
57310
57513
|
return;
|
|
57311
57514
|
}
|
|
57312
57515
|
const base = flags.get("server") ?? process.env["OASIS_SERVER"] ?? "http://127.0.0.1:7320";
|
|
57313
|
-
const tokenFile =
|
|
57314
|
-
const token = flags.get("token") ?? process.env["OASIS_TOKEN"] ?? (
|
|
57516
|
+
const tokenFile = path18.join(dir, "operator-token");
|
|
57517
|
+
const token = flags.get("token") ?? process.env["OASIS_TOKEN"] ?? (fs19.existsSync(tokenFile) ? fs19.readFileSync(tokenFile, "utf8").trim() : void 0);
|
|
57315
57518
|
if (!token) {
|
|
57316
57519
|
throw new Error(`\u65E0 token\uFF1A\u5148 oasis serve\uFF08\u4F1A\u751F\u6210 ${tokenFile}\uFF09\uFF0C\u6216\u663E\u5F0F --token / $OASIS_TOKEN`);
|
|
57317
57520
|
}
|
|
57318
57521
|
const api = makeClient(base, token);
|
|
57319
|
-
const readFileArg = (file) =>
|
|
57522
|
+
const readFileArg = (file) => fs19.readFileSync(file, "utf8");
|
|
57320
57523
|
const parseJsonFlag = (value, name) => {
|
|
57321
57524
|
const parsed = JSON.parse(value);
|
|
57322
57525
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -57334,11 +57537,11 @@ async function runCli(argv, println = console.log) {
|
|
|
57334
57537
|
const readDirFiles = (root) => {
|
|
57335
57538
|
const out = [];
|
|
57336
57539
|
const walk = (abs, rel) => {
|
|
57337
|
-
for (const name of
|
|
57338
|
-
const childAbs =
|
|
57540
|
+
for (const name of fs19.readdirSync(abs)) {
|
|
57541
|
+
const childAbs = path18.join(abs, name);
|
|
57339
57542
|
const childRel = rel ? `${rel}/${name}` : name;
|
|
57340
|
-
if (
|
|
57341
|
-
else out.push({ path: childRel, contentBase64:
|
|
57543
|
+
if (fs19.statSync(childAbs).isDirectory()) walk(childAbs, childRel);
|
|
57544
|
+
else out.push({ path: childRel, contentBase64: fs19.readFileSync(childAbs).toString("base64") });
|
|
57342
57545
|
}
|
|
57343
57546
|
};
|
|
57344
57547
|
walk(root, "");
|
|
@@ -57464,7 +57667,7 @@ async function runCli(argv, println = console.log) {
|
|
|
57464
57667
|
}
|
|
57465
57668
|
switch (command) {
|
|
57466
57669
|
case "create-workorder": {
|
|
57467
|
-
const planRaw = flags.get("plan-file") !== void 0 ?
|
|
57670
|
+
const planRaw = flags.get("plan-file") !== void 0 ? fs19.readFileSync(flags.get("plan-file"), "utf8") : flags.get("plan");
|
|
57468
57671
|
const acceptanceFlag = flags.get("acceptance");
|
|
57469
57672
|
const args = {
|
|
57470
57673
|
createdVia: "seed",
|
|
@@ -57685,9 +57888,9 @@ async function runCli(argv, println = console.log) {
|
|
|
57685
57888
|
if (verb === "add") {
|
|
57686
57889
|
const file = flags.get("file");
|
|
57687
57890
|
if (file !== void 0) {
|
|
57688
|
-
const bytes =
|
|
57891
|
+
const bytes = fs19.readFileSync(file);
|
|
57689
57892
|
const res = await api.request("POST", `/api/projects/${encodeURIComponent(projectId)}/files`, {
|
|
57690
|
-
name: flags.get("name") ??
|
|
57893
|
+
name: flags.get("name") ?? path18.basename(file),
|
|
57691
57894
|
...flags.has("path") ? { path: flags.get("path") } : {},
|
|
57692
57895
|
content_base64: bytes.toString("base64"),
|
|
57693
57896
|
...flags.has("content-type") ? { content_type: flags.get("content-type") } : {}
|
|
@@ -57844,6 +58047,38 @@ ${res.warning}`);
|
|
|
57844
58047
|
println(message);
|
|
57845
58048
|
break;
|
|
57846
58049
|
}
|
|
58050
|
+
case "design": {
|
|
58051
|
+
const sub = positional[0];
|
|
58052
|
+
if (sub !== "run") throw new Error("\u7528\u6CD5\uFF1Aoasis design run <artifactId> [--brief <t>] [--reason <t>] [--od-url <url>] [--title <t>] [--agent <id>]");
|
|
58053
|
+
const artifactId = needPos(positional, 1, "oasis design run <artifactId>");
|
|
58054
|
+
const odBase = (flags.get("od-url") ?? process.env["OASIS_OPEN_DESIGN_URL"] ?? "http://127.0.0.1:7457").replace(/\/$/, "");
|
|
58055
|
+
const odPublic = (flags.get("od-public-url") ?? process.env["OASIS_OPEN_DESIGN_PUBLIC_URL"] ?? "https://design.open-friday.com").replace(/\/$/, "");
|
|
58056
|
+
const brief = flags.get("brief") ?? (fs19.existsSync("TASK.md") ? fs19.readFileSync("TASK.md", "utf8") : "");
|
|
58057
|
+
if (!brief.trim()) throw new Error("\u65E0\u8BBE\u8BA1\u4EFB\u52A1\uFF1A\u7ED9 --brief <text> \u6216\u5728\u5F53\u524D\u76EE\u5F55\u653E TASK.md");
|
|
58058
|
+
const contextFiles = { "TASK.md": brief };
|
|
58059
|
+
if (fs19.existsSync("inputs") && fs19.statSync("inputs").isDirectory()) {
|
|
58060
|
+
for (const f2 of readDirFiles("inputs")) {
|
|
58061
|
+
contextFiles[`inputs/${f2.path}`] = Buffer.from(f2.contentBase64, "base64").toString("utf8");
|
|
58062
|
+
}
|
|
58063
|
+
}
|
|
58064
|
+
println(`[design] \u753B\u677F ${deriveBoardKey(artifactId)} \u2190 ${artifactId}\uFF1B\u9A71\u52A8 od \u5F15\u64CE ${odBase} \u2026`);
|
|
58065
|
+
const { dir: dir2, entry, boardKey, runId } = await runOpenDesignSession({
|
|
58066
|
+
base: odBase,
|
|
58067
|
+
publicBase: odPublic,
|
|
58068
|
+
agentId: flags.get("agent") ?? "claude",
|
|
58069
|
+
artifactId,
|
|
58070
|
+
title: flags.get("title") ?? artifactId,
|
|
58071
|
+
message: brief,
|
|
58072
|
+
systemPrompt: "\u4F60\u662F\u8BBE\u8BA1\u5F15\u64CE\u4E2D\u7684\u754C\u9762\u8BBE\u8BA1\u5E08\u3002\u4EFB\u52A1\u4E66\u89C1\u672C\u6761\u6D88\u606F\uFF1B\u4E0A\u6E38\u8F93\u5165\u7B49\u4E0A\u4E0B\u6587\u6587\u4EF6\u5728\u9879\u76EE task-context/ \u76EE\u5F55\u3002\u6309\u4EFB\u52A1\u4E66\u7684\u300C\u600E\u4E48\u63D0\u4EA4\u300D\u534F\u8BAE\u5DE5\u4F5C\uFF1A\u4EA7\u51FA\u81EA\u5305\u542B HTML \u5165\u53E3\u7A3F\u4E0E acceptance.md\uFF0C\u5B8C\u6210\u5373\u7ED3\u675F\u56DE\u590D\uFF0C\u4EA4\u7A3F\u7531\u7CFB\u7EDF\u4EE3\u529E\u3002",
|
|
58073
|
+
contextFiles,
|
|
58074
|
+
onLine: (line) => println(`[od] ${line.length > 500 ? line.slice(0, 500) + "\u2026" : line}`)
|
|
58075
|
+
});
|
|
58076
|
+
println(`[design] \u753B\u677F\u4EA7\u51FA ${entry}\uFF08board ${boardKey}, run ${runId.slice(0, 8)}\uFF09\u2192 \u4EA4\u7A3F\u4E2D \u2026`);
|
|
58077
|
+
const reason = flags.get("reason") ?? `\u753B\u677F\u5FEB\u7167\u4EA4\u4ED8\uFF1A${entry}\uFF08board ${boardKey}, run ${runId.slice(0, 8)}\uFF09`;
|
|
58078
|
+
const { message } = await api.cmd("propose", { artifactId, files: readDirFiles(dir2), reason });
|
|
58079
|
+
println(message);
|
|
58080
|
+
break;
|
|
58081
|
+
}
|
|
57847
58082
|
case "merge": {
|
|
57848
58083
|
const artifactId = needPos(positional, 0, "oasis merge <artifactId> [revisionId]");
|
|
57849
58084
|
const { message } = await api.cmd("merge", { artifactId, revisionId: positional[1] });
|
|
@@ -58236,8 +58471,8 @@ ${res.warning}`);
|
|
|
58236
58471
|
}
|
|
58237
58472
|
case "content": {
|
|
58238
58473
|
const id = needPos(positional, 0, "oasis content <artifactId> [path]");
|
|
58239
|
-
const
|
|
58240
|
-
const c = await api.view("content", id,
|
|
58474
|
+
const path20 = positional[1];
|
|
58475
|
+
const c = await api.view("content", id, path20 ? { path: path20 } : void 0);
|
|
58241
58476
|
if (c.kind === "empty") println("\uFF08\u672C\u4EA7\u7269\u5C1A\u65E0\u5185\u5BB9\uFF09");
|
|
58242
58477
|
else if (c.kind === "external-pin") println(`\u4EE3\u7801/\u5916\u90E8\u4EA4\u4ED8\u7269\uFF1A\u5185\u5BB9\u5728 git/\u5916\u90E8 \u2192 ${c.ref}\uFF08\u6309\u300C\u600E\u4E48\u63D0\u4EA4\u300D\u91CC\u7684\u4ED3\u5E93\u6E05\u5355 clone \u53D6\uFF09`);
|
|
58243
58478
|
else if (c.kind === "text") println(c.text);
|
|
@@ -58410,14 +58645,14 @@ ${res.warning}`);
|
|
|
58410
58645
|
}
|
|
58411
58646
|
|
|
58412
58647
|
// src/index.ts
|
|
58413
|
-
var PKG_VERSION = true ? "0.1.
|
|
58414
|
-
var OASIS_DIR =
|
|
58415
|
-
var CONFIG_FILE =
|
|
58416
|
-
var PID_FILE =
|
|
58417
|
-
var BIN_FILE =
|
|
58418
|
-
var LOCAL_BIN =
|
|
58419
|
-
var LOG_FILE =
|
|
58420
|
-
var NPM_PREFIX =
|
|
58648
|
+
var PKG_VERSION = true ? "0.1.46" : "dev";
|
|
58649
|
+
var OASIS_DIR = path19.join(os11.homedir(), ".oasis");
|
|
58650
|
+
var CONFIG_FILE = path19.join(OASIS_DIR, "node-config.json");
|
|
58651
|
+
var PID_FILE = path19.join(OASIS_DIR, "node.pid");
|
|
58652
|
+
var BIN_FILE = path19.join(OASIS_DIR, "bin", "oasis.js");
|
|
58653
|
+
var LOCAL_BIN = path19.join(os11.homedir(), ".local", "bin", "oasis");
|
|
58654
|
+
var LOG_FILE = path19.join(OASIS_DIR, "node.log");
|
|
58655
|
+
var NPM_PREFIX = path19.join(OASIS_DIR, "npm-global");
|
|
58421
58656
|
var PKG_NAME = "oasis_test";
|
|
58422
58657
|
var parseFlags = (argv) => {
|
|
58423
58658
|
const flags = /* @__PURE__ */ new Map();
|
|
@@ -58429,18 +58664,18 @@ var parseFlags = (argv) => {
|
|
|
58429
58664
|
};
|
|
58430
58665
|
var readConfig = () => {
|
|
58431
58666
|
try {
|
|
58432
|
-
return JSON.parse(
|
|
58667
|
+
return JSON.parse(fs20.readFileSync(CONFIG_FILE, "utf8"));
|
|
58433
58668
|
} catch {
|
|
58434
58669
|
return null;
|
|
58435
58670
|
}
|
|
58436
58671
|
};
|
|
58437
58672
|
var saveConfig = (c) => {
|
|
58438
|
-
|
|
58439
|
-
|
|
58673
|
+
fs20.mkdirSync(OASIS_DIR, { recursive: true });
|
|
58674
|
+
fs20.writeFileSync(CONFIG_FILE, JSON.stringify(c), { mode: 384 });
|
|
58440
58675
|
};
|
|
58441
58676
|
var readPid = () => {
|
|
58442
58677
|
try {
|
|
58443
|
-
const p2 = parseInt(
|
|
58678
|
+
const p2 = parseInt(fs20.readFileSync(PID_FILE, "utf8").trim(), 10);
|
|
58444
58679
|
return isNaN(p2) ? null : p2;
|
|
58445
58680
|
} catch {
|
|
58446
58681
|
return null;
|
|
@@ -58456,26 +58691,26 @@ var isRunning = (pid) => {
|
|
|
58456
58691
|
};
|
|
58457
58692
|
var httpBase = (wsUrl) => wsUrl.replace(/^ws(s?):\/\//, "http$1://").replace(/\/node-gateway.*$/, "");
|
|
58458
58693
|
function installBinary() {
|
|
58459
|
-
|
|
58460
|
-
|
|
58461
|
-
|
|
58462
|
-
|
|
58694
|
+
fs20.mkdirSync(path19.dirname(BIN_FILE), { recursive: true });
|
|
58695
|
+
fs20.copyFileSync(process.argv[1], BIN_FILE);
|
|
58696
|
+
fs20.mkdirSync(path19.dirname(LOCAL_BIN), { recursive: true });
|
|
58697
|
+
fs20.writeFileSync(LOCAL_BIN, `#!/bin/sh
|
|
58463
58698
|
exec node "${BIN_FILE}" "$@"
|
|
58464
58699
|
`, { mode: 493 });
|
|
58465
58700
|
}
|
|
58466
58701
|
function setupAutostart() {
|
|
58467
58702
|
const cmd = `${process.execPath} "${BIN_FILE}" --_daemon`;
|
|
58468
|
-
const home =
|
|
58703
|
+
const home = os11.homedir();
|
|
58469
58704
|
const extraBins = [
|
|
58470
|
-
|
|
58471
|
-
|
|
58705
|
+
path19.join(home, ".npm-global", "bin"),
|
|
58706
|
+
path19.join(home, ".local", "bin"),
|
|
58472
58707
|
"/usr/local/bin"
|
|
58473
58708
|
];
|
|
58474
58709
|
const daemonPath = [process.env["PATH"] ?? "", ...extraBins].filter(Boolean).join(":");
|
|
58475
58710
|
if (process.platform === "linux") {
|
|
58476
|
-
const unitDir =
|
|
58477
|
-
|
|
58478
|
-
|
|
58711
|
+
const unitDir = path19.join(os11.homedir(), ".config", "systemd", "user");
|
|
58712
|
+
fs20.mkdirSync(unitDir, { recursive: true });
|
|
58713
|
+
fs20.writeFileSync(path19.join(unitDir, "oasis-node.service"), [
|
|
58479
58714
|
"[Unit]",
|
|
58480
58715
|
"Description=Oasis Node Daemon",
|
|
58481
58716
|
"After=network.target",
|
|
@@ -58497,9 +58732,9 @@ function setupAutostart() {
|
|
|
58497
58732
|
} catch {
|
|
58498
58733
|
}
|
|
58499
58734
|
} else if (process.platform === "darwin") {
|
|
58500
|
-
const plist =
|
|
58501
|
-
|
|
58502
|
-
|
|
58735
|
+
const plist = path19.join(os11.homedir(), "Library", "LaunchAgents", "com.oasis.node.plist");
|
|
58736
|
+
fs20.mkdirSync(path19.dirname(plist), { recursive: true });
|
|
58737
|
+
fs20.writeFileSync(plist, `<?xml version="1.0" encoding="UTF-8"?>
|
|
58503
58738
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
58504
58739
|
<plist version="1.0"><dict>
|
|
58505
58740
|
<key>Label</key><string>com.oasis.node</string>
|
|
@@ -58516,14 +58751,14 @@ function setupAutostart() {
|
|
|
58516
58751
|
}
|
|
58517
58752
|
}
|
|
58518
58753
|
function spawnDaemon() {
|
|
58519
|
-
const log3 =
|
|
58754
|
+
const log3 = fs20.openSync(LOG_FILE, "a");
|
|
58520
58755
|
const child = (0, import_node_child_process15.spawn)(process.execPath, [BIN_FILE, "--_daemon"], {
|
|
58521
58756
|
detached: true,
|
|
58522
58757
|
stdio: ["ignore", log3, log3]
|
|
58523
58758
|
});
|
|
58524
58759
|
child.unref();
|
|
58525
58760
|
const pid = child.pid ?? 0;
|
|
58526
|
-
|
|
58761
|
+
fs20.writeFileSync(PID_FILE, String(pid));
|
|
58527
58762
|
return pid;
|
|
58528
58763
|
}
|
|
58529
58764
|
function stopDaemon() {
|
|
@@ -58535,7 +58770,7 @@ function stopDaemon() {
|
|
|
58535
58770
|
}
|
|
58536
58771
|
}
|
|
58537
58772
|
try {
|
|
58538
|
-
|
|
58773
|
+
fs20.unlinkSync(PID_FILE);
|
|
58539
58774
|
} catch {
|
|
58540
58775
|
}
|
|
58541
58776
|
try {
|
|
@@ -58551,7 +58786,7 @@ function selfUpdate() {
|
|
|
58551
58786
|
const cfg = readConfig();
|
|
58552
58787
|
if (!cfg?.serverUrl) throw new Error("no config \u2014 run `oasis start` first");
|
|
58553
58788
|
const nameArg = cfg.name ? ` --name '${cfg.name.replace(/'/g, "'\\''")}'` : "";
|
|
58554
|
-
const oasisBin =
|
|
58789
|
+
const oasisBin = path19.join(NPM_PREFIX, "bin", "oasis");
|
|
58555
58790
|
const startCmd = `"${oasisBin}" start --server-ws '${cfg.serverUrl}'${nameArg}`;
|
|
58556
58791
|
const inner = `{ echo "[oasis] self-update \u2192 npm install --prefix ${NPM_PREFIX} ${PKG_NAME}@latest"; sleep 2; npm install -g --prefer-online --prefix '${NPM_PREFIX}' '${PKG_NAME}@latest' && ${startCmd}; } >> '${LOG_FILE}' 2>&1`;
|
|
58557
58792
|
const hasSystemd = process.platform === "linux" && (() => {
|
|
@@ -58562,7 +58797,7 @@ function selfUpdate() {
|
|
|
58562
58797
|
return false;
|
|
58563
58798
|
}
|
|
58564
58799
|
})();
|
|
58565
|
-
const log3 =
|
|
58800
|
+
const log3 = fs20.openSync(LOG_FILE, "a");
|
|
58566
58801
|
if (hasSystemd) {
|
|
58567
58802
|
const child = (0, import_node_child_process15.spawn)("systemd-run", ["--user", "--scope", "--quiet", "sh", "-c", inner], {
|
|
58568
58803
|
detached: true,
|
|
@@ -58588,10 +58823,10 @@ void (async () => {
|
|
|
58588
58823
|
console.error(`[oasis] daemon already running (PID ${alivePid}) \u2014 exiting duplicate`);
|
|
58589
58824
|
process.exit(0);
|
|
58590
58825
|
}
|
|
58591
|
-
|
|
58826
|
+
fs20.writeFileSync(PID_FILE, String(process.pid));
|
|
58592
58827
|
const cleanup = () => {
|
|
58593
58828
|
try {
|
|
58594
|
-
|
|
58829
|
+
fs20.unlinkSync(PID_FILE);
|
|
58595
58830
|
} catch {
|
|
58596
58831
|
}
|
|
58597
58832
|
};
|
|
@@ -58651,7 +58886,7 @@ void (async () => {
|
|
|
58651
58886
|
const res = await fetch(`${httpBase(serverUrl)}/api/nodes/exchange`, {
|
|
58652
58887
|
method: "POST",
|
|
58653
58888
|
headers: { "content-type": "application/json" },
|
|
58654
|
-
body: JSON.stringify({ enrollToken, nodeId: derivedNodeId, hostname:
|
|
58889
|
+
body: JSON.stringify({ enrollToken, nodeId: derivedNodeId, hostname: os11.hostname() })
|
|
58655
58890
|
});
|
|
58656
58891
|
if (!res.ok) throw new Error(`enroll token exchange failed: HTTP ${res.status}`);
|
|
58657
58892
|
const body = await res.json();
|
|
@@ -58674,7 +58909,7 @@ void (async () => {
|
|
|
58674
58909
|
const pid = spawnDaemon();
|
|
58675
58910
|
console.log(`\u2713 daemon started (PID ${pid})${nameChanged ? ` [name updated: ${prev.name} \u2192 ${name}]` : ""}`);
|
|
58676
58911
|
console.log(` logs: tail -f ${LOG_FILE}`);
|
|
58677
|
-
if (!process.env["PATH"]?.includes(
|
|
58912
|
+
if (!process.env["PATH"]?.includes(path19.dirname(LOCAL_BIN)))
|
|
58678
58913
|
console.log(` add to PATH: echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc`);
|
|
58679
58914
|
return;
|
|
58680
58915
|
}
|