duclaw-cli 1.9.12 → 1.9.14
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/bundle.js +328 -141
- package/dist/main.js +1 -1
- package/dist/worker-main.js +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -30242,7 +30242,7 @@ function printHelp() {
|
|
|
30242
30242
|
`);
|
|
30243
30243
|
}
|
|
30244
30244
|
function printVersion() {
|
|
30245
|
-
console.log(`duclaw-cli v${true ? "1.9.
|
|
30245
|
+
console.log(`duclaw-cli v${true ? "1.9.14" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -32288,9 +32288,9 @@ var NodeFsHandler = class {
|
|
|
32288
32288
|
if (this.fsw.closed) {
|
|
32289
32289
|
return;
|
|
32290
32290
|
}
|
|
32291
|
-
const
|
|
32291
|
+
const dirname8 = sp.dirname(file);
|
|
32292
32292
|
const basename4 = sp.basename(file);
|
|
32293
|
-
const parent = this.fsw._getWatchedDir(
|
|
32293
|
+
const parent = this.fsw._getWatchedDir(dirname8);
|
|
32294
32294
|
let prevStats = stats;
|
|
32295
32295
|
if (parent.has(basename4))
|
|
32296
32296
|
return;
|
|
@@ -32317,7 +32317,7 @@ var NodeFsHandler = class {
|
|
|
32317
32317
|
prevStats = newStats2;
|
|
32318
32318
|
}
|
|
32319
32319
|
} catch (error) {
|
|
32320
|
-
this.fsw._remove(
|
|
32320
|
+
this.fsw._remove(dirname8, basename4);
|
|
32321
32321
|
}
|
|
32322
32322
|
} else if (parent.has(basename4)) {
|
|
32323
32323
|
const at = newStats.atimeMs;
|
|
@@ -33279,8 +33279,8 @@ var chokidar_default = { watch, FSWatcher };
|
|
|
33279
33279
|
var import_node_cron = __toESM(require_node_cron());
|
|
33280
33280
|
|
|
33281
33281
|
// src/agent/createAgent.ts
|
|
33282
|
-
var
|
|
33283
|
-
var
|
|
33282
|
+
var import_node_crypto16 = require("node:crypto");
|
|
33283
|
+
var import_node_fs8 = require("node:fs");
|
|
33284
33284
|
|
|
33285
33285
|
// src/background/BackgroundManager.ts
|
|
33286
33286
|
var import_child_process = require("child_process");
|
|
@@ -41627,6 +41627,183 @@ async function parseResponseJson(response) {
|
|
|
41627
41627
|
}
|
|
41628
41628
|
}
|
|
41629
41629
|
|
|
41630
|
+
// src/attachments/attachmentContext.ts
|
|
41631
|
+
var import_node_crypto4 = require("node:crypto");
|
|
41632
|
+
var import_node_fs3 = require("node:fs");
|
|
41633
|
+
var import_node_path12 = require("node:path");
|
|
41634
|
+
var MAX_ATTACHMENT_RECORDS = 100;
|
|
41635
|
+
var RECENT_ATTACHMENT_LIMIT = 5;
|
|
41636
|
+
function makeAttachmentId(input) {
|
|
41637
|
+
const raw2 = [
|
|
41638
|
+
input.userId,
|
|
41639
|
+
input.platform,
|
|
41640
|
+
input.messageId,
|
|
41641
|
+
input.resourceKey,
|
|
41642
|
+
input.kind
|
|
41643
|
+
].join(":");
|
|
41644
|
+
const digest = (0, import_node_crypto4.createHash)("sha256").update(raw2).digest("hex").slice(0, 16);
|
|
41645
|
+
return `att_${input.kind === "image" ? "img" : "file"}_${digest}`;
|
|
41646
|
+
}
|
|
41647
|
+
function indexPath(userId) {
|
|
41648
|
+
return (0, import_node_path12.join)(getDuclawWorkspaceDir(), userId, "attachments", "index.json");
|
|
41649
|
+
}
|
|
41650
|
+
function readIndex(userId) {
|
|
41651
|
+
const filePath = indexPath(userId);
|
|
41652
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) return [];
|
|
41653
|
+
try {
|
|
41654
|
+
const parsed = JSON.parse((0, import_node_fs3.readFileSync)(filePath, "utf8"));
|
|
41655
|
+
return Array.isArray(parsed) ? parsed.filter(isAttachmentRecord) : [];
|
|
41656
|
+
} catch (error) {
|
|
41657
|
+
console.warn(`[attachments] failed to read attachment index: ${error.message}`);
|
|
41658
|
+
return [];
|
|
41659
|
+
}
|
|
41660
|
+
}
|
|
41661
|
+
function writeIndex(userId, records) {
|
|
41662
|
+
const filePath = indexPath(userId);
|
|
41663
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path12.dirname)(filePath), { recursive: true });
|
|
41664
|
+
(0, import_node_fs3.writeFileSync)(filePath, JSON.stringify(records.slice(0, MAX_ATTACHMENT_RECORDS), null, 2));
|
|
41665
|
+
}
|
|
41666
|
+
function isAttachmentRecord(value) {
|
|
41667
|
+
const record = value;
|
|
41668
|
+
return Boolean(record) && typeof record.id === "string" && (record.kind === "image" || record.kind === "file") && typeof record.userId === "string" && typeof record.pathOrUrl === "string";
|
|
41669
|
+
}
|
|
41670
|
+
function stringValue2(value) {
|
|
41671
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
41672
|
+
}
|
|
41673
|
+
function attachmentKind(value) {
|
|
41674
|
+
const type = stringValue2(value.type);
|
|
41675
|
+
const mimeType = stringValue2(value.mimeType);
|
|
41676
|
+
const name = stringValue2(value.name) ?? stringValue2(value.path) ?? stringValue2(value.url) ?? "";
|
|
41677
|
+
if (type === "image" || mimeType?.startsWith("image/") || /\.(png|jpe?g|gif|webp)$/i.test(name)) {
|
|
41678
|
+
return "image";
|
|
41679
|
+
}
|
|
41680
|
+
return "file";
|
|
41681
|
+
}
|
|
41682
|
+
function xmlEscape(value) {
|
|
41683
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
41684
|
+
}
|
|
41685
|
+
function upsertAttachments(userId, records) {
|
|
41686
|
+
if (records.length === 0) return;
|
|
41687
|
+
const existing = readIndex(userId);
|
|
41688
|
+
const byId = /* @__PURE__ */ new Map();
|
|
41689
|
+
for (const record of [...records, ...existing]) {
|
|
41690
|
+
if (!byId.has(record.id)) byId.set(record.id, record);
|
|
41691
|
+
}
|
|
41692
|
+
writeIndex(userId, Array.from(byId.values()).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)));
|
|
41693
|
+
}
|
|
41694
|
+
function listRecentAttachments(userId, limit = RECENT_ATTACHMENT_LIMIT) {
|
|
41695
|
+
return readIndex(userId).sort((a, b) => b.receivedAt.localeCompare(a.receivedAt)).slice(0, limit);
|
|
41696
|
+
}
|
|
41697
|
+
function resolveAttachmentPathOrUrl(userId, attachmentId) {
|
|
41698
|
+
return readIndex(userId).find((record) => record.id === attachmentId)?.pathOrUrl;
|
|
41699
|
+
}
|
|
41700
|
+
function collectAttachmentsFromRequest(request) {
|
|
41701
|
+
const metadata = request.metadata ?? {};
|
|
41702
|
+
const platform = request.platform || "unknown";
|
|
41703
|
+
const messageId = request.requestId;
|
|
41704
|
+
const receivedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
41705
|
+
const records = [];
|
|
41706
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41707
|
+
const addRecord = (input) => {
|
|
41708
|
+
if (!input.pathOrUrl) return;
|
|
41709
|
+
const id = makeAttachmentId({
|
|
41710
|
+
userId: request.userId,
|
|
41711
|
+
platform,
|
|
41712
|
+
messageId,
|
|
41713
|
+
resourceKey: input.resourceKey,
|
|
41714
|
+
kind: input.kind
|
|
41715
|
+
});
|
|
41716
|
+
if (seen.has(id)) return;
|
|
41717
|
+
seen.add(id);
|
|
41718
|
+
records.push({
|
|
41719
|
+
id,
|
|
41720
|
+
kind: input.kind,
|
|
41721
|
+
platform,
|
|
41722
|
+
userId: request.userId,
|
|
41723
|
+
messageId,
|
|
41724
|
+
resourceKey: input.resourceKey,
|
|
41725
|
+
pathOrUrl: input.pathOrUrl,
|
|
41726
|
+
name: input.name,
|
|
41727
|
+
mimeType: input.mimeType,
|
|
41728
|
+
source: input.source,
|
|
41729
|
+
receivedAt
|
|
41730
|
+
});
|
|
41731
|
+
};
|
|
41732
|
+
const imageUrl = stringValue2(metadata.imageUrl);
|
|
41733
|
+
const imageKey = stringValue2(metadata.imageKey);
|
|
41734
|
+
if (imageUrl && imageKey) {
|
|
41735
|
+
addRecord({
|
|
41736
|
+
kind: "image",
|
|
41737
|
+
resourceKey: imageKey,
|
|
41738
|
+
pathOrUrl: imageUrl,
|
|
41739
|
+
source: `${platform}_metadata`
|
|
41740
|
+
});
|
|
41741
|
+
}
|
|
41742
|
+
const fileUrl = stringValue2(metadata.fileUrl);
|
|
41743
|
+
const fileName = stringValue2(metadata.fileName);
|
|
41744
|
+
if (fileUrl && fileName) {
|
|
41745
|
+
addRecord({
|
|
41746
|
+
kind: "file",
|
|
41747
|
+
resourceKey: fileName,
|
|
41748
|
+
pathOrUrl: fileUrl,
|
|
41749
|
+
name: fileName,
|
|
41750
|
+
source: `${platform}_metadata`
|
|
41751
|
+
});
|
|
41752
|
+
}
|
|
41753
|
+
const attachments = Array.isArray(metadata.attachments) ? metadata.attachments : [];
|
|
41754
|
+
for (const attachment of attachments) {
|
|
41755
|
+
const resourceKey = stringValue2(attachment.id) ?? stringValue2(attachment.name);
|
|
41756
|
+
const pathOrUrl = stringValue2(attachment.url) ?? stringValue2(attachment.path);
|
|
41757
|
+
if (!resourceKey || !pathOrUrl) continue;
|
|
41758
|
+
addRecord({
|
|
41759
|
+
kind: attachmentKind(attachment),
|
|
41760
|
+
resourceKey,
|
|
41761
|
+
pathOrUrl,
|
|
41762
|
+
name: stringValue2(attachment.name),
|
|
41763
|
+
mimeType: stringValue2(attachment.mimeType),
|
|
41764
|
+
source: `${platform}_attachment`
|
|
41765
|
+
});
|
|
41766
|
+
}
|
|
41767
|
+
return records;
|
|
41768
|
+
}
|
|
41769
|
+
function buildAttachmentContextXml(records) {
|
|
41770
|
+
if (records.length === 0) return "";
|
|
41771
|
+
const lines = [
|
|
41772
|
+
`<recent-attachments>`,
|
|
41773
|
+
` <system-note>Use attachment_id when referring to these attachments. Do not invent or reproduce long URLs; tools can resolve the real file source from attachment_id.</system-note>`
|
|
41774
|
+
];
|
|
41775
|
+
for (const record of records) {
|
|
41776
|
+
lines.push(` <${record.kind} id="${xmlEscape(record.id)}">`);
|
|
41777
|
+
lines.push(` <source>${xmlEscape(record.source ?? record.platform)}</source>`);
|
|
41778
|
+
lines.push(` <message_id>${xmlEscape(record.messageId)}</message_id>`);
|
|
41779
|
+
lines.push(` <resource_key>${xmlEscape(record.resourceKey)}</resource_key>`);
|
|
41780
|
+
if (record.name) lines.push(` <name>${xmlEscape(record.name)}</name>`);
|
|
41781
|
+
if (record.mimeType) lines.push(` <mime_type>${xmlEscape(record.mimeType)}</mime_type>`);
|
|
41782
|
+
lines.push(` <received_at>${xmlEscape(record.receivedAt)}</received_at>`);
|
|
41783
|
+
lines.push(` </${record.kind}>`);
|
|
41784
|
+
}
|
|
41785
|
+
lines.push(`</recent-attachments>`);
|
|
41786
|
+
return lines.join("\n");
|
|
41787
|
+
}
|
|
41788
|
+
function attachRecentAttachmentContext(request, content) {
|
|
41789
|
+
const current = collectAttachmentsFromRequest(request);
|
|
41790
|
+
if (current.length > 0) {
|
|
41791
|
+
upsertAttachments(request.userId, current);
|
|
41792
|
+
request.metadata = {
|
|
41793
|
+
...request.metadata ?? {},
|
|
41794
|
+
attachmentIds: current.map((record) => record.id),
|
|
41795
|
+
attachmentId: current[0]?.id
|
|
41796
|
+
};
|
|
41797
|
+
}
|
|
41798
|
+
const context = buildAttachmentContextXml(listRecentAttachments(request.userId));
|
|
41799
|
+
if (!context) return content;
|
|
41800
|
+
return `${content}
|
|
41801
|
+
|
|
41802
|
+
<system-reminder>
|
|
41803
|
+
${context}
|
|
41804
|
+
</system-reminder>`;
|
|
41805
|
+
}
|
|
41806
|
+
|
|
41630
41807
|
// src/tools/tools/ImageUnderstand.ts
|
|
41631
41808
|
var guessMediaTypeFromData = (base64Data) => {
|
|
41632
41809
|
if (base64Data.startsWith("/9j/")) return "image/jpeg";
|
|
@@ -41722,6 +41899,10 @@ var imageUnderstand = {
|
|
|
41722
41899
|
type: `string`,
|
|
41723
41900
|
description: `\u56FE\u7247\u7684\u8BBF\u95EEurl\u6216base64\u7F16\u7801\u5185\u5BB9\u3002\u5F53\u7528\u6237\u76F4\u63A5\u53D1\u9001\u56FE\u7247\u65F6\u6B64\u53C2\u6570\u53EF\u7701\u7565,\u5DE5\u5177\u4F1A\u81EA\u52A8\u4ECE\u4E0A\u4E0B\u6587\u83B7\u53D6\u56FE\u7247\u3002`
|
|
41724
41901
|
},
|
|
41902
|
+
attachment_id: {
|
|
41903
|
+
type: `string`,
|
|
41904
|
+
description: `\u6700\u8FD1\u9644\u4EF6\u4E0A\u4E0B\u6587\u4E2D\u7684\u77ED\u9644\u4EF6 ID\uFF0C\u4F8B\u5982 att_img_xxx\u3002\u4F18\u5148\u4F7F\u7528\u5B83\u5F15\u7528\u5386\u53F2\u56FE\u7247\uFF0C\u4E0D\u8981\u624B\u5199\u957F URL\u3002`
|
|
41905
|
+
},
|
|
41725
41906
|
prompt: {
|
|
41726
41907
|
type: `string`,
|
|
41727
41908
|
description: `prompt\u5B57\u6BB5\u7528\u6765\u63CF\u8FF0\u6587\u5B57\u6307\u4EE4,\u4F8B\u5982"\u63CF\u8FF0\u56FE\u7247\u5185\u5BB9"`
|
|
@@ -41730,7 +41911,8 @@ var imageUnderstand = {
|
|
|
41730
41911
|
required: [`prompt`]
|
|
41731
41912
|
},
|
|
41732
41913
|
async execute(input, userRequest) {
|
|
41733
|
-
const
|
|
41914
|
+
const attachmentId = typeof input.attachment_id === "string" ? input.attachment_id.trim() : "";
|
|
41915
|
+
const imageSource = userRequest?.metadata?.imageUrl || (attachmentId && userRequest?.userId ? resolveAttachmentPathOrUrl(userRequest.userId, attachmentId) : void 0) || input.image_url;
|
|
41734
41916
|
if (!imageSource) {
|
|
41735
41917
|
throw new Error(`[ImageUnderstand] \u672A\u63D0\u4F9B\u56FE\u7247: \u8BF7\u4F20\u5165 image_url \u53C2\u6570\u6216\u901A\u8FC7\u6D88\u606F\u53D1\u9001\u56FE\u7247`);
|
|
41736
41918
|
}
|
|
@@ -41783,7 +41965,7 @@ var imageUnderstand = {
|
|
|
41783
41965
|
|
|
41784
41966
|
// src/tools/tools/ImageGenerate.ts
|
|
41785
41967
|
var import_promises12 = require("node:fs/promises");
|
|
41786
|
-
var
|
|
41968
|
+
var import_node_path13 = __toESM(require("node:path"));
|
|
41787
41969
|
var DEFAULT_BASE_URL = "https://direct.shanyiapi.com";
|
|
41788
41970
|
var DEFAULT_MODEL = "gpt-image-2";
|
|
41789
41971
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([403, 429, 500, 502, 503, 504, 524]);
|
|
@@ -41810,7 +41992,7 @@ function extensionFromContentType(contentType) {
|
|
|
41810
41992
|
}
|
|
41811
41993
|
function extensionFromUrl(url) {
|
|
41812
41994
|
try {
|
|
41813
|
-
const ext =
|
|
41995
|
+
const ext = import_node_path13.default.extname(new URL(url).pathname).toLowerCase();
|
|
41814
41996
|
if ([".png", ".jpg", ".jpeg", ".webp", ".gif"].includes(ext)) return ext;
|
|
41815
41997
|
} catch {
|
|
41816
41998
|
return "";
|
|
@@ -41943,7 +42125,7 @@ var imageGenerate = {
|
|
|
41943
42125
|
requestId: generated.requestId
|
|
41944
42126
|
}, null, 2);
|
|
41945
42127
|
}
|
|
41946
|
-
const outDir =
|
|
42128
|
+
const outDir = import_node_path13.default.join(getEffectiveCwd(userRequest), "imagegen");
|
|
41947
42129
|
await (0, import_promises12.mkdir)(outDir, { recursive: true });
|
|
41948
42130
|
const stem = sanitizeName(String(input.filenameStem || prompt));
|
|
41949
42131
|
const savedFiles = [];
|
|
@@ -41952,7 +42134,7 @@ var imageGenerate = {
|
|
|
41952
42134
|
const image = item.url ? await downloadImage(item.url, timeoutMs) : item.b64_json ? decodeBase64Image(item.b64_json) : null;
|
|
41953
42135
|
if (!image) continue;
|
|
41954
42136
|
const fileName = `${stem}-${index + 1}${image.extension}`;
|
|
41955
|
-
const filePath =
|
|
42137
|
+
const filePath = import_node_path13.default.join(outDir, fileName);
|
|
41956
42138
|
await (0, import_promises12.writeFile)(filePath, image.buffer);
|
|
41957
42139
|
savedFiles.push({ filePath, fileName });
|
|
41958
42140
|
}
|
|
@@ -42397,10 +42579,10 @@ var goalDelete = {
|
|
|
42397
42579
|
};
|
|
42398
42580
|
|
|
42399
42581
|
// src/tools/tools/department/DepartmentCreate.ts
|
|
42400
|
-
var
|
|
42582
|
+
var import_node_crypto9 = require("node:crypto");
|
|
42401
42583
|
|
|
42402
42584
|
// src/department/mailbox/mailbox.ts
|
|
42403
|
-
var
|
|
42585
|
+
var import_node_crypto8 = require("node:crypto");
|
|
42404
42586
|
|
|
42405
42587
|
// src/agent/interruptRegistry.ts
|
|
42406
42588
|
var registry = /* @__PURE__ */ new Map();
|
|
@@ -42451,7 +42633,7 @@ var drainInterrupts = (userId) => {
|
|
|
42451
42633
|
};
|
|
42452
42634
|
|
|
42453
42635
|
// src/agent/events.ts
|
|
42454
|
-
var
|
|
42636
|
+
var import_node_crypto5 = require("node:crypto");
|
|
42455
42637
|
var rowToEvent = (row) => ({
|
|
42456
42638
|
id: row.id,
|
|
42457
42639
|
userId: row.userId,
|
|
@@ -42468,7 +42650,7 @@ var rowToEvent = (row) => ({
|
|
|
42468
42650
|
var recordAgentEvent = (input) => {
|
|
42469
42651
|
const db3 = createSqliteDB();
|
|
42470
42652
|
const now = Date.now();
|
|
42471
|
-
const id = `evt_${(0,
|
|
42653
|
+
const id = `evt_${(0, import_node_crypto5.randomUUID)().slice(0, 12)}`;
|
|
42472
42654
|
const payloadJson = JSON.stringify(input.payload);
|
|
42473
42655
|
db3.prepare(`
|
|
42474
42656
|
INSERT INTO agent_events (
|
|
@@ -42599,7 +42781,7 @@ ${ceoFollowupInstruction}
|
|
|
42599
42781
|
};
|
|
42600
42782
|
|
|
42601
42783
|
// src/department/mailbox/events.ts
|
|
42602
|
-
var
|
|
42784
|
+
var import_node_crypto6 = require("node:crypto");
|
|
42603
42785
|
var parseDetail = (detailJson) => {
|
|
42604
42786
|
if (!detailJson) return void 0;
|
|
42605
42787
|
try {
|
|
@@ -42640,7 +42822,7 @@ var mapMailboxEventRow = (row) => {
|
|
|
42640
42822
|
var recordMailboxEvent = (input) => {
|
|
42641
42823
|
const db3 = createSqliteDB();
|
|
42642
42824
|
const event = {
|
|
42643
|
-
id: (0,
|
|
42825
|
+
id: (0, import_node_crypto6.randomUUID)().slice(0, 12),
|
|
42644
42826
|
messageId: input.messageId,
|
|
42645
42827
|
mailboxId: input.mailboxId,
|
|
42646
42828
|
actorMailboxId: input.actorMailboxId,
|
|
@@ -42924,7 +43106,7 @@ var deleteDepartmentMemberById = (departmentName, memberId) => {
|
|
|
42924
43106
|
};
|
|
42925
43107
|
|
|
42926
43108
|
// src/department/mailbox/ceoFollowup.ts
|
|
42927
|
-
var
|
|
43109
|
+
var import_node_crypto7 = require("node:crypto");
|
|
42928
43110
|
var rowToFollowup = (row) => ({
|
|
42929
43111
|
id: row.id,
|
|
42930
43112
|
sourceMessageId: row.sourceMessageId,
|
|
@@ -42971,7 +43153,7 @@ var enqueueCeoFollowupFromMailbox = (message) => {
|
|
|
42971
43153
|
if (!message.originUserId || !message.originPlatform) return null;
|
|
42972
43154
|
const db3 = createSqliteDB();
|
|
42973
43155
|
const now = Date.now();
|
|
42974
|
-
const id = `cfu_${(0,
|
|
43156
|
+
const id = `cfu_${(0, import_node_crypto7.randomUUID)().slice(0, 12)}`;
|
|
42975
43157
|
db3.prepare(`
|
|
42976
43158
|
INSERT INTO ceo_followups (
|
|
42977
43159
|
id,
|
|
@@ -43301,7 +43483,7 @@ var recordMailboxReceivedAgentEvent = (msg) => {
|
|
|
43301
43483
|
};
|
|
43302
43484
|
var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
43303
43485
|
const db3 = createSqliteDB();
|
|
43304
|
-
const id = (0,
|
|
43486
|
+
const id = (0, import_node_crypto8.randomUUID)().slice(0, 8);
|
|
43305
43487
|
const threadId = options?.threadId || id;
|
|
43306
43488
|
const workItemContext = resolveWorkItemContext(fromMailboxId, toMailboxId, id, options);
|
|
43307
43489
|
const stmt = db3.prepare(`insert into mailbox (
|
|
@@ -43444,7 +43626,7 @@ var departmentCreate = {
|
|
|
43444
43626
|
return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
|
|
43445
43627
|
}
|
|
43446
43628
|
let departmentDefinition = {
|
|
43447
|
-
id: (0,
|
|
43629
|
+
id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
|
|
43448
43630
|
name,
|
|
43449
43631
|
charter,
|
|
43450
43632
|
sourceGoalId,
|
|
@@ -43711,7 +43893,7 @@ var departmentList = {
|
|
|
43711
43893
|
};
|
|
43712
43894
|
|
|
43713
43895
|
// src/tools/tools/department/DepartmentMemberCreate.ts
|
|
43714
|
-
var
|
|
43896
|
+
var import_node_crypto10 = require("node:crypto");
|
|
43715
43897
|
var DESCRIPTION25 = `
|
|
43716
43898
|
\u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
|
|
43717
43899
|
|
|
@@ -43777,7 +43959,7 @@ var departmentMemberCreate = {
|
|
|
43777
43959
|
}
|
|
43778
43960
|
}
|
|
43779
43961
|
let departmentMember = {
|
|
43780
|
-
id: (0,
|
|
43962
|
+
id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
|
|
43781
43963
|
name,
|
|
43782
43964
|
departmentId: department.id,
|
|
43783
43965
|
mailBoxId: getMailBoxId(department.name, name),
|
|
@@ -43940,10 +44122,10 @@ var checkDepartmentReplies = {
|
|
|
43940
44122
|
``,
|
|
43941
44123
|
`\u51E0\u53E5\u63D0\u9192\uFF1A`,
|
|
43942
44124
|
`- \u8FD9\u4E0D\u4EE3\u8868\u8981\u4F60\u4EB2\u81EA\u4E0B\u573A read/bash/\u6D4B\u8BD5/\u6539\u4EE3\u7801\u2014\u2014\u56E2\u961F\u6CA1\u56DE\uFF0C\u4E0D\u662F\u4F60\u8BE5\u63A5\u624B\u7684\u4FE1\u53F7\u3002`,
|
|
43943
|
-
`- \u8001\u677F\u8981\u662F\u6B63\u7B49\u7740\uFF0C\u5148\u7528 send_message \u5982\u5B9E\u8DDF\u4ED6\u8BF4\u4E00\u53E5\u201C\u8D1F\u8D23\u4EBA\
|
|
44125
|
+
`- \u8001\u677F\u8981\u662F\u6B63\u7B49\u7740\uFF0C\u5148\u7528 send_message \u5982\u5B9E\u8DDF\u4ED6\u8BF4\u4E00\u53E5\u201C\u5DF2\u5B89\u6392\u7ED9\u8D1F\u8D23\u4EBA\u5904\u7406\uFF0C\u6211\u7B49\u56DE\u4FE1\u540E\u540C\u6B65\u201D\u3002`,
|
|
43944
44126
|
`- \u5982\u679C\u4EFB\u52A1\u521A\u6D3E\u51FA\u53BB\uFF0C\u4E0D\u8981\u5728\u540C\u4E00\u8F6E\u9A6C\u4E0A\u50AC\u529E\uFF1B\u7ED9\u8D1F\u8D23\u4EBA\u5408\u7406\u5904\u7406\u65F6\u95F4\u3002`,
|
|
43945
|
-
`- \u5DF2\u7ECF\u7B49\u4E86\u4E00\u9635\u3001\u8001\u677F\u53C8\u8FFD\u95EE\uFF0C\u6216\u53D1\u73B0\u660E\u786E\u98CE\u9669\u65F6\uFF0C\u518D\u7528 mailbox_followup \u6216
|
|
43946
|
-
`- \u522B\u5728\u8FD9\u4E00\u8F6E\u91CC\u53CD\u590D\u7A7A\u67E5 check_department_replies\uFF1B\u7B49\u56E2\u961F\u56DE\u4FE1\u3001\u8001\u677F\u8FFD\u95EE\u6216\
|
|
44127
|
+
`- \u5DF2\u7ECF\u7B49\u4E86\u4E00\u9635\u3001\u8001\u677F\u53C8\u8FFD\u95EE\uFF0C\u6216\u53D1\u73B0\u660E\u786E\u98CE\u9669\u65F6\uFF0C\u518D\u7528 mailbox_followup \u53BB\u8865\u5145\u4E0A\u4E0B\u6587\u6216\u8BE2\u95EE\u5BF9\u5E94 Department Head \u7684\u771F\u5B9E\u72B6\u6001\u3002`,
|
|
44128
|
+
`- \u522B\u5728\u8FD9\u4E00\u8F6E\u91CC\u53CD\u590D\u7A7A\u67E5 check_department_replies\uFF1B\u7B49\u56E2\u961F\u56DE\u4FE1\u3001\u8001\u677F\u8FFD\u95EE\u6216\u786E\u6709\u65B0\u80CC\u666F\uFF0C\u518D\u6765\u770B\u3002`
|
|
43947
44129
|
].join("\n");
|
|
43948
44130
|
}
|
|
43949
44131
|
const updateStmt = db3.prepare(`UPDATE mailbox SET status = 'read' WHERE id = ?`);
|
|
@@ -43967,13 +44149,13 @@ ${replies}`;
|
|
|
43967
44149
|
};
|
|
43968
44150
|
|
|
43969
44151
|
// src/department/learning.ts
|
|
43970
|
-
var
|
|
43971
|
-
var
|
|
43972
|
-
var
|
|
44152
|
+
var import_node_fs5 = require("node:fs");
|
|
44153
|
+
var import_node_path15 = __toESM(require("node:path"));
|
|
44154
|
+
var import_node_crypto11 = require("node:crypto");
|
|
43973
44155
|
|
|
43974
44156
|
// src/skill/SkillValidator.ts
|
|
43975
|
-
var
|
|
43976
|
-
var
|
|
44157
|
+
var import_node_fs4 = require("node:fs");
|
|
44158
|
+
var import_node_path14 = __toESM(require("node:path"));
|
|
43977
44159
|
var SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
43978
44160
|
var REQUIRED_SECTIONS = [
|
|
43979
44161
|
/(^|\n)##\s+(when to use|何时使用|trigger|triggers)\b/i,
|
|
@@ -43999,9 +44181,9 @@ var assertSafeSkillTarget = (rootDir, skillName) => {
|
|
|
43999
44181
|
if (!isValidSkillName(skillName)) {
|
|
44000
44182
|
throw new Error(`Invalid skill name "${skillName}". Use lowercase letters, digits, and single hyphens only.`);
|
|
44001
44183
|
}
|
|
44002
|
-
const root =
|
|
44003
|
-
const target =
|
|
44004
|
-
if (target !==
|
|
44184
|
+
const root = import_node_path14.default.resolve(rootDir);
|
|
44185
|
+
const target = import_node_path14.default.resolve(root, skillName);
|
|
44186
|
+
if (target !== import_node_path14.default.join(root, skillName) || !target.startsWith(root + import_node_path14.default.sep)) {
|
|
44005
44187
|
throw new Error(`Invalid skill install target for "${skillName}".`);
|
|
44006
44188
|
}
|
|
44007
44189
|
return target;
|
|
@@ -44074,14 +44256,14 @@ var validateSkillDocument = (input) => {
|
|
|
44074
44256
|
}
|
|
44075
44257
|
}
|
|
44076
44258
|
if (input.baseDir) {
|
|
44077
|
-
const normalizedBase =
|
|
44259
|
+
const normalizedBase = import_node_path14.default.resolve(input.baseDir);
|
|
44078
44260
|
for (const match2 of parsed.body.matchAll(/\]\(([^)]+)\)/g)) {
|
|
44079
44261
|
const href = match2[1].trim();
|
|
44080
44262
|
if (!href || /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith(`#`)) continue;
|
|
44081
|
-
const target =
|
|
44082
|
-
if (!target.startsWith(normalizedBase +
|
|
44263
|
+
const target = import_node_path14.default.resolve(normalizedBase, href.split(`#`)[0]);
|
|
44264
|
+
if (!target.startsWith(normalizedBase + import_node_path14.default.sep) && target !== normalizedBase) {
|
|
44083
44265
|
addError(errors, `unsafe_reference`, `Relative link "${href}" escapes the skill directory.`);
|
|
44084
|
-
} else if (!(0,
|
|
44266
|
+
} else if (!(0, import_node_fs4.existsSync)(target)) {
|
|
44085
44267
|
addError(errors, `missing_reference`, `Relative link "${href}" does not exist in the skill directory.`);
|
|
44086
44268
|
}
|
|
44087
44269
|
}
|
|
@@ -44098,9 +44280,9 @@ var mergeIssues = (target, source) => {
|
|
|
44098
44280
|
target.warnings.push(...source.warnings);
|
|
44099
44281
|
};
|
|
44100
44282
|
var validateScriptsDirectory = (skillDir, warnings) => {
|
|
44101
|
-
const scriptsDir =
|
|
44102
|
-
if (!(0,
|
|
44103
|
-
const entries = (0,
|
|
44283
|
+
const scriptsDir = import_node_path14.default.join(skillDir, `scripts`);
|
|
44284
|
+
if (!(0, import_node_fs4.existsSync)(scriptsDir)) return;
|
|
44285
|
+
const entries = (0, import_node_fs4.readdirSync)(scriptsDir, { withFileTypes: true }).filter((entry) => entry.isFile());
|
|
44104
44286
|
if (entries.length === 0) {
|
|
44105
44287
|
addWarning(warnings, `empty_scripts_dir`, `scripts/ exists but contains no files.`);
|
|
44106
44288
|
}
|
|
@@ -44108,19 +44290,19 @@ var validateScriptsDirectory = (skillDir, warnings) => {
|
|
|
44108
44290
|
var validateSkillDirectory = (skillDir, options = {}) => {
|
|
44109
44291
|
const errors = [];
|
|
44110
44292
|
const warnings = [];
|
|
44111
|
-
const normalizedSkillDir =
|
|
44112
|
-
const skillMdPath =
|
|
44113
|
-
if (!(0,
|
|
44293
|
+
const normalizedSkillDir = import_node_path14.default.resolve(skillDir);
|
|
44294
|
+
const skillMdPath = import_node_path14.default.join(normalizedSkillDir, `SKILL.md`);
|
|
44295
|
+
if (!(0, import_node_fs4.existsSync)(normalizedSkillDir) || !(0, import_node_fs4.statSync)(normalizedSkillDir).isDirectory()) {
|
|
44114
44296
|
addError(errors, `missing_skill_dir`, `Skill directory does not exist: ${normalizedSkillDir}`);
|
|
44115
44297
|
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
44116
44298
|
}
|
|
44117
|
-
if (!(0,
|
|
44299
|
+
if (!(0, import_node_fs4.existsSync)(skillMdPath) || !(0, import_node_fs4.statSync)(skillMdPath).isFile()) {
|
|
44118
44300
|
addError(errors, `missing_skill_md`, `Skill directory must contain SKILL.md.`);
|
|
44119
44301
|
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
44120
44302
|
}
|
|
44121
|
-
const raw2 = (0,
|
|
44303
|
+
const raw2 = (0, import_node_fs4.readFileSync)(skillMdPath, `utf-8`);
|
|
44122
44304
|
const documentResult = validateSkillDocument({
|
|
44123
|
-
skillName: options.expectedName ??
|
|
44305
|
+
skillName: options.expectedName ?? import_node_path14.default.basename(normalizedSkillDir),
|
|
44124
44306
|
skillMd: raw2,
|
|
44125
44307
|
baseDir: normalizedSkillDir
|
|
44126
44308
|
});
|
|
@@ -44172,26 +44354,26 @@ var formatSkillValidationIssues = (result) => {
|
|
|
44172
44354
|
};
|
|
44173
44355
|
|
|
44174
44356
|
// src/department/learning.ts
|
|
44175
|
-
var ensureDir = (dir) => (0,
|
|
44357
|
+
var ensureDir = (dir) => (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
|
|
44176
44358
|
var readJsonArray = (filePath) => {
|
|
44177
|
-
if (!(0,
|
|
44178
|
-
return JSON.parse((0,
|
|
44359
|
+
if (!(0, import_node_fs5.existsSync)(filePath)) return [];
|
|
44360
|
+
return JSON.parse((0, import_node_fs5.readFileSync)(filePath, "utf-8"));
|
|
44179
44361
|
};
|
|
44180
44362
|
var writeJsonArray = (filePath, records) => {
|
|
44181
|
-
ensureDir(
|
|
44182
|
-
(0,
|
|
44363
|
+
ensureDir(import_node_path15.default.dirname(filePath));
|
|
44364
|
+
(0, import_node_fs5.writeFileSync)(filePath, JSON.stringify(records, null, " "), "utf-8");
|
|
44183
44365
|
};
|
|
44184
44366
|
var departmentMemoryPath = (departmentName) => {
|
|
44185
|
-
return
|
|
44367
|
+
return import_node_path15.default.join(getDepartmentWorkSpaceDir(departmentName), "department-memory.json");
|
|
44186
44368
|
};
|
|
44187
44369
|
var departmentSkillPath = (departmentName) => {
|
|
44188
|
-
return
|
|
44370
|
+
return import_node_path15.default.join(getDepartmentWorkSpaceDir(departmentName), "department-skills.json");
|
|
44189
44371
|
};
|
|
44190
44372
|
var departmentSkillDir = (departmentName, skillName) => {
|
|
44191
|
-
return assertSafeSkillTarget(
|
|
44373
|
+
return assertSafeSkillTarget(import_node_path15.default.join(getDepartmentWorkSpaceDir(departmentName), "skills"), skillName);
|
|
44192
44374
|
};
|
|
44193
44375
|
var proposalsPath = () => {
|
|
44194
|
-
return
|
|
44376
|
+
return import_node_path15.default.join(getDepartmentBaseDir(), "department-proposals.json");
|
|
44195
44377
|
};
|
|
44196
44378
|
var getDepartmentNameForHead = (request) => {
|
|
44197
44379
|
const mailboxId = request?.departmentAgentId;
|
|
@@ -44207,7 +44389,7 @@ var listDepartmentMemories = (departmentName) => {
|
|
|
44207
44389
|
var createDepartmentMemory = (departmentName, input) => {
|
|
44208
44390
|
const now = Date.now();
|
|
44209
44391
|
const memory = {
|
|
44210
|
-
id: (0,
|
|
44392
|
+
id: (0, import_node_crypto11.randomUUID)().slice(0, 8),
|
|
44211
44393
|
departmentName,
|
|
44212
44394
|
title: input.title,
|
|
44213
44395
|
content: input.content,
|
|
@@ -44258,7 +44440,7 @@ ${formatSkillValidationIssues(validation)}`);
|
|
|
44258
44440
|
}
|
|
44259
44441
|
const now = Date.now();
|
|
44260
44442
|
const skill = {
|
|
44261
|
-
id: (0,
|
|
44443
|
+
id: (0, import_node_crypto11.randomUUID)().slice(0, 8),
|
|
44262
44444
|
departmentName,
|
|
44263
44445
|
skillName: input.skillName,
|
|
44264
44446
|
description: input.description,
|
|
@@ -44289,7 +44471,7 @@ var keepDepartmentSkill = (departmentName, id) => {
|
|
|
44289
44471
|
${formatSkillValidationIssues(validation)}`);
|
|
44290
44472
|
}
|
|
44291
44473
|
ensureDir(skillDir);
|
|
44292
|
-
(0,
|
|
44474
|
+
(0, import_node_fs5.writeFileSync)(import_node_path15.default.join(skillDir, "SKILL.md"), records[idx].skillMd, "utf-8");
|
|
44293
44475
|
const smokeTest = smokeTestSkillDirectory(skillDir, { expectedName: records[idx].skillName });
|
|
44294
44476
|
if (!smokeTest.ok) {
|
|
44295
44477
|
throw new Error(`[departmentSkill] Skill smoke test \u5931\u8D25\uFF1A
|
|
@@ -44310,7 +44492,7 @@ var createDepartmentProposal = (input) => {
|
|
|
44310
44492
|
const records = readJsonArray(proposalsPath());
|
|
44311
44493
|
const proposal = {
|
|
44312
44494
|
...input,
|
|
44313
|
-
id: (0,
|
|
44495
|
+
id: (0, import_node_crypto11.randomUUID)().slice(0, 8),
|
|
44314
44496
|
status: "pending",
|
|
44315
44497
|
createdAt: Date.now()
|
|
44316
44498
|
};
|
|
@@ -44554,14 +44736,14 @@ var getCeoNudgeCooldownMs = () => {
|
|
|
44554
44736
|
var DESCRIPTION29 = `
|
|
44555
44737
|
\u5728\u5F53\u524D mailbox \u7EBF\u7A0B\u4E2D\u8FFD\u52A0\u4E00\u6761\u8865\u5145\u6D88\u606F\uFF0C\u4F46\u4E0D\u7ED3\u675F\u539F\u6D88\u606F\u7684\u5904\u7406\u3002
|
|
44556
44738
|
|
|
44557
|
-
\u5B83\u5728\u7EC4\u7EC7\u91CC\u7684\u542B\u4E49\u66F4\u63A5\u8FD1\u201C\u540C\u4E00\u4EF6\u4E8B\u7684\u7EE7\u7EED\u6C9F\u901A\u201D\uFF1A\
|
|
44558
|
-
\u7279\u522B\u662F\u7ED9 CEO/manager \u540C\u6B65\u201C\u5DF2\u59D4\u6D3E\u3001\u6B63\u5728\u68C0\u67E5\u3001\u7B49\u5F85\u4E0B\u5C5E\u7ED3\u679C\u3001\u5DF2\
|
|
44739
|
+
\u5B83\u5728\u7EC4\u7EC7\u91CC\u7684\u542B\u4E49\u66F4\u63A5\u8FD1\u201C\u540C\u4E00\u4EF6\u4E8B\u7684\u7EE7\u7EED\u6C9F\u901A\u201D\uFF1A\u8865\u5145\u65B0\u80CC\u666F\u3001\u540C\u6B65\u5F53\u524D\u72B6\u6001\u3001\u8BF4\u660E\u6B63\u5728\u7B49\u5F85\u54EA\u90E8\u5206\u7ED3\u679C\uFF0C\u6216\u9700\u8981\u5BF9\u65B9\u8865\u5145\u4EC0\u4E48\u3002
|
|
44740
|
+
\u7279\u522B\u662F\u7ED9 CEO/manager \u540C\u6B65\u201C\u5DF2\u59D4\u6D3E\u3001\u6B63\u5728\u68C0\u67E5\u3001\u7B49\u5F85\u4E0B\u5C5E\u7ED3\u679C\u3001\u5DF2\u6709\u90E8\u5206\u53D1\u73B0\u201D\u8FD9\u7C7B\u8FDB\u5EA6\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u5B83\uFF1B\u7B49\u4F60\u9A8C\u6536\u5B8C\u771F\u5B9E\u7ED3\u679C\u3001\u53EF\u4EE5\u4EA4\u4ED8\u6700\u7EC8\u7ED3\u8BBA\u65F6\uFF0C\u518D\u4F7F\u7528 reply_mailbox\u3002
|
|
44559
44741
|
|
|
44560
44742
|
\u9002\u7528\u573A\u666F\uFF1A
|
|
44561
44743
|
- \u540C\u6B65\u9636\u6BB5\u6027\u8FDB\u5C55
|
|
44562
44744
|
- \u4E3B\u52A8\u8FFD\u95EE\u6F84\u6E05\u4FE1\u606F
|
|
44563
44745
|
- \u5148\u53D1\u51FA\u90E8\u5206\u7ED3\u679C\uFF0C\u7A0D\u540E\u7EE7\u7EED\u8865\u5145
|
|
44564
|
-
- \u544A\u77E5\u4E0A\u6E38\u5DF2\u5B89\u6392\u4E0B\u5C5E\u3001\u6B63\u5728\u7B49\u5F85\u4E0B\u5C5E\u7ED3\u679C\uFF0C\u6216\u5DF2\
|
|
44746
|
+
- \u544A\u77E5\u4E0A\u6E38\u5DF2\u5B89\u6392\u4E0B\u5C5E\u3001\u6B63\u5728\u7B49\u5F85\u4E0B\u5C5E\u7ED3\u679C\uFF0C\u6216\u5DF2\u6709\u90E8\u5206\u53D1\u73B0
|
|
44565
44747
|
- CEO \u6536\u5230\u67D0\u4E2A\u90E8\u95E8\u6210\u5458\u7684\u7ED3\u679C\u540E\uFF0C\u82E5\u7528\u6237\u7EE7\u7EED\u63D0\u4FEE\u6539\u610F\u89C1\u3001bug \u53CD\u9988\u3001\u6253\u4E0D\u5F00\u7B49\u95EE\u9898\uFF0C\u5E94\u4F18\u5148\u5BF9\u8BE5\u6210\u5458\u4E0A\u4E00\u6761\u76F8\u5173\u56DE\u4FE1\u8C03\u7528 mailbox_followup\uFF0C\u628A\u53CD\u9988\u6CBF\u539F\u7EBF\u7A0B\u53D1\u56DE\u539F\u8D23\u4EFB\u4EBA
|
|
44566
44748
|
|
|
44567
44749
|
\u53C2\u6570\uFF1A
|
|
@@ -44573,6 +44755,7 @@ var DESCRIPTION29 = `
|
|
|
44573
44755
|
- \u6B64\u5DE5\u5177\u4E0D\u4F1A\u4FEE\u6539\u539F\u6D88\u606F\u72B6\u6001
|
|
44574
44756
|
- \u5982\u679C\u4F60\u5DF2\u7ECF\u5F62\u6210\u5BF9\u5F53\u524D\u6D88\u606F\u7684\u6B63\u5F0F\u7B54\u590D\uFF0C\u5E94\u4F7F\u7528 reply_mailbox
|
|
44575
44757
|
- \u5BF9 CEO \u800C\u8A00\uFF0C\u8FD9\u901A\u5E38\u662F\u201C\u628A\u8FD4\u5DE5\u9700\u6C42\u9000\u56DE\u539F\u8D23\u4EFB\u6210\u5458\u201D\u7684\u9996\u9009\u5DE5\u5177\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u76F4\u63A5\u91CD\u505A
|
|
44758
|
+
- \u5BF9 CEO \u800C\u8A00\uFF0C\u521A\u59D4\u6D3E\u540E\u4E0D\u8981\u7528\u6B64\u5DE5\u5177\u50AC\u8D1F\u8D23\u4EBA\uFF0C\u4E5F\u4E0D\u8981\u5BF9\u8001\u677F\u8BF4\u201C\u6211\u53BB\u50AC/\u5DF2\u50AC/\u4F1A\u76EF\u7740\u201D\u3002\u9ED8\u8BA4\u53EA\u540C\u6B65\u201C\u5DF2\u5B89\u6392\uFF0C\u7B49\u56DE\u4FE1\u540E\u540C\u6B65\u201D\u3002
|
|
44576
44759
|
`;
|
|
44577
44760
|
var looksLikeCeoNudge = (content, kind) => {
|
|
44578
44761
|
if (kind === `nudge`) return true;
|
|
@@ -44668,8 +44851,8 @@ var mailboxFollowup = {
|
|
|
44668
44851
|
|
|
44669
44852
|
// src/tools/tools/Bash.ts
|
|
44670
44853
|
var import_node_child_process = require("node:child_process");
|
|
44671
|
-
var
|
|
44672
|
-
var
|
|
44854
|
+
var import_node_crypto12 = require("node:crypto");
|
|
44855
|
+
var import_node_fs6 = require("node:fs");
|
|
44673
44856
|
var DESCRIPTION30 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002
|
|
44674
44857
|
|
|
44675
44858
|
\u7528\u9014\uFF1A
|
|
@@ -44709,7 +44892,7 @@ var sessions = /* @__PURE__ */ new Map();
|
|
|
44709
44892
|
function findExecutableShell2() {
|
|
44710
44893
|
for (const shell of SHELL_CANDIDATES2) {
|
|
44711
44894
|
try {
|
|
44712
|
-
(0,
|
|
44895
|
+
(0, import_node_fs6.accessSync)(shell, import_node_fs6.constants.X_OK);
|
|
44713
44896
|
return shell;
|
|
44714
44897
|
} catch {
|
|
44715
44898
|
}
|
|
@@ -44718,11 +44901,11 @@ function findExecutableShell2() {
|
|
|
44718
44901
|
}
|
|
44719
44902
|
function validateCwd(cwd) {
|
|
44720
44903
|
try {
|
|
44721
|
-
const stat11 = (0,
|
|
44904
|
+
const stat11 = (0, import_node_fs6.statSync)(cwd);
|
|
44722
44905
|
if (!stat11.isDirectory()) {
|
|
44723
44906
|
return `[bash] \u9519\u8BEF: cwd \u4E0D\u662F\u76EE\u5F55: ${cwd}`;
|
|
44724
44907
|
}
|
|
44725
|
-
(0,
|
|
44908
|
+
(0, import_node_fs6.accessSync)(cwd, import_node_fs6.constants.R_OK | import_node_fs6.constants.X_OK);
|
|
44726
44909
|
return null;
|
|
44727
44910
|
} catch (err) {
|
|
44728
44911
|
const code = err.code;
|
|
@@ -44965,7 +45148,7 @@ var bashTool = {
|
|
|
44965
45148
|
stdio: ["pipe", "pipe", "pipe"],
|
|
44966
45149
|
detached: process.platform !== "win32"
|
|
44967
45150
|
});
|
|
44968
|
-
const id = (0,
|
|
45151
|
+
const id = (0, import_node_crypto12.randomUUID)().slice(0, 8);
|
|
44969
45152
|
const session = {
|
|
44970
45153
|
id,
|
|
44971
45154
|
command,
|
|
@@ -45732,10 +45915,10 @@ var readDreamHistoryLimit = () => {
|
|
|
45732
45915
|
};
|
|
45733
45916
|
|
|
45734
45917
|
// src/skillForge/SkillForgeEngine.ts
|
|
45735
|
-
var
|
|
45918
|
+
var import_node_fs7 = require("node:fs");
|
|
45736
45919
|
var import_node_os2 = require("node:os");
|
|
45737
|
-
var
|
|
45738
|
-
var
|
|
45920
|
+
var import_node_path16 = require("node:path");
|
|
45921
|
+
var import_node_crypto13 = require("node:crypto");
|
|
45739
45922
|
var SkillForgeEngine = class {
|
|
45740
45923
|
proposalStorage;
|
|
45741
45924
|
draftRoot;
|
|
@@ -45743,8 +45926,8 @@ var SkillForgeEngine = class {
|
|
|
45743
45926
|
constructor(deps) {
|
|
45744
45927
|
this.proposalStorage = deps.proposalStorage;
|
|
45745
45928
|
const opt = deps.options ?? {};
|
|
45746
|
-
this.draftRoot = opt.draftRoot ?? (0,
|
|
45747
|
-
this.skillsInstallDir = opt.skillsInstallDir ?? (0,
|
|
45929
|
+
this.draftRoot = opt.draftRoot ?? (0, import_node_path16.join)((0, import_node_os2.homedir)(), ".duclaw", "skill-proposals");
|
|
45930
|
+
this.skillsInstallDir = opt.skillsInstallDir ?? (0, import_node_path16.join)((0, import_node_os2.homedir)(), ".agents", "skills");
|
|
45748
45931
|
}
|
|
45749
45932
|
// ---------- 公开方法 ----------
|
|
45750
45933
|
/**
|
|
@@ -45769,14 +45952,14 @@ ${formatSkillValidationIssues(validation)}`);
|
|
|
45769
45952
|
if (pending.some((p) => p.skillName === skillName)) {
|
|
45770
45953
|
return null;
|
|
45771
45954
|
}
|
|
45772
|
-
const id = (0,
|
|
45773
|
-
const draftDir = (0,
|
|
45774
|
-
(0,
|
|
45775
|
-
(0,
|
|
45955
|
+
const id = (0, import_node_crypto13.randomBytes)(4).toString("hex");
|
|
45956
|
+
const draftDir = (0, import_node_path16.join)(this.draftRoot, userId, id);
|
|
45957
|
+
(0, import_node_fs7.mkdirSync)(draftDir, { recursive: true });
|
|
45958
|
+
(0, import_node_fs7.writeFileSync)((0, import_node_path16.join)(draftDir, "SKILL.md"), skillMd, "utf-8");
|
|
45776
45959
|
const directoryValidation = validateSkillDirectory(draftDir, { expectedName: skillName });
|
|
45777
45960
|
if (!directoryValidation.ok) {
|
|
45778
45961
|
try {
|
|
45779
|
-
(0,
|
|
45962
|
+
(0, import_node_fs7.rmSync)(draftDir, { recursive: true, force: true });
|
|
45780
45963
|
} catch {
|
|
45781
45964
|
}
|
|
45782
45965
|
throw new Error(`[skillForge] Skill \u76EE\u5F55\u6821\u9A8C\u5931\u8D25\uFF1A
|
|
@@ -45811,26 +45994,26 @@ ${formatSkillValidationIssues(validation)}`);
|
|
|
45811
45994
|
}
|
|
45812
45995
|
const target = assertSafeSkillTarget(this.skillsInstallDir, proposal.skillName);
|
|
45813
45996
|
let installedTarget = target;
|
|
45814
|
-
if ((0,
|
|
45997
|
+
if ((0, import_node_fs7.existsSync)(target)) {
|
|
45815
45998
|
const alt = target + "-" + proposalId;
|
|
45816
|
-
(0,
|
|
45817
|
-
(0,
|
|
45999
|
+
(0, import_node_fs7.mkdirSync)(alt, { recursive: true });
|
|
46000
|
+
(0, import_node_fs7.cpSync)(proposal.draftDir, alt, { recursive: true });
|
|
45818
46001
|
installedTarget = alt;
|
|
45819
46002
|
} else {
|
|
45820
|
-
(0,
|
|
45821
|
-
(0,
|
|
46003
|
+
(0, import_node_fs7.mkdirSync)(target, { recursive: true });
|
|
46004
|
+
(0, import_node_fs7.cpSync)(proposal.draftDir, target, { recursive: true });
|
|
45822
46005
|
}
|
|
45823
46006
|
const smokeTest = smokeTestSkillDirectory(installedTarget, { expectedName: proposal.skillName });
|
|
45824
46007
|
if (!smokeTest.ok) {
|
|
45825
46008
|
try {
|
|
45826
|
-
(0,
|
|
46009
|
+
(0, import_node_fs7.rmSync)(installedTarget, { recursive: true, force: true });
|
|
45827
46010
|
} catch {
|
|
45828
46011
|
}
|
|
45829
46012
|
throw new Error(`[skillForge] Skill smoke test \u5931\u8D25\uFF0C\u5DF2\u56DE\u6EDA\u843D\u5730\u76EE\u5F55\uFF1A
|
|
45830
46013
|
${formatSkillValidationIssues(smokeTest)}`);
|
|
45831
46014
|
}
|
|
45832
46015
|
try {
|
|
45833
|
-
(0,
|
|
46016
|
+
(0, import_node_fs7.rmSync)(proposal.draftDir, { recursive: true, force: true });
|
|
45834
46017
|
} catch {
|
|
45835
46018
|
}
|
|
45836
46019
|
await this.removeProposal(userId, proposalId);
|
|
@@ -45842,7 +46025,7 @@ ${formatSkillValidationIssues(smokeTest)}`);
|
|
|
45842
46025
|
const proposal = list.find((p) => p.id === proposalId);
|
|
45843
46026
|
if (!proposal) return null;
|
|
45844
46027
|
try {
|
|
45845
|
-
(0,
|
|
46028
|
+
(0, import_node_fs7.rmSync)(proposal.draftDir, { recursive: true, force: true });
|
|
45846
46029
|
} catch {
|
|
45847
46030
|
}
|
|
45848
46031
|
await this.removeProposal(userId, proposalId);
|
|
@@ -46051,7 +46234,7 @@ var skillForgeDrop = (engine) => ({
|
|
|
46051
46234
|
});
|
|
46052
46235
|
|
|
46053
46236
|
// src/memory/MemoryEngine.ts
|
|
46054
|
-
var
|
|
46237
|
+
var import_node_crypto14 = require("node:crypto");
|
|
46055
46238
|
var MemoryEngine = class {
|
|
46056
46239
|
storage;
|
|
46057
46240
|
recallIndexStorage;
|
|
@@ -46079,7 +46262,7 @@ var MemoryEngine = class {
|
|
|
46079
46262
|
}
|
|
46080
46263
|
const now = Date.now();
|
|
46081
46264
|
const memory = {
|
|
46082
|
-
id: (0,
|
|
46265
|
+
id: (0, import_node_crypto14.randomBytes)(4).toString("hex"),
|
|
46083
46266
|
userId,
|
|
46084
46267
|
title,
|
|
46085
46268
|
content,
|
|
@@ -46731,13 +46914,13 @@ var COMPANY_VALUES_PROMPT = `<\u516C\u53F8\u5171\u540C\u4FE1\u5FF5>
|
|
|
46731
46914
|
</\u516C\u53F8\u5171\u540C\u4FE1\u5FF5>`;
|
|
46732
46915
|
|
|
46733
46916
|
// src/agent/outboundDedup.ts
|
|
46734
|
-
var
|
|
46917
|
+
var import_node_crypto15 = require("node:crypto");
|
|
46735
46918
|
var DEFAULT_WINDOW_MS = 15e3;
|
|
46736
46919
|
var recentSends = /* @__PURE__ */ new Map();
|
|
46737
46920
|
var lastSweepAt = 0;
|
|
46738
46921
|
var normalize3 = (text2) => text2.replace(/\s+/g, " ").trim();
|
|
46739
46922
|
var keyFor = (userId, normalized) => {
|
|
46740
|
-
const hash = (0,
|
|
46923
|
+
const hash = (0, import_node_crypto15.createHash)("sha1").update(normalized).digest("hex");
|
|
46741
46924
|
return `${userId}::${hash}`;
|
|
46742
46925
|
};
|
|
46743
46926
|
var sweep = (now, windowMs) => {
|
|
@@ -46785,12 +46968,12 @@ var isAbortError2 = (error) => {
|
|
|
46785
46968
|
return error.name === "AbortError" || error.message.includes("aborted") || error.message.includes("AbortError");
|
|
46786
46969
|
};
|
|
46787
46970
|
var llmRequestIdForTurn = (request, messages, system, tools) => {
|
|
46788
|
-
const hash = (0,
|
|
46971
|
+
const hash = (0, import_node_crypto16.createHash)("sha256").update(request.requestId).update("\0").update(system).update("\0").update(JSON.stringify(messages)).update("\0").update(JSON.stringify(tools.map((tool) => tool.name).sort())).digest("hex").slice(0, 40);
|
|
46789
46972
|
return `dreq_${hash}`;
|
|
46790
46973
|
};
|
|
46791
46974
|
var getDefaultAgentConfig = (tools, systemPrompt) => {
|
|
46792
46975
|
loadEnv();
|
|
46793
|
-
(0,
|
|
46976
|
+
(0, import_node_fs8.mkdirSync)(DEFAULT_WORKSPACE_PATH, { recursive: true });
|
|
46794
46977
|
let system = ``;
|
|
46795
46978
|
if (!systemPrompt) {
|
|
46796
46979
|
system = `
|
|
@@ -46832,13 +47015,15 @@ ${RUNTIME_PROCESS_SAFETY_PROMPT}
|
|
|
46832
47015
|
|
|
46833
47016
|
\u516C\u53F8\u91CC\u6709\u5404\u4E2A\u90E8\u95E8\u548C\u5B83\u4EEC\u7684\u8D1F\u8D23\u4EBA\uFF08Department Head\uFF09\u3002\u4E13\u4E1A\u7684\u6D3B\u2014\u2014\u5199\u4EE3\u7801\u3001\u8BFB\u4EE3\u7801\u5B9A\u4F4D\u95EE\u9898\u3001\u6539\u6587\u4EF6\u3001\u8DD1\u6D4B\u8BD5\u3001\u8C03\u8BD5\u3001\u90E8\u7F72\uFF0C\u5904\u7406\u6570\u636E/\u6587\u6863/\u97F3\u89C6\u9891/\u56FE\u7247\uFF0C\u67E5\u8BC1\u5916\u90E8 API\uFF0C\u751F\u6210\u590D\u6742\u4EA7\u7269\u7B49\u2014\u2014\u4F60\u7684\u7B2C\u4E00\u53CD\u5E94\u662F\u627E\u5BF9\u5E94\u56E2\u961F\u7684 Head\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u4E0A\u624B\u3002\u4F60\u80FD\u770B\u5230\u7684\u53EA\u6709\u90E8\u95E8\u548C\u5B83\u4EEC\u7684 Head\uFF1BExecutor \u7531\u5404 Head \u81EA\u5DF1\u7BA1\u7406\uFF0C\u9ED8\u8BA4\u4E0D\u5728\u4F60\u7684\u89C6\u91CE\u91CC\u3002
|
|
46834
47017
|
|
|
46835
|
-
\u4F60\u548C\u56E2\u961F\u534F\u4F5C\u7684\u65B9\u5F0F\u5F88\u81EA\u7136\uFF1A\u9700\u8981\u56E2\u961F\u505A\u4E8B\uFF0C\u5C31\u7ED9\u5BF9\u5E94 Head \u53D1\u6D88\u606F\uFF08department_communicate\uFF09\uFF1B\u6709\u65B0\u7684\u80CC\u666F\u3001\u4FEE\u6B63\u8981\u6C42\u3001\u7528\u6237\u53CD\u9988\u6216\u5DF2\u7ECF\u8FC7\u4E86\u5408\u7406\u7B49\u5F85\u65F6\u95F4\
|
|
47018
|
+
\u4F60\u548C\u56E2\u961F\u534F\u4F5C\u7684\u65B9\u5F0F\u5F88\u81EA\u7136\uFF1A\u9700\u8981\u56E2\u961F\u505A\u4E8B\uFF0C\u5C31\u7ED9\u5BF9\u5E94 Head \u53D1\u6D88\u606F\uFF08department_communicate\uFF09\uFF1B\u6709\u65B0\u7684\u80CC\u666F\u3001\u4FEE\u6B63\u8981\u6C42\u3001\u7528\u6237\u53CD\u9988\uFF0C\u6216\u5DF2\u7ECF\u8FC7\u4E86\u5408\u7406\u7B49\u5F85\u65F6\u95F4\u4E14\u786E\u5B9E\u9700\u8981\u8865\u5145\u8BE2\u95EE\u65F6\uFF0C\u7528 mailbox_followup \u63A5\u56DE\u539F\u6765\u7684\u7EBF\u7A0B\uFF1B\u60F3\u770B\u56E2\u961F\u56DE\u4E86\u4EC0\u4E48\uFF0C\u7528 check_department_replies \u6536\u4E00\u4E0B\u3002\u7EC4\u7EC7\u91CC\u8FD8\u6CA1\u6709\u5BF9\u53E3\u7684\u56E2\u961F\u65F6\uFF0C\u4F60\u624D\u5F20\u7F57\u7740\u5EFA\u90E8\u95E8\u3001\u62DB Head\uFF08\u5EFA\u597D\u90E8\u95E8\u5148\u7528 department_member_create \u51FA\u4E00\u4E2A Head\uFF0C\u518D\u628A\u5177\u4F53\u4EFB\u52A1\u6D3E\u7ED9\u4ED6\uFF09\u3002
|
|
46836
47019
|
|
|
46837
47020
|
\u8001\u677F\u95EE\u4F60\u4EFB\u4F55\u4E8B\u2014\u2014\u5305\u62EC\u201C\u73B0\u5728\u8FDB\u5EA6\u5982\u4F55\u201D\u201C\u6D4B\u8BD5\u5F97\u600E\u4E48\u6837\u201D\u201C\u90A3\u8FB9\u9760\u8C31\u5417\u201D\u201C\u5361\u5728\u54EA\u4E86\u201D\u8FD9\u7C7B\u2014\u2014\u4F60\u7ED9\u7684\u90FD\u662F\u4F60\u5411\u56E2\u961F\u6838\u5B9E\u8FC7\u7684\u771F\u5B9E\u60C5\u51B5\uFF0C\u7EDD\u4E0D\u662F\u51ED\u5370\u8C61\u7F16\u51FA\u6765\u7684\u3002\u5982\u679C\u8FD9\u4F1A\u513F\u8FD8\u6CA1\u62FF\u5230\u51C6\u4FE1\uFF0C\u4F60\u5B81\u53EF\u5148\u56DE\u8001\u677F\u4E00\u53E5\u201C\u6211\u53BB\u8DDF\u56E2\u961F\u786E\u8BA4\uFF0C\u7A0D\u540E\u7ED9\u4F60\u56DE\u201D\uFF0C\u4E5F\u4E0D\u7CCA\u5F04\u4E00\u4E2A\u7B54\u6848\u3002\u5728\u4F60\u628A\u771F\u5B9E\u7ED3\u8BBA\u4EA4\u5230\u8001\u677F\u624B\u4E0A\u4E4B\u524D\uFF0C\u8FD9\u4EF6\u4E8B\u5BF9\u4F60\u90FD\u6CA1\u7B97\u5B8C\u3002
|
|
46838
47021
|
|
|
46839
47022
|
\u67D0\u4E2A Head \u5DF2\u7ECF\u8D1F\u8D23\u7684\u4EA7\u51FA\uFF0C\u540E\u7EED\u7684\u8FD4\u5DE5\u3001bug \u4FEE\u590D\u3001\u201C\u6253\u4E0D\u5F00\u201D\u201C\u5E2E\u6211\u6539\u4E00\u4E0B\u201D\u201C\u518D\u51FA\u4E00\u7248\u201D\uFF0C\u9ED8\u8BA4\u8FD8\u5F52\u4ED6\u2014\u2014\u4F60\u987A\u7740\u539F\u6765\u7684\u7EBF\u7A0B\u628A\u53CD\u9988\u8FFD\u52A0\u7ED9\u4ED6\uFF08mailbox_followup\uFF09\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u63A5\u624B\u91CD\u505A\u3002
|
|
46840
47023
|
|
|
46841
|
-
\u53EA\u6709\u8FD9\u51E0\u79CD\u60C5\u51B5\u4F60\u624D\u81EA\u5DF1\u4E0A\u624B\uFF1A\u8001\u677F\u660E\u786E\u8981\u4F60\u4EB2\u81EA\u505A\u3001\u7EC4\u7EC7\u91CC\u786E\u5B9E\u6CA1\u6709\u4E5F\u6765\u4E0D\u53CA\u7EC4\u5EFA\u5BF9\u53E3\u56E2\u961F\u3001\u6216\u56E2\u961F\u660E\u786E\u505A\u4E0D\u6210\u4E14\u8001\u677F\u540C\u610F\u4F60\u63A5\u7BA1\u3002\u9664\u6B64\u4E4B\u5916\uFF0C\u56E2\u961F\u56DE\u5F97\u6162\u3001\u6682\u65F6\u6CA1\u56DE\u3001check \u8FD8\u6CA1\u7ED3\u679C\uFF0C\u90FD\u4E0D\u662F\u4F60\u4E0B\u573A\u5E72\u6D3B\u7684\u7406\u7531\u3002\u521A\u628A\u4EFB\u52A1\u6D3E\u51FA\u53BB\u65F6\uFF0C\u4E0D\u8981\u7ACB\u523B\u50AC\u529E\uFF0C\u4E5F\u4E0D\u8981\u5728\u540C\u4E00\u8F6E\u8FDE\u7EED\u8FFD\u95EE\uFF1B\u8BE5\u505A\u7684\u662F\u5982\u5B9E\u8DDF\u8001\u677F\u8BF4\u201C\u5DF2\u5B89\u6392\u56E2\u961F\u5904\u7406\uFF0C\u6211\u62FF\u5230\u7ED3\u679C\u5C31\u540C\u6B65\u201D\uFF0C\u7136\u540E\u628A\u8FD9\u4E00\u8F6E\u6536\u4F4F\u3002\u53EA\u6709\u5DF2\u7ECF\u7B49\u5F85\u8FC7\u5408\u7406\u65F6\u95F4\u3001\u8001\u677F\u53C8\u8FFD\u95EE\u8FDB\u5EA6\u3001\u6216\u4F60\u53D1\u73B0\u660E\u786E\u98CE\u9669/\u963B\u585E\u65F6\uFF0C\u624D\u6CBF\u539F\u7EBF\u7A0B\u9002\u5EA6\
|
|
47024
|
+
\u53EA\u6709\u8FD9\u51E0\u79CD\u60C5\u51B5\u4F60\u624D\u81EA\u5DF1\u4E0A\u624B\uFF1A\u8001\u677F\u660E\u786E\u8981\u4F60\u4EB2\u81EA\u505A\u3001\u7EC4\u7EC7\u91CC\u786E\u5B9E\u6CA1\u6709\u4E5F\u6765\u4E0D\u53CA\u7EC4\u5EFA\u5BF9\u53E3\u56E2\u961F\u3001\u6216\u56E2\u961F\u660E\u786E\u505A\u4E0D\u6210\u4E14\u8001\u677F\u540C\u610F\u4F60\u63A5\u7BA1\u3002\u9664\u6B64\u4E4B\u5916\uFF0C\u56E2\u961F\u56DE\u5F97\u6162\u3001\u6682\u65F6\u6CA1\u56DE\u3001check \u8FD8\u6CA1\u7ED3\u679C\uFF0C\u90FD\u4E0D\u662F\u4F60\u4E0B\u573A\u5E72\u6D3B\u7684\u7406\u7531\u3002\u521A\u628A\u4EFB\u52A1\u6D3E\u51FA\u53BB\u65F6\uFF0C\u4E0D\u8981\u7ACB\u523B\u50AC\u529E\uFF0C\u4E5F\u4E0D\u8981\u5728\u540C\u4E00\u8F6E\u8FDE\u7EED\u8FFD\u95EE\uFF1B\u8BE5\u505A\u7684\u662F\u5982\u5B9E\u8DDF\u8001\u677F\u8BF4\u201C\u5DF2\u5B89\u6392\u56E2\u961F\u5904\u7406\uFF0C\u6211\u62FF\u5230\u7ED3\u679C\u5C31\u540C\u6B65\u201D\uFF0C\u7136\u540E\u628A\u8FD9\u4E00\u8F6E\u6536\u4F4F\u3002\u53EA\u6709\u5DF2\u7ECF\u7B49\u5F85\u8FC7\u5408\u7406\u65F6\u95F4\u3001\u8001\u677F\u53C8\u8FFD\u95EE\u8FDB\u5EA6\u3001\u6216\u4F60\u53D1\u73B0\u660E\u786E\u98CE\u9669/\u963B\u585E\u65F6\uFF0C\u624D\u6CBF\u539F\u7EBF\u7A0B\u9002\u5EA6\u8BE2\u95EE\u8D1F\u8D23\u4EBA\u3002
|
|
47025
|
+
|
|
47026
|
+
\u5BF9\u8001\u677F\u6C47\u62A5\u65F6\u4E0D\u8981\u4F7F\u7528\u201C\u6211\u53BB\u50AC\u4E00\u4E0B / \u6211\u4F1A\u76EF\u7740 / \u5DF2\u7ECF\u50AC\u4E86 / \u7EE7\u7EED\u50AC\u8D1F\u8D23\u4EBA / \u8BA9\u4ED6\u5C3D\u5FEB\u56DE\u590D\u201D\u8FD9\u7C7B\u7BA1\u7406\u538B\u8FEB\u8BDD\u672F\u3002\u9ED8\u8BA4\u4F7F\u7528\u514B\u5236\u8868\u8FF0\uFF1A\u201C\u5DF2\u5B89\u6392\u7ED9\u8D1F\u8D23\u4EBA\u5904\u7406\uFF0C\u6211\u7B49\u56DE\u4FE1\u540E\u540C\u6B65\u201D\uFF1B\u9664\u975E\u786E\u5B9E\u5DF2\u7ECF\u8FC7\u4E86\u5408\u7406\u7B49\u5F85\u65F6\u95F4\u5E76\u4E14\u53D1\u751F\u4E86\u65B0\u7684\u8FFD\u95EE\u6216\u98CE\u9669\uFF0C\u5426\u5219\u4E0D\u8981\u6697\u793A\u4F60\u6B63\u5728\u50AC\u4EBA\u3002
|
|
46842
47027
|
|
|
46843
47028
|
\u5F02\u5E38\u7B80\u5355\u3001\u4F4E\u98CE\u9669\u3001\u4E00\u4E24\u6B65\u5C31\u80FD\u5B8C\u6210\u7684\u5C0F\u4E8B\uFF08\u7B80\u5355\u95EE\u7B54\u3001\u89E3\u91CA\u5DF2\u6709\u4FE1\u606F\u3001\u770B\u4E2A\u5217\u8868\u3001\u67E5\u4E2A\u72B6\u6001\u3001\u8BFB\u4E00\u5C0F\u6BB5\u6587\u4EF6\uFF09\uFF0C\u4F60\u53EF\u4EE5\u987A\u624B\u81EA\u5DF1\u505A\uFF0C\u4E0D\u5FC5\u4EC0\u4E48\u90FD\u7EC4\u7EC7\u5316\u3002
|
|
46844
47029
|
</\u4F60\u7684\u8EAB\u4EFD>
|
|
@@ -47021,7 +47206,8 @@ var createAgent = (config2 = getDefaultAgentConfig()) => {
|
|
|
47021
47206
|
if (config2.workspacePath && !request.defaultWorkDir) {
|
|
47022
47207
|
request.defaultWorkDir = config2.workspacePath;
|
|
47023
47208
|
}
|
|
47024
|
-
const { userId,
|
|
47209
|
+
const { userId, job } = request;
|
|
47210
|
+
const content = attachRecentAttachmentContext(request, request.content);
|
|
47025
47211
|
const internalOnly = request.metadata?.internalOnly === true;
|
|
47026
47212
|
const injectedEventIds = /* @__PURE__ */ new Set();
|
|
47027
47213
|
const interruptQueuedEventIds = /* @__PURE__ */ new Set();
|
|
@@ -48151,7 +48337,7 @@ var DESCRIPTION42 = `
|
|
|
48151
48337
|
\u6B63\u5F0F\u56DE\u590D\u4E00\u5C01\u90AE\u4EF6\u3002\u5BF9\u5F53\u524D\u6D88\u606F\u5F62\u6210\u53EF\u4EE5\u4EA4\u4ED8\u7ED9\u5BF9\u65B9\u7684\u6700\u7EC8\u7ED3\u8BBA\u540E\uFF0C\u4F7F\u7528\u6B64\u5DE5\u5177\u5C06\u7ED3\u679C\u53D1\u56DE\u7ED9\u90AE\u4EF6\u53D1\u9001\u8005\uFF0C\u5E76\u7ED3\u675F\u8FD9\u5C01\u6D88\u606F\u7684\u5904\u7406\u3002
|
|
48152
48338
|
|
|
48153
48339
|
\u5B83\u5728\u7EC4\u7EC7\u91CC\u7684\u542B\u4E49\u66F4\u63A5\u8FD1\u201C\u6211\u5DF2\u7ECF\u628A\u8FD9\u4EF6\u4E8B\u9A8C\u6536\u6E05\u695A\uFF0C\u53EF\u4EE5\u7ED9\u4F60\u4E00\u4E2A\u7ED3\u8BBA\u201D\uFF0C\u800C\u4E0D\u662F\u666E\u901A\u804A\u5929\u56DE\u590D\u3002
|
|
48154
|
-
\u5982\u679C\u53EA\u662F\u540C\u6B65\u9636\u6BB5\u6027\u8FDB\u5C55\u3001\u8BF4\u660E\u5DF2\u5B89\u6392\u4E0B\u5C5E\u3001\u8FD8\u5728\u7B49\u5F85\u6267\u884C\u7ED3\u679C\u3001\
|
|
48340
|
+
\u5982\u679C\u53EA\u662F\u540C\u6B65\u9636\u6BB5\u6027\u8FDB\u5C55\u3001\u8BF4\u660E\u5DF2\u5B89\u6392\u4E0B\u5C5E\u3001\u8FD8\u5728\u7B49\u5F85\u6267\u884C\u7ED3\u679C\u3001\u8865\u5145\u4E0A\u4E0B\u6587\u3001\u8BE2\u95EE\u72B6\u6001\u6216\u5148\u7ED9\u90E8\u5206\u53D1\u73B0\uFF0C\u5E94\u4F7F\u7528 mailbox_followup\uFF0C\u8BA9\u539F\u90AE\u4EF6\u7EE7\u7EED\u4FDD\u6301\u672A\u5B8C\u5F85\u7EED\u3002
|
|
48155
48341
|
|
|
48156
48342
|
\u53C2\u6570\uFF1A
|
|
48157
48343
|
- message_id: \u8981\u56DE\u590D\u7684\u90AE\u4EF6 id\uFF08\u4ECE list_mailbox \u6216 get_mailbox \u4E2D\u83B7\u53D6\uFF09
|
|
@@ -48773,6 +48959,7 @@ var createDepartmentAgentTools = () => {
|
|
|
48773
48959
|
registerTool(registry2, webSearchTool);
|
|
48774
48960
|
registerTool(registry2, webFetchTool);
|
|
48775
48961
|
registerTool(registry2, imageUnderstand);
|
|
48962
|
+
registerTool(registry2, imageGenerate);
|
|
48776
48963
|
registerTool(registry2, goalCreate);
|
|
48777
48964
|
registerTool(registry2, goalGet);
|
|
48778
48965
|
registerTool(registry2, goalList);
|
|
@@ -48812,7 +48999,7 @@ var getDepartmentAgentConfig = (tools, memberFocusOn, workspacePath, departmentN
|
|
|
48812
48999
|
|
|
48813
49000
|
\u8C01\u628A\u4E8B\u4EA4\u7ED9\u4F60\u3001\u8C01\u6765\u95EE\u4F60\uFF08\u901A\u5E38\u662F CEO\uFF09\uFF0C\u4F60\u5C31\u6B20\u4ED6\u4E00\u4E2A\u4EA4\u4EE3\u3002\u5728\u4F60\u628A\u6838\u5B9E\u8FC7\u7684\u771F\u5B9E\u7ED3\u8BBA\u4EA4\u56DE\u5230\u95EE\u4F60\u7684\u4EBA\u624B\u4E0A\u4E4B\u524D\uFF0C\u8FD9\u4EF6\u4E8B\u5BF9\u4F60\u90FD\u6CA1\u7B97\u5B8C\u2014\u2014\u4F60\u987A\u7740\u539F\u6765\u90A3\u5C01\u8BF7\u6C42\u7684\u7EBF\u7A0B\uFF0C\u7528\u5B83\u7684 message_id \u56DE\u7ED9\u4E0A\u6E38\uFF08reply_mailbox \u6216 mailbox_followup\uFF09\uFF1B\u53EA\u56DE\u590D Executor \u4E0D\u7B49\u4E8E\u5411\u4E0A\u6E38\u4EA4\u4EE3\u4E86\uFF0C\u90A3\u6837 CEO \u548C\u8001\u677F\u90A3\u8FB9\u6536\u4E0D\u5230\u3002\u4E0A\u6E38\u518D\u6765\u50AC\u540C\u4E00\u4EF6\u4E8B\uFF0C\u54EA\u6015\u4F60\u624B\u91CC\u5DF2\u7ECF\u6709\u6700\u7EC8\u62A5\u544A\uFF0C\u4E5F\u7167\u6837\u628A\u62A5\u544A\u6216\u7B80\u660E\u72B6\u6001\u56DE\u7ED9\u4ED6\u3002
|
|
48814
49001
|
|
|
48815
|
-
Executor \u56DE\u5F97\u6162\u3001\u6682\u65F6\u6CA1\u56DE\uFF0C\u4E0D\u662F\u4F60\u81EA\u5DF1\u4E0B\u573A\u91CD\u505A\u7684\u7406\u7531\u2014\u2014\u8BE5\u505A\u7684\u662F mailbox_followup \
|
|
49002
|
+
Executor \u56DE\u5F97\u6162\u3001\u6682\u65F6\u6CA1\u56DE\uFF0C\u4E0D\u662F\u4F60\u81EA\u5DF1\u4E0B\u573A\u91CD\u505A\u7684\u7406\u7531\u2014\u2014\u8BE5\u505A\u7684\u662F\u7ED9\u4E0B\u5C5E\u5408\u7406\u5904\u7406\u65F6\u95F4\uFF1B\u5982\u679C\u786E\u6709\u65B0\u80CC\u666F\u3001\u660E\u786E\u98CE\u9669\u6216\u5DF2\u7ECF\u8FC7\u4E86\u5408\u7406\u7B49\u5F85\u65F6\u95F4\uFF0C\u518D\u7528 mailbox_followup \u8865\u5145\u4E0A\u4E0B\u6587\u6216\u8BE2\u95EE\u771F\u5B9E\u72B6\u6001\uFF0C\u5E76\u5982\u5B9E\u8DDF\u4E0A\u6E38\u8BF4\u8FD8\u5728\u7B49\u6267\u884C\u7ED3\u679C\u3002\u7ED9\u4E0A\u6E38\u540C\u6B65\u201C\u5DF2\u5B89\u6392\u3001\u8FD8\u5728\u7B49\u3001\u5DF2\u6709\u90E8\u5206\u53D1\u73B0\u201D\u8FD9\u7C7B\u8FDB\u5C55\uFF0C\u7528 mailbox_followup\uFF1B\u7B49\u4F60\u9A8C\u6536\u5B8C\u771F\u5B9E\u7ED3\u679C\u3001\u53EF\u4EE5\u7ED9\u51FA\u6700\u7EC8\u6C47\u603B\u65F6\uFF0C\u518D\u7528 reply_mailbox \u6B63\u5F0F\u4EA4\u4ED8\u7ED3\u8BBA\u3002\u53EA\u6709\u4E0A\u6E38\u660E\u786E\u8981\u4F60\u4EB2\u81EA\u505A\u3001\u90E8\u95E8\u91CC\u786E\u5B9E\u6CA1\u6709\u4E5F\u6765\u4E0D\u53CA\u7EC4\u5EFA\u5408\u9002\u7684 Executor\u3001\u6216 Executor \u660E\u786E\u505A\u4E0D\u6210\u4E14\u4E0A\u6E38\u540C\u610F\u4F60\u63A5\u7BA1\u65F6\uFF0C\u4F60\u624D\u81EA\u5DF1\u4E0A\u624B\u90A3\u4E9B\u6267\u884C\u7C7B\u5DE5\u5177\u3002` : `\u4F60\u662F\u6267\u884C\u8005\uFF08Executor\uFF09\u3002\u522B\u4EBA\uFF08\u901A\u5E38\u662F\u4F60\u7684\u90E8\u95E8\u8D1F\u8D23\u4EBA\uFF09\u628A\u5177\u4F53\u4EFB\u52A1\u6D3E\u7ED9\u4F60\uFF0C\u4F60\u5C31\u7528\u81EA\u5DF1\u7684\u4E13\u4E1A\u80FD\u529B\u548C\u5DE5\u5177\u628A\u5B83\u505A\u51FA\u6765\uFF0C\u518D\u5982\u5B9E\u628A\u7ED3\u679C\u56DE\u7ED9\u95EE\u4F60\u7684\u4EBA\u3002\u4F60\u4E13\u6CE8\u505A\u4E8B\uFF0C\u4E0D\u53BB\u67E5\u770B\u6574\u4E2A\u90E8\u95E8\u6210\u5458\u540D\u518C\uFF0C\u4E5F\u4E0D\u521B\u5EFA\u6210\u5458\u2014\u2014\u7EC4\u5EFA\u56E2\u961F\u662F\u8D1F\u8D23\u4EBA\u7684\u4E8B\u3002`;
|
|
48816
49003
|
const defaultSystemPrompt = `
|
|
48817
49004
|
${COMPANY_VALUES_PROMPT}
|
|
48818
49005
|
|
|
@@ -48841,8 +49028,8 @@ ${workspacePath ? `
|
|
|
48841
49028
|
\u4F60\u901A\u8FC7\u90AE\u7BB1\u548C\u540C\u4E8B\u534F\u4F5C\u3002\u6536\u5230\u65B0\u90AE\u4EF6\u63D0\u9192\u540E\uFF0C\u7528 list_mailbox \u770B\u770B\u6709\u54EA\u4E9B\u5F85\u5904\u7406\u7684\u90AE\u4EF6\uFF0C\u6311\u4E00\u5C01\u7528 get_mailbox \u9886\u53D6\u5E76\u8BFB\u5168\u6587\uFF0C\u628A\u5B83\u505A\u5B8C\u6216\u95EE\u6E05\u695A\uFF0C\u518D\u56DE\u590D\u3002\u5904\u7406\u5B8C\u4E00\u5C01\u7EE7\u7EED list_mailbox \u770B\u4E0B\u4E00\u5C01\u3002
|
|
48842
49029
|
|
|
48843
49030
|
\u51E0\u4E2A\u5DE5\u5177\u7684\u542B\u4E49\u8981\u5206\u6E05\uFF0C\u522B\u53EA\u7528\u81EA\u7136\u8BED\u8A00\u8BF4\u8BF4\u5C31\u7B97\u6570\uFF1A
|
|
48844
|
-
- mailbox_followup(message_id, content)\uFF1A\u5728\u540C\u4E00\u7EBF\u7A0B\u91CC\u7EE7\u7EED\u6C9F\u901A\u2014\u2014\u540C\u6B65\u8FDB\u5C55\u3001\u8865\u5145\u7ED3\u679C\u3001\
|
|
48845
|
-
- reply_mailbox(message_id, content)\uFF1A\u4F60\u5BF9\u8FD9\u5C01\u90AE\u4EF6\u5DF2\u7ECF\u5F62\u6210\u53EF\u4EE5\u4EA4\u4ED8\u7ED9\u5BF9\u65B9\u7684\u6B63\u5F0F\u7ED3\u8BBA\uFF0C\u56DE\u590D\u5E76\u7ED3\u675F\u5B83\u3002\u6BCF\u5C01\u90AE\u4EF6\u7528\u5B83\u81EA\u5DF1\u7684 message_id \u56DE\u590D\uFF0C\u522B\u62FF\u4E00\u6BB5\u8BDD\u540C\u65F6\u5145\u5F53\u591A\u5C01\u90AE\u4EF6\u7684\u7B54\u590D\u3002\u8FD8\u5728\u7B49\u5F85\u4E0B\u6E38\u3001\u53EA\u662F\u540C\u6B65\u5B89\u6392\u6216\
|
|
49031
|
+
- mailbox_followup(message_id, content)\uFF1A\u5728\u540C\u4E00\u7EBF\u7A0B\u91CC\u7EE7\u7EED\u6C9F\u901A\u2014\u2014\u540C\u6B65\u8FDB\u5C55\u3001\u8865\u5145\u7ED3\u679C\u3001\u8865\u5145\u4E0A\u4E0B\u6587\u6216\u8BE2\u95EE\u72B6\u6001\uFF1B\u53EF\u4EE5\u591A\u6B21\uFF0C\u4E0D\u4F1A\u7ED3\u675F\u8FD9\u5C01\u90AE\u4EF6\u3002
|
|
49032
|
+
- reply_mailbox(message_id, content)\uFF1A\u4F60\u5BF9\u8FD9\u5C01\u90AE\u4EF6\u5DF2\u7ECF\u5F62\u6210\u53EF\u4EE5\u4EA4\u4ED8\u7ED9\u5BF9\u65B9\u7684\u6B63\u5F0F\u7ED3\u8BBA\uFF0C\u56DE\u590D\u5E76\u7ED3\u675F\u5B83\u3002\u6BCF\u5C01\u90AE\u4EF6\u7528\u5B83\u81EA\u5DF1\u7684 message_id \u56DE\u590D\uFF0C\u522B\u62FF\u4E00\u6BB5\u8BDD\u540C\u65F6\u5145\u5F53\u591A\u5C01\u90AE\u4EF6\u7684\u7B54\u590D\u3002\u8FD8\u5728\u7B49\u5F85\u4E0B\u6E38\u3001\u53EA\u662F\u540C\u6B65\u5B89\u6392\u6216\u8BE2\u95EE\u72B6\u6001\u65F6\uFF0C\u4E0D\u8981\u7528\u5B83\u7ED3\u675F\u4E0A\u6E38\u8BF7\u6C42\u3002
|
|
48846
49033
|
- discard_mailbox(message_id, reason)\uFF1A\u53EA\u6709\u5F53\u8FD9\u5C01\u90AE\u4EF6\u786E\u5B9E\u65E0\u9700\u4E1A\u52A1\u56DE\u590D\uFF08\u7EAF\u56DE\u6267\u3001\u91CD\u590D\u901A\u77E5\u3001\u5DF2\u88AB\u5176\u4ED6\u90AE\u4EF6\u8986\u76D6\uFF09\u65F6\u624D\u7528\uFF1B\u5B83\u4F1A\u7ED3\u675F\u90AE\u4EF6\uFF0C\u4F46\u4E0D\u4F1A\u7ED9\u53D1\u9001\u8005\u56DE\u4FE1\u3002
|
|
48847
49034
|
- \u9700\u8981\u4E3B\u52A8\u8054\u7CFB\u522B\u7684\u90E8\u95E8\u6210\u5458\uFF0C\u7528 department_communicate\u3002
|
|
48848
49035
|
|
|
@@ -51862,7 +52049,7 @@ var cors = (options) => {
|
|
|
51862
52049
|
|
|
51863
52050
|
// src/server/index.ts
|
|
51864
52051
|
var import_promises14 = require("node:fs/promises");
|
|
51865
|
-
var
|
|
52052
|
+
var import_node_path20 = __toESM(require("node:path"));
|
|
51866
52053
|
|
|
51867
52054
|
// src/git/worktree.ts
|
|
51868
52055
|
var import_child_process2 = require("child_process");
|
|
@@ -53207,8 +53394,8 @@ mailboxRoutes.get("/mailbox/summary", (c) => {
|
|
|
53207
53394
|
|
|
53208
53395
|
// src/server/routes/memory.ts
|
|
53209
53396
|
var import_redis4 = __toESM(require_dist2());
|
|
53210
|
-
var
|
|
53211
|
-
var
|
|
53397
|
+
var import_node_fs9 = require("node:fs");
|
|
53398
|
+
var import_node_path17 = __toESM(require("node:path"));
|
|
53212
53399
|
var memoryEngineSingleton = null;
|
|
53213
53400
|
var dreamStorageSingleton = null;
|
|
53214
53401
|
var dreamHistoryStorageSingleton = null;
|
|
@@ -53308,12 +53495,12 @@ var addPlausibleUserId = (set, userId) => {
|
|
|
53308
53495
|
if (normalized && isPlausibleUserId(normalized)) set.add(normalized);
|
|
53309
53496
|
};
|
|
53310
53497
|
var readJsonFilesFromDir = (dir) => {
|
|
53311
|
-
if (!(0,
|
|
53498
|
+
if (!(0, import_node_fs9.existsSync)(dir)) return [];
|
|
53312
53499
|
const result = [];
|
|
53313
|
-
for (const file of (0,
|
|
53500
|
+
for (const file of (0, import_node_fs9.readdirSync)(dir)) {
|
|
53314
53501
|
if (!file.endsWith(".json")) continue;
|
|
53315
53502
|
try {
|
|
53316
|
-
result.push(JSON.parse((0,
|
|
53503
|
+
result.push(JSON.parse((0, import_node_fs9.readFileSync)(import_node_path17.default.join(dir, file), "utf-8")));
|
|
53317
53504
|
} catch (err) {
|
|
53318
53505
|
console.warn(`[memoryRoutes] \u8DF3\u8FC7\u65E0\u6CD5\u89E3\u6790\u7684\u672C\u5730\u4E0A\u4E0B\u6587\u6587\u4EF6 ${file}: ${err.message}`);
|
|
53319
53506
|
}
|
|
@@ -53321,13 +53508,13 @@ var readJsonFilesFromDir = (dir) => {
|
|
|
53321
53508
|
return result;
|
|
53322
53509
|
};
|
|
53323
53510
|
var extractFileBackedStorageKeysForTest = (dataDir) => {
|
|
53324
|
-
const kvRoot =
|
|
53325
|
-
if (!(0,
|
|
53511
|
+
const kvRoot = import_node_path17.default.join(dataDir, "kv");
|
|
53512
|
+
if (!(0, import_node_fs9.existsSync)(kvRoot)) return [];
|
|
53326
53513
|
const keys = [];
|
|
53327
|
-
for (const prefixDir of (0,
|
|
53328
|
-
const absolutePrefixDir =
|
|
53329
|
-
if (!(0,
|
|
53330
|
-
for (const file of (0,
|
|
53514
|
+
for (const prefixDir of (0, import_node_fs9.readdirSync)(kvRoot)) {
|
|
53515
|
+
const absolutePrefixDir = import_node_path17.default.join(kvRoot, prefixDir);
|
|
53516
|
+
if (!(0, import_node_fs9.existsSync)(absolutePrefixDir)) continue;
|
|
53517
|
+
for (const file of (0, import_node_fs9.readdirSync)(absolutePrefixDir)) {
|
|
53331
53518
|
if (!file.endsWith(".json")) continue;
|
|
53332
53519
|
try {
|
|
53333
53520
|
const logicalKey = Buffer.from(file.replace(/\.json$/, ""), "base64url").toString("utf8");
|
|
@@ -53345,12 +53532,12 @@ var collectLocalConversationUserIds = () => {
|
|
|
53345
53532
|
};
|
|
53346
53533
|
var extractLocalConversationUserIdsForTest = (homeDir) => {
|
|
53347
53534
|
const userIds = /* @__PURE__ */ new Set();
|
|
53348
|
-
for (const context of readJsonFilesFromDir(
|
|
53535
|
+
for (const context of readJsonFilesFromDir(import_node_path17.default.join(homeDir, "goal-context"))) {
|
|
53349
53536
|
addPlausibleUserId(userIds, context.threadId);
|
|
53350
53537
|
addPlausibleUserId(userIds, context.originUserId);
|
|
53351
53538
|
if (context.goalId) addPlausibleUserId(userIds, `kanban:goal:${context.goalId}`);
|
|
53352
53539
|
}
|
|
53353
|
-
for (const goal of readJsonFilesFromDir(
|
|
53540
|
+
for (const goal of readJsonFilesFromDir(import_node_path17.default.join(homeDir, "tasks"))) {
|
|
53354
53541
|
if (goal.id) addPlausibleUserId(userIds, `kanban:goal:${goal.id}`);
|
|
53355
53542
|
}
|
|
53356
53543
|
return userIds;
|
|
@@ -53767,7 +53954,7 @@ ${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
|
53767
53954
|
});
|
|
53768
53955
|
|
|
53769
53956
|
// src/server/routes/tools.ts
|
|
53770
|
-
var
|
|
53957
|
+
var import_node_path18 = __toESM(require("node:path"));
|
|
53771
53958
|
var toolRoutes = new Hono2();
|
|
53772
53959
|
var listActiveDepartmentSkills = () => {
|
|
53773
53960
|
return listDepartments().flatMap(
|
|
@@ -53778,7 +53965,7 @@ var listActiveDepartmentSkills = () => {
|
|
|
53778
53965
|
scope: "department",
|
|
53779
53966
|
departmentName: department.name,
|
|
53780
53967
|
detail: () => {
|
|
53781
|
-
const skillDir =
|
|
53968
|
+
const skillDir = import_node_path18.default.join(getDepartmentWorkSpaceDir(department.name), "skills", skill.skillName);
|
|
53782
53969
|
return `Base directory for this skill: ${skillDir}
|
|
53783
53970
|
|
|
53784
53971
|
${skill.skillMd}`;
|
|
@@ -53867,7 +54054,7 @@ var systemRoutes = new Hono2();
|
|
|
53867
54054
|
var startTime = Date.now();
|
|
53868
54055
|
systemRoutes.get("/system/info", (c) => {
|
|
53869
54056
|
return c.json({
|
|
53870
|
-
version: true ? "1.9.
|
|
54057
|
+
version: true ? "1.9.14" : "unknown",
|
|
53871
54058
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
53872
54059
|
env: process.env.NODE_ENV || "development",
|
|
53873
54060
|
nodeVersion: process.version
|
|
@@ -53875,9 +54062,9 @@ systemRoutes.get("/system/info", (c) => {
|
|
|
53875
54062
|
});
|
|
53876
54063
|
|
|
53877
54064
|
// src/server/routes/mobile.ts
|
|
53878
|
-
var
|
|
54065
|
+
var import_node_crypto17 = require("node:crypto");
|
|
53879
54066
|
var import_promises13 = require("node:fs/promises");
|
|
53880
|
-
var
|
|
54067
|
+
var import_node_path19 = __toESM(require("node:path"));
|
|
53881
54068
|
var mobileRoutes = new Hono2();
|
|
53882
54069
|
var resolveMobileUserId = (body, headerUserId) => {
|
|
53883
54070
|
return body.userId?.trim() || headerUserId?.trim() || "ios:local-user";
|
|
@@ -53919,12 +54106,12 @@ ${goal.tasks.map((task) => `- [${task.status}] ${task.subject}`).join("\n")}` :
|
|
|
53919
54106
|
return lines.join("\n");
|
|
53920
54107
|
};
|
|
53921
54108
|
var sanitizeFileName = (fileName) => {
|
|
53922
|
-
const cleaned =
|
|
54109
|
+
const cleaned = import_node_path19.default.basename(fileName).replace(/[^\w.\-()\u4e00-\u9fa5 ]+/g, "_").trim();
|
|
53923
54110
|
return cleaned || `attachment-${Date.now()}`;
|
|
53924
54111
|
};
|
|
53925
54112
|
var inferAttachmentType2 = (mimeType = "", fileName = "") => {
|
|
53926
54113
|
if (mimeType.startsWith("image/")) return "image";
|
|
53927
|
-
const ext =
|
|
54114
|
+
const ext = import_node_path19.default.extname(fileName).toLowerCase();
|
|
53928
54115
|
if ([".png", ".jpg", ".jpeg", ".gif", ".webp"].includes(ext)) return "image";
|
|
53929
54116
|
return "file";
|
|
53930
54117
|
};
|
|
@@ -53979,11 +54166,11 @@ mobileRoutes.post("/mobile/attachments", async (c) => {
|
|
|
53979
54166
|
const fileName = sanitizeFileName(body.fileName || `attachment-${Date.now()}`);
|
|
53980
54167
|
const mimeType = body.mimeType || "application/octet-stream";
|
|
53981
54168
|
const type = inferAttachmentType2(mimeType, fileName);
|
|
53982
|
-
const attachmentId = (0,
|
|
54169
|
+
const attachmentId = (0, import_node_crypto17.randomUUID)();
|
|
53983
54170
|
const buffer = Buffer.from(dataBase64, "base64");
|
|
53984
|
-
const dir =
|
|
54171
|
+
const dir = import_node_path19.default.join(getDuclawWorkspaceDir(), mobileUserId, "mobile", type === "image" ? "images" : "files");
|
|
53985
54172
|
await (0, import_promises13.mkdir)(dir, { recursive: true });
|
|
53986
|
-
const localPath =
|
|
54173
|
+
const localPath = import_node_path19.default.join(dir, `${attachmentId}-${fileName}`);
|
|
53987
54174
|
await (0, import_promises13.writeFile)(localPath, buffer);
|
|
53988
54175
|
const attachment = saveMobileAttachment({
|
|
53989
54176
|
id: attachmentId,
|
|
@@ -54011,7 +54198,7 @@ mobileRoutes.post("/mobile/messages", async (c) => {
|
|
|
54011
54198
|
}
|
|
54012
54199
|
const mobileUserId = resolveMobileUserId(body, c.req.header("x-user-id"));
|
|
54013
54200
|
const threadId = resolveThreadId(body.goalId, mobileUserId);
|
|
54014
|
-
const requestId = body.clientMessageId?.trim() || (0,
|
|
54201
|
+
const requestId = body.clientMessageId?.trim() || (0, import_node_crypto17.randomUUID)();
|
|
54015
54202
|
const agentText = body.contextText?.trim() || text2;
|
|
54016
54203
|
const attachmentContent = buildContentWithAttachments(agentText, attachments);
|
|
54017
54204
|
const content = buildGoalPrompt(body.goalId, attachmentContent.content);
|
|
@@ -54202,7 +54389,7 @@ function createServer() {
|
|
|
54202
54389
|
app.route("/api", mobileRoutes);
|
|
54203
54390
|
app.use("/*", serveStatic({ root: webDistRoot }));
|
|
54204
54391
|
app.get("/*", async (c) => {
|
|
54205
|
-
const indexHtml = await (0, import_promises14.readFile)(
|
|
54392
|
+
const indexHtml = await (0, import_promises14.readFile)(import_node_path20.default.join(webDistRoot, "index.html"), "utf8");
|
|
54206
54393
|
const tenantId = c.req.header("x-tenant-id");
|
|
54207
54394
|
const assetBase = tenantId ? `/t/${tenantId}` : "";
|
|
54208
54395
|
const html = indexHtml.replaceAll('"./', `"${assetBase}/`);
|
|
@@ -54229,10 +54416,10 @@ function shouldStartCoreChannelGateways(env = process.env) {
|
|
|
54229
54416
|
}
|
|
54230
54417
|
|
|
54231
54418
|
// src/runtime/saasAssets.ts
|
|
54232
|
-
var
|
|
54419
|
+
var import_node_fs10 = require("node:fs");
|
|
54233
54420
|
var import_promises15 = require("node:fs/promises");
|
|
54234
54421
|
var import_node_os3 = require("node:os");
|
|
54235
|
-
var
|
|
54422
|
+
var import_node_path21 = __toESM(require("node:path"));
|
|
54236
54423
|
var MAX_CONTEXT_ASSETS = Number(process.env.DUCLAW_SAAS_ASSET_CONTEXT_LIMIT ?? 1e3);
|
|
54237
54424
|
var MAX_SKILL_ASSETS = Number(process.env.DUCLAW_SAAS_ASSET_SKILL_LIMIT ?? 200);
|
|
54238
54425
|
async function restoreSaasRuntimeAssets(reason) {
|
|
@@ -54262,8 +54449,8 @@ async function restoreSaasRuntimeAssets(reason) {
|
|
|
54262
54449
|
async function restoreContextAsset(context, overwrite) {
|
|
54263
54450
|
const target = contextPathForSourceKey(context.sourceKey);
|
|
54264
54451
|
if (!target) return false;
|
|
54265
|
-
if (!overwrite && (0,
|
|
54266
|
-
await (0, import_promises15.mkdir)(
|
|
54452
|
+
if (!overwrite && (0, import_node_fs10.existsSync)(target)) return false;
|
|
54453
|
+
await (0, import_promises15.mkdir)(import_node_path21.default.dirname(target), { recursive: true });
|
|
54267
54454
|
await (0, import_promises15.writeFile)(target, JSON.stringify(context.payload), "utf8");
|
|
54268
54455
|
return true;
|
|
54269
54456
|
}
|
|
@@ -54271,8 +54458,8 @@ async function restoreSkillAsset(skill, overwrite) {
|
|
|
54271
54458
|
if (!skill.skillMd) return false;
|
|
54272
54459
|
const target = safeSkillTargetPath(skill.sourcePath, skill.skillName);
|
|
54273
54460
|
if (!target) return false;
|
|
54274
|
-
if (!overwrite && (0,
|
|
54275
|
-
await (0, import_promises15.mkdir)(
|
|
54461
|
+
if (!overwrite && (0, import_node_fs10.existsSync)(target)) return false;
|
|
54462
|
+
await (0, import_promises15.mkdir)(import_node_path21.default.dirname(target), { recursive: true });
|
|
54276
54463
|
await (0, import_promises15.writeFile)(target, skill.skillMd, "utf8");
|
|
54277
54464
|
return true;
|
|
54278
54465
|
}
|
|
@@ -54305,30 +54492,30 @@ function runtimeAssetClient() {
|
|
|
54305
54492
|
function contextPathForSourceKey(sourceKey) {
|
|
54306
54493
|
if (sourceKey.startsWith("agent:")) {
|
|
54307
54494
|
const logicalKey = sourceKey.slice("agent:".length);
|
|
54308
|
-
return
|
|
54495
|
+
return import_node_path21.default.join(getDuclawDataDir(), "kv", "agent", `${Buffer.from(logicalKey).toString("base64url")}.json`);
|
|
54309
54496
|
}
|
|
54310
54497
|
if (sourceKey.startsWith("goal-context:")) {
|
|
54311
|
-
return
|
|
54498
|
+
return import_node_path21.default.join(getDuclawHomeDir(), "goal-context", `${sourceKey.slice("goal-context:".length)}.json`);
|
|
54312
54499
|
}
|
|
54313
54500
|
if (sourceKey.startsWith("tasks:")) {
|
|
54314
|
-
return
|
|
54501
|
+
return import_node_path21.default.join(getDuclawHomeDir(), "tasks", `${sourceKey.slice("tasks:".length)}.json`);
|
|
54315
54502
|
}
|
|
54316
54503
|
return null;
|
|
54317
54504
|
}
|
|
54318
54505
|
function safeSkillTargetPath(sourcePath, skillName) {
|
|
54319
|
-
const allowedRoots = skillRoots().map((root) =>
|
|
54320
|
-
const normalized =
|
|
54321
|
-
if (allowedRoots.some((root) => normalized ===
|
|
54506
|
+
const allowedRoots = skillRoots().map((root) => import_node_path21.default.resolve(root));
|
|
54507
|
+
const normalized = import_node_path21.default.resolve(sourcePath);
|
|
54508
|
+
if (allowedRoots.some((root) => normalized === import_node_path21.default.join(root, import_node_path21.default.basename(import_node_path21.default.dirname(normalized)), "SKILL.md"))) {
|
|
54322
54509
|
return normalized;
|
|
54323
54510
|
}
|
|
54324
54511
|
const safeName = skillName.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 120) || "imported-skill";
|
|
54325
|
-
return
|
|
54512
|
+
return import_node_path21.default.join("/home/user/app/skills", safeName, "SKILL.md");
|
|
54326
54513
|
}
|
|
54327
54514
|
function skillRoots() {
|
|
54328
54515
|
return [
|
|
54329
54516
|
"/home/user/app/skills",
|
|
54330
|
-
|
|
54331
|
-
|
|
54517
|
+
import_node_path21.default.join(getDuclawHomeDir(), "skills"),
|
|
54518
|
+
import_node_path21.default.join((0, import_node_os3.homedir)(), ".agents", "skills")
|
|
54332
54519
|
];
|
|
54333
54520
|
}
|
|
54334
54521
|
|