duclaw-cli 1.9.9 → 1.9.11
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 +1009 -933
- package/dist/main.js +1 -1
- package/dist/web/assets/{index-CiEOENzL.js → index-DnD9jpKq.js} +1 -1
- package/dist/web/index.html +1 -1
- package/dist/worker-main.js +1 -1
- package/package.json +2 -1
package/dist/bundle.js
CHANGED
|
@@ -115,7 +115,7 @@ var require_package = __commonJS({
|
|
|
115
115
|
var require_main = __commonJS({
|
|
116
116
|
"node_modules/.pnpm/dotenv@17.3.1/node_modules/dotenv/lib/main.js"(exports2, module2) {
|
|
117
117
|
var fs3 = require("fs");
|
|
118
|
-
var
|
|
118
|
+
var path21 = require("path");
|
|
119
119
|
var os = require("os");
|
|
120
120
|
var crypto2 = require("crypto");
|
|
121
121
|
var packageJson = require_package();
|
|
@@ -261,7 +261,7 @@ var require_main = __commonJS({
|
|
|
261
261
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
262
262
|
}
|
|
263
263
|
} else {
|
|
264
|
-
possibleVaultPath =
|
|
264
|
+
possibleVaultPath = path21.resolve(process.cwd(), ".env.vault");
|
|
265
265
|
}
|
|
266
266
|
if (fs3.existsSync(possibleVaultPath)) {
|
|
267
267
|
return possibleVaultPath;
|
|
@@ -269,7 +269,7 @@ var require_main = __commonJS({
|
|
|
269
269
|
return null;
|
|
270
270
|
}
|
|
271
271
|
function _resolveHome(envPath) {
|
|
272
|
-
return envPath[0] === "~" ?
|
|
272
|
+
return envPath[0] === "~" ? path21.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
273
273
|
}
|
|
274
274
|
function _configVault(options) {
|
|
275
275
|
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
@@ -286,7 +286,7 @@ var require_main = __commonJS({
|
|
|
286
286
|
return { parsed };
|
|
287
287
|
}
|
|
288
288
|
function configDotenv(options) {
|
|
289
|
-
const dotenvPath =
|
|
289
|
+
const dotenvPath = path21.resolve(process.cwd(), ".env");
|
|
290
290
|
let encoding = "utf8";
|
|
291
291
|
let processEnv = process.env;
|
|
292
292
|
if (options && options.processEnv != null) {
|
|
@@ -314,13 +314,13 @@ var require_main = __commonJS({
|
|
|
314
314
|
}
|
|
315
315
|
let lastError;
|
|
316
316
|
const parsedAll = {};
|
|
317
|
-
for (const
|
|
317
|
+
for (const path22 of optionPaths) {
|
|
318
318
|
try {
|
|
319
|
-
const parsed = DotenvModule.parse(fs3.readFileSync(
|
|
319
|
+
const parsed = DotenvModule.parse(fs3.readFileSync(path22, { encoding }));
|
|
320
320
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
321
321
|
} catch (e) {
|
|
322
322
|
if (debug) {
|
|
323
|
-
_debug(`Failed to load ${
|
|
323
|
+
_debug(`Failed to load ${path22} ${e.message}`);
|
|
324
324
|
}
|
|
325
325
|
lastError = e;
|
|
326
326
|
}
|
|
@@ -333,7 +333,7 @@ var require_main = __commonJS({
|
|
|
333
333
|
const shortPaths = [];
|
|
334
334
|
for (const filePath of optionPaths) {
|
|
335
335
|
try {
|
|
336
|
-
const relative4 =
|
|
336
|
+
const relative4 = path21.relative(process.cwd(), filePath);
|
|
337
337
|
shortPaths.push(relative4);
|
|
338
338
|
} catch (e) {
|
|
339
339
|
if (debug) {
|
|
@@ -8237,8 +8237,8 @@ var require_MODULE_LOAD = __commonJS({
|
|
|
8237
8237
|
* @param moduleArguments - Optional arguments to pass to the module
|
|
8238
8238
|
* @see https://redis.io/commands/module-load/
|
|
8239
8239
|
*/
|
|
8240
|
-
parseCommand(parser,
|
|
8241
|
-
parser.push("MODULE", "LOAD",
|
|
8240
|
+
parseCommand(parser, path21, moduleArguments) {
|
|
8241
|
+
parser.push("MODULE", "LOAD", path21);
|
|
8242
8242
|
if (moduleArguments) {
|
|
8243
8243
|
parser.push(...moduleArguments);
|
|
8244
8244
|
}
|
|
@@ -23539,10 +23539,10 @@ var require_ARRAPPEND = __commonJS({
|
|
|
23539
23539
|
* @param json - The first value to append
|
|
23540
23540
|
* @param jsons - Additional values to append
|
|
23541
23541
|
*/
|
|
23542
|
-
parseCommand(parser, key,
|
|
23542
|
+
parseCommand(parser, key, path21, json, ...jsons) {
|
|
23543
23543
|
parser.push("JSON.ARRAPPEND");
|
|
23544
23544
|
parser.pushKey(key);
|
|
23545
|
-
parser.push(
|
|
23545
|
+
parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
|
|
23546
23546
|
for (let i = 0; i < jsons.length; i++) {
|
|
23547
23547
|
parser.push((0, generic_transformers_1.transformRedisJsonArgument)(jsons[i]));
|
|
23548
23548
|
}
|
|
@@ -23572,10 +23572,10 @@ var require_ARRINDEX = __commonJS({
|
|
|
23572
23572
|
* @param options.range.start - Starting index for the search
|
|
23573
23573
|
* @param options.range.stop - Optional ending index for the search
|
|
23574
23574
|
*/
|
|
23575
|
-
parseCommand(parser, key,
|
|
23575
|
+
parseCommand(parser, key, path21, json, options) {
|
|
23576
23576
|
parser.push("JSON.ARRINDEX");
|
|
23577
23577
|
parser.pushKey(key);
|
|
23578
|
-
parser.push(
|
|
23578
|
+
parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
|
|
23579
23579
|
if (options?.range) {
|
|
23580
23580
|
parser.push(options.range.start.toString());
|
|
23581
23581
|
if (options.range.stop !== void 0) {
|
|
@@ -23607,10 +23607,10 @@ var require_ARRINSERT = __commonJS({
|
|
|
23607
23607
|
* @param json - The first value to insert
|
|
23608
23608
|
* @param jsons - Additional values to insert
|
|
23609
23609
|
*/
|
|
23610
|
-
parseCommand(parser, key,
|
|
23610
|
+
parseCommand(parser, key, path21, index, json, ...jsons) {
|
|
23611
23611
|
parser.push("JSON.ARRINSERT");
|
|
23612
23612
|
parser.pushKey(key);
|
|
23613
|
-
parser.push(
|
|
23613
|
+
parser.push(path21, index.toString(), (0, generic_transformers_1.transformRedisJsonArgument)(json));
|
|
23614
23614
|
for (let i = 0; i < jsons.length; i++) {
|
|
23615
23615
|
parser.push((0, generic_transformers_1.transformRedisJsonArgument)(jsons[i]));
|
|
23616
23616
|
}
|
|
@@ -23700,10 +23700,10 @@ var require_ARRTRIM = __commonJS({
|
|
|
23700
23700
|
* @param start - Starting index (inclusive)
|
|
23701
23701
|
* @param stop - Ending index (inclusive)
|
|
23702
23702
|
*/
|
|
23703
|
-
parseCommand(parser, key,
|
|
23703
|
+
parseCommand(parser, key, path21, start, stop) {
|
|
23704
23704
|
parser.push("JSON.ARRTRIM");
|
|
23705
23705
|
parser.pushKey(key);
|
|
23706
|
-
parser.push(
|
|
23706
|
+
parser.push(path21, start.toString(), stop.toString());
|
|
23707
23707
|
},
|
|
23708
23708
|
transformReply: void 0
|
|
23709
23709
|
};
|
|
@@ -23868,10 +23868,10 @@ var require_MERGE3 = __commonJS({
|
|
|
23868
23868
|
* @param path - Path to merge into
|
|
23869
23869
|
* @param value - JSON value to merge
|
|
23870
23870
|
*/
|
|
23871
|
-
parseCommand(parser, key,
|
|
23871
|
+
parseCommand(parser, key, path21, value) {
|
|
23872
23872
|
parser.push("JSON.MERGE");
|
|
23873
23873
|
parser.pushKey(key);
|
|
23874
|
-
parser.push(
|
|
23874
|
+
parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(value));
|
|
23875
23875
|
},
|
|
23876
23876
|
transformReply: void 0
|
|
23877
23877
|
};
|
|
@@ -23894,10 +23894,10 @@ var require_MGET2 = __commonJS({
|
|
|
23894
23894
|
* @param keys - Array of keys containing JSON documents
|
|
23895
23895
|
* @param path - Path to retrieve from each document
|
|
23896
23896
|
*/
|
|
23897
|
-
parseCommand(parser, keys,
|
|
23897
|
+
parseCommand(parser, keys, path21) {
|
|
23898
23898
|
parser.push("JSON.MGET");
|
|
23899
23899
|
parser.pushKeys(keys);
|
|
23900
|
-
parser.push(
|
|
23900
|
+
parser.push(path21);
|
|
23901
23901
|
},
|
|
23902
23902
|
transformReply(reply) {
|
|
23903
23903
|
return reply.map((json) => (0, generic_transformers_1.transformRedisJsonNullReply)(json));
|
|
@@ -23952,10 +23952,10 @@ var require_NUMINCRBY = __commonJS({
|
|
|
23952
23952
|
* @param path - Path to the numeric value
|
|
23953
23953
|
* @param by - Amount to increment by
|
|
23954
23954
|
*/
|
|
23955
|
-
parseCommand(parser, key,
|
|
23955
|
+
parseCommand(parser, key, path21, by) {
|
|
23956
23956
|
parser.push("JSON.NUMINCRBY");
|
|
23957
23957
|
parser.pushKey(key);
|
|
23958
|
-
parser.push(
|
|
23958
|
+
parser.push(path21, by.toString());
|
|
23959
23959
|
},
|
|
23960
23960
|
transformReply: {
|
|
23961
23961
|
2: (reply) => {
|
|
@@ -23987,10 +23987,10 @@ var require_NUMMULTBY = __commonJS({
|
|
|
23987
23987
|
* @param path - Path to the numeric value
|
|
23988
23988
|
* @param by - Amount to multiply by
|
|
23989
23989
|
*/
|
|
23990
|
-
parseCommand(parser, key,
|
|
23990
|
+
parseCommand(parser, key, path21, by) {
|
|
23991
23991
|
parser.push("JSON.NUMMULTBY");
|
|
23992
23992
|
parser.pushKey(key);
|
|
23993
|
-
parser.push(
|
|
23993
|
+
parser.push(path21, by.toString());
|
|
23994
23994
|
},
|
|
23995
23995
|
transformReply: NUMINCRBY_1.default.transformReply
|
|
23996
23996
|
};
|
|
@@ -24074,10 +24074,10 @@ var require_SET2 = __commonJS({
|
|
|
24074
24074
|
* @deprecated options.NX - Use options.condition instead
|
|
24075
24075
|
* @deprecated options.XX - Use options.condition instead
|
|
24076
24076
|
*/
|
|
24077
|
-
parseCommand(parser, key,
|
|
24077
|
+
parseCommand(parser, key, path21, json, options) {
|
|
24078
24078
|
parser.push("JSON.SET");
|
|
24079
24079
|
parser.pushKey(key);
|
|
24080
|
-
parser.push(
|
|
24080
|
+
parser.push(path21, (0, generic_transformers_1.transformRedisJsonArgument)(json));
|
|
24081
24081
|
if (options?.condition) {
|
|
24082
24082
|
parser.push(options?.condition);
|
|
24083
24083
|
} else if (options?.NX) {
|
|
@@ -24165,10 +24165,10 @@ var require_TOGGLE = __commonJS({
|
|
|
24165
24165
|
* @param key - The key containing the JSON document
|
|
24166
24166
|
* @param path - Path to the boolean value
|
|
24167
24167
|
*/
|
|
24168
|
-
parseCommand(parser, key,
|
|
24168
|
+
parseCommand(parser, key, path21) {
|
|
24169
24169
|
parser.push("JSON.TOGGLE");
|
|
24170
24170
|
parser.pushKey(key);
|
|
24171
|
-
parser.push(
|
|
24171
|
+
parser.push(path21);
|
|
24172
24172
|
},
|
|
24173
24173
|
transformReply: void 0
|
|
24174
24174
|
};
|
|
@@ -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.11" : "unknown"}`);
|
|
30246
30246
|
}
|
|
30247
30247
|
function getDuclawTemplate() {
|
|
30248
30248
|
return {
|
|
@@ -31633,7 +31633,7 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
31633
31633
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
31634
31634
|
const statMethod = opts.lstat ? import_promises3.lstat : import_promises3.stat;
|
|
31635
31635
|
if (wantBigintFsStats) {
|
|
31636
|
-
this._stat = (
|
|
31636
|
+
this._stat = (path21) => statMethod(path21, { bigint: true });
|
|
31637
31637
|
} else {
|
|
31638
31638
|
this._stat = statMethod;
|
|
31639
31639
|
}
|
|
@@ -31658,8 +31658,8 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
31658
31658
|
const par = this.parent;
|
|
31659
31659
|
const fil = par && par.files;
|
|
31660
31660
|
if (fil && fil.length > 0) {
|
|
31661
|
-
const { path:
|
|
31662
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
31661
|
+
const { path: path21, depth } = par;
|
|
31662
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path21));
|
|
31663
31663
|
const awaited = await Promise.all(slice);
|
|
31664
31664
|
for (const entry of awaited) {
|
|
31665
31665
|
if (!entry)
|
|
@@ -31699,20 +31699,20 @@ var ReaddirpStream = class extends import_node_stream.Readable {
|
|
|
31699
31699
|
this.reading = false;
|
|
31700
31700
|
}
|
|
31701
31701
|
}
|
|
31702
|
-
async _exploreDir(
|
|
31702
|
+
async _exploreDir(path21, depth) {
|
|
31703
31703
|
let files;
|
|
31704
31704
|
try {
|
|
31705
|
-
files = await (0, import_promises3.readdir)(
|
|
31705
|
+
files = await (0, import_promises3.readdir)(path21, this._rdOptions);
|
|
31706
31706
|
} catch (error) {
|
|
31707
31707
|
this._onError(error);
|
|
31708
31708
|
}
|
|
31709
|
-
return { files, depth, path:
|
|
31709
|
+
return { files, depth, path: path21 };
|
|
31710
31710
|
}
|
|
31711
|
-
async _formatEntry(dirent,
|
|
31711
|
+
async _formatEntry(dirent, path21) {
|
|
31712
31712
|
let entry;
|
|
31713
31713
|
const basename4 = this._isDirent ? dirent.name : dirent;
|
|
31714
31714
|
try {
|
|
31715
|
-
const fullPath = (0, import_node_path4.resolve)((0, import_node_path4.join)(
|
|
31715
|
+
const fullPath = (0, import_node_path4.resolve)((0, import_node_path4.join)(path21, basename4));
|
|
31716
31716
|
entry = { path: (0, import_node_path4.relative)(this._root, fullPath), fullPath, basename: basename4 };
|
|
31717
31717
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
31718
31718
|
} catch (err) {
|
|
@@ -32112,16 +32112,16 @@ var delFromSet = (main2, prop, item) => {
|
|
|
32112
32112
|
};
|
|
32113
32113
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
32114
32114
|
var FsWatchInstances = /* @__PURE__ */ new Map();
|
|
32115
|
-
function createFsWatchInstance(
|
|
32115
|
+
function createFsWatchInstance(path21, options, listener, errHandler, emitRaw) {
|
|
32116
32116
|
const handleEvent = (rawEvent, evPath) => {
|
|
32117
|
-
listener(
|
|
32118
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
32119
|
-
if (evPath &&
|
|
32120
|
-
fsWatchBroadcast(sp.resolve(
|
|
32117
|
+
listener(path21);
|
|
32118
|
+
emitRaw(rawEvent, evPath, { watchedPath: path21 });
|
|
32119
|
+
if (evPath && path21 !== evPath) {
|
|
32120
|
+
fsWatchBroadcast(sp.resolve(path21, evPath), KEY_LISTENERS, sp.join(path21, evPath));
|
|
32121
32121
|
}
|
|
32122
32122
|
};
|
|
32123
32123
|
try {
|
|
32124
|
-
return (0, import_node_fs.watch)(
|
|
32124
|
+
return (0, import_node_fs.watch)(path21, {
|
|
32125
32125
|
persistent: options.persistent
|
|
32126
32126
|
}, handleEvent);
|
|
32127
32127
|
} catch (error) {
|
|
@@ -32137,12 +32137,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
32137
32137
|
listener(val1, val2, val3);
|
|
32138
32138
|
});
|
|
32139
32139
|
};
|
|
32140
|
-
var setFsWatchListener = (
|
|
32140
|
+
var setFsWatchListener = (path21, fullPath, options, handlers) => {
|
|
32141
32141
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
32142
32142
|
let cont = FsWatchInstances.get(fullPath);
|
|
32143
32143
|
let watcher;
|
|
32144
32144
|
if (!options.persistent) {
|
|
32145
|
-
watcher = createFsWatchInstance(
|
|
32145
|
+
watcher = createFsWatchInstance(path21, options, listener, errHandler, rawEmitter);
|
|
32146
32146
|
if (!watcher)
|
|
32147
32147
|
return;
|
|
32148
32148
|
return watcher.close.bind(watcher);
|
|
@@ -32153,7 +32153,7 @@ var setFsWatchListener = (path20, fullPath, options, handlers) => {
|
|
|
32153
32153
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
32154
32154
|
} else {
|
|
32155
32155
|
watcher = createFsWatchInstance(
|
|
32156
|
-
|
|
32156
|
+
path21,
|
|
32157
32157
|
options,
|
|
32158
32158
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
32159
32159
|
errHandler,
|
|
@@ -32168,7 +32168,7 @@ var setFsWatchListener = (path20, fullPath, options, handlers) => {
|
|
|
32168
32168
|
cont.watcherUnusable = true;
|
|
32169
32169
|
if (isWindows && error.code === "EPERM") {
|
|
32170
32170
|
try {
|
|
32171
|
-
const fd = await (0, import_promises4.open)(
|
|
32171
|
+
const fd = await (0, import_promises4.open)(path21, "r");
|
|
32172
32172
|
await fd.close();
|
|
32173
32173
|
broadcastErr(error);
|
|
32174
32174
|
} catch (err) {
|
|
@@ -32199,7 +32199,7 @@ var setFsWatchListener = (path20, fullPath, options, handlers) => {
|
|
|
32199
32199
|
};
|
|
32200
32200
|
};
|
|
32201
32201
|
var FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
32202
|
-
var setFsWatchFileListener = (
|
|
32202
|
+
var setFsWatchFileListener = (path21, fullPath, options, handlers) => {
|
|
32203
32203
|
const { listener, rawEmitter } = handlers;
|
|
32204
32204
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
32205
32205
|
const copts = cont && cont.options;
|
|
@@ -32221,7 +32221,7 @@ var setFsWatchFileListener = (path20, fullPath, options, handlers) => {
|
|
|
32221
32221
|
});
|
|
32222
32222
|
const currmtime = curr.mtimeMs;
|
|
32223
32223
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
32224
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
32224
|
+
foreach(cont.listeners, (listener2) => listener2(path21, curr));
|
|
32225
32225
|
}
|
|
32226
32226
|
})
|
|
32227
32227
|
};
|
|
@@ -32251,13 +32251,13 @@ var NodeFsHandler = class {
|
|
|
32251
32251
|
* @param listener on fs change
|
|
32252
32252
|
* @returns closer for the watcher instance
|
|
32253
32253
|
*/
|
|
32254
|
-
_watchWithNodeFs(
|
|
32254
|
+
_watchWithNodeFs(path21, listener) {
|
|
32255
32255
|
const opts = this.fsw.options;
|
|
32256
|
-
const directory = sp.dirname(
|
|
32257
|
-
const basename4 = sp.basename(
|
|
32256
|
+
const directory = sp.dirname(path21);
|
|
32257
|
+
const basename4 = sp.basename(path21);
|
|
32258
32258
|
const parent = this.fsw._getWatchedDir(directory);
|
|
32259
32259
|
parent.add(basename4);
|
|
32260
|
-
const absolutePath = sp.resolve(
|
|
32260
|
+
const absolutePath = sp.resolve(path21);
|
|
32261
32261
|
const options = {
|
|
32262
32262
|
persistent: opts.persistent
|
|
32263
32263
|
};
|
|
@@ -32267,12 +32267,12 @@ var NodeFsHandler = class {
|
|
|
32267
32267
|
if (opts.usePolling) {
|
|
32268
32268
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
32269
32269
|
options.interval = enableBin && isBinaryPath(basename4) ? opts.binaryInterval : opts.interval;
|
|
32270
|
-
closer = setFsWatchFileListener(
|
|
32270
|
+
closer = setFsWatchFileListener(path21, absolutePath, options, {
|
|
32271
32271
|
listener,
|
|
32272
32272
|
rawEmitter: this.fsw._emitRaw
|
|
32273
32273
|
});
|
|
32274
32274
|
} else {
|
|
32275
|
-
closer = setFsWatchListener(
|
|
32275
|
+
closer = setFsWatchListener(path21, absolutePath, options, {
|
|
32276
32276
|
listener,
|
|
32277
32277
|
errHandler: this._boundHandleError,
|
|
32278
32278
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -32294,7 +32294,7 @@ var NodeFsHandler = class {
|
|
|
32294
32294
|
let prevStats = stats;
|
|
32295
32295
|
if (parent.has(basename4))
|
|
32296
32296
|
return;
|
|
32297
|
-
const listener = async (
|
|
32297
|
+
const listener = async (path21, newStats) => {
|
|
32298
32298
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
32299
32299
|
return;
|
|
32300
32300
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -32308,11 +32308,11 @@ var NodeFsHandler = class {
|
|
|
32308
32308
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
32309
32309
|
}
|
|
32310
32310
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
32311
|
-
this.fsw._closeFile(
|
|
32311
|
+
this.fsw._closeFile(path21);
|
|
32312
32312
|
prevStats = newStats2;
|
|
32313
32313
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
32314
32314
|
if (closer2)
|
|
32315
|
-
this.fsw._addPathCloser(
|
|
32315
|
+
this.fsw._addPathCloser(path21, closer2);
|
|
32316
32316
|
} else {
|
|
32317
32317
|
prevStats = newStats2;
|
|
32318
32318
|
}
|
|
@@ -32344,7 +32344,7 @@ var NodeFsHandler = class {
|
|
|
32344
32344
|
* @param item basename of this item
|
|
32345
32345
|
* @returns true if no more processing is needed for this entry.
|
|
32346
32346
|
*/
|
|
32347
|
-
async _handleSymlink(entry, directory,
|
|
32347
|
+
async _handleSymlink(entry, directory, path21, item) {
|
|
32348
32348
|
if (this.fsw.closed) {
|
|
32349
32349
|
return;
|
|
32350
32350
|
}
|
|
@@ -32354,7 +32354,7 @@ var NodeFsHandler = class {
|
|
|
32354
32354
|
this.fsw._incrReadyCount();
|
|
32355
32355
|
let linkPath;
|
|
32356
32356
|
try {
|
|
32357
|
-
linkPath = await (0, import_promises4.realpath)(
|
|
32357
|
+
linkPath = await (0, import_promises4.realpath)(path21);
|
|
32358
32358
|
} catch (e) {
|
|
32359
32359
|
this.fsw._emitReady();
|
|
32360
32360
|
return true;
|
|
@@ -32364,12 +32364,12 @@ var NodeFsHandler = class {
|
|
|
32364
32364
|
if (dir.has(item)) {
|
|
32365
32365
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
32366
32366
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
32367
|
-
this.fsw._emit(EV.CHANGE,
|
|
32367
|
+
this.fsw._emit(EV.CHANGE, path21, entry.stats);
|
|
32368
32368
|
}
|
|
32369
32369
|
} else {
|
|
32370
32370
|
dir.add(item);
|
|
32371
32371
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
32372
|
-
this.fsw._emit(EV.ADD,
|
|
32372
|
+
this.fsw._emit(EV.ADD, path21, entry.stats);
|
|
32373
32373
|
}
|
|
32374
32374
|
this.fsw._emitReady();
|
|
32375
32375
|
return true;
|
|
@@ -32399,9 +32399,9 @@ var NodeFsHandler = class {
|
|
|
32399
32399
|
return;
|
|
32400
32400
|
}
|
|
32401
32401
|
const item = entry.path;
|
|
32402
|
-
let
|
|
32402
|
+
let path21 = sp.join(directory, item);
|
|
32403
32403
|
current.add(item);
|
|
32404
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
32404
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path21, item)) {
|
|
32405
32405
|
return;
|
|
32406
32406
|
}
|
|
32407
32407
|
if (this.fsw.closed) {
|
|
@@ -32410,8 +32410,8 @@ var NodeFsHandler = class {
|
|
|
32410
32410
|
}
|
|
32411
32411
|
if (item === target || !target && !previous.has(item)) {
|
|
32412
32412
|
this.fsw._incrReadyCount();
|
|
32413
|
-
|
|
32414
|
-
this._addToNodeFs(
|
|
32413
|
+
path21 = sp.join(dir, sp.relative(dir, path21));
|
|
32414
|
+
this._addToNodeFs(path21, initialAdd, wh, depth + 1);
|
|
32415
32415
|
}
|
|
32416
32416
|
}).on(EV.ERROR, this._boundHandleError);
|
|
32417
32417
|
return new Promise((resolve11, reject) => {
|
|
@@ -32480,13 +32480,13 @@ var NodeFsHandler = class {
|
|
|
32480
32480
|
* @param depth Child path actually targeted for watch
|
|
32481
32481
|
* @param target Child path actually targeted for watch
|
|
32482
32482
|
*/
|
|
32483
|
-
async _addToNodeFs(
|
|
32483
|
+
async _addToNodeFs(path21, initialAdd, priorWh, depth, target) {
|
|
32484
32484
|
const ready = this.fsw._emitReady;
|
|
32485
|
-
if (this.fsw._isIgnored(
|
|
32485
|
+
if (this.fsw._isIgnored(path21) || this.fsw.closed) {
|
|
32486
32486
|
ready();
|
|
32487
32487
|
return false;
|
|
32488
32488
|
}
|
|
32489
|
-
const wh = this.fsw._getWatchHelpers(
|
|
32489
|
+
const wh = this.fsw._getWatchHelpers(path21);
|
|
32490
32490
|
if (priorWh) {
|
|
32491
32491
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
32492
32492
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -32502,8 +32502,8 @@ var NodeFsHandler = class {
|
|
|
32502
32502
|
const follow = this.fsw.options.followSymlinks;
|
|
32503
32503
|
let closer;
|
|
32504
32504
|
if (stats.isDirectory()) {
|
|
32505
|
-
const absPath = sp.resolve(
|
|
32506
|
-
const targetPath = follow ? await (0, import_promises4.realpath)(
|
|
32505
|
+
const absPath = sp.resolve(path21);
|
|
32506
|
+
const targetPath = follow ? await (0, import_promises4.realpath)(path21) : path21;
|
|
32507
32507
|
if (this.fsw.closed)
|
|
32508
32508
|
return;
|
|
32509
32509
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -32513,29 +32513,29 @@ var NodeFsHandler = class {
|
|
|
32513
32513
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
32514
32514
|
}
|
|
32515
32515
|
} else if (stats.isSymbolicLink()) {
|
|
32516
|
-
const targetPath = follow ? await (0, import_promises4.realpath)(
|
|
32516
|
+
const targetPath = follow ? await (0, import_promises4.realpath)(path21) : path21;
|
|
32517
32517
|
if (this.fsw.closed)
|
|
32518
32518
|
return;
|
|
32519
32519
|
const parent = sp.dirname(wh.watchPath);
|
|
32520
32520
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
32521
32521
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
32522
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
32522
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path21, wh, targetPath);
|
|
32523
32523
|
if (this.fsw.closed)
|
|
32524
32524
|
return;
|
|
32525
32525
|
if (targetPath !== void 0) {
|
|
32526
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
32526
|
+
this.fsw._symlinkPaths.set(sp.resolve(path21), targetPath);
|
|
32527
32527
|
}
|
|
32528
32528
|
} else {
|
|
32529
32529
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
32530
32530
|
}
|
|
32531
32531
|
ready();
|
|
32532
32532
|
if (closer)
|
|
32533
|
-
this.fsw._addPathCloser(
|
|
32533
|
+
this.fsw._addPathCloser(path21, closer);
|
|
32534
32534
|
return false;
|
|
32535
32535
|
} catch (error) {
|
|
32536
32536
|
if (this.fsw._handleError(error)) {
|
|
32537
32537
|
ready();
|
|
32538
|
-
return
|
|
32538
|
+
return path21;
|
|
32539
32539
|
}
|
|
32540
32540
|
}
|
|
32541
32541
|
}
|
|
@@ -32578,24 +32578,24 @@ function createPattern(matcher) {
|
|
|
32578
32578
|
}
|
|
32579
32579
|
return () => false;
|
|
32580
32580
|
}
|
|
32581
|
-
function normalizePath(
|
|
32582
|
-
if (typeof
|
|
32581
|
+
function normalizePath(path21) {
|
|
32582
|
+
if (typeof path21 !== "string")
|
|
32583
32583
|
throw new Error("string expected");
|
|
32584
|
-
|
|
32585
|
-
|
|
32584
|
+
path21 = sp2.normalize(path21);
|
|
32585
|
+
path21 = path21.replace(/\\/g, "/");
|
|
32586
32586
|
let prepend = false;
|
|
32587
|
-
if (
|
|
32587
|
+
if (path21.startsWith("//"))
|
|
32588
32588
|
prepend = true;
|
|
32589
|
-
|
|
32589
|
+
path21 = path21.replace(DOUBLE_SLASH_RE, "/");
|
|
32590
32590
|
if (prepend)
|
|
32591
|
-
|
|
32592
|
-
return
|
|
32591
|
+
path21 = "/" + path21;
|
|
32592
|
+
return path21;
|
|
32593
32593
|
}
|
|
32594
32594
|
function matchPatterns(patterns, testString, stats) {
|
|
32595
|
-
const
|
|
32595
|
+
const path21 = normalizePath(testString);
|
|
32596
32596
|
for (let index = 0; index < patterns.length; index++) {
|
|
32597
32597
|
const pattern = patterns[index];
|
|
32598
|
-
if (pattern(
|
|
32598
|
+
if (pattern(path21, stats)) {
|
|
32599
32599
|
return true;
|
|
32600
32600
|
}
|
|
32601
32601
|
}
|
|
@@ -32633,19 +32633,19 @@ var toUnix = (string) => {
|
|
|
32633
32633
|
}
|
|
32634
32634
|
return str;
|
|
32635
32635
|
};
|
|
32636
|
-
var normalizePathToUnix = (
|
|
32637
|
-
var normalizeIgnored = (cwd = "") => (
|
|
32638
|
-
if (typeof
|
|
32639
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
32636
|
+
var normalizePathToUnix = (path21) => toUnix(sp2.normalize(toUnix(path21)));
|
|
32637
|
+
var normalizeIgnored = (cwd = "") => (path21) => {
|
|
32638
|
+
if (typeof path21 === "string") {
|
|
32639
|
+
return normalizePathToUnix(sp2.isAbsolute(path21) ? path21 : sp2.join(cwd, path21));
|
|
32640
32640
|
} else {
|
|
32641
|
-
return
|
|
32641
|
+
return path21;
|
|
32642
32642
|
}
|
|
32643
32643
|
};
|
|
32644
|
-
var getAbsolutePath = (
|
|
32645
|
-
if (sp2.isAbsolute(
|
|
32646
|
-
return
|
|
32644
|
+
var getAbsolutePath = (path21, cwd) => {
|
|
32645
|
+
if (sp2.isAbsolute(path21)) {
|
|
32646
|
+
return path21;
|
|
32647
32647
|
}
|
|
32648
|
-
return sp2.join(cwd,
|
|
32648
|
+
return sp2.join(cwd, path21);
|
|
32649
32649
|
};
|
|
32650
32650
|
var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
32651
32651
|
var DirEntry = class {
|
|
@@ -32710,10 +32710,10 @@ var WatchHelper = class {
|
|
|
32710
32710
|
dirParts;
|
|
32711
32711
|
followSymlinks;
|
|
32712
32712
|
statMethod;
|
|
32713
|
-
constructor(
|
|
32713
|
+
constructor(path21, follow, fsw) {
|
|
32714
32714
|
this.fsw = fsw;
|
|
32715
|
-
const watchPath =
|
|
32716
|
-
this.path =
|
|
32715
|
+
const watchPath = path21;
|
|
32716
|
+
this.path = path21 = path21.replace(REPLACER_RE, "");
|
|
32717
32717
|
this.watchPath = watchPath;
|
|
32718
32718
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
32719
32719
|
this.dirParts = [];
|
|
@@ -32853,20 +32853,20 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
32853
32853
|
this._closePromise = void 0;
|
|
32854
32854
|
let paths = unifyPaths(paths_);
|
|
32855
32855
|
if (cwd) {
|
|
32856
|
-
paths = paths.map((
|
|
32857
|
-
const absPath = getAbsolutePath(
|
|
32856
|
+
paths = paths.map((path21) => {
|
|
32857
|
+
const absPath = getAbsolutePath(path21, cwd);
|
|
32858
32858
|
return absPath;
|
|
32859
32859
|
});
|
|
32860
32860
|
}
|
|
32861
|
-
paths.forEach((
|
|
32862
|
-
this._removeIgnoredPath(
|
|
32861
|
+
paths.forEach((path21) => {
|
|
32862
|
+
this._removeIgnoredPath(path21);
|
|
32863
32863
|
});
|
|
32864
32864
|
this._userIgnored = void 0;
|
|
32865
32865
|
if (!this._readyCount)
|
|
32866
32866
|
this._readyCount = 0;
|
|
32867
32867
|
this._readyCount += paths.length;
|
|
32868
|
-
Promise.all(paths.map(async (
|
|
32869
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
32868
|
+
Promise.all(paths.map(async (path21) => {
|
|
32869
|
+
const res = await this._nodeFsHandler._addToNodeFs(path21, !_internal, void 0, 0, _origAdd);
|
|
32870
32870
|
if (res)
|
|
32871
32871
|
this._emitReady();
|
|
32872
32872
|
return res;
|
|
@@ -32888,17 +32888,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
32888
32888
|
return this;
|
|
32889
32889
|
const paths = unifyPaths(paths_);
|
|
32890
32890
|
const { cwd } = this.options;
|
|
32891
|
-
paths.forEach((
|
|
32892
|
-
if (!sp2.isAbsolute(
|
|
32891
|
+
paths.forEach((path21) => {
|
|
32892
|
+
if (!sp2.isAbsolute(path21) && !this._closers.has(path21)) {
|
|
32893
32893
|
if (cwd)
|
|
32894
|
-
|
|
32895
|
-
|
|
32894
|
+
path21 = sp2.join(cwd, path21);
|
|
32895
|
+
path21 = sp2.resolve(path21);
|
|
32896
32896
|
}
|
|
32897
|
-
this._closePath(
|
|
32898
|
-
this._addIgnoredPath(
|
|
32899
|
-
if (this._watched.has(
|
|
32897
|
+
this._closePath(path21);
|
|
32898
|
+
this._addIgnoredPath(path21);
|
|
32899
|
+
if (this._watched.has(path21)) {
|
|
32900
32900
|
this._addIgnoredPath({
|
|
32901
|
-
path:
|
|
32901
|
+
path: path21,
|
|
32902
32902
|
recursive: true
|
|
32903
32903
|
});
|
|
32904
32904
|
}
|
|
@@ -32962,38 +32962,38 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
32962
32962
|
* @param stats arguments to be passed with event
|
|
32963
32963
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
32964
32964
|
*/
|
|
32965
|
-
async _emit(event,
|
|
32965
|
+
async _emit(event, path21, stats) {
|
|
32966
32966
|
if (this.closed)
|
|
32967
32967
|
return;
|
|
32968
32968
|
const opts = this.options;
|
|
32969
32969
|
if (isWindows)
|
|
32970
|
-
|
|
32970
|
+
path21 = sp2.normalize(path21);
|
|
32971
32971
|
if (opts.cwd)
|
|
32972
|
-
|
|
32973
|
-
const args = [
|
|
32972
|
+
path21 = sp2.relative(opts.cwd, path21);
|
|
32973
|
+
const args = [path21];
|
|
32974
32974
|
if (stats != null)
|
|
32975
32975
|
args.push(stats);
|
|
32976
32976
|
const awf = opts.awaitWriteFinish;
|
|
32977
32977
|
let pw;
|
|
32978
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
32978
|
+
if (awf && (pw = this._pendingWrites.get(path21))) {
|
|
32979
32979
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
32980
32980
|
return this;
|
|
32981
32981
|
}
|
|
32982
32982
|
if (opts.atomic) {
|
|
32983
32983
|
if (event === EVENTS.UNLINK) {
|
|
32984
|
-
this._pendingUnlinks.set(
|
|
32984
|
+
this._pendingUnlinks.set(path21, [event, ...args]);
|
|
32985
32985
|
setTimeout(() => {
|
|
32986
|
-
this._pendingUnlinks.forEach((entry,
|
|
32986
|
+
this._pendingUnlinks.forEach((entry, path22) => {
|
|
32987
32987
|
this.emit(...entry);
|
|
32988
32988
|
this.emit(EVENTS.ALL, ...entry);
|
|
32989
|
-
this._pendingUnlinks.delete(
|
|
32989
|
+
this._pendingUnlinks.delete(path22);
|
|
32990
32990
|
});
|
|
32991
32991
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
32992
32992
|
return this;
|
|
32993
32993
|
}
|
|
32994
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
32994
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path21)) {
|
|
32995
32995
|
event = EVENTS.CHANGE;
|
|
32996
|
-
this._pendingUnlinks.delete(
|
|
32996
|
+
this._pendingUnlinks.delete(path21);
|
|
32997
32997
|
}
|
|
32998
32998
|
}
|
|
32999
32999
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -33011,16 +33011,16 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33011
33011
|
this.emitWithAll(event, args);
|
|
33012
33012
|
}
|
|
33013
33013
|
};
|
|
33014
|
-
this._awaitWriteFinish(
|
|
33014
|
+
this._awaitWriteFinish(path21, awf.stabilityThreshold, event, awfEmit);
|
|
33015
33015
|
return this;
|
|
33016
33016
|
}
|
|
33017
33017
|
if (event === EVENTS.CHANGE) {
|
|
33018
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
33018
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path21, 50);
|
|
33019
33019
|
if (isThrottled)
|
|
33020
33020
|
return this;
|
|
33021
33021
|
}
|
|
33022
33022
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
33023
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
33023
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path21) : path21;
|
|
33024
33024
|
let stats2;
|
|
33025
33025
|
try {
|
|
33026
33026
|
stats2 = await (0, import_promises5.stat)(fullPath);
|
|
@@ -33051,23 +33051,23 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33051
33051
|
* @param timeout duration of time to suppress duplicate actions
|
|
33052
33052
|
* @returns tracking object or false if action should be suppressed
|
|
33053
33053
|
*/
|
|
33054
|
-
_throttle(actionType,
|
|
33054
|
+
_throttle(actionType, path21, timeout) {
|
|
33055
33055
|
if (!this._throttled.has(actionType)) {
|
|
33056
33056
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
33057
33057
|
}
|
|
33058
33058
|
const action = this._throttled.get(actionType);
|
|
33059
33059
|
if (!action)
|
|
33060
33060
|
throw new Error("invalid throttle");
|
|
33061
|
-
const actionPath = action.get(
|
|
33061
|
+
const actionPath = action.get(path21);
|
|
33062
33062
|
if (actionPath) {
|
|
33063
33063
|
actionPath.count++;
|
|
33064
33064
|
return false;
|
|
33065
33065
|
}
|
|
33066
33066
|
let timeoutObject;
|
|
33067
33067
|
const clear = () => {
|
|
33068
|
-
const item = action.get(
|
|
33068
|
+
const item = action.get(path21);
|
|
33069
33069
|
const count = item ? item.count : 0;
|
|
33070
|
-
action.delete(
|
|
33070
|
+
action.delete(path21);
|
|
33071
33071
|
clearTimeout(timeoutObject);
|
|
33072
33072
|
if (item)
|
|
33073
33073
|
clearTimeout(item.timeoutObject);
|
|
@@ -33075,7 +33075,7 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33075
33075
|
};
|
|
33076
33076
|
timeoutObject = setTimeout(clear, timeout);
|
|
33077
33077
|
const thr = { timeoutObject, clear, count: 0 };
|
|
33078
|
-
action.set(
|
|
33078
|
+
action.set(path21, thr);
|
|
33079
33079
|
return thr;
|
|
33080
33080
|
}
|
|
33081
33081
|
_incrReadyCount() {
|
|
@@ -33089,44 +33089,44 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33089
33089
|
* @param event
|
|
33090
33090
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
33091
33091
|
*/
|
|
33092
|
-
_awaitWriteFinish(
|
|
33092
|
+
_awaitWriteFinish(path21, threshold, event, awfEmit) {
|
|
33093
33093
|
const awf = this.options.awaitWriteFinish;
|
|
33094
33094
|
if (typeof awf !== "object")
|
|
33095
33095
|
return;
|
|
33096
33096
|
const pollInterval = awf.pollInterval;
|
|
33097
33097
|
let timeoutHandler;
|
|
33098
|
-
let fullPath =
|
|
33099
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
33100
|
-
fullPath = sp2.join(this.options.cwd,
|
|
33098
|
+
let fullPath = path21;
|
|
33099
|
+
if (this.options.cwd && !sp2.isAbsolute(path21)) {
|
|
33100
|
+
fullPath = sp2.join(this.options.cwd, path21);
|
|
33101
33101
|
}
|
|
33102
33102
|
const now = /* @__PURE__ */ new Date();
|
|
33103
33103
|
const writes = this._pendingWrites;
|
|
33104
33104
|
function awaitWriteFinishFn(prevStat) {
|
|
33105
33105
|
(0, import_node_fs2.stat)(fullPath, (err, curStat) => {
|
|
33106
|
-
if (err || !writes.has(
|
|
33106
|
+
if (err || !writes.has(path21)) {
|
|
33107
33107
|
if (err && err.code !== "ENOENT")
|
|
33108
33108
|
awfEmit(err);
|
|
33109
33109
|
return;
|
|
33110
33110
|
}
|
|
33111
33111
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
33112
33112
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
33113
|
-
writes.get(
|
|
33113
|
+
writes.get(path21).lastChange = now2;
|
|
33114
33114
|
}
|
|
33115
|
-
const pw = writes.get(
|
|
33115
|
+
const pw = writes.get(path21);
|
|
33116
33116
|
const df = now2 - pw.lastChange;
|
|
33117
33117
|
if (df >= threshold) {
|
|
33118
|
-
writes.delete(
|
|
33118
|
+
writes.delete(path21);
|
|
33119
33119
|
awfEmit(void 0, curStat);
|
|
33120
33120
|
} else {
|
|
33121
33121
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
33122
33122
|
}
|
|
33123
33123
|
});
|
|
33124
33124
|
}
|
|
33125
|
-
if (!writes.has(
|
|
33126
|
-
writes.set(
|
|
33125
|
+
if (!writes.has(path21)) {
|
|
33126
|
+
writes.set(path21, {
|
|
33127
33127
|
lastChange: now,
|
|
33128
33128
|
cancelWait: () => {
|
|
33129
|
-
writes.delete(
|
|
33129
|
+
writes.delete(path21);
|
|
33130
33130
|
clearTimeout(timeoutHandler);
|
|
33131
33131
|
return event;
|
|
33132
33132
|
}
|
|
@@ -33137,8 +33137,8 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33137
33137
|
/**
|
|
33138
33138
|
* Determines whether user has asked to ignore this path.
|
|
33139
33139
|
*/
|
|
33140
|
-
_isIgnored(
|
|
33141
|
-
if (this.options.atomic && DOT_RE.test(
|
|
33140
|
+
_isIgnored(path21, stats) {
|
|
33141
|
+
if (this.options.atomic && DOT_RE.test(path21))
|
|
33142
33142
|
return true;
|
|
33143
33143
|
if (!this._userIgnored) {
|
|
33144
33144
|
const { cwd } = this.options;
|
|
@@ -33148,17 +33148,17 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33148
33148
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
33149
33149
|
this._userIgnored = anymatch(list, void 0);
|
|
33150
33150
|
}
|
|
33151
|
-
return this._userIgnored(
|
|
33151
|
+
return this._userIgnored(path21, stats);
|
|
33152
33152
|
}
|
|
33153
|
-
_isntIgnored(
|
|
33154
|
-
return !this._isIgnored(
|
|
33153
|
+
_isntIgnored(path21, stat11) {
|
|
33154
|
+
return !this._isIgnored(path21, stat11);
|
|
33155
33155
|
}
|
|
33156
33156
|
/**
|
|
33157
33157
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
33158
33158
|
* @param path file or directory pattern being watched
|
|
33159
33159
|
*/
|
|
33160
|
-
_getWatchHelpers(
|
|
33161
|
-
return new WatchHelper(
|
|
33160
|
+
_getWatchHelpers(path21) {
|
|
33161
|
+
return new WatchHelper(path21, this.options.followSymlinks, this);
|
|
33162
33162
|
}
|
|
33163
33163
|
// Directory helpers
|
|
33164
33164
|
// -----------------
|
|
@@ -33190,63 +33190,63 @@ var FSWatcher = class extends import_node_events.EventEmitter {
|
|
|
33190
33190
|
* @param item base path of item/directory
|
|
33191
33191
|
*/
|
|
33192
33192
|
_remove(directory, item, isDirectory) {
|
|
33193
|
-
const
|
|
33194
|
-
const fullPath = sp2.resolve(
|
|
33195
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
33196
|
-
if (!this._throttle("remove",
|
|
33193
|
+
const path21 = sp2.join(directory, item);
|
|
33194
|
+
const fullPath = sp2.resolve(path21);
|
|
33195
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path21) || this._watched.has(fullPath);
|
|
33196
|
+
if (!this._throttle("remove", path21, 100))
|
|
33197
33197
|
return;
|
|
33198
33198
|
if (!isDirectory && this._watched.size === 1) {
|
|
33199
33199
|
this.add(directory, item, true);
|
|
33200
33200
|
}
|
|
33201
|
-
const wp = this._getWatchedDir(
|
|
33201
|
+
const wp = this._getWatchedDir(path21);
|
|
33202
33202
|
const nestedDirectoryChildren = wp.getChildren();
|
|
33203
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
33203
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path21, nested));
|
|
33204
33204
|
const parent = this._getWatchedDir(directory);
|
|
33205
33205
|
const wasTracked = parent.has(item);
|
|
33206
33206
|
parent.remove(item);
|
|
33207
33207
|
if (this._symlinkPaths.has(fullPath)) {
|
|
33208
33208
|
this._symlinkPaths.delete(fullPath);
|
|
33209
33209
|
}
|
|
33210
|
-
let relPath =
|
|
33210
|
+
let relPath = path21;
|
|
33211
33211
|
if (this.options.cwd)
|
|
33212
|
-
relPath = sp2.relative(this.options.cwd,
|
|
33212
|
+
relPath = sp2.relative(this.options.cwd, path21);
|
|
33213
33213
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
33214
33214
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
33215
33215
|
if (event === EVENTS.ADD)
|
|
33216
33216
|
return;
|
|
33217
33217
|
}
|
|
33218
|
-
this._watched.delete(
|
|
33218
|
+
this._watched.delete(path21);
|
|
33219
33219
|
this._watched.delete(fullPath);
|
|
33220
33220
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
33221
|
-
if (wasTracked && !this._isIgnored(
|
|
33222
|
-
this._emit(eventName,
|
|
33223
|
-
this._closePath(
|
|
33221
|
+
if (wasTracked && !this._isIgnored(path21))
|
|
33222
|
+
this._emit(eventName, path21);
|
|
33223
|
+
this._closePath(path21);
|
|
33224
33224
|
}
|
|
33225
33225
|
/**
|
|
33226
33226
|
* Closes all watchers for a path
|
|
33227
33227
|
*/
|
|
33228
|
-
_closePath(
|
|
33229
|
-
this._closeFile(
|
|
33230
|
-
const dir = sp2.dirname(
|
|
33231
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
33228
|
+
_closePath(path21) {
|
|
33229
|
+
this._closeFile(path21);
|
|
33230
|
+
const dir = sp2.dirname(path21);
|
|
33231
|
+
this._getWatchedDir(dir).remove(sp2.basename(path21));
|
|
33232
33232
|
}
|
|
33233
33233
|
/**
|
|
33234
33234
|
* Closes only file-specific watchers
|
|
33235
33235
|
*/
|
|
33236
|
-
_closeFile(
|
|
33237
|
-
const closers = this._closers.get(
|
|
33236
|
+
_closeFile(path21) {
|
|
33237
|
+
const closers = this._closers.get(path21);
|
|
33238
33238
|
if (!closers)
|
|
33239
33239
|
return;
|
|
33240
33240
|
closers.forEach((closer) => closer());
|
|
33241
|
-
this._closers.delete(
|
|
33241
|
+
this._closers.delete(path21);
|
|
33242
33242
|
}
|
|
33243
|
-
_addPathCloser(
|
|
33243
|
+
_addPathCloser(path21, closer) {
|
|
33244
33244
|
if (!closer)
|
|
33245
33245
|
return;
|
|
33246
|
-
let list = this._closers.get(
|
|
33246
|
+
let list = this._closers.get(path21);
|
|
33247
33247
|
if (!list) {
|
|
33248
33248
|
list = [];
|
|
33249
|
-
this._closers.set(
|
|
33249
|
+
this._closers.set(path21, list);
|
|
33250
33250
|
}
|
|
33251
33251
|
list.push(closer);
|
|
33252
33252
|
}
|
|
@@ -34710,12 +34710,12 @@ function encodeURIPath(str) {
|
|
|
34710
34710
|
return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
|
|
34711
34711
|
}
|
|
34712
34712
|
var EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
34713
|
-
var createPathTagFunction = (pathEncoder = encodeURIPath) => function
|
|
34713
|
+
var createPathTagFunction = (pathEncoder = encodeURIPath) => function path21(statics, ...params) {
|
|
34714
34714
|
if (statics.length === 1)
|
|
34715
34715
|
return statics[0];
|
|
34716
34716
|
let postPath = false;
|
|
34717
34717
|
const invalidSegments = [];
|
|
34718
|
-
const
|
|
34718
|
+
const path22 = statics.reduce((previousValue, currentValue, index) => {
|
|
34719
34719
|
if (/[?#]/.test(currentValue)) {
|
|
34720
34720
|
postPath = true;
|
|
34721
34721
|
}
|
|
@@ -34732,7 +34732,7 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path20(sta
|
|
|
34732
34732
|
}
|
|
34733
34733
|
return previousValue + currentValue + (index === params.length ? "" : encoded);
|
|
34734
34734
|
}, "");
|
|
34735
|
-
const pathOnly =
|
|
34735
|
+
const pathOnly = path22.split(/[?#]/, 1)[0];
|
|
34736
34736
|
const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
|
|
34737
34737
|
let match2;
|
|
34738
34738
|
while ((match2 = invalidSegmentPattern.exec(pathOnly)) !== null) {
|
|
@@ -34753,10 +34753,10 @@ var createPathTagFunction = (pathEncoder = encodeURIPath) => function path20(sta
|
|
|
34753
34753
|
}, "");
|
|
34754
34754
|
throw new AnthropicError(`Path parameters result in path with invalid segments:
|
|
34755
34755
|
${invalidSegments.map((e) => e.error).join("\n")}
|
|
34756
|
-
${
|
|
34756
|
+
${path22}
|
|
34757
34757
|
${underline}`);
|
|
34758
34758
|
}
|
|
34759
|
-
return
|
|
34759
|
+
return path22;
|
|
34760
34760
|
};
|
|
34761
34761
|
var path5 = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
|
|
34762
34762
|
|
|
@@ -37867,9 +37867,9 @@ var BaseAnthropic = class {
|
|
|
37867
37867
|
makeStatusError(status, error, message, headers) {
|
|
37868
37868
|
return APIError.generate(status, error, message, headers);
|
|
37869
37869
|
}
|
|
37870
|
-
buildURL(
|
|
37870
|
+
buildURL(path21, query, defaultBaseURL) {
|
|
37871
37871
|
const baseURL = !__classPrivateFieldGet(this, _BaseAnthropic_instances, "m", _BaseAnthropic_baseURLOverridden).call(this) && defaultBaseURL || this.baseURL;
|
|
37872
|
-
const url = isAbsoluteURL(
|
|
37872
|
+
const url = isAbsoluteURL(path21) ? new URL(path21) : new URL(baseURL + (baseURL.endsWith("/") && path21.startsWith("/") ? path21.slice(1) : path21));
|
|
37873
37873
|
const defaultQuery = this.defaultQuery();
|
|
37874
37874
|
if (!isEmptyObj(defaultQuery)) {
|
|
37875
37875
|
query = { ...defaultQuery, ...query };
|
|
@@ -37900,24 +37900,24 @@ var BaseAnthropic = class {
|
|
|
37900
37900
|
*/
|
|
37901
37901
|
async prepareRequest(request, { url, options }) {
|
|
37902
37902
|
}
|
|
37903
|
-
get(
|
|
37904
|
-
return this.methodRequest("get",
|
|
37903
|
+
get(path21, opts) {
|
|
37904
|
+
return this.methodRequest("get", path21, opts);
|
|
37905
37905
|
}
|
|
37906
|
-
post(
|
|
37907
|
-
return this.methodRequest("post",
|
|
37906
|
+
post(path21, opts) {
|
|
37907
|
+
return this.methodRequest("post", path21, opts);
|
|
37908
37908
|
}
|
|
37909
|
-
patch(
|
|
37910
|
-
return this.methodRequest("patch",
|
|
37909
|
+
patch(path21, opts) {
|
|
37910
|
+
return this.methodRequest("patch", path21, opts);
|
|
37911
37911
|
}
|
|
37912
|
-
put(
|
|
37913
|
-
return this.methodRequest("put",
|
|
37912
|
+
put(path21, opts) {
|
|
37913
|
+
return this.methodRequest("put", path21, opts);
|
|
37914
37914
|
}
|
|
37915
|
-
delete(
|
|
37916
|
-
return this.methodRequest("delete",
|
|
37915
|
+
delete(path21, opts) {
|
|
37916
|
+
return this.methodRequest("delete", path21, opts);
|
|
37917
37917
|
}
|
|
37918
|
-
methodRequest(method,
|
|
37918
|
+
methodRequest(method, path21, opts) {
|
|
37919
37919
|
return this.request(Promise.resolve(opts).then((opts2) => {
|
|
37920
|
-
return { method, path:
|
|
37920
|
+
return { method, path: path21, ...opts2 };
|
|
37921
37921
|
}));
|
|
37922
37922
|
}
|
|
37923
37923
|
request(options, remainingRetries = null) {
|
|
@@ -38021,8 +38021,8 @@ var BaseAnthropic = class {
|
|
|
38021
38021
|
}));
|
|
38022
38022
|
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime: startTime2 };
|
|
38023
38023
|
}
|
|
38024
|
-
getAPIList(
|
|
38025
|
-
return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path:
|
|
38024
|
+
getAPIList(path21, Page2, opts) {
|
|
38025
|
+
return this.requestAPIList(Page2, opts && "then" in opts ? opts.then((opts2) => ({ method: "get", path: path21, ...opts2 })) : { method: "get", path: path21, ...opts });
|
|
38026
38026
|
}
|
|
38027
38027
|
requestAPIList(Page2, options) {
|
|
38028
38028
|
const request = this.makeRequest(options, null, void 0);
|
|
@@ -38110,8 +38110,8 @@ var BaseAnthropic = class {
|
|
|
38110
38110
|
}
|
|
38111
38111
|
async buildRequest(inputOptions, { retryCount = 0 } = {}) {
|
|
38112
38112
|
const options = { ...inputOptions };
|
|
38113
|
-
const { method, path:
|
|
38114
|
-
const url = this.buildURL(
|
|
38113
|
+
const { method, path: path21, query, defaultBaseURL } = options;
|
|
38114
|
+
const url = this.buildURL(path21, query, defaultBaseURL);
|
|
38115
38115
|
if ("timeout" in options)
|
|
38116
38116
|
validatePositiveInteger("timeout", options.timeout);
|
|
38117
38117
|
options.timeout = options.timeout ?? this.timeout;
|
|
@@ -40321,16 +40321,16 @@ var Diff = class {
|
|
|
40321
40321
|
}
|
|
40322
40322
|
}
|
|
40323
40323
|
}
|
|
40324
|
-
addToPath(
|
|
40325
|
-
const last =
|
|
40324
|
+
addToPath(path21, added, removed, oldPosInc, options) {
|
|
40325
|
+
const last = path21.lastComponent;
|
|
40326
40326
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
40327
40327
|
return {
|
|
40328
|
-
oldPos:
|
|
40328
|
+
oldPos: path21.oldPos + oldPosInc,
|
|
40329
40329
|
lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
|
|
40330
40330
|
};
|
|
40331
40331
|
} else {
|
|
40332
40332
|
return {
|
|
40333
|
-
oldPos:
|
|
40333
|
+
oldPos: path21.oldPos + oldPosInc,
|
|
40334
40334
|
lastComponent: { count: 1, added, removed, previousComponent: last }
|
|
40335
40335
|
};
|
|
40336
40336
|
}
|
|
@@ -41782,9 +41782,9 @@ var imageUnderstand = {
|
|
|
41782
41782
|
};
|
|
41783
41783
|
|
|
41784
41784
|
// src/skill/SkillRegistry.ts
|
|
41785
|
-
var
|
|
41785
|
+
var import_fs11 = require("fs");
|
|
41786
41786
|
var import_os3 = require("os");
|
|
41787
|
-
var
|
|
41787
|
+
var import_path16 = __toESM(require("path"));
|
|
41788
41788
|
|
|
41789
41789
|
// src/runtime/paths.ts
|
|
41790
41790
|
var import_fs10 = require("fs");
|
|
@@ -41829,592 +41829,17 @@ var resolveWebDistRoot = () => {
|
|
|
41829
41829
|
return candidates[0];
|
|
41830
41830
|
};
|
|
41831
41831
|
|
|
41832
|
-
// src/department/Department.ts
|
|
41833
|
-
var import_path16 = __toESM(require("path"));
|
|
41834
|
-
var import_fs11 = require("fs");
|
|
41835
|
-
var legacyMigrationChecked = false;
|
|
41836
|
-
var getDepartmentBaseDir = () => {
|
|
41837
|
-
return import_path16.default.join(getDuclawHomeDir(), "department");
|
|
41838
|
-
};
|
|
41839
|
-
var getLegacyTeamBaseDir = () => {
|
|
41840
|
-
return import_path16.default.join(getDuclawHomeDir(), "team");
|
|
41841
|
-
};
|
|
41842
|
-
var getDepartmentWorkSpaceDir = (departmentName) => {
|
|
41843
|
-
return import_path16.default.join(getDepartmentBaseDir(), "workspace", departmentName);
|
|
41844
|
-
};
|
|
41845
|
-
var getLegacyTeamWorkSpaceDir = (teamName) => {
|
|
41846
|
-
return import_path16.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
|
|
41847
|
-
};
|
|
41848
|
-
var getDepartmentJsonPath = (departmentName) => {
|
|
41849
|
-
return import_path16.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
|
|
41850
|
-
};
|
|
41851
|
-
var getLegacyTeamJsonPath = (teamName) => {
|
|
41852
|
-
return import_path16.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
|
|
41853
|
-
};
|
|
41854
|
-
var mapLegacyRole = (role) => {
|
|
41855
|
-
return role === "team_manager" ? "department_head" : "executor";
|
|
41856
|
-
};
|
|
41857
|
-
var mapLegacyDepartment = (legacy) => {
|
|
41858
|
-
const departmentMembers = (legacy.teamMembers ?? []).map((member) => ({
|
|
41859
|
-
id: member.id,
|
|
41860
|
-
name: member.name,
|
|
41861
|
-
departmentId: legacy.id,
|
|
41862
|
-
mailBoxId: member.mailBoxId,
|
|
41863
|
-
workspaceId: member.workspaceId,
|
|
41864
|
-
role: mapLegacyRole(member.role),
|
|
41865
|
-
focusOn: member.focusOn
|
|
41866
|
-
}));
|
|
41867
|
-
const headMemberId = legacy.managerMemberId ?? departmentMembers.find((member) => member.role === "department_head")?.id;
|
|
41868
|
-
return {
|
|
41869
|
-
id: legacy.id,
|
|
41870
|
-
name: legacy.name,
|
|
41871
|
-
sourceGoalId: legacy.goalId,
|
|
41872
|
-
charter: legacy.goalId ? `Legacy department migrated from team goal ${legacy.goalId}.` : "Legacy department migrated from team data.",
|
|
41873
|
-
workpath: legacy.workpath,
|
|
41874
|
-
headMemberId,
|
|
41875
|
-
departmentMembers
|
|
41876
|
-
};
|
|
41877
|
-
};
|
|
41878
|
-
var migrateLegacyTeamsToDepartments = () => {
|
|
41879
|
-
if (legacyMigrationChecked) return;
|
|
41880
|
-
legacyMigrationChecked = true;
|
|
41881
|
-
const legacyWorkspaceDir = import_path16.default.join(getLegacyTeamBaseDir(), "workspace");
|
|
41882
|
-
if (!(0, import_fs11.existsSync)(legacyWorkspaceDir)) return;
|
|
41883
|
-
for (const legacyName of (0, import_fs11.readdirSync)(legacyWorkspaceDir)) {
|
|
41884
|
-
const legacyJsonPath = getLegacyTeamJsonPath(legacyName);
|
|
41885
|
-
if (!(0, import_fs11.existsSync)(legacyJsonPath)) continue;
|
|
41886
|
-
const departmentJsonPath = getDepartmentJsonPath(legacyName);
|
|
41887
|
-
if ((0, import_fs11.existsSync)(departmentJsonPath)) continue;
|
|
41888
|
-
try {
|
|
41889
|
-
const legacy = JSON.parse((0, import_fs11.readFileSync)(legacyJsonPath, "utf-8"));
|
|
41890
|
-
const department = mapLegacyDepartment(legacy);
|
|
41891
|
-
(0, import_fs11.mkdirSync)(getDepartmentWorkSpaceDir(department.name), { recursive: true });
|
|
41892
|
-
(0, import_fs11.writeFileSync)(departmentJsonPath, JSON.stringify(department, null, " "), "utf-8");
|
|
41893
|
-
} catch (err) {
|
|
41894
|
-
console.warn(`[department] Failed to migrate legacy team ${legacyName}: ${err.message}`);
|
|
41895
|
-
}
|
|
41896
|
-
}
|
|
41897
|
-
};
|
|
41898
|
-
var createDepartment = (departmentDefinition) => {
|
|
41899
|
-
if (!departmentDefinition) throw new Error(`[createDepartment] departmentDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
41900
|
-
const departmentPath = getDepartmentWorkSpaceDir(departmentDefinition.name);
|
|
41901
|
-
(0, import_fs11.mkdirSync)(departmentPath, { recursive: true });
|
|
41902
|
-
(0, import_fs11.writeFileSync)(getDepartmentJsonPath(departmentDefinition.name), JSON.stringify(departmentDefinition, null, " "), "utf-8");
|
|
41903
|
-
return departmentDefinition;
|
|
41904
|
-
};
|
|
41905
|
-
var getDepartment = (name) => {
|
|
41906
|
-
migrateLegacyTeamsToDepartments();
|
|
41907
|
-
const departmentJsonPath = getDepartmentJsonPath(name);
|
|
41908
|
-
if (!(0, import_fs11.existsSync)(departmentJsonPath)) return null;
|
|
41909
|
-
const text2 = (0, import_fs11.readFileSync)(departmentJsonPath, "utf-8");
|
|
41910
|
-
return JSON.parse(text2);
|
|
41911
|
-
};
|
|
41912
|
-
var listDepartments = () => {
|
|
41913
|
-
migrateLegacyTeamsToDepartments();
|
|
41914
|
-
const workspaceDir = import_path16.default.join(getDepartmentBaseDir(), "workspace");
|
|
41915
|
-
if (!(0, import_fs11.existsSync)(workspaceDir)) return [];
|
|
41916
|
-
const departments = [];
|
|
41917
|
-
for (const departmentName of (0, import_fs11.readdirSync)(workspaceDir)) {
|
|
41918
|
-
const department = getDepartment(departmentName);
|
|
41919
|
-
if (department) departments.push(department);
|
|
41920
|
-
}
|
|
41921
|
-
return departments;
|
|
41922
|
-
};
|
|
41923
|
-
var getDepartmentById = (id) => {
|
|
41924
|
-
const department = listDepartments().find((item) => item.id === id);
|
|
41925
|
-
return department ?? null;
|
|
41926
|
-
};
|
|
41927
|
-
var deleteDepartment = (name) => {
|
|
41928
|
-
if (!(0, import_fs11.existsSync)(getDepartmentJsonPath(name))) {
|
|
41929
|
-
throw new Error(`[deleteDepartment] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u90E8\u95E8 ${name} \u7684 department.json \u6587\u4EF6`);
|
|
41930
|
-
}
|
|
41931
|
-
(0, import_fs11.rmSync)(getDepartmentJsonPath(name));
|
|
41932
|
-
};
|
|
41933
|
-
|
|
41934
|
-
// src/department/learning.ts
|
|
41935
|
-
var import_node_fs4 = require("node:fs");
|
|
41936
|
-
var import_node_path13 = __toESM(require("node:path"));
|
|
41937
|
-
var import_node_crypto4 = require("node:crypto");
|
|
41938
|
-
|
|
41939
|
-
// src/department/DepartmentMember.ts
|
|
41940
|
-
var import_fs12 = require("fs");
|
|
41941
|
-
var import_path17 = __toESM(require("path"));
|
|
41942
|
-
|
|
41943
|
-
// src/department/workspace/workspace.ts
|
|
41944
|
-
var db = createSqliteDB();
|
|
41945
|
-
var getWorkspaceId = (departmentName, memberName) => {
|
|
41946
|
-
return `${departmentName}::${memberName}`;
|
|
41947
|
-
};
|
|
41948
|
-
var createWorkspace = (workspace) => {
|
|
41949
|
-
const stmt = db.prepare(`INSERT INTO workspace (id, team_name, teammate_name, team_workpath) VALUES (?, ?, ?, ?) `);
|
|
41950
|
-
stmt.run(
|
|
41951
|
-
workspace.id,
|
|
41952
|
-
workspace.departmentName,
|
|
41953
|
-
workspace.memberName,
|
|
41954
|
-
workspace.departmentWorkPath
|
|
41955
|
-
);
|
|
41956
|
-
};
|
|
41957
|
-
var deleteWorkspace = (workspaceId) => {
|
|
41958
|
-
const stmt = db.prepare(`delete from workspace where id = ?`);
|
|
41959
|
-
stmt.run(workspaceId);
|
|
41960
|
-
};
|
|
41961
|
-
|
|
41962
|
-
// src/department/DepartmentMember.ts
|
|
41963
|
-
var createDepartmentMember = (departmentMemberDefinition) => {
|
|
41964
|
-
if (!departmentMemberDefinition) throw new Error(`[createDepartmentMember] departmentMemberDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
41965
|
-
const { name, departmentId, workspaceId } = departmentMemberDefinition;
|
|
41966
|
-
const department = getDepartmentById(departmentId);
|
|
41967
|
-
if (!department) throw new Error(`[createDepartmentMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentId}`);
|
|
41968
|
-
const memberPath = import_path17.default.join(getDepartmentWorkSpaceDir(department.name), name);
|
|
41969
|
-
(0, import_fs12.mkdirSync)(memberPath, { recursive: true });
|
|
41970
|
-
const workspace = {
|
|
41971
|
-
id: getWorkspaceId(department.name, departmentMemberDefinition.name),
|
|
41972
|
-
departmentName: department.name,
|
|
41973
|
-
memberName: name,
|
|
41974
|
-
departmentWorkPath: memberPath
|
|
41975
|
-
};
|
|
41976
|
-
createWorkspace(workspace);
|
|
41977
|
-
if (!department.departmentMembers) {
|
|
41978
|
-
department.departmentMembers = [];
|
|
41979
|
-
}
|
|
41980
|
-
if (department.departmentMembers.some((member) => member.id === departmentMemberDefinition.id || member.name === departmentMemberDefinition.name)) {
|
|
41981
|
-
throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728\u540C\u540D\u6216\u540C id \u6210\u5458: ${departmentMemberDefinition.name}/${departmentMemberDefinition.id}`);
|
|
41982
|
-
}
|
|
41983
|
-
if (departmentMemberDefinition.role === "department_head") {
|
|
41984
|
-
const existingHead = department.headMemberId ? department.departmentMembers.find((member) => member.id === department.headMemberId) : department.departmentMembers.find((member) => member.role === "department_head");
|
|
41985
|
-
if (existingHead) {
|
|
41986
|
-
throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728 Department Head: ${existingHead.name}`);
|
|
41987
|
-
}
|
|
41988
|
-
department.headMemberId = departmentMemberDefinition.id;
|
|
41989
|
-
}
|
|
41990
|
-
department.departmentMembers.push(departmentMemberDefinition);
|
|
41991
|
-
(0, import_fs12.writeFileSync)(getDepartmentJsonPath(department.name), JSON.stringify(department, null, " "), "utf-8");
|
|
41992
|
-
return departmentMemberDefinition;
|
|
41993
|
-
};
|
|
41994
|
-
var listDepartmentMembers = (departmentName) => {
|
|
41995
|
-
const departmentJsonPath = getDepartmentJsonPath(departmentName);
|
|
41996
|
-
if (!(0, import_fs12.existsSync)(departmentJsonPath)) return [];
|
|
41997
|
-
const text2 = (0, import_fs12.readFileSync)(departmentJsonPath, "utf-8");
|
|
41998
|
-
const department = JSON.parse(text2);
|
|
41999
|
-
if (!department) throw new Error(`[listDepartmentMembers] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
|
|
42000
|
-
return department.departmentMembers ?? [];
|
|
42001
|
-
};
|
|
42002
|
-
var getDepartmentMember = (departmentName, departmentMemberId) => {
|
|
42003
|
-
const members = listDepartmentMembers(departmentName);
|
|
42004
|
-
return members.find((member) => member.id === departmentMemberId) || null;
|
|
42005
|
-
};
|
|
42006
|
-
var getDepartmentMemberByName = (departmentName, departmentMemberName) => {
|
|
42007
|
-
const members = listDepartmentMembers(departmentName);
|
|
42008
|
-
return members.find((member) => member.name === departmentMemberName) || null;
|
|
42009
|
-
};
|
|
42010
|
-
var getDepartmentMemberByMailboxId = (mailboxId) => {
|
|
42011
|
-
const [departmentName, memberName] = mailboxId.split("::");
|
|
42012
|
-
if (!departmentName || !memberName) return null;
|
|
42013
|
-
return getDepartmentMemberByName(departmentName, memberName);
|
|
42014
|
-
};
|
|
42015
|
-
var getDepartmentMemberById = (memberId) => {
|
|
42016
|
-
for (const department of listDepartments()) {
|
|
42017
|
-
const targetMember = department.departmentMembers.find((member) => member.id === memberId);
|
|
42018
|
-
if (targetMember) return targetMember;
|
|
42019
|
-
}
|
|
42020
|
-
return null;
|
|
42021
|
-
};
|
|
42022
|
-
var deleteDepartmentMemberById = (departmentName, memberId) => {
|
|
42023
|
-
const department = getDepartment(departmentName);
|
|
42024
|
-
if (!department) throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
|
|
42025
|
-
const memberIdx = department.departmentMembers.findIndex((member) => member.id === memberId);
|
|
42026
|
-
if (memberIdx === -1) {
|
|
42027
|
-
throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94 id \u7684 department member: ${memberId}`);
|
|
42028
|
-
}
|
|
42029
|
-
const workspaceId = department.departmentMembers[memberIdx].workspaceId;
|
|
42030
|
-
if (department.headMemberId === memberId) {
|
|
42031
|
-
delete department.headMemberId;
|
|
42032
|
-
}
|
|
42033
|
-
department.departmentMembers = department.departmentMembers.filter((_, index) => index !== memberIdx);
|
|
42034
|
-
(0, import_fs12.writeFileSync)(getDepartmentJsonPath(departmentName), JSON.stringify(department, null, " "), "utf-8");
|
|
42035
|
-
deleteWorkspace(workspaceId);
|
|
42036
|
-
};
|
|
42037
|
-
|
|
42038
|
-
// src/skill/SkillValidator.ts
|
|
42039
|
-
var import_node_fs3 = require("node:fs");
|
|
42040
|
-
var import_node_path12 = __toESM(require("node:path"));
|
|
42041
|
-
var SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
42042
|
-
var REQUIRED_SECTIONS = [
|
|
42043
|
-
/(^|\n)##\s+(when to use|何时使用|trigger|triggers)\b/i,
|
|
42044
|
-
/(^|\n)##\s+(steps|workflow|procedure|执行步骤|工作流)\b/i
|
|
42045
|
-
];
|
|
42046
|
-
var stripYamlQuotes = (value) => {
|
|
42047
|
-
const trimmed = value.trim();
|
|
42048
|
-
if (trimmed.startsWith(`"`) && trimmed.endsWith(`"`) || trimmed.startsWith(`'`) && trimmed.endsWith(`'`)) {
|
|
42049
|
-
return trimmed.slice(1, -1).trim();
|
|
42050
|
-
}
|
|
42051
|
-
return trimmed;
|
|
42052
|
-
};
|
|
42053
|
-
var addError = (errors, code, message) => {
|
|
42054
|
-
errors.push({ code, message });
|
|
42055
|
-
};
|
|
42056
|
-
var addWarning = (warnings, code, message) => {
|
|
42057
|
-
warnings.push({ code, message });
|
|
42058
|
-
};
|
|
42059
|
-
var isValidSkillName = (name) => {
|
|
42060
|
-
return SKILL_NAME_PATTERN.test(name) && !name.includes(`--`);
|
|
42061
|
-
};
|
|
42062
|
-
var assertSafeSkillTarget = (rootDir, skillName) => {
|
|
42063
|
-
if (!isValidSkillName(skillName)) {
|
|
42064
|
-
throw new Error(`Invalid skill name "${skillName}". Use lowercase letters, digits, and single hyphens only.`);
|
|
42065
|
-
}
|
|
42066
|
-
const root = import_node_path12.default.resolve(rootDir);
|
|
42067
|
-
const target = import_node_path12.default.resolve(root, skillName);
|
|
42068
|
-
if (target !== import_node_path12.default.join(root, skillName) || !target.startsWith(root + import_node_path12.default.sep)) {
|
|
42069
|
-
throw new Error(`Invalid skill install target for "${skillName}".`);
|
|
42070
|
-
}
|
|
42071
|
-
return target;
|
|
42072
|
-
};
|
|
42073
|
-
var parseSkillDocument = (skillMd) => {
|
|
42074
|
-
const fmMatch = skillMd.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
42075
|
-
if (!fmMatch) return null;
|
|
42076
|
-
const frontmatter = {};
|
|
42077
|
-
for (const rawLine of fmMatch[1].split(/\r?\n/)) {
|
|
42078
|
-
const line = rawLine.trim();
|
|
42079
|
-
if (!line || line.startsWith(`#`)) continue;
|
|
42080
|
-
const match2 = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
42081
|
-
if (!match2) {
|
|
42082
|
-
frontmatter[`__invalid__${Object.keys(frontmatter).length}`] = line;
|
|
42083
|
-
continue;
|
|
42084
|
-
}
|
|
42085
|
-
frontmatter[match2[1]] = stripYamlQuotes(match2[2]);
|
|
42086
|
-
}
|
|
42087
|
-
return {
|
|
42088
|
-
name: frontmatter.name ?? ``,
|
|
42089
|
-
description: frontmatter.description ?? ``,
|
|
42090
|
-
body: skillMd.slice(fmMatch[0].length).trim(),
|
|
42091
|
-
frontmatter
|
|
42092
|
-
};
|
|
42093
|
-
};
|
|
42094
|
-
var validateSkillDocument = (input) => {
|
|
42095
|
-
const errors = [];
|
|
42096
|
-
const warnings = [];
|
|
42097
|
-
const skillMd = input.skillMd;
|
|
42098
|
-
if (!skillMd || !skillMd.trim()) {
|
|
42099
|
-
addError(errors, `empty_skill_md`, `SKILL.md content is required.`);
|
|
42100
|
-
return { ok: false, errors, warnings };
|
|
42101
|
-
}
|
|
42102
|
-
const parsed = parseSkillDocument(skillMd);
|
|
42103
|
-
if (!parsed) {
|
|
42104
|
-
addError(errors, `missing_frontmatter`, `SKILL.md must start with YAML frontmatter delimited by "---".`);
|
|
42105
|
-
return { ok: false, errors, warnings };
|
|
42106
|
-
}
|
|
42107
|
-
const invalidFrontmatterLines = Object.keys(parsed.frontmatter).filter((key) => key.startsWith(`__invalid__`));
|
|
42108
|
-
if (invalidFrontmatterLines.length > 0) {
|
|
42109
|
-
addError(errors, `invalid_frontmatter`, `Frontmatter must contain simple "key: value" lines.`);
|
|
42110
|
-
}
|
|
42111
|
-
if (!parsed.name) {
|
|
42112
|
-
addError(errors, `missing_name`, `Frontmatter field "name" is required.`);
|
|
42113
|
-
} else if (!isValidSkillName(parsed.name)) {
|
|
42114
|
-
addError(errors, `invalid_name`, `Skill name "${parsed.name}" must be kebab-case, under 64 characters, and path-safe.`);
|
|
42115
|
-
}
|
|
42116
|
-
if (!parsed.description) {
|
|
42117
|
-
addError(errors, `missing_description`, `Frontmatter field "description" is required.`);
|
|
42118
|
-
} else if (parsed.description.length > 500) {
|
|
42119
|
-
addWarning(warnings, `long_description`, `Skill description is long; keep trigger metadata concise.`);
|
|
42120
|
-
}
|
|
42121
|
-
if (input.skillName && parsed.name && input.skillName !== parsed.name) {
|
|
42122
|
-
addError(errors, `name_mismatch`, `Input skillName "${input.skillName}" must match frontmatter name "${parsed.name}".`);
|
|
42123
|
-
}
|
|
42124
|
-
if (input.description && parsed.description && input.description !== parsed.description) {
|
|
42125
|
-
addError(errors, `description_mismatch`, `Input description must match frontmatter description.`);
|
|
42126
|
-
}
|
|
42127
|
-
if (!parsed.body) {
|
|
42128
|
-
addError(errors, `empty_body`, `SKILL.md body is required.`);
|
|
42129
|
-
} else {
|
|
42130
|
-
if (!/(^|\n)#\s+\S/.test(parsed.body)) {
|
|
42131
|
-
addWarning(warnings, `missing_title`, `Skill body should start with a Markdown H1 title.`);
|
|
42132
|
-
}
|
|
42133
|
-
for (const sectionPattern of REQUIRED_SECTIONS) {
|
|
42134
|
-
if (!sectionPattern.test(parsed.body)) {
|
|
42135
|
-
addWarning(warnings, `missing_recommended_section`, `Skill body should include when-to-use and execution workflow sections.`);
|
|
42136
|
-
break;
|
|
42137
|
-
}
|
|
42138
|
-
}
|
|
42139
|
-
}
|
|
42140
|
-
if (input.baseDir) {
|
|
42141
|
-
const normalizedBase = import_node_path12.default.resolve(input.baseDir);
|
|
42142
|
-
for (const match2 of parsed.body.matchAll(/\]\(([^)]+)\)/g)) {
|
|
42143
|
-
const href = match2[1].trim();
|
|
42144
|
-
if (!href || /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith(`#`)) continue;
|
|
42145
|
-
const target = import_node_path12.default.resolve(normalizedBase, href.split(`#`)[0]);
|
|
42146
|
-
if (!target.startsWith(normalizedBase + import_node_path12.default.sep) && target !== normalizedBase) {
|
|
42147
|
-
addError(errors, `unsafe_reference`, `Relative link "${href}" escapes the skill directory.`);
|
|
42148
|
-
} else if (!(0, import_node_fs3.existsSync)(target)) {
|
|
42149
|
-
addError(errors, `missing_reference`, `Relative link "${href}" does not exist in the skill directory.`);
|
|
42150
|
-
}
|
|
42151
|
-
}
|
|
42152
|
-
}
|
|
42153
|
-
return {
|
|
42154
|
-
ok: errors.length === 0,
|
|
42155
|
-
skill: parsed,
|
|
42156
|
-
errors,
|
|
42157
|
-
warnings
|
|
42158
|
-
};
|
|
42159
|
-
};
|
|
42160
|
-
var mergeIssues = (target, source) => {
|
|
42161
|
-
target.errors.push(...source.errors);
|
|
42162
|
-
target.warnings.push(...source.warnings);
|
|
42163
|
-
};
|
|
42164
|
-
var validateScriptsDirectory = (skillDir, warnings) => {
|
|
42165
|
-
const scriptsDir = import_node_path12.default.join(skillDir, `scripts`);
|
|
42166
|
-
if (!(0, import_node_fs3.existsSync)(scriptsDir)) return;
|
|
42167
|
-
const entries = (0, import_node_fs3.readdirSync)(scriptsDir, { withFileTypes: true }).filter((entry) => entry.isFile());
|
|
42168
|
-
if (entries.length === 0) {
|
|
42169
|
-
addWarning(warnings, `empty_scripts_dir`, `scripts/ exists but contains no files.`);
|
|
42170
|
-
}
|
|
42171
|
-
};
|
|
42172
|
-
var validateSkillDirectory = (skillDir, options = {}) => {
|
|
42173
|
-
const errors = [];
|
|
42174
|
-
const warnings = [];
|
|
42175
|
-
const normalizedSkillDir = import_node_path12.default.resolve(skillDir);
|
|
42176
|
-
const skillMdPath = import_node_path12.default.join(normalizedSkillDir, `SKILL.md`);
|
|
42177
|
-
if (!(0, import_node_fs3.existsSync)(normalizedSkillDir) || !(0, import_node_fs3.statSync)(normalizedSkillDir).isDirectory()) {
|
|
42178
|
-
addError(errors, `missing_skill_dir`, `Skill directory does not exist: ${normalizedSkillDir}`);
|
|
42179
|
-
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
42180
|
-
}
|
|
42181
|
-
if (!(0, import_node_fs3.existsSync)(skillMdPath) || !(0, import_node_fs3.statSync)(skillMdPath).isFile()) {
|
|
42182
|
-
addError(errors, `missing_skill_md`, `Skill directory must contain SKILL.md.`);
|
|
42183
|
-
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
42184
|
-
}
|
|
42185
|
-
const raw2 = (0, import_node_fs3.readFileSync)(skillMdPath, `utf-8`);
|
|
42186
|
-
const documentResult = validateSkillDocument({
|
|
42187
|
-
skillName: options.expectedName ?? import_node_path12.default.basename(normalizedSkillDir),
|
|
42188
|
-
skillMd: raw2,
|
|
42189
|
-
baseDir: normalizedSkillDir
|
|
42190
|
-
});
|
|
42191
|
-
mergeIssues({ errors, warnings }, documentResult);
|
|
42192
|
-
validateScriptsDirectory(normalizedSkillDir, warnings);
|
|
42193
|
-
return {
|
|
42194
|
-
ok: errors.length === 0,
|
|
42195
|
-
skill: documentResult.skill,
|
|
42196
|
-
errors,
|
|
42197
|
-
warnings,
|
|
42198
|
-
skillDir: normalizedSkillDir,
|
|
42199
|
-
skillMdPath
|
|
42200
|
-
};
|
|
42201
|
-
};
|
|
42202
|
-
var smokeTestSkillDirectory = (skillDir, options = {}) => {
|
|
42203
|
-
const directoryResult = validateSkillDirectory(skillDir, options);
|
|
42204
|
-
const errors = [...directoryResult.errors];
|
|
42205
|
-
const warnings = [...directoryResult.warnings];
|
|
42206
|
-
let detail;
|
|
42207
|
-
if (directoryResult.ok && directoryResult.skill) {
|
|
42208
|
-
detail = `Base directory for this skill: ${directoryResult.skillDir}
|
|
42209
|
-
|
|
42210
|
-
${directoryResult.skill.body}`;
|
|
42211
|
-
if (!detail.includes(directoryResult.skillDir)) {
|
|
42212
|
-
addError(errors, `smoke_missing_base_dir`, `Skill detail does not include its base directory.`);
|
|
42213
|
-
}
|
|
42214
|
-
if (!detail.includes(directoryResult.skill.body)) {
|
|
42215
|
-
addError(errors, `smoke_missing_body`, `Skill detail does not include the SKILL.md body.`);
|
|
42216
|
-
}
|
|
42217
|
-
if (detail.length < 80) {
|
|
42218
|
-
addWarning(warnings, `smoke_short_detail`, `Skill detail is unusually short.`);
|
|
42219
|
-
}
|
|
42220
|
-
}
|
|
42221
|
-
return {
|
|
42222
|
-
...directoryResult,
|
|
42223
|
-
ok: errors.length === 0,
|
|
42224
|
-
errors,
|
|
42225
|
-
warnings,
|
|
42226
|
-
detail
|
|
42227
|
-
};
|
|
42228
|
-
};
|
|
42229
|
-
var formatSkillValidationIssues = (result) => {
|
|
42230
|
-
const lines = [
|
|
42231
|
-
...result.errors.map((issue) => `- [${issue.code}] ${issue.message}`),
|
|
42232
|
-
...result.warnings.map((issue) => `- [warning:${issue.code}] ${issue.message}`)
|
|
42233
|
-
];
|
|
42234
|
-
return lines.join(`
|
|
42235
|
-
`);
|
|
42236
|
-
};
|
|
42237
|
-
|
|
42238
|
-
// src/department/learning.ts
|
|
42239
|
-
var ensureDir = (dir) => (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
42240
|
-
var readJsonArray = (filePath) => {
|
|
42241
|
-
if (!(0, import_node_fs4.existsSync)(filePath)) return [];
|
|
42242
|
-
return JSON.parse((0, import_node_fs4.readFileSync)(filePath, "utf-8"));
|
|
42243
|
-
};
|
|
42244
|
-
var writeJsonArray = (filePath, records) => {
|
|
42245
|
-
ensureDir(import_node_path13.default.dirname(filePath));
|
|
42246
|
-
(0, import_node_fs4.writeFileSync)(filePath, JSON.stringify(records, null, " "), "utf-8");
|
|
42247
|
-
};
|
|
42248
|
-
var departmentMemoryPath = (departmentName) => {
|
|
42249
|
-
return import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "department-memory.json");
|
|
42250
|
-
};
|
|
42251
|
-
var departmentSkillPath = (departmentName) => {
|
|
42252
|
-
return import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "department-skills.json");
|
|
42253
|
-
};
|
|
42254
|
-
var departmentSkillDir = (departmentName, skillName) => {
|
|
42255
|
-
return assertSafeSkillTarget(import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "skills"), skillName);
|
|
42256
|
-
};
|
|
42257
|
-
var proposalsPath = () => {
|
|
42258
|
-
return import_node_path13.default.join(getDepartmentBaseDir(), "department-proposals.json");
|
|
42259
|
-
};
|
|
42260
|
-
var getDepartmentNameForHead = (request) => {
|
|
42261
|
-
const mailboxId = request?.departmentAgentId;
|
|
42262
|
-
if (!mailboxId) return null;
|
|
42263
|
-
const member = getDepartmentMemberByMailboxId(mailboxId);
|
|
42264
|
-
if (!member || member.role !== "department_head") return null;
|
|
42265
|
-
const [departmentName] = mailboxId.split("::");
|
|
42266
|
-
return departmentName || null;
|
|
42267
|
-
};
|
|
42268
|
-
var listDepartmentMemories = (departmentName) => {
|
|
42269
|
-
return readJsonArray(departmentMemoryPath(departmentName)).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
42270
|
-
};
|
|
42271
|
-
var createDepartmentMemory = (departmentName, input) => {
|
|
42272
|
-
const now = Date.now();
|
|
42273
|
-
const memory = {
|
|
42274
|
-
id: (0, import_node_crypto4.randomUUID)().slice(0, 8),
|
|
42275
|
-
departmentName,
|
|
42276
|
-
title: input.title,
|
|
42277
|
-
content: input.content,
|
|
42278
|
-
sourceMailboxId: input.sourceMailboxId,
|
|
42279
|
-
createdAt: now,
|
|
42280
|
-
updatedAt: now
|
|
42281
|
-
};
|
|
42282
|
-
const records = listDepartmentMemories(departmentName);
|
|
42283
|
-
records.push(memory);
|
|
42284
|
-
writeJsonArray(departmentMemoryPath(departmentName), records);
|
|
42285
|
-
return memory;
|
|
42286
|
-
};
|
|
42287
|
-
var updateDepartmentMemory = (departmentName, id, patch) => {
|
|
42288
|
-
const records = listDepartmentMemories(departmentName);
|
|
42289
|
-
const idx = records.findIndex((record) => record.id === id);
|
|
42290
|
-
if (idx < 0) return null;
|
|
42291
|
-
records[idx] = {
|
|
42292
|
-
...records[idx],
|
|
42293
|
-
...patch.title !== void 0 ? { title: patch.title } : {},
|
|
42294
|
-
...patch.content !== void 0 ? { content: patch.content } : {},
|
|
42295
|
-
updatedAt: Date.now()
|
|
42296
|
-
};
|
|
42297
|
-
writeJsonArray(departmentMemoryPath(departmentName), records);
|
|
42298
|
-
return records[idx];
|
|
42299
|
-
};
|
|
42300
|
-
var deleteDepartmentMemory = (departmentName, id) => {
|
|
42301
|
-
const records = listDepartmentMemories(departmentName);
|
|
42302
|
-
const target = records.find((record) => record.id === id) ?? null;
|
|
42303
|
-
writeJsonArray(departmentMemoryPath(departmentName), records.filter((record) => record.id !== id));
|
|
42304
|
-
return target;
|
|
42305
|
-
};
|
|
42306
|
-
var listDepartmentSkills = (departmentName) => {
|
|
42307
|
-
return readJsonArray(departmentSkillPath(departmentName)).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
42308
|
-
};
|
|
42309
|
-
var proposeDepartmentSkill = (departmentName, input) => {
|
|
42310
|
-
const validation = validateSkillDocument({
|
|
42311
|
-
skillName: input.skillName,
|
|
42312
|
-
description: input.description,
|
|
42313
|
-
skillMd: input.skillMd
|
|
42314
|
-
});
|
|
42315
|
-
if (!validation.ok) {
|
|
42316
|
-
throw new Error(`[departmentSkill] Skill \u8349\u7A3F\u6821\u9A8C\u5931\u8D25\uFF1A
|
|
42317
|
-
${formatSkillValidationIssues(validation)}`);
|
|
42318
|
-
}
|
|
42319
|
-
const records = listDepartmentSkills(departmentName);
|
|
42320
|
-
if (records.some((record) => record.skillName === input.skillName && record.status !== "dropped")) {
|
|
42321
|
-
return null;
|
|
42322
|
-
}
|
|
42323
|
-
const now = Date.now();
|
|
42324
|
-
const skill = {
|
|
42325
|
-
id: (0, import_node_crypto4.randomUUID)().slice(0, 8),
|
|
42326
|
-
departmentName,
|
|
42327
|
-
skillName: input.skillName,
|
|
42328
|
-
description: input.description,
|
|
42329
|
-
skillMd: input.skillMd,
|
|
42330
|
-
status: "pending",
|
|
42331
|
-
createdByMailboxId: input.createdByMailboxId,
|
|
42332
|
-
createdAt: now,
|
|
42333
|
-
updatedAt: now
|
|
42334
|
-
};
|
|
42335
|
-
records.push(skill);
|
|
42336
|
-
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
42337
|
-
return skill;
|
|
42338
|
-
};
|
|
42339
|
-
var keepDepartmentSkill = (departmentName, id) => {
|
|
42340
|
-
const records = listDepartmentSkills(departmentName);
|
|
42341
|
-
const idx = records.findIndex((record) => record.id === id);
|
|
42342
|
-
if (idx < 0) return null;
|
|
42343
|
-
records[idx] = { ...records[idx], status: "active", updatedAt: Date.now() };
|
|
42344
|
-
const skillDir = departmentSkillDir(departmentName, records[idx].skillName);
|
|
42345
|
-
const validation = validateSkillDocument({
|
|
42346
|
-
skillName: records[idx].skillName,
|
|
42347
|
-
description: records[idx].description,
|
|
42348
|
-
skillMd: records[idx].skillMd,
|
|
42349
|
-
baseDir: skillDir
|
|
42350
|
-
});
|
|
42351
|
-
if (!validation.ok) {
|
|
42352
|
-
throw new Error(`[departmentSkill] Skill \u8349\u7A3F\u6821\u9A8C\u5931\u8D25\uFF0C\u62D2\u7EDD\u4FDD\u7559\uFF1A
|
|
42353
|
-
${formatSkillValidationIssues(validation)}`);
|
|
42354
|
-
}
|
|
42355
|
-
ensureDir(skillDir);
|
|
42356
|
-
(0, import_node_fs4.writeFileSync)(import_node_path13.default.join(skillDir, "SKILL.md"), records[idx].skillMd, "utf-8");
|
|
42357
|
-
const smokeTest = smokeTestSkillDirectory(skillDir, { expectedName: records[idx].skillName });
|
|
42358
|
-
if (!smokeTest.ok) {
|
|
42359
|
-
throw new Error(`[departmentSkill] Skill smoke test \u5931\u8D25\uFF1A
|
|
42360
|
-
${formatSkillValidationIssues(smokeTest)}`);
|
|
42361
|
-
}
|
|
42362
|
-
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
42363
|
-
return records[idx];
|
|
42364
|
-
};
|
|
42365
|
-
var dropDepartmentSkill = (departmentName, id) => {
|
|
42366
|
-
const records = listDepartmentSkills(departmentName);
|
|
42367
|
-
const idx = records.findIndex((record) => record.id === id);
|
|
42368
|
-
if (idx < 0) return null;
|
|
42369
|
-
records[idx] = { ...records[idx], status: "dropped", updatedAt: Date.now() };
|
|
42370
|
-
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
42371
|
-
return records[idx];
|
|
42372
|
-
};
|
|
42373
|
-
var createDepartmentProposal = (input) => {
|
|
42374
|
-
const records = readJsonArray(proposalsPath());
|
|
42375
|
-
const proposal = {
|
|
42376
|
-
...input,
|
|
42377
|
-
id: (0, import_node_crypto4.randomUUID)().slice(0, 8),
|
|
42378
|
-
status: "pending",
|
|
42379
|
-
createdAt: Date.now()
|
|
42380
|
-
};
|
|
42381
|
-
records.push(proposal);
|
|
42382
|
-
writeJsonArray(proposalsPath(), records);
|
|
42383
|
-
return proposal;
|
|
42384
|
-
};
|
|
42385
|
-
var buildDepartmentLearningContext = (departmentName) => {
|
|
42386
|
-
if (!departmentName) return "";
|
|
42387
|
-
const memories = listDepartmentMemories(departmentName);
|
|
42388
|
-
const activeSkills = listDepartmentSkills(departmentName).filter((skill) => skill.status === "active");
|
|
42389
|
-
if (memories.length === 0 && activeSkills.length === 0) return "";
|
|
42390
|
-
const memoryLines = memories.map(
|
|
42391
|
-
(memory) => ` - [id=${memory.id}] ${memory.title}
|
|
42392
|
-
${memory.content.replace(/\n/g, "\n ")}`
|
|
42393
|
-
).join("\n");
|
|
42394
|
-
const skillLines = activeSkills.map(
|
|
42395
|
-
(skill) => ` - ${skill.skillName}: ${skill.description}`
|
|
42396
|
-
).join("\n");
|
|
42397
|
-
return [
|
|
42398
|
-
`<department-learning-context department="${departmentName}">`,
|
|
42399
|
-
memories.length > 0 ? `Department memories:
|
|
42400
|
-
${memoryLines}` : "",
|
|
42401
|
-
activeSkills.length > 0 ? `Department skills:
|
|
42402
|
-
${skillLines}` : "",
|
|
42403
|
-
`</department-learning-context>`
|
|
42404
|
-
].filter(Boolean).join("\n");
|
|
42405
|
-
};
|
|
42406
|
-
|
|
42407
41832
|
// src/skill/SkillRegistry.ts
|
|
42408
41833
|
var getProjectSkillsPath = () => {
|
|
42409
41834
|
const projectRoot = findProjectRoot();
|
|
42410
|
-
return projectRoot ? (0,
|
|
41835
|
+
return projectRoot ? (0, import_path16.join)(projectRoot, "skills") : null;
|
|
42411
41836
|
};
|
|
42412
41837
|
var getSkillPaths = () => {
|
|
42413
41838
|
const paths = [];
|
|
42414
41839
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
42415
41840
|
const pushPath = (candidate) => {
|
|
42416
|
-
if (!(0,
|
|
42417
|
-
const normalized =
|
|
41841
|
+
if (!(0, import_fs11.existsSync)(candidate) || !(0, import_fs11.statSync)(candidate).isDirectory()) return;
|
|
41842
|
+
const normalized = import_path16.default.resolve(candidate);
|
|
42418
41843
|
if (seenPaths.has(normalized)) return;
|
|
42419
41844
|
seenPaths.add(normalized);
|
|
42420
41845
|
paths.push(normalized);
|
|
@@ -42423,16 +41848,16 @@ var getSkillPaths = () => {
|
|
|
42423
41848
|
if (projectSkillsPath) {
|
|
42424
41849
|
pushPath(projectSkillsPath);
|
|
42425
41850
|
}
|
|
42426
|
-
pushPath((0,
|
|
42427
|
-
pushPath((0,
|
|
41851
|
+
pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".duclaw", "skills"));
|
|
41852
|
+
pushPath((0, import_path16.join)((0, import_os3.homedir)(), ".agents", "skills"));
|
|
42428
41853
|
return paths;
|
|
42429
41854
|
};
|
|
42430
41855
|
var getDirectories = (dirPath) => {
|
|
42431
|
-
return (0,
|
|
41856
|
+
return (0, import_fs11.readdirSync)(dirPath).filter((name) => (0, import_fs11.statSync)((0, import_path16.join)(dirPath, name)).isDirectory());
|
|
42432
41857
|
};
|
|
42433
41858
|
var parseSkill = (mdPath, skillDir, options = {}) => {
|
|
42434
|
-
if (!(0,
|
|
42435
|
-
const raw2 = (0,
|
|
41859
|
+
if (!(0, import_fs11.existsSync)(mdPath)) return null;
|
|
41860
|
+
const raw2 = (0, import_fs11.readFileSync)(mdPath, "utf-8");
|
|
42436
41861
|
let name = "";
|
|
42437
41862
|
let description = "";
|
|
42438
41863
|
let body = raw2;
|
|
@@ -42448,14 +41873,14 @@ var parseSkill = (mdPath, skillDir, options = {}) => {
|
|
|
42448
41873
|
}
|
|
42449
41874
|
}
|
|
42450
41875
|
if (!name) {
|
|
42451
|
-
name =
|
|
41876
|
+
name = import_path16.default.basename(import_path16.default.dirname(mdPath));
|
|
42452
41877
|
}
|
|
42453
41878
|
if (!description && body) {
|
|
42454
41879
|
description = body.split("\n")[0].replace(/^#+\s*/, "").trim();
|
|
42455
41880
|
}
|
|
42456
|
-
const normalizedSkillDir =
|
|
41881
|
+
const normalizedSkillDir = import_path16.default.resolve(skillDir);
|
|
42457
41882
|
const projectSkillsPath = getProjectSkillsPath();
|
|
42458
|
-
const isProjectSkill = projectSkillsPath ? normalizedSkillDir ===
|
|
41883
|
+
const isProjectSkill = projectSkillsPath ? normalizedSkillDir === import_path16.default.resolve(projectSkillsPath, import_path16.default.basename(normalizedSkillDir)) && normalizedSkillDir.startsWith(import_path16.default.resolve(projectSkillsPath) + import_path16.default.sep) : false;
|
|
42459
41884
|
const scope = options.scope ?? (isProjectSkill ? "project" : "global");
|
|
42460
41885
|
const deletable = options.deletable ?? (scope === "project" && isProjectSkill);
|
|
42461
41886
|
return {
|
|
@@ -42473,26 +41898,6 @@ ${content}`;
|
|
|
42473
41898
|
}
|
|
42474
41899
|
};
|
|
42475
41900
|
};
|
|
42476
|
-
var loadDepartmentSkills = (seen) => {
|
|
42477
|
-
const skills = [];
|
|
42478
|
-
for (const department of listDepartments()) {
|
|
42479
|
-
const activeSkills = listDepartmentSkills(department.name).filter((skill) => skill.status === "active");
|
|
42480
|
-
for (const departmentSkill of activeSkills) {
|
|
42481
|
-
if (seen.has(departmentSkill.skillName)) continue;
|
|
42482
|
-
const skillDir = (0, import_path18.join)(getDepartmentWorkSpaceDir(department.name), "skills", departmentSkill.skillName);
|
|
42483
|
-
const skill = parseSkill((0, import_path18.join)(skillDir, "SKILL.md"), skillDir, {
|
|
42484
|
-
scope: "department",
|
|
42485
|
-
departmentName: department.name,
|
|
42486
|
-
deletable: false
|
|
42487
|
-
});
|
|
42488
|
-
if (skill) {
|
|
42489
|
-
seen.add(skill.name);
|
|
42490
|
-
skills.push(skill);
|
|
42491
|
-
}
|
|
42492
|
-
}
|
|
42493
|
-
}
|
|
42494
|
-
return skills;
|
|
42495
|
-
};
|
|
42496
41901
|
var loadSkill = () => {
|
|
42497
41902
|
const skillPaths = getSkillPaths();
|
|
42498
41903
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -42500,8 +41905,8 @@ var loadSkill = () => {
|
|
|
42500
41905
|
for (const skillPath of skillPaths) {
|
|
42501
41906
|
const dirs = getDirectories(skillPath);
|
|
42502
41907
|
for (const skillName of dirs) {
|
|
42503
|
-
const eachSkillPath = (0,
|
|
42504
|
-
const eachSkillMdPath = (0,
|
|
41908
|
+
const eachSkillPath = (0, import_path16.join)(skillPath, skillName);
|
|
41909
|
+
const eachSkillMdPath = (0, import_path16.join)(eachSkillPath, "SKILL.md");
|
|
42505
41910
|
const skill = parseSkill(eachSkillMdPath, eachSkillPath);
|
|
42506
41911
|
if (skill && !seen.has(skill.name)) {
|
|
42507
41912
|
seen.add(skill.name);
|
|
@@ -42509,14 +41914,13 @@ var loadSkill = () => {
|
|
|
42509
41914
|
}
|
|
42510
41915
|
}
|
|
42511
41916
|
}
|
|
42512
|
-
skills.push(...loadDepartmentSkills(seen));
|
|
42513
41917
|
return skills;
|
|
42514
41918
|
};
|
|
42515
41919
|
var deleteSkill = (name) => {
|
|
42516
41920
|
const skills = loadSkill();
|
|
42517
41921
|
const skill = skills.find((s) => s.name === name);
|
|
42518
41922
|
if (!skill || !skill.deletable) return false;
|
|
42519
|
-
(0,
|
|
41923
|
+
(0, import_fs11.rmSync)(skill.baseDir, { recursive: true, force: false });
|
|
42520
41924
|
return true;
|
|
42521
41925
|
};
|
|
42522
41926
|
var SkillRegistry_default = loadSkill;
|
|
@@ -42803,10 +42207,10 @@ var goalDelete = {
|
|
|
42803
42207
|
};
|
|
42804
42208
|
|
|
42805
42209
|
// src/tools/tools/department/DepartmentCreate.ts
|
|
42806
|
-
var
|
|
42210
|
+
var import_node_crypto8 = require("node:crypto");
|
|
42807
42211
|
|
|
42808
42212
|
// src/department/mailbox/mailbox.ts
|
|
42809
|
-
var
|
|
42213
|
+
var import_node_crypto7 = require("node:crypto");
|
|
42810
42214
|
|
|
42811
42215
|
// src/agent/interruptRegistry.ts
|
|
42812
42216
|
var registry = /* @__PURE__ */ new Map();
|
|
@@ -42857,7 +42261,7 @@ var drainInterrupts = (userId) => {
|
|
|
42857
42261
|
};
|
|
42858
42262
|
|
|
42859
42263
|
// src/agent/events.ts
|
|
42860
|
-
var
|
|
42264
|
+
var import_node_crypto4 = require("node:crypto");
|
|
42861
42265
|
var rowToEvent = (row) => ({
|
|
42862
42266
|
id: row.id,
|
|
42863
42267
|
userId: row.userId,
|
|
@@ -42874,7 +42278,7 @@ var rowToEvent = (row) => ({
|
|
|
42874
42278
|
var recordAgentEvent = (input) => {
|
|
42875
42279
|
const db3 = createSqliteDB();
|
|
42876
42280
|
const now = Date.now();
|
|
42877
|
-
const id = `evt_${(0,
|
|
42281
|
+
const id = `evt_${(0, import_node_crypto4.randomUUID)().slice(0, 12)}`;
|
|
42878
42282
|
const payloadJson = JSON.stringify(input.payload);
|
|
42879
42283
|
db3.prepare(`
|
|
42880
42284
|
INSERT INTO agent_events (
|
|
@@ -43005,7 +42409,7 @@ ${ceoFollowupInstruction}
|
|
|
43005
42409
|
};
|
|
43006
42410
|
|
|
43007
42411
|
// src/department/mailbox/events.ts
|
|
43008
|
-
var
|
|
42412
|
+
var import_node_crypto5 = require("node:crypto");
|
|
43009
42413
|
var parseDetail = (detailJson) => {
|
|
43010
42414
|
if (!detailJson) return void 0;
|
|
43011
42415
|
try {
|
|
@@ -43046,7 +42450,7 @@ var mapMailboxEventRow = (row) => {
|
|
|
43046
42450
|
var recordMailboxEvent = (input) => {
|
|
43047
42451
|
const db3 = createSqliteDB();
|
|
43048
42452
|
const event = {
|
|
43049
|
-
id: (0,
|
|
42453
|
+
id: (0, import_node_crypto5.randomUUID)().slice(0, 12),
|
|
43050
42454
|
messageId: input.messageId,
|
|
43051
42455
|
mailboxId: input.mailboxId,
|
|
43052
42456
|
actorMailboxId: input.actorMailboxId,
|
|
@@ -43128,8 +42532,209 @@ var listMailboxEvents = (params) => {
|
|
|
43128
42532
|
return rows.map(mapMailboxEventRow);
|
|
43129
42533
|
};
|
|
43130
42534
|
|
|
42535
|
+
// src/department/DepartmentMember.ts
|
|
42536
|
+
var import_fs13 = require("fs");
|
|
42537
|
+
var import_path18 = __toESM(require("path"));
|
|
42538
|
+
|
|
42539
|
+
// src/department/Department.ts
|
|
42540
|
+
var import_path17 = __toESM(require("path"));
|
|
42541
|
+
var import_fs12 = require("fs");
|
|
42542
|
+
var legacyMigrationChecked = false;
|
|
42543
|
+
var getDepartmentBaseDir = () => {
|
|
42544
|
+
return import_path17.default.join(getDuclawHomeDir(), "department");
|
|
42545
|
+
};
|
|
42546
|
+
var getLegacyTeamBaseDir = () => {
|
|
42547
|
+
return import_path17.default.join(getDuclawHomeDir(), "team");
|
|
42548
|
+
};
|
|
42549
|
+
var getDepartmentWorkSpaceDir = (departmentName) => {
|
|
42550
|
+
return import_path17.default.join(getDepartmentBaseDir(), "workspace", departmentName);
|
|
42551
|
+
};
|
|
42552
|
+
var getLegacyTeamWorkSpaceDir = (teamName) => {
|
|
42553
|
+
return import_path17.default.join(getLegacyTeamBaseDir(), "workspace", teamName);
|
|
42554
|
+
};
|
|
42555
|
+
var getDepartmentJsonPath = (departmentName) => {
|
|
42556
|
+
return import_path17.default.join(getDepartmentWorkSpaceDir(departmentName), "department.json");
|
|
42557
|
+
};
|
|
42558
|
+
var getLegacyTeamJsonPath = (teamName) => {
|
|
42559
|
+
return import_path17.default.join(getLegacyTeamWorkSpaceDir(teamName), "team.json");
|
|
42560
|
+
};
|
|
42561
|
+
var mapLegacyRole = (role) => {
|
|
42562
|
+
return role === "team_manager" ? "department_head" : "executor";
|
|
42563
|
+
};
|
|
42564
|
+
var mapLegacyDepartment = (legacy) => {
|
|
42565
|
+
const departmentMembers = (legacy.teamMembers ?? []).map((member) => ({
|
|
42566
|
+
id: member.id,
|
|
42567
|
+
name: member.name,
|
|
42568
|
+
departmentId: legacy.id,
|
|
42569
|
+
mailBoxId: member.mailBoxId,
|
|
42570
|
+
workspaceId: member.workspaceId,
|
|
42571
|
+
role: mapLegacyRole(member.role),
|
|
42572
|
+
focusOn: member.focusOn
|
|
42573
|
+
}));
|
|
42574
|
+
const headMemberId = legacy.managerMemberId ?? departmentMembers.find((member) => member.role === "department_head")?.id;
|
|
42575
|
+
return {
|
|
42576
|
+
id: legacy.id,
|
|
42577
|
+
name: legacy.name,
|
|
42578
|
+
sourceGoalId: legacy.goalId,
|
|
42579
|
+
charter: legacy.goalId ? `Legacy department migrated from team goal ${legacy.goalId}.` : "Legacy department migrated from team data.",
|
|
42580
|
+
workpath: legacy.workpath,
|
|
42581
|
+
headMemberId,
|
|
42582
|
+
departmentMembers
|
|
42583
|
+
};
|
|
42584
|
+
};
|
|
42585
|
+
var migrateLegacyTeamsToDepartments = () => {
|
|
42586
|
+
if (legacyMigrationChecked) return;
|
|
42587
|
+
legacyMigrationChecked = true;
|
|
42588
|
+
const legacyWorkspaceDir = import_path17.default.join(getLegacyTeamBaseDir(), "workspace");
|
|
42589
|
+
if (!(0, import_fs12.existsSync)(legacyWorkspaceDir)) return;
|
|
42590
|
+
for (const legacyName of (0, import_fs12.readdirSync)(legacyWorkspaceDir)) {
|
|
42591
|
+
const legacyJsonPath = getLegacyTeamJsonPath(legacyName);
|
|
42592
|
+
if (!(0, import_fs12.existsSync)(legacyJsonPath)) continue;
|
|
42593
|
+
const departmentJsonPath = getDepartmentJsonPath(legacyName);
|
|
42594
|
+
if ((0, import_fs12.existsSync)(departmentJsonPath)) continue;
|
|
42595
|
+
try {
|
|
42596
|
+
const legacy = JSON.parse((0, import_fs12.readFileSync)(legacyJsonPath, "utf-8"));
|
|
42597
|
+
const department = mapLegacyDepartment(legacy);
|
|
42598
|
+
(0, import_fs12.mkdirSync)(getDepartmentWorkSpaceDir(department.name), { recursive: true });
|
|
42599
|
+
(0, import_fs12.writeFileSync)(departmentJsonPath, JSON.stringify(department, null, " "), "utf-8");
|
|
42600
|
+
} catch (err) {
|
|
42601
|
+
console.warn(`[department] Failed to migrate legacy team ${legacyName}: ${err.message}`);
|
|
42602
|
+
}
|
|
42603
|
+
}
|
|
42604
|
+
};
|
|
42605
|
+
var createDepartment = (departmentDefinition) => {
|
|
42606
|
+
if (!departmentDefinition) throw new Error(`[createDepartment] departmentDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
42607
|
+
const departmentPath = getDepartmentWorkSpaceDir(departmentDefinition.name);
|
|
42608
|
+
(0, import_fs12.mkdirSync)(departmentPath, { recursive: true });
|
|
42609
|
+
(0, import_fs12.writeFileSync)(getDepartmentJsonPath(departmentDefinition.name), JSON.stringify(departmentDefinition, null, " "), "utf-8");
|
|
42610
|
+
return departmentDefinition;
|
|
42611
|
+
};
|
|
42612
|
+
var getDepartment = (name) => {
|
|
42613
|
+
migrateLegacyTeamsToDepartments();
|
|
42614
|
+
const departmentJsonPath = getDepartmentJsonPath(name);
|
|
42615
|
+
if (!(0, import_fs12.existsSync)(departmentJsonPath)) return null;
|
|
42616
|
+
const text2 = (0, import_fs12.readFileSync)(departmentJsonPath, "utf-8");
|
|
42617
|
+
return JSON.parse(text2);
|
|
42618
|
+
};
|
|
42619
|
+
var listDepartments = () => {
|
|
42620
|
+
migrateLegacyTeamsToDepartments();
|
|
42621
|
+
const workspaceDir = import_path17.default.join(getDepartmentBaseDir(), "workspace");
|
|
42622
|
+
if (!(0, import_fs12.existsSync)(workspaceDir)) return [];
|
|
42623
|
+
const departments = [];
|
|
42624
|
+
for (const departmentName of (0, import_fs12.readdirSync)(workspaceDir)) {
|
|
42625
|
+
const department = getDepartment(departmentName);
|
|
42626
|
+
if (department) departments.push(department);
|
|
42627
|
+
}
|
|
42628
|
+
return departments;
|
|
42629
|
+
};
|
|
42630
|
+
var getDepartmentById = (id) => {
|
|
42631
|
+
const department = listDepartments().find((item) => item.id === id);
|
|
42632
|
+
return department ?? null;
|
|
42633
|
+
};
|
|
42634
|
+
var deleteDepartment = (name) => {
|
|
42635
|
+
if (!(0, import_fs12.existsSync)(getDepartmentJsonPath(name))) {
|
|
42636
|
+
throw new Error(`[deleteDepartment] \u4E0D\u5B58\u5728\u5BF9\u5E94\u7684\u90E8\u95E8 ${name} \u7684 department.json \u6587\u4EF6`);
|
|
42637
|
+
}
|
|
42638
|
+
(0, import_fs12.rmSync)(getDepartmentJsonPath(name));
|
|
42639
|
+
};
|
|
42640
|
+
|
|
42641
|
+
// src/department/workspace/workspace.ts
|
|
42642
|
+
var db = createSqliteDB();
|
|
42643
|
+
var getWorkspaceId = (departmentName, memberName) => {
|
|
42644
|
+
return `${departmentName}::${memberName}`;
|
|
42645
|
+
};
|
|
42646
|
+
var createWorkspace = (workspace) => {
|
|
42647
|
+
const stmt = db.prepare(`INSERT INTO workspace (id, team_name, teammate_name, team_workpath) VALUES (?, ?, ?, ?) `);
|
|
42648
|
+
stmt.run(
|
|
42649
|
+
workspace.id,
|
|
42650
|
+
workspace.departmentName,
|
|
42651
|
+
workspace.memberName,
|
|
42652
|
+
workspace.departmentWorkPath
|
|
42653
|
+
);
|
|
42654
|
+
};
|
|
42655
|
+
var deleteWorkspace = (workspaceId) => {
|
|
42656
|
+
const stmt = db.prepare(`delete from workspace where id = ?`);
|
|
42657
|
+
stmt.run(workspaceId);
|
|
42658
|
+
};
|
|
42659
|
+
|
|
42660
|
+
// src/department/DepartmentMember.ts
|
|
42661
|
+
var createDepartmentMember = (departmentMemberDefinition) => {
|
|
42662
|
+
if (!departmentMemberDefinition) throw new Error(`[createDepartmentMember] departmentMemberDefinition\u4E0D\u80FD\u4E3A\u7A7A`);
|
|
42663
|
+
const { name, departmentId, workspaceId } = departmentMemberDefinition;
|
|
42664
|
+
const department = getDepartmentById(departmentId);
|
|
42665
|
+
if (!department) throw new Error(`[createDepartmentMember] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentId}`);
|
|
42666
|
+
const memberPath = import_path18.default.join(getDepartmentWorkSpaceDir(department.name), name);
|
|
42667
|
+
(0, import_fs13.mkdirSync)(memberPath, { recursive: true });
|
|
42668
|
+
const workspace = {
|
|
42669
|
+
id: getWorkspaceId(department.name, departmentMemberDefinition.name),
|
|
42670
|
+
departmentName: department.name,
|
|
42671
|
+
memberName: name,
|
|
42672
|
+
departmentWorkPath: memberPath
|
|
42673
|
+
};
|
|
42674
|
+
createWorkspace(workspace);
|
|
42675
|
+
if (!department.departmentMembers) {
|
|
42676
|
+
department.departmentMembers = [];
|
|
42677
|
+
}
|
|
42678
|
+
if (department.departmentMembers.some((member) => member.id === departmentMemberDefinition.id || member.name === departmentMemberDefinition.name)) {
|
|
42679
|
+
throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728\u540C\u540D\u6216\u540C id \u6210\u5458: ${departmentMemberDefinition.name}/${departmentMemberDefinition.id}`);
|
|
42680
|
+
}
|
|
42681
|
+
if (departmentMemberDefinition.role === "department_head") {
|
|
42682
|
+
const existingHead = department.headMemberId ? department.departmentMembers.find((member) => member.id === department.headMemberId) : department.departmentMembers.find((member) => member.role === "department_head");
|
|
42683
|
+
if (existingHead) {
|
|
42684
|
+
throw new Error(`[createDepartmentMember] \u90E8\u95E8 ${department.name} \u5DF2\u5B58\u5728 Department Head: ${existingHead.name}`);
|
|
42685
|
+
}
|
|
42686
|
+
department.headMemberId = departmentMemberDefinition.id;
|
|
42687
|
+
}
|
|
42688
|
+
department.departmentMembers.push(departmentMemberDefinition);
|
|
42689
|
+
(0, import_fs13.writeFileSync)(getDepartmentJsonPath(department.name), JSON.stringify(department, null, " "), "utf-8");
|
|
42690
|
+
return departmentMemberDefinition;
|
|
42691
|
+
};
|
|
42692
|
+
var listDepartmentMembers = (departmentName) => {
|
|
42693
|
+
const departmentJsonPath = getDepartmentJsonPath(departmentName);
|
|
42694
|
+
if (!(0, import_fs13.existsSync)(departmentJsonPath)) return [];
|
|
42695
|
+
const text2 = (0, import_fs13.readFileSync)(departmentJsonPath, "utf-8");
|
|
42696
|
+
const department = JSON.parse(text2);
|
|
42697
|
+
if (!department) throw new Error(`[listDepartmentMembers] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
|
|
42698
|
+
return department.departmentMembers ?? [];
|
|
42699
|
+
};
|
|
42700
|
+
var getDepartmentMember = (departmentName, departmentMemberId) => {
|
|
42701
|
+
const members = listDepartmentMembers(departmentName);
|
|
42702
|
+
return members.find((member) => member.id === departmentMemberId) || null;
|
|
42703
|
+
};
|
|
42704
|
+
var getDepartmentMemberByName = (departmentName, departmentMemberName) => {
|
|
42705
|
+
const members = listDepartmentMembers(departmentName);
|
|
42706
|
+
return members.find((member) => member.name === departmentMemberName) || null;
|
|
42707
|
+
};
|
|
42708
|
+
var getDepartmentMemberByMailboxId = (mailboxId) => {
|
|
42709
|
+
const [departmentName, memberName] = mailboxId.split("::");
|
|
42710
|
+
if (!departmentName || !memberName) return null;
|
|
42711
|
+
return getDepartmentMemberByName(departmentName, memberName);
|
|
42712
|
+
};
|
|
42713
|
+
var getDepartmentMemberById = (memberId) => {
|
|
42714
|
+
for (const department of listDepartments()) {
|
|
42715
|
+
const targetMember = department.departmentMembers.find((member) => member.id === memberId);
|
|
42716
|
+
if (targetMember) return targetMember;
|
|
42717
|
+
}
|
|
42718
|
+
return null;
|
|
42719
|
+
};
|
|
42720
|
+
var deleteDepartmentMemberById = (departmentName, memberId) => {
|
|
42721
|
+
const department = getDepartment(departmentName);
|
|
42722
|
+
if (!department) throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94\u7684 department: ${departmentName}`);
|
|
42723
|
+
const memberIdx = department.departmentMembers.findIndex((member) => member.id === memberId);
|
|
42724
|
+
if (memberIdx === -1) {
|
|
42725
|
+
throw new Error(`[deleteDepartmentMemberById] \u627E\u4E0D\u5230\u5BF9\u5E94 id \u7684 department member: ${memberId}`);
|
|
42726
|
+
}
|
|
42727
|
+
const workspaceId = department.departmentMembers[memberIdx].workspaceId;
|
|
42728
|
+
if (department.headMemberId === memberId) {
|
|
42729
|
+
delete department.headMemberId;
|
|
42730
|
+
}
|
|
42731
|
+
department.departmentMembers = department.departmentMembers.filter((_, index) => index !== memberIdx);
|
|
42732
|
+
(0, import_fs13.writeFileSync)(getDepartmentJsonPath(departmentName), JSON.stringify(department, null, " "), "utf-8");
|
|
42733
|
+
deleteWorkspace(workspaceId);
|
|
42734
|
+
};
|
|
42735
|
+
|
|
43131
42736
|
// src/department/mailbox/ceoFollowup.ts
|
|
43132
|
-
var
|
|
42737
|
+
var import_node_crypto6 = require("node:crypto");
|
|
43133
42738
|
var rowToFollowup = (row) => ({
|
|
43134
42739
|
id: row.id,
|
|
43135
42740
|
sourceMessageId: row.sourceMessageId,
|
|
@@ -43176,7 +42781,7 @@ var enqueueCeoFollowupFromMailbox = (message) => {
|
|
|
43176
42781
|
if (!message.originUserId || !message.originPlatform) return null;
|
|
43177
42782
|
const db3 = createSqliteDB();
|
|
43178
42783
|
const now = Date.now();
|
|
43179
|
-
const id = `cfu_${(0,
|
|
42784
|
+
const id = `cfu_${(0, import_node_crypto6.randomUUID)().slice(0, 12)}`;
|
|
43180
42785
|
db3.prepare(`
|
|
43181
42786
|
INSERT INTO ceo_followups (
|
|
43182
42787
|
id,
|
|
@@ -43506,7 +43111,7 @@ var recordMailboxReceivedAgentEvent = (msg) => {
|
|
|
43506
43111
|
};
|
|
43507
43112
|
var sendMessage2 = (fromMailboxId, toMailboxId, content, options) => {
|
|
43508
43113
|
const db3 = createSqliteDB();
|
|
43509
|
-
const id = (0,
|
|
43114
|
+
const id = (0, import_node_crypto7.randomUUID)().slice(0, 8);
|
|
43510
43115
|
const threadId = options?.threadId || id;
|
|
43511
43116
|
const workItemContext = resolveWorkItemContext(fromMailboxId, toMailboxId, id, options);
|
|
43512
43117
|
const stmt = db3.prepare(`insert into mailbox (
|
|
@@ -43649,7 +43254,7 @@ var departmentCreate = {
|
|
|
43649
43254
|
return `[departmentCreate] \u4E0D\u5B58\u5728 id=${sourceGoalId} \u7684\u76EE\u6807`;
|
|
43650
43255
|
}
|
|
43651
43256
|
let departmentDefinition = {
|
|
43652
|
-
id: (0,
|
|
43257
|
+
id: (0, import_node_crypto8.randomUUID)().slice(0, 8),
|
|
43653
43258
|
name,
|
|
43654
43259
|
charter,
|
|
43655
43260
|
sourceGoalId,
|
|
@@ -43916,7 +43521,7 @@ var departmentList = {
|
|
|
43916
43521
|
};
|
|
43917
43522
|
|
|
43918
43523
|
// src/tools/tools/department/DepartmentMemberCreate.ts
|
|
43919
|
-
var
|
|
43524
|
+
var import_node_crypto9 = require("node:crypto");
|
|
43920
43525
|
var DESCRIPTION24 = `
|
|
43921
43526
|
\u521B\u5EFA\u90E8\u95E8\u6210\u5458\u3002
|
|
43922
43527
|
|
|
@@ -43982,7 +43587,7 @@ var departmentMemberCreate = {
|
|
|
43982
43587
|
}
|
|
43983
43588
|
}
|
|
43984
43589
|
let departmentMember = {
|
|
43985
|
-
id: (0,
|
|
43590
|
+
id: (0, import_node_crypto9.randomUUID)().slice(0, 8),
|
|
43986
43591
|
name,
|
|
43987
43592
|
departmentId: department.id,
|
|
43988
43593
|
mailBoxId: getMailBoxId(department.name, name),
|
|
@@ -44171,6 +43776,380 @@ ${replies}`;
|
|
|
44171
43776
|
}
|
|
44172
43777
|
};
|
|
44173
43778
|
|
|
43779
|
+
// src/department/learning.ts
|
|
43780
|
+
var import_node_fs4 = require("node:fs");
|
|
43781
|
+
var import_node_path13 = __toESM(require("node:path"));
|
|
43782
|
+
var import_node_crypto10 = require("node:crypto");
|
|
43783
|
+
|
|
43784
|
+
// src/skill/SkillValidator.ts
|
|
43785
|
+
var import_node_fs3 = require("node:fs");
|
|
43786
|
+
var import_node_path12 = __toESM(require("node:path"));
|
|
43787
|
+
var SKILL_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|
|
43788
|
+
var REQUIRED_SECTIONS = [
|
|
43789
|
+
/(^|\n)##\s+(when to use|何时使用|trigger|triggers)\b/i,
|
|
43790
|
+
/(^|\n)##\s+(steps|workflow|procedure|执行步骤|工作流)\b/i
|
|
43791
|
+
];
|
|
43792
|
+
var stripYamlQuotes = (value) => {
|
|
43793
|
+
const trimmed = value.trim();
|
|
43794
|
+
if (trimmed.startsWith(`"`) && trimmed.endsWith(`"`) || trimmed.startsWith(`'`) && trimmed.endsWith(`'`)) {
|
|
43795
|
+
return trimmed.slice(1, -1).trim();
|
|
43796
|
+
}
|
|
43797
|
+
return trimmed;
|
|
43798
|
+
};
|
|
43799
|
+
var addError = (errors, code, message) => {
|
|
43800
|
+
errors.push({ code, message });
|
|
43801
|
+
};
|
|
43802
|
+
var addWarning = (warnings, code, message) => {
|
|
43803
|
+
warnings.push({ code, message });
|
|
43804
|
+
};
|
|
43805
|
+
var isValidSkillName = (name) => {
|
|
43806
|
+
return SKILL_NAME_PATTERN.test(name) && !name.includes(`--`);
|
|
43807
|
+
};
|
|
43808
|
+
var assertSafeSkillTarget = (rootDir, skillName) => {
|
|
43809
|
+
if (!isValidSkillName(skillName)) {
|
|
43810
|
+
throw new Error(`Invalid skill name "${skillName}". Use lowercase letters, digits, and single hyphens only.`);
|
|
43811
|
+
}
|
|
43812
|
+
const root = import_node_path12.default.resolve(rootDir);
|
|
43813
|
+
const target = import_node_path12.default.resolve(root, skillName);
|
|
43814
|
+
if (target !== import_node_path12.default.join(root, skillName) || !target.startsWith(root + import_node_path12.default.sep)) {
|
|
43815
|
+
throw new Error(`Invalid skill install target for "${skillName}".`);
|
|
43816
|
+
}
|
|
43817
|
+
return target;
|
|
43818
|
+
};
|
|
43819
|
+
var parseSkillDocument = (skillMd) => {
|
|
43820
|
+
const fmMatch = skillMd.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
43821
|
+
if (!fmMatch) return null;
|
|
43822
|
+
const frontmatter = {};
|
|
43823
|
+
for (const rawLine of fmMatch[1].split(/\r?\n/)) {
|
|
43824
|
+
const line = rawLine.trim();
|
|
43825
|
+
if (!line || line.startsWith(`#`)) continue;
|
|
43826
|
+
const match2 = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
43827
|
+
if (!match2) {
|
|
43828
|
+
frontmatter[`__invalid__${Object.keys(frontmatter).length}`] = line;
|
|
43829
|
+
continue;
|
|
43830
|
+
}
|
|
43831
|
+
frontmatter[match2[1]] = stripYamlQuotes(match2[2]);
|
|
43832
|
+
}
|
|
43833
|
+
return {
|
|
43834
|
+
name: frontmatter.name ?? ``,
|
|
43835
|
+
description: frontmatter.description ?? ``,
|
|
43836
|
+
body: skillMd.slice(fmMatch[0].length).trim(),
|
|
43837
|
+
frontmatter
|
|
43838
|
+
};
|
|
43839
|
+
};
|
|
43840
|
+
var validateSkillDocument = (input) => {
|
|
43841
|
+
const errors = [];
|
|
43842
|
+
const warnings = [];
|
|
43843
|
+
const skillMd = input.skillMd;
|
|
43844
|
+
if (!skillMd || !skillMd.trim()) {
|
|
43845
|
+
addError(errors, `empty_skill_md`, `SKILL.md content is required.`);
|
|
43846
|
+
return { ok: false, errors, warnings };
|
|
43847
|
+
}
|
|
43848
|
+
const parsed = parseSkillDocument(skillMd);
|
|
43849
|
+
if (!parsed) {
|
|
43850
|
+
addError(errors, `missing_frontmatter`, `SKILL.md must start with YAML frontmatter delimited by "---".`);
|
|
43851
|
+
return { ok: false, errors, warnings };
|
|
43852
|
+
}
|
|
43853
|
+
const invalidFrontmatterLines = Object.keys(parsed.frontmatter).filter((key) => key.startsWith(`__invalid__`));
|
|
43854
|
+
if (invalidFrontmatterLines.length > 0) {
|
|
43855
|
+
addError(errors, `invalid_frontmatter`, `Frontmatter must contain simple "key: value" lines.`);
|
|
43856
|
+
}
|
|
43857
|
+
if (!parsed.name) {
|
|
43858
|
+
addError(errors, `missing_name`, `Frontmatter field "name" is required.`);
|
|
43859
|
+
} else if (!isValidSkillName(parsed.name)) {
|
|
43860
|
+
addError(errors, `invalid_name`, `Skill name "${parsed.name}" must be kebab-case, under 64 characters, and path-safe.`);
|
|
43861
|
+
}
|
|
43862
|
+
if (!parsed.description) {
|
|
43863
|
+
addError(errors, `missing_description`, `Frontmatter field "description" is required.`);
|
|
43864
|
+
} else if (parsed.description.length > 500) {
|
|
43865
|
+
addWarning(warnings, `long_description`, `Skill description is long; keep trigger metadata concise.`);
|
|
43866
|
+
}
|
|
43867
|
+
if (input.skillName && parsed.name && input.skillName !== parsed.name) {
|
|
43868
|
+
addError(errors, `name_mismatch`, `Input skillName "${input.skillName}" must match frontmatter name "${parsed.name}".`);
|
|
43869
|
+
}
|
|
43870
|
+
if (input.description && parsed.description && input.description !== parsed.description) {
|
|
43871
|
+
addError(errors, `description_mismatch`, `Input description must match frontmatter description.`);
|
|
43872
|
+
}
|
|
43873
|
+
if (!parsed.body) {
|
|
43874
|
+
addError(errors, `empty_body`, `SKILL.md body is required.`);
|
|
43875
|
+
} else {
|
|
43876
|
+
if (!/(^|\n)#\s+\S/.test(parsed.body)) {
|
|
43877
|
+
addWarning(warnings, `missing_title`, `Skill body should start with a Markdown H1 title.`);
|
|
43878
|
+
}
|
|
43879
|
+
for (const sectionPattern of REQUIRED_SECTIONS) {
|
|
43880
|
+
if (!sectionPattern.test(parsed.body)) {
|
|
43881
|
+
addWarning(warnings, `missing_recommended_section`, `Skill body should include when-to-use and execution workflow sections.`);
|
|
43882
|
+
break;
|
|
43883
|
+
}
|
|
43884
|
+
}
|
|
43885
|
+
}
|
|
43886
|
+
if (input.baseDir) {
|
|
43887
|
+
const normalizedBase = import_node_path12.default.resolve(input.baseDir);
|
|
43888
|
+
for (const match2 of parsed.body.matchAll(/\]\(([^)]+)\)/g)) {
|
|
43889
|
+
const href = match2[1].trim();
|
|
43890
|
+
if (!href || /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith(`#`)) continue;
|
|
43891
|
+
const target = import_node_path12.default.resolve(normalizedBase, href.split(`#`)[0]);
|
|
43892
|
+
if (!target.startsWith(normalizedBase + import_node_path12.default.sep) && target !== normalizedBase) {
|
|
43893
|
+
addError(errors, `unsafe_reference`, `Relative link "${href}" escapes the skill directory.`);
|
|
43894
|
+
} else if (!(0, import_node_fs3.existsSync)(target)) {
|
|
43895
|
+
addError(errors, `missing_reference`, `Relative link "${href}" does not exist in the skill directory.`);
|
|
43896
|
+
}
|
|
43897
|
+
}
|
|
43898
|
+
}
|
|
43899
|
+
return {
|
|
43900
|
+
ok: errors.length === 0,
|
|
43901
|
+
skill: parsed,
|
|
43902
|
+
errors,
|
|
43903
|
+
warnings
|
|
43904
|
+
};
|
|
43905
|
+
};
|
|
43906
|
+
var mergeIssues = (target, source) => {
|
|
43907
|
+
target.errors.push(...source.errors);
|
|
43908
|
+
target.warnings.push(...source.warnings);
|
|
43909
|
+
};
|
|
43910
|
+
var validateScriptsDirectory = (skillDir, warnings) => {
|
|
43911
|
+
const scriptsDir = import_node_path12.default.join(skillDir, `scripts`);
|
|
43912
|
+
if (!(0, import_node_fs3.existsSync)(scriptsDir)) return;
|
|
43913
|
+
const entries = (0, import_node_fs3.readdirSync)(scriptsDir, { withFileTypes: true }).filter((entry) => entry.isFile());
|
|
43914
|
+
if (entries.length === 0) {
|
|
43915
|
+
addWarning(warnings, `empty_scripts_dir`, `scripts/ exists but contains no files.`);
|
|
43916
|
+
}
|
|
43917
|
+
};
|
|
43918
|
+
var validateSkillDirectory = (skillDir, options = {}) => {
|
|
43919
|
+
const errors = [];
|
|
43920
|
+
const warnings = [];
|
|
43921
|
+
const normalizedSkillDir = import_node_path12.default.resolve(skillDir);
|
|
43922
|
+
const skillMdPath = import_node_path12.default.join(normalizedSkillDir, `SKILL.md`);
|
|
43923
|
+
if (!(0, import_node_fs3.existsSync)(normalizedSkillDir) || !(0, import_node_fs3.statSync)(normalizedSkillDir).isDirectory()) {
|
|
43924
|
+
addError(errors, `missing_skill_dir`, `Skill directory does not exist: ${normalizedSkillDir}`);
|
|
43925
|
+
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
43926
|
+
}
|
|
43927
|
+
if (!(0, import_node_fs3.existsSync)(skillMdPath) || !(0, import_node_fs3.statSync)(skillMdPath).isFile()) {
|
|
43928
|
+
addError(errors, `missing_skill_md`, `Skill directory must contain SKILL.md.`);
|
|
43929
|
+
return { ok: false, errors, warnings, skillDir: normalizedSkillDir, skillMdPath };
|
|
43930
|
+
}
|
|
43931
|
+
const raw2 = (0, import_node_fs3.readFileSync)(skillMdPath, `utf-8`);
|
|
43932
|
+
const documentResult = validateSkillDocument({
|
|
43933
|
+
skillName: options.expectedName ?? import_node_path12.default.basename(normalizedSkillDir),
|
|
43934
|
+
skillMd: raw2,
|
|
43935
|
+
baseDir: normalizedSkillDir
|
|
43936
|
+
});
|
|
43937
|
+
mergeIssues({ errors, warnings }, documentResult);
|
|
43938
|
+
validateScriptsDirectory(normalizedSkillDir, warnings);
|
|
43939
|
+
return {
|
|
43940
|
+
ok: errors.length === 0,
|
|
43941
|
+
skill: documentResult.skill,
|
|
43942
|
+
errors,
|
|
43943
|
+
warnings,
|
|
43944
|
+
skillDir: normalizedSkillDir,
|
|
43945
|
+
skillMdPath
|
|
43946
|
+
};
|
|
43947
|
+
};
|
|
43948
|
+
var smokeTestSkillDirectory = (skillDir, options = {}) => {
|
|
43949
|
+
const directoryResult = validateSkillDirectory(skillDir, options);
|
|
43950
|
+
const errors = [...directoryResult.errors];
|
|
43951
|
+
const warnings = [...directoryResult.warnings];
|
|
43952
|
+
let detail;
|
|
43953
|
+
if (directoryResult.ok && directoryResult.skill) {
|
|
43954
|
+
detail = `Base directory for this skill: ${directoryResult.skillDir}
|
|
43955
|
+
|
|
43956
|
+
${directoryResult.skill.body}`;
|
|
43957
|
+
if (!detail.includes(directoryResult.skillDir)) {
|
|
43958
|
+
addError(errors, `smoke_missing_base_dir`, `Skill detail does not include its base directory.`);
|
|
43959
|
+
}
|
|
43960
|
+
if (!detail.includes(directoryResult.skill.body)) {
|
|
43961
|
+
addError(errors, `smoke_missing_body`, `Skill detail does not include the SKILL.md body.`);
|
|
43962
|
+
}
|
|
43963
|
+
if (detail.length < 80) {
|
|
43964
|
+
addWarning(warnings, `smoke_short_detail`, `Skill detail is unusually short.`);
|
|
43965
|
+
}
|
|
43966
|
+
}
|
|
43967
|
+
return {
|
|
43968
|
+
...directoryResult,
|
|
43969
|
+
ok: errors.length === 0,
|
|
43970
|
+
errors,
|
|
43971
|
+
warnings,
|
|
43972
|
+
detail
|
|
43973
|
+
};
|
|
43974
|
+
};
|
|
43975
|
+
var formatSkillValidationIssues = (result) => {
|
|
43976
|
+
const lines = [
|
|
43977
|
+
...result.errors.map((issue) => `- [${issue.code}] ${issue.message}`),
|
|
43978
|
+
...result.warnings.map((issue) => `- [warning:${issue.code}] ${issue.message}`)
|
|
43979
|
+
];
|
|
43980
|
+
return lines.join(`
|
|
43981
|
+
`);
|
|
43982
|
+
};
|
|
43983
|
+
|
|
43984
|
+
// src/department/learning.ts
|
|
43985
|
+
var ensureDir = (dir) => (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
43986
|
+
var readJsonArray = (filePath) => {
|
|
43987
|
+
if (!(0, import_node_fs4.existsSync)(filePath)) return [];
|
|
43988
|
+
return JSON.parse((0, import_node_fs4.readFileSync)(filePath, "utf-8"));
|
|
43989
|
+
};
|
|
43990
|
+
var writeJsonArray = (filePath, records) => {
|
|
43991
|
+
ensureDir(import_node_path13.default.dirname(filePath));
|
|
43992
|
+
(0, import_node_fs4.writeFileSync)(filePath, JSON.stringify(records, null, " "), "utf-8");
|
|
43993
|
+
};
|
|
43994
|
+
var departmentMemoryPath = (departmentName) => {
|
|
43995
|
+
return import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "department-memory.json");
|
|
43996
|
+
};
|
|
43997
|
+
var departmentSkillPath = (departmentName) => {
|
|
43998
|
+
return import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "department-skills.json");
|
|
43999
|
+
};
|
|
44000
|
+
var departmentSkillDir = (departmentName, skillName) => {
|
|
44001
|
+
return assertSafeSkillTarget(import_node_path13.default.join(getDepartmentWorkSpaceDir(departmentName), "skills"), skillName);
|
|
44002
|
+
};
|
|
44003
|
+
var proposalsPath = () => {
|
|
44004
|
+
return import_node_path13.default.join(getDepartmentBaseDir(), "department-proposals.json");
|
|
44005
|
+
};
|
|
44006
|
+
var getDepartmentNameForHead = (request) => {
|
|
44007
|
+
const mailboxId = request?.departmentAgentId;
|
|
44008
|
+
if (!mailboxId) return null;
|
|
44009
|
+
const member = getDepartmentMemberByMailboxId(mailboxId);
|
|
44010
|
+
if (!member || member.role !== "department_head") return null;
|
|
44011
|
+
const [departmentName] = mailboxId.split("::");
|
|
44012
|
+
return departmentName || null;
|
|
44013
|
+
};
|
|
44014
|
+
var listDepartmentMemories = (departmentName) => {
|
|
44015
|
+
return readJsonArray(departmentMemoryPath(departmentName)).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
44016
|
+
};
|
|
44017
|
+
var createDepartmentMemory = (departmentName, input) => {
|
|
44018
|
+
const now = Date.now();
|
|
44019
|
+
const memory = {
|
|
44020
|
+
id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
|
|
44021
|
+
departmentName,
|
|
44022
|
+
title: input.title,
|
|
44023
|
+
content: input.content,
|
|
44024
|
+
sourceMailboxId: input.sourceMailboxId,
|
|
44025
|
+
createdAt: now,
|
|
44026
|
+
updatedAt: now
|
|
44027
|
+
};
|
|
44028
|
+
const records = listDepartmentMemories(departmentName);
|
|
44029
|
+
records.push(memory);
|
|
44030
|
+
writeJsonArray(departmentMemoryPath(departmentName), records);
|
|
44031
|
+
return memory;
|
|
44032
|
+
};
|
|
44033
|
+
var updateDepartmentMemory = (departmentName, id, patch) => {
|
|
44034
|
+
const records = listDepartmentMemories(departmentName);
|
|
44035
|
+
const idx = records.findIndex((record) => record.id === id);
|
|
44036
|
+
if (idx < 0) return null;
|
|
44037
|
+
records[idx] = {
|
|
44038
|
+
...records[idx],
|
|
44039
|
+
...patch.title !== void 0 ? { title: patch.title } : {},
|
|
44040
|
+
...patch.content !== void 0 ? { content: patch.content } : {},
|
|
44041
|
+
updatedAt: Date.now()
|
|
44042
|
+
};
|
|
44043
|
+
writeJsonArray(departmentMemoryPath(departmentName), records);
|
|
44044
|
+
return records[idx];
|
|
44045
|
+
};
|
|
44046
|
+
var deleteDepartmentMemory = (departmentName, id) => {
|
|
44047
|
+
const records = listDepartmentMemories(departmentName);
|
|
44048
|
+
const target = records.find((record) => record.id === id) ?? null;
|
|
44049
|
+
writeJsonArray(departmentMemoryPath(departmentName), records.filter((record) => record.id !== id));
|
|
44050
|
+
return target;
|
|
44051
|
+
};
|
|
44052
|
+
var listDepartmentSkills = (departmentName) => {
|
|
44053
|
+
return readJsonArray(departmentSkillPath(departmentName)).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
44054
|
+
};
|
|
44055
|
+
var proposeDepartmentSkill = (departmentName, input) => {
|
|
44056
|
+
const validation = validateSkillDocument({
|
|
44057
|
+
skillName: input.skillName,
|
|
44058
|
+
description: input.description,
|
|
44059
|
+
skillMd: input.skillMd
|
|
44060
|
+
});
|
|
44061
|
+
if (!validation.ok) {
|
|
44062
|
+
throw new Error(`[departmentSkill] Skill \u8349\u7A3F\u6821\u9A8C\u5931\u8D25\uFF1A
|
|
44063
|
+
${formatSkillValidationIssues(validation)}`);
|
|
44064
|
+
}
|
|
44065
|
+
const records = listDepartmentSkills(departmentName);
|
|
44066
|
+
if (records.some((record) => record.skillName === input.skillName && record.status !== "dropped")) {
|
|
44067
|
+
return null;
|
|
44068
|
+
}
|
|
44069
|
+
const now = Date.now();
|
|
44070
|
+
const skill = {
|
|
44071
|
+
id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
|
|
44072
|
+
departmentName,
|
|
44073
|
+
skillName: input.skillName,
|
|
44074
|
+
description: input.description,
|
|
44075
|
+
skillMd: input.skillMd,
|
|
44076
|
+
status: "pending",
|
|
44077
|
+
createdByMailboxId: input.createdByMailboxId,
|
|
44078
|
+
createdAt: now,
|
|
44079
|
+
updatedAt: now
|
|
44080
|
+
};
|
|
44081
|
+
records.push(skill);
|
|
44082
|
+
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
44083
|
+
return skill;
|
|
44084
|
+
};
|
|
44085
|
+
var keepDepartmentSkill = (departmentName, id) => {
|
|
44086
|
+
const records = listDepartmentSkills(departmentName);
|
|
44087
|
+
const idx = records.findIndex((record) => record.id === id);
|
|
44088
|
+
if (idx < 0) return null;
|
|
44089
|
+
records[idx] = { ...records[idx], status: "active", updatedAt: Date.now() };
|
|
44090
|
+
const skillDir = departmentSkillDir(departmentName, records[idx].skillName);
|
|
44091
|
+
const validation = validateSkillDocument({
|
|
44092
|
+
skillName: records[idx].skillName,
|
|
44093
|
+
description: records[idx].description,
|
|
44094
|
+
skillMd: records[idx].skillMd,
|
|
44095
|
+
baseDir: skillDir
|
|
44096
|
+
});
|
|
44097
|
+
if (!validation.ok) {
|
|
44098
|
+
throw new Error(`[departmentSkill] Skill \u8349\u7A3F\u6821\u9A8C\u5931\u8D25\uFF0C\u62D2\u7EDD\u4FDD\u7559\uFF1A
|
|
44099
|
+
${formatSkillValidationIssues(validation)}`);
|
|
44100
|
+
}
|
|
44101
|
+
ensureDir(skillDir);
|
|
44102
|
+
(0, import_node_fs4.writeFileSync)(import_node_path13.default.join(skillDir, "SKILL.md"), records[idx].skillMd, "utf-8");
|
|
44103
|
+
const smokeTest = smokeTestSkillDirectory(skillDir, { expectedName: records[idx].skillName });
|
|
44104
|
+
if (!smokeTest.ok) {
|
|
44105
|
+
throw new Error(`[departmentSkill] Skill smoke test \u5931\u8D25\uFF1A
|
|
44106
|
+
${formatSkillValidationIssues(smokeTest)}`);
|
|
44107
|
+
}
|
|
44108
|
+
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
44109
|
+
return records[idx];
|
|
44110
|
+
};
|
|
44111
|
+
var dropDepartmentSkill = (departmentName, id) => {
|
|
44112
|
+
const records = listDepartmentSkills(departmentName);
|
|
44113
|
+
const idx = records.findIndex((record) => record.id === id);
|
|
44114
|
+
if (idx < 0) return null;
|
|
44115
|
+
records[idx] = { ...records[idx], status: "dropped", updatedAt: Date.now() };
|
|
44116
|
+
writeJsonArray(departmentSkillPath(departmentName), records);
|
|
44117
|
+
return records[idx];
|
|
44118
|
+
};
|
|
44119
|
+
var createDepartmentProposal = (input) => {
|
|
44120
|
+
const records = readJsonArray(proposalsPath());
|
|
44121
|
+
const proposal = {
|
|
44122
|
+
...input,
|
|
44123
|
+
id: (0, import_node_crypto10.randomUUID)().slice(0, 8),
|
|
44124
|
+
status: "pending",
|
|
44125
|
+
createdAt: Date.now()
|
|
44126
|
+
};
|
|
44127
|
+
records.push(proposal);
|
|
44128
|
+
writeJsonArray(proposalsPath(), records);
|
|
44129
|
+
return proposal;
|
|
44130
|
+
};
|
|
44131
|
+
var buildDepartmentLearningContext = (departmentName) => {
|
|
44132
|
+
if (!departmentName) return "";
|
|
44133
|
+
const memories = listDepartmentMemories(departmentName);
|
|
44134
|
+
const activeSkills = listDepartmentSkills(departmentName).filter((skill) => skill.status === "active");
|
|
44135
|
+
if (memories.length === 0 && activeSkills.length === 0) return "";
|
|
44136
|
+
const memoryLines = memories.map(
|
|
44137
|
+
(memory) => ` - [id=${memory.id}] ${memory.title}
|
|
44138
|
+
${memory.content.replace(/\n/g, "\n ")}`
|
|
44139
|
+
).join("\n");
|
|
44140
|
+
const skillLines = activeSkills.map(
|
|
44141
|
+
(skill) => ` - ${skill.skillName}: ${skill.description}`
|
|
44142
|
+
).join("\n");
|
|
44143
|
+
return [
|
|
44144
|
+
`<department-learning-context department="${departmentName}">`,
|
|
44145
|
+
memories.length > 0 ? `Department memories:
|
|
44146
|
+
${memoryLines}` : "",
|
|
44147
|
+
activeSkills.length > 0 ? `Department skills:
|
|
44148
|
+
${skillLines}` : "",
|
|
44149
|
+
`</department-learning-context>`
|
|
44150
|
+
].filter(Boolean).join("\n");
|
|
44151
|
+
};
|
|
44152
|
+
|
|
44174
44153
|
// src/tools/tools/department/DepartmentLearning.ts
|
|
44175
44154
|
var requireDepartmentHead = (request) => {
|
|
44176
44155
|
return getDepartmentNameForHead(request);
|
|
@@ -44526,6 +44505,8 @@ var DESCRIPTION29 = `\u5728\u7CFB\u7EDF shell \u4E2D\u6267\u884C\u547D\u4EE4\u30
|
|
|
44526
44505
|
- \u4E0D\u8981\u6267\u884C\u7834\u574F\u6027\u547D\u4EE4\uFF08\u5982 rm -rf /\uFF09
|
|
44527
44506
|
- \u957F\u65F6\u95F4\u8FD0\u884C\u7684\u547D\u4EE4\uFF08\u5982\u542F\u52A8\u670D\u52A1\u5668\uFF09\u8D85\u8FC7\u7B49\u5F85\u65F6\u95F4\u540E\u4F1A\u4FDD\u7559\u4F1A\u8BDD\uFF0C\u53EF\u7528 session_id \u67E5\u8BE2\u589E\u91CF\u8F93\u51FA
|
|
44528
44507
|
- \u5982\u679C\u4F60\u5904\u4E8E\u90E8\u95E8\u5DE5\u4F5C\u533A\u6A21\u5F0F\uFF0Ccwd \u5FC5\u987B\u5728\u5DE5\u4F5C\u533A\u8303\u56F4\u5185
|
|
44508
|
+
- Duclaw runtime \u4FDD\u7559\u7AEF\u53E3 3100 \u627F\u8F7D\u5F53\u524D\u667A\u80FD\u4F53 HTTP/gateway\uFF0Cduclaw-cli start \u548C duclaw-worker \u662F\u7CFB\u7EDF\u8FDB\u7A0B\u3002\u4E0D\u8981\u5BF9 3100 \u6216\u8FD9\u4E9B\u8FDB\u7A0B\u6267\u884C kill/pkill/killall/fuser/lsof|xargs kill/ss|xargs kill\uFF0C\u5426\u5219 iOS \u4F1A\u663E\u793A\u5DF2\u5173\u673A\u6216 502\u3002
|
|
44509
|
+
- \u505C\u6B62\u81EA\u5DF1\u542F\u52A8\u7684\u5F00\u53D1\u670D\u52A1\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528 action=stop \u548C session_id\uFF1B\u65E0\u6CD5\u786E\u8BA4 PID \u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\u65F6\u4E0D\u8981 kill\u3002
|
|
44529
44510
|
`;
|
|
44530
44511
|
var MAX_OUTPUT_LENGTH = 1e4;
|
|
44531
44512
|
var MAX_SESSION_OUTPUT_LENGTH = 5e4;
|
|
@@ -44533,6 +44514,7 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
44533
44514
|
var DEFAULT_SESSION_TTL_MS = 30 * 60 * 1e3;
|
|
44534
44515
|
var SHELL_CANDIDATES2 = ["/bin/sh", "/usr/bin/sh", "/bin/bash"];
|
|
44535
44516
|
var DEFAULT_PROTECTED_PORTS = ["3100"];
|
|
44517
|
+
var RESERVED_PORT_ENV_KEYS = ["PORT", "KANBAN_PORT"];
|
|
44536
44518
|
var sessions = /* @__PURE__ */ new Map();
|
|
44537
44519
|
function findExecutableShell2() {
|
|
44538
44520
|
for (const shell of SHELL_CANDIDATES2) {
|
|
@@ -44593,6 +44575,17 @@ function validateProtectedRuntimeCommand(command) {
|
|
|
44593
44575
|
}
|
|
44594
44576
|
return null;
|
|
44595
44577
|
}
|
|
44578
|
+
function createBashChildEnv() {
|
|
44579
|
+
const env = { ...process.env, PAGER: "cat" };
|
|
44580
|
+
const protectedPorts = new Set(getProtectedPorts());
|
|
44581
|
+
for (const key of RESERVED_PORT_ENV_KEYS) {
|
|
44582
|
+
const value = env[key]?.trim();
|
|
44583
|
+
if (value && protectedPorts.has(value)) {
|
|
44584
|
+
delete env[key];
|
|
44585
|
+
}
|
|
44586
|
+
}
|
|
44587
|
+
return env;
|
|
44588
|
+
}
|
|
44596
44589
|
function listProtectedRuntimeProcesses() {
|
|
44597
44590
|
try {
|
|
44598
44591
|
const output = (0, import_node_child_process.execFileSync)("ps", ["-eo", "pid=,ppid=,args="], { encoding: "utf8" });
|
|
@@ -44621,6 +44614,21 @@ function validateProtectedRuntimePidCommand(command) {
|
|
|
44621
44614
|
}
|
|
44622
44615
|
return null;
|
|
44623
44616
|
}
|
|
44617
|
+
function terminateSessionProcessGroup(session, signal = "SIGTERM") {
|
|
44618
|
+
const pid = session.child.pid;
|
|
44619
|
+
if (!pid) {
|
|
44620
|
+
session.child.kill(signal);
|
|
44621
|
+
return;
|
|
44622
|
+
}
|
|
44623
|
+
try {
|
|
44624
|
+
if (process.platform !== "win32") {
|
|
44625
|
+
process.kill(-pid, signal);
|
|
44626
|
+
return;
|
|
44627
|
+
}
|
|
44628
|
+
} catch {
|
|
44629
|
+
}
|
|
44630
|
+
session.child.kill(signal);
|
|
44631
|
+
}
|
|
44624
44632
|
function truncateOutput(output, limit = MAX_OUTPUT_LENGTH) {
|
|
44625
44633
|
if (output.length <= limit) return output;
|
|
44626
44634
|
return output.slice(0, limit) + `
|
|
@@ -44726,7 +44734,7 @@ var bashTool = {
|
|
|
44726
44734
|
}
|
|
44727
44735
|
if (action === "stop") {
|
|
44728
44736
|
if (session.status === "running") {
|
|
44729
|
-
session
|
|
44737
|
+
terminateSessionProcessGroup(session, "SIGTERM");
|
|
44730
44738
|
finishSession(session, "stopped", null, "SIGTERM");
|
|
44731
44739
|
}
|
|
44732
44740
|
return renderSessionDelta(session, `[bash] \u5DF2\u505C\u6B62 session ${session.id}`);
|
|
@@ -44759,12 +44767,13 @@ var bashTool = {
|
|
|
44759
44767
|
}
|
|
44760
44768
|
return new Promise(async (resolve11) => {
|
|
44761
44769
|
const options = {
|
|
44762
|
-
env:
|
|
44770
|
+
env: createBashChildEnv()
|
|
44763
44771
|
};
|
|
44764
44772
|
if (cwd) options.cwd = cwd;
|
|
44765
44773
|
const child = (0, import_node_child_process.spawn)(shell, ["-c", command], {
|
|
44766
44774
|
...options,
|
|
44767
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
44775
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
44776
|
+
detached: process.platform !== "win32"
|
|
44768
44777
|
});
|
|
44769
44778
|
const id = (0, import_node_crypto11.randomUUID)().slice(0, 8);
|
|
44770
44779
|
const session = {
|
|
@@ -44779,7 +44788,7 @@ var bashTool = {
|
|
|
44779
44788
|
const current = sessions.get(id);
|
|
44780
44789
|
if (!current) return;
|
|
44781
44790
|
if (current.status === "running") {
|
|
44782
|
-
current
|
|
44791
|
+
terminateSessionProcessGroup(current, "SIGTERM");
|
|
44783
44792
|
finishSession(current, "stopped", null, "SIGTERM");
|
|
44784
44793
|
}
|
|
44785
44794
|
sessions.delete(id);
|
|
@@ -44932,11 +44941,26 @@ var createRuntimeActivityToolHookPlugin = () => ({
|
|
|
44932
44941
|
}
|
|
44933
44942
|
});
|
|
44934
44943
|
function activityMetadata(ctx) {
|
|
44935
|
-
|
|
44944
|
+
const metadata = {
|
|
44936
44945
|
platform: ctx.userRequest?.platform,
|
|
44937
44946
|
requestId: ctx.userRequest?.requestId,
|
|
44938
44947
|
departmentAgentId: ctx.userRequest?.departmentAgentId
|
|
44939
44948
|
};
|
|
44949
|
+
if (ctx.toolName === "bash") {
|
|
44950
|
+
if (typeof ctx.input.command === "string") {
|
|
44951
|
+
metadata.command = summarizeText2(ctx.input.command, 1e3);
|
|
44952
|
+
}
|
|
44953
|
+
if (typeof ctx.input.action === "string") {
|
|
44954
|
+
metadata.action = ctx.input.action;
|
|
44955
|
+
}
|
|
44956
|
+
if (typeof ctx.input.session_id === "string") {
|
|
44957
|
+
metadata.sessionId = ctx.input.session_id;
|
|
44958
|
+
}
|
|
44959
|
+
}
|
|
44960
|
+
return metadata;
|
|
44961
|
+
}
|
|
44962
|
+
function summarizeText2(value, maxChars) {
|
|
44963
|
+
return value.length <= maxChars ? value : `${value.slice(0, maxChars)}...`;
|
|
44940
44964
|
}
|
|
44941
44965
|
|
|
44942
44966
|
// src/runtime/plugins/saasCreditToolHook.ts
|
|
@@ -46546,6 +46570,16 @@ var claimOutboundSend = (userId, text2, windowMs = DEFAULT_WINDOW_MS) => {
|
|
|
46546
46570
|
return true;
|
|
46547
46571
|
};
|
|
46548
46572
|
|
|
46573
|
+
// src/runtime/runtimeSafetyPrompt.ts
|
|
46574
|
+
var RUNTIME_PROCESS_SAFETY_PROMPT = `
|
|
46575
|
+
<Runtime Process Safety>
|
|
46576
|
+
- Duclaw runtime \u81EA\u8EAB\u5360\u7528\u4FDD\u7559\u7AEF\u53E3 3100\uFF0C\u5E76\u7531 duclaw-cli start \u63D0\u4F9B HTTP/gateway\uFF0C\u7531 duclaw-worker \u5904\u7406\u540E\u53F0 mailbox/worker \u5DE5\u4F5C\u3002\u4E0D\u8981\u7EC8\u6B62\u8FD9\u4E9B\u8FDB\u7A0B\u3002
|
|
46577
|
+
- \u4E0D\u8981\u5BF9 3100\u3001duclaw-cli start\u3001duclaw-worker \u6267\u884C kill\u3001pkill\u3001killall\u3001fuser\u3001lsof|xargs kill\u3001ss|xargs kill\uFF0C\u6740\u6389\u5B83\u4F1A\u5BFC\u81F4 iOS \u663E\u793A\u5DF2\u5173\u673A\u6216 HTTP 502\u3002
|
|
46578
|
+
- \u53D1\u73B0 3100 \u88AB\u5360\u7528\u65F6\uFF0C\u9ED8\u8BA4\u5B83\u662F\u7CFB\u7EDF\u4FDD\u7559\u7AEF\u53E3\uFF0C\u4E0D\u8981\u6E05\u7406\uFF1B\u9879\u76EE\u5F00\u53D1\u670D\u52A1\u8BF7\u6539\u7528\u81EA\u5DF1\u7684\u7AEF\u53E3\uFF0C\u4F8B\u5982 3001\u30015173\u30015174\u3002
|
|
46579
|
+
- \u505C\u6B62\u81EA\u5DF1\u542F\u52A8\u7684\u5F00\u53D1\u670D\u52A1\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528 bash \u7684 action=stop \u548C\u5BF9\u5E94 session_id\u3002\u53EA\u6709\u80FD\u660E\u786E PID \u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\u5F00\u53D1\u670D\u52A1\u65F6\u624D\u53EF\u4EE5\u7EC8\u6B62\uFF1B\u65E0\u6CD5\u5224\u65AD\u65F6\u5148\u6C47\u62A5\uFF0C\u4E0D\u8981 kill\u3002
|
|
46580
|
+
</Runtime Process Safety>
|
|
46581
|
+
`.trim();
|
|
46582
|
+
|
|
46549
46583
|
// src/agent/createAgent.ts
|
|
46550
46584
|
var DEFAULT_WORKSPACE_PATH = getDuclawWorkspaceDir();
|
|
46551
46585
|
var assistantMessageFromResponse = (response) => ({
|
|
@@ -46600,6 +46634,8 @@ The user will primarily request you perform software engineering tasks. This inc
|
|
|
46600
46634
|
- \u5982\u679C\u5386\u53F2\u4E2D\u51FA\u73B0 <department-agent-reply ... owner_mailbox_id="...">\uFF0C\u628A\u8BE5\u6210\u5458\u89C6\u4E3A\u5BF9\u5E94\u4EA7\u51FA/\u5B9E\u73B0\u7EBF\u7A0B\u7684\u8D23\u4EFB\u4EBA\uFF1B\u5F53\u7528\u6237\u968F\u540E\u63D0\u51FA bug\u3001\u4FEE\u6539\u3001\u8FD4\u5DE5\u3001\u6253\u4E0D\u5F00\u3001\u518D\u4F18\u5316\u7B49\u53CD\u9988\u65F6\uFF0C\u4F18\u5148\u6CBF\u8BE5 reply \u7684 mailbox \u7EBF\u7A0B\u7EE7\u7EED\u59D4\u6D3E\u7ED9\u539F\u8D23\u4EFB\u4EBA\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u63A5\u624B\u5B9E\u73B0\u3002
|
|
46601
46635
|
</Doing tasks>
|
|
46602
46636
|
|
|
46637
|
+
${RUNTIME_PROCESS_SAFETY_PROMPT}
|
|
46638
|
+
|
|
46603
46639
|
<\u4F60\u7684\u8EAB\u4EFD>
|
|
46604
46640
|
\u4F60\u662F\u8FD9\u5BB6 AI \u516C\u53F8\u7684 CEO\uFF0C\u76F4\u63A5\u5411\u8001\u677F\uFF08\u7528\u6237\uFF09\u8D1F\u8D23\u3002\u4F60\u7684\u672C\u4E8B\u662F\u901A\u8FC7\u56E2\u961F\u628A\u4E8B\u60C5\u505A\u6210\uFF0C\u800C\u4E0D\u662F\u81EA\u5DF1\u57CB\u5934\u505A\u3002
|
|
46605
46641
|
|
|
@@ -48621,6 +48657,8 @@ ${workspacePath ? `
|
|
|
48621
48657
|
\u56DE\u590D\u5199\u5F97\u6E05\u695A\u3001\u6709\u6761\u7406\uFF0C\u65B9\u4FBF\u5BF9\u65B9\u63A5\u7740\u5E72\u3002
|
|
48622
48658
|
</Mailbox \u5DE5\u4F5C\u65B9\u5F0F>
|
|
48623
48659
|
|
|
48660
|
+
${RUNTIME_PROCESS_SAFETY_PROMPT}
|
|
48661
|
+
|
|
48624
48662
|
<Task Execution>
|
|
48625
48663
|
- Use available tools to complete the work.
|
|
48626
48664
|
- For file operations, use the dedicated file tools:
|
|
@@ -48816,26 +48854,26 @@ var handleParsingNestedValues = (form, key, value) => {
|
|
|
48816
48854
|
};
|
|
48817
48855
|
|
|
48818
48856
|
// node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/utils/url.js
|
|
48819
|
-
var splitPath = (
|
|
48820
|
-
const paths =
|
|
48857
|
+
var splitPath = (path21) => {
|
|
48858
|
+
const paths = path21.split("/");
|
|
48821
48859
|
if (paths[0] === "") {
|
|
48822
48860
|
paths.shift();
|
|
48823
48861
|
}
|
|
48824
48862
|
return paths;
|
|
48825
48863
|
};
|
|
48826
48864
|
var splitRoutingPath = (routePath) => {
|
|
48827
|
-
const { groups, path:
|
|
48828
|
-
const paths = splitPath(
|
|
48865
|
+
const { groups, path: path21 } = extractGroupsFromPath(routePath);
|
|
48866
|
+
const paths = splitPath(path21);
|
|
48829
48867
|
return replaceGroupMarks(paths, groups);
|
|
48830
48868
|
};
|
|
48831
|
-
var extractGroupsFromPath = (
|
|
48869
|
+
var extractGroupsFromPath = (path21) => {
|
|
48832
48870
|
const groups = [];
|
|
48833
|
-
|
|
48871
|
+
path21 = path21.replace(/\{[^}]+\}/g, (match2, index) => {
|
|
48834
48872
|
const mark = `@${index}`;
|
|
48835
48873
|
groups.push([mark, match2]);
|
|
48836
48874
|
return mark;
|
|
48837
48875
|
});
|
|
48838
|
-
return { groups, path:
|
|
48876
|
+
return { groups, path: path21 };
|
|
48839
48877
|
};
|
|
48840
48878
|
var replaceGroupMarks = (paths, groups) => {
|
|
48841
48879
|
for (let i = groups.length - 1; i >= 0; i--) {
|
|
@@ -48892,8 +48930,8 @@ var getPath = (request) => {
|
|
|
48892
48930
|
const queryIndex = url.indexOf("?", i);
|
|
48893
48931
|
const hashIndex = url.indexOf("#", i);
|
|
48894
48932
|
const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
|
|
48895
|
-
const
|
|
48896
|
-
return tryDecodeURI(
|
|
48933
|
+
const path21 = url.slice(start, end);
|
|
48934
|
+
return tryDecodeURI(path21.includes("%25") ? path21.replace(/%25/g, "%2525") : path21);
|
|
48897
48935
|
} else if (charCode === 63 || charCode === 35) {
|
|
48898
48936
|
break;
|
|
48899
48937
|
}
|
|
@@ -48910,11 +48948,11 @@ var mergePath = (base, sub, ...rest) => {
|
|
|
48910
48948
|
}
|
|
48911
48949
|
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
|
|
48912
48950
|
};
|
|
48913
|
-
var checkOptionalParameter = (
|
|
48914
|
-
if (
|
|
48951
|
+
var checkOptionalParameter = (path21) => {
|
|
48952
|
+
if (path21.charCodeAt(path21.length - 1) !== 63 || !path21.includes(":")) {
|
|
48915
48953
|
return null;
|
|
48916
48954
|
}
|
|
48917
|
-
const segments =
|
|
48955
|
+
const segments = path21.split("/");
|
|
48918
48956
|
const results = [];
|
|
48919
48957
|
let basePath = "";
|
|
48920
48958
|
segments.forEach((segment) => {
|
|
@@ -49055,9 +49093,9 @@ var HonoRequest = class {
|
|
|
49055
49093
|
*/
|
|
49056
49094
|
path;
|
|
49057
49095
|
bodyCache = {};
|
|
49058
|
-
constructor(request,
|
|
49096
|
+
constructor(request, path21 = "/", matchResult = [[]]) {
|
|
49059
49097
|
this.raw = request;
|
|
49060
|
-
this.path =
|
|
49098
|
+
this.path = path21;
|
|
49061
49099
|
this.#matchResult = matchResult;
|
|
49062
49100
|
this.#validatedData = {};
|
|
49063
49101
|
}
|
|
@@ -49794,8 +49832,8 @@ var Hono = class _Hono {
|
|
|
49794
49832
|
return this;
|
|
49795
49833
|
};
|
|
49796
49834
|
});
|
|
49797
|
-
this.on = (method,
|
|
49798
|
-
for (const p of [
|
|
49835
|
+
this.on = (method, path21, ...handlers) => {
|
|
49836
|
+
for (const p of [path21].flat()) {
|
|
49799
49837
|
this.#path = p;
|
|
49800
49838
|
for (const m of [method].flat()) {
|
|
49801
49839
|
handlers.map((handler) => {
|
|
@@ -49852,8 +49890,8 @@ var Hono = class _Hono {
|
|
|
49852
49890
|
* app.route("/api", app2) // GET /api/user
|
|
49853
49891
|
* ```
|
|
49854
49892
|
*/
|
|
49855
|
-
route(
|
|
49856
|
-
const subApp = this.basePath(
|
|
49893
|
+
route(path21, app) {
|
|
49894
|
+
const subApp = this.basePath(path21);
|
|
49857
49895
|
app.routes.map((r) => {
|
|
49858
49896
|
let handler;
|
|
49859
49897
|
if (app.errorHandler === errorHandler) {
|
|
@@ -49879,9 +49917,9 @@ var Hono = class _Hono {
|
|
|
49879
49917
|
* const api = new Hono().basePath('/api')
|
|
49880
49918
|
* ```
|
|
49881
49919
|
*/
|
|
49882
|
-
basePath(
|
|
49920
|
+
basePath(path21) {
|
|
49883
49921
|
const subApp = this.#clone();
|
|
49884
|
-
subApp._basePath = mergePath(this._basePath,
|
|
49922
|
+
subApp._basePath = mergePath(this._basePath, path21);
|
|
49885
49923
|
return subApp;
|
|
49886
49924
|
}
|
|
49887
49925
|
/**
|
|
@@ -49955,7 +49993,7 @@ var Hono = class _Hono {
|
|
|
49955
49993
|
* })
|
|
49956
49994
|
* ```
|
|
49957
49995
|
*/
|
|
49958
|
-
mount(
|
|
49996
|
+
mount(path21, applicationHandler, options) {
|
|
49959
49997
|
let replaceRequest;
|
|
49960
49998
|
let optionHandler;
|
|
49961
49999
|
if (options) {
|
|
@@ -49982,7 +50020,7 @@ var Hono = class _Hono {
|
|
|
49982
50020
|
return [c.env, executionContext];
|
|
49983
50021
|
};
|
|
49984
50022
|
replaceRequest ||= (() => {
|
|
49985
|
-
const mergedPath = mergePath(this._basePath,
|
|
50023
|
+
const mergedPath = mergePath(this._basePath, path21);
|
|
49986
50024
|
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
|
49987
50025
|
return (request) => {
|
|
49988
50026
|
const url = new URL(request.url);
|
|
@@ -49997,14 +50035,14 @@ var Hono = class _Hono {
|
|
|
49997
50035
|
}
|
|
49998
50036
|
await next();
|
|
49999
50037
|
};
|
|
50000
|
-
this.#addRoute(METHOD_NAME_ALL, mergePath(
|
|
50038
|
+
this.#addRoute(METHOD_NAME_ALL, mergePath(path21, "*"), handler);
|
|
50001
50039
|
return this;
|
|
50002
50040
|
}
|
|
50003
|
-
#addRoute(method,
|
|
50041
|
+
#addRoute(method, path21, handler) {
|
|
50004
50042
|
method = method.toUpperCase();
|
|
50005
|
-
|
|
50006
|
-
const r = { basePath: this._basePath, path:
|
|
50007
|
-
this.router.add(method,
|
|
50043
|
+
path21 = mergePath(this._basePath, path21);
|
|
50044
|
+
const r = { basePath: this._basePath, path: path21, method, handler };
|
|
50045
|
+
this.router.add(method, path21, [handler, r]);
|
|
50008
50046
|
this.routes.push(r);
|
|
50009
50047
|
}
|
|
50010
50048
|
#handleError(err, c) {
|
|
@@ -50017,10 +50055,10 @@ var Hono = class _Hono {
|
|
|
50017
50055
|
if (method === "HEAD") {
|
|
50018
50056
|
return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
|
|
50019
50057
|
}
|
|
50020
|
-
const
|
|
50021
|
-
const matchResult = this.router.match(method,
|
|
50058
|
+
const path21 = this.getPath(request, { env });
|
|
50059
|
+
const matchResult = this.router.match(method, path21);
|
|
50022
50060
|
const c = new Context(request, {
|
|
50023
|
-
path:
|
|
50061
|
+
path: path21,
|
|
50024
50062
|
matchResult,
|
|
50025
50063
|
env,
|
|
50026
50064
|
executionCtx,
|
|
@@ -50120,7 +50158,7 @@ var Hono = class _Hono {
|
|
|
50120
50158
|
|
|
50121
50159
|
// node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
50122
50160
|
var emptyParam = [];
|
|
50123
|
-
function match(method,
|
|
50161
|
+
function match(method, path21) {
|
|
50124
50162
|
const matchers = this.buildAllMatchers();
|
|
50125
50163
|
const match2 = ((method2, path22) => {
|
|
50126
50164
|
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
|
|
@@ -50136,7 +50174,7 @@ function match(method, path20) {
|
|
|
50136
50174
|
return [matcher[1][index], match3];
|
|
50137
50175
|
});
|
|
50138
50176
|
this.match = match2;
|
|
50139
|
-
return match2(method,
|
|
50177
|
+
return match2(method, path21);
|
|
50140
50178
|
}
|
|
50141
50179
|
|
|
50142
50180
|
// node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
@@ -50251,12 +50289,12 @@ var Node = class _Node {
|
|
|
50251
50289
|
var Trie = class {
|
|
50252
50290
|
#context = { varIndex: 0 };
|
|
50253
50291
|
#root = new Node();
|
|
50254
|
-
insert(
|
|
50292
|
+
insert(path21, index, pathErrorCheckOnly) {
|
|
50255
50293
|
const paramAssoc = [];
|
|
50256
50294
|
const groups = [];
|
|
50257
50295
|
for (let i = 0; ; ) {
|
|
50258
50296
|
let replaced = false;
|
|
50259
|
-
|
|
50297
|
+
path21 = path21.replace(/\{[^}]+\}/g, (m) => {
|
|
50260
50298
|
const mark = `@\\${i}`;
|
|
50261
50299
|
groups[i] = [mark, m];
|
|
50262
50300
|
i++;
|
|
@@ -50267,7 +50305,7 @@ var Trie = class {
|
|
|
50267
50305
|
break;
|
|
50268
50306
|
}
|
|
50269
50307
|
}
|
|
50270
|
-
const tokens =
|
|
50308
|
+
const tokens = path21.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
|
|
50271
50309
|
for (let i = groups.length - 1; i >= 0; i--) {
|
|
50272
50310
|
const [mark] = groups[i];
|
|
50273
50311
|
for (let j = tokens.length - 1; j >= 0; j--) {
|
|
@@ -50306,9 +50344,9 @@ var Trie = class {
|
|
|
50306
50344
|
// node_modules/.pnpm/hono@4.12.9/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
50307
50345
|
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
50308
50346
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
50309
|
-
function buildWildcardRegExp(
|
|
50310
|
-
return wildcardRegExpCache[
|
|
50311
|
-
|
|
50347
|
+
function buildWildcardRegExp(path21) {
|
|
50348
|
+
return wildcardRegExpCache[path21] ??= new RegExp(
|
|
50349
|
+
path21 === "*" ? "" : `^${path21.replace(
|
|
50312
50350
|
/\/\*$|([.\\+*[^\]$()])/g,
|
|
50313
50351
|
(_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
|
|
50314
50352
|
)}$`
|
|
@@ -50330,17 +50368,17 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
50330
50368
|
);
|
|
50331
50369
|
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
50332
50370
|
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
|
|
50333
|
-
const [pathErrorCheckOnly,
|
|
50371
|
+
const [pathErrorCheckOnly, path21, handlers] = routesWithStaticPathFlag[i];
|
|
50334
50372
|
if (pathErrorCheckOnly) {
|
|
50335
|
-
staticMap[
|
|
50373
|
+
staticMap[path21] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
50336
50374
|
} else {
|
|
50337
50375
|
j++;
|
|
50338
50376
|
}
|
|
50339
50377
|
let paramAssoc;
|
|
50340
50378
|
try {
|
|
50341
|
-
paramAssoc = trie.insert(
|
|
50379
|
+
paramAssoc = trie.insert(path21, j, pathErrorCheckOnly);
|
|
50342
50380
|
} catch (e) {
|
|
50343
|
-
throw e === PATH_ERROR ? new UnsupportedPathError(
|
|
50381
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(path21) : e;
|
|
50344
50382
|
}
|
|
50345
50383
|
if (pathErrorCheckOnly) {
|
|
50346
50384
|
continue;
|
|
@@ -50374,12 +50412,12 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
50374
50412
|
}
|
|
50375
50413
|
return [regexp, handlerMap, staticMap];
|
|
50376
50414
|
}
|
|
50377
|
-
function findMiddleware(middleware,
|
|
50415
|
+
function findMiddleware(middleware, path21) {
|
|
50378
50416
|
if (!middleware) {
|
|
50379
50417
|
return void 0;
|
|
50380
50418
|
}
|
|
50381
50419
|
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
|
|
50382
|
-
if (buildWildcardRegExp(k).test(
|
|
50420
|
+
if (buildWildcardRegExp(k).test(path21)) {
|
|
50383
50421
|
return [...middleware[k]];
|
|
50384
50422
|
}
|
|
50385
50423
|
}
|
|
@@ -50393,7 +50431,7 @@ var RegExpRouter = class {
|
|
|
50393
50431
|
this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
50394
50432
|
this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
50395
50433
|
}
|
|
50396
|
-
add(method,
|
|
50434
|
+
add(method, path21, handler) {
|
|
50397
50435
|
const middleware = this.#middleware;
|
|
50398
50436
|
const routes = this.#routes;
|
|
50399
50437
|
if (!middleware || !routes) {
|
|
@@ -50408,18 +50446,18 @@ var RegExpRouter = class {
|
|
|
50408
50446
|
});
|
|
50409
50447
|
});
|
|
50410
50448
|
}
|
|
50411
|
-
if (
|
|
50412
|
-
|
|
50449
|
+
if (path21 === "/*") {
|
|
50450
|
+
path21 = "*";
|
|
50413
50451
|
}
|
|
50414
|
-
const paramCount = (
|
|
50415
|
-
if (/\*$/.test(
|
|
50416
|
-
const re = buildWildcardRegExp(
|
|
50452
|
+
const paramCount = (path21.match(/\/:/g) || []).length;
|
|
50453
|
+
if (/\*$/.test(path21)) {
|
|
50454
|
+
const re = buildWildcardRegExp(path21);
|
|
50417
50455
|
if (method === METHOD_NAME_ALL) {
|
|
50418
50456
|
Object.keys(middleware).forEach((m) => {
|
|
50419
|
-
middleware[m][
|
|
50457
|
+
middleware[m][path21] ||= findMiddleware(middleware[m], path21) || findMiddleware(middleware[METHOD_NAME_ALL], path21) || [];
|
|
50420
50458
|
});
|
|
50421
50459
|
} else {
|
|
50422
|
-
middleware[method][
|
|
50460
|
+
middleware[method][path21] ||= findMiddleware(middleware[method], path21) || findMiddleware(middleware[METHOD_NAME_ALL], path21) || [];
|
|
50423
50461
|
}
|
|
50424
50462
|
Object.keys(middleware).forEach((m) => {
|
|
50425
50463
|
if (method === METHOD_NAME_ALL || method === m) {
|
|
@@ -50437,7 +50475,7 @@ var RegExpRouter = class {
|
|
|
50437
50475
|
});
|
|
50438
50476
|
return;
|
|
50439
50477
|
}
|
|
50440
|
-
const paths = checkOptionalParameter(
|
|
50478
|
+
const paths = checkOptionalParameter(path21) || [path21];
|
|
50441
50479
|
for (let i = 0, len = paths.length; i < len; i++) {
|
|
50442
50480
|
const path22 = paths[i];
|
|
50443
50481
|
Object.keys(routes).forEach((m) => {
|
|
@@ -50464,13 +50502,13 @@ var RegExpRouter = class {
|
|
|
50464
50502
|
const routes = [];
|
|
50465
50503
|
let hasOwnRoute = method === METHOD_NAME_ALL;
|
|
50466
50504
|
[this.#middleware, this.#routes].forEach((r) => {
|
|
50467
|
-
const ownRoute = r[method] ? Object.keys(r[method]).map((
|
|
50505
|
+
const ownRoute = r[method] ? Object.keys(r[method]).map((path21) => [path21, r[method][path21]]) : [];
|
|
50468
50506
|
if (ownRoute.length !== 0) {
|
|
50469
50507
|
hasOwnRoute ||= true;
|
|
50470
50508
|
routes.push(...ownRoute);
|
|
50471
50509
|
} else if (method !== METHOD_NAME_ALL) {
|
|
50472
50510
|
routes.push(
|
|
50473
|
-
...Object.keys(r[METHOD_NAME_ALL]).map((
|
|
50511
|
+
...Object.keys(r[METHOD_NAME_ALL]).map((path21) => [path21, r[METHOD_NAME_ALL][path21]])
|
|
50474
50512
|
);
|
|
50475
50513
|
}
|
|
50476
50514
|
});
|
|
@@ -50490,13 +50528,13 @@ var SmartRouter = class {
|
|
|
50490
50528
|
constructor(init) {
|
|
50491
50529
|
this.#routers = init.routers;
|
|
50492
50530
|
}
|
|
50493
|
-
add(method,
|
|
50531
|
+
add(method, path21, handler) {
|
|
50494
50532
|
if (!this.#routes) {
|
|
50495
50533
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
50496
50534
|
}
|
|
50497
|
-
this.#routes.push([method,
|
|
50535
|
+
this.#routes.push([method, path21, handler]);
|
|
50498
50536
|
}
|
|
50499
|
-
match(method,
|
|
50537
|
+
match(method, path21) {
|
|
50500
50538
|
if (!this.#routes) {
|
|
50501
50539
|
throw new Error("Fatal error");
|
|
50502
50540
|
}
|
|
@@ -50511,7 +50549,7 @@ var SmartRouter = class {
|
|
|
50511
50549
|
for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
|
|
50512
50550
|
router.add(...routes[i2]);
|
|
50513
50551
|
}
|
|
50514
|
-
res = router.match(method,
|
|
50552
|
+
res = router.match(method, path21);
|
|
50515
50553
|
} catch (e) {
|
|
50516
50554
|
if (e instanceof UnsupportedPathError) {
|
|
50517
50555
|
continue;
|
|
@@ -50561,10 +50599,10 @@ var Node2 = class _Node2 {
|
|
|
50561
50599
|
}
|
|
50562
50600
|
this.#patterns = [];
|
|
50563
50601
|
}
|
|
50564
|
-
insert(method,
|
|
50602
|
+
insert(method, path21, handler) {
|
|
50565
50603
|
this.#order = ++this.#order;
|
|
50566
50604
|
let curNode = this;
|
|
50567
|
-
const parts = splitRoutingPath(
|
|
50605
|
+
const parts = splitRoutingPath(path21);
|
|
50568
50606
|
const possibleKeys = [];
|
|
50569
50607
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
50570
50608
|
const p = parts[i];
|
|
@@ -50613,12 +50651,12 @@ var Node2 = class _Node2 {
|
|
|
50613
50651
|
}
|
|
50614
50652
|
}
|
|
50615
50653
|
}
|
|
50616
|
-
search(method,
|
|
50654
|
+
search(method, path21) {
|
|
50617
50655
|
const handlerSets = [];
|
|
50618
50656
|
this.#params = emptyParams;
|
|
50619
50657
|
const curNode = this;
|
|
50620
50658
|
let curNodes = [curNode];
|
|
50621
|
-
const parts = splitPath(
|
|
50659
|
+
const parts = splitPath(path21);
|
|
50622
50660
|
const curNodesQueue = [];
|
|
50623
50661
|
const len = parts.length;
|
|
50624
50662
|
let partOffsets = null;
|
|
@@ -50660,13 +50698,13 @@ var Node2 = class _Node2 {
|
|
|
50660
50698
|
if (matcher instanceof RegExp) {
|
|
50661
50699
|
if (partOffsets === null) {
|
|
50662
50700
|
partOffsets = new Array(len);
|
|
50663
|
-
let offset =
|
|
50701
|
+
let offset = path21[0] === "/" ? 1 : 0;
|
|
50664
50702
|
for (let p = 0; p < len; p++) {
|
|
50665
50703
|
partOffsets[p] = offset;
|
|
50666
50704
|
offset += parts[p].length + 1;
|
|
50667
50705
|
}
|
|
50668
50706
|
}
|
|
50669
|
-
const restPathString =
|
|
50707
|
+
const restPathString = path21.substring(partOffsets[i]);
|
|
50670
50708
|
const m = matcher.exec(restPathString);
|
|
50671
50709
|
if (m) {
|
|
50672
50710
|
params[name] = m[0];
|
|
@@ -50719,18 +50757,18 @@ var TrieRouter = class {
|
|
|
50719
50757
|
constructor() {
|
|
50720
50758
|
this.#node = new Node2();
|
|
50721
50759
|
}
|
|
50722
|
-
add(method,
|
|
50723
|
-
const results = checkOptionalParameter(
|
|
50760
|
+
add(method, path21, handler) {
|
|
50761
|
+
const results = checkOptionalParameter(path21);
|
|
50724
50762
|
if (results) {
|
|
50725
50763
|
for (let i = 0, len = results.length; i < len; i++) {
|
|
50726
50764
|
this.#node.insert(method, results[i], handler);
|
|
50727
50765
|
}
|
|
50728
50766
|
return;
|
|
50729
50767
|
}
|
|
50730
|
-
this.#node.insert(method,
|
|
50768
|
+
this.#node.insert(method, path21, handler);
|
|
50731
50769
|
}
|
|
50732
|
-
match(method,
|
|
50733
|
-
return this.#node.search(method,
|
|
50770
|
+
match(method, path21) {
|
|
50771
|
+
return this.#node.search(method, path21);
|
|
50734
50772
|
}
|
|
50735
50773
|
};
|
|
50736
50774
|
|
|
@@ -51432,10 +51470,10 @@ var createStreamBody = (stream) => {
|
|
|
51432
51470
|
});
|
|
51433
51471
|
return body;
|
|
51434
51472
|
};
|
|
51435
|
-
var getStats = (
|
|
51473
|
+
var getStats = (path21) => {
|
|
51436
51474
|
let stats;
|
|
51437
51475
|
try {
|
|
51438
|
-
stats = (0, import_fs15.statSync)(
|
|
51476
|
+
stats = (0, import_fs15.statSync)(path21);
|
|
51439
51477
|
} catch {
|
|
51440
51478
|
}
|
|
51441
51479
|
return stats;
|
|
@@ -51478,21 +51516,21 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
51478
51516
|
return next();
|
|
51479
51517
|
}
|
|
51480
51518
|
}
|
|
51481
|
-
let
|
|
51519
|
+
let path21 = (0, import_path19.join)(
|
|
51482
51520
|
root,
|
|
51483
51521
|
!optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename
|
|
51484
51522
|
);
|
|
51485
|
-
let stats = getStats(
|
|
51523
|
+
let stats = getStats(path21);
|
|
51486
51524
|
if (stats && stats.isDirectory()) {
|
|
51487
51525
|
const indexFile = options.index ?? "index.html";
|
|
51488
|
-
|
|
51489
|
-
stats = getStats(
|
|
51526
|
+
path21 = (0, import_path19.join)(path21, indexFile);
|
|
51527
|
+
stats = getStats(path21);
|
|
51490
51528
|
}
|
|
51491
51529
|
if (!stats) {
|
|
51492
|
-
await options.onNotFound?.(
|
|
51530
|
+
await options.onNotFound?.(path21, c);
|
|
51493
51531
|
return next();
|
|
51494
51532
|
}
|
|
51495
|
-
const mimeType = getMimeType(
|
|
51533
|
+
const mimeType = getMimeType(path21);
|
|
51496
51534
|
c.header("Content-Type", mimeType || "application/octet-stream");
|
|
51497
51535
|
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
51498
51536
|
const acceptEncodingSet = new Set(
|
|
@@ -51502,12 +51540,12 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
51502
51540
|
if (!acceptEncodingSet.has(encoding)) {
|
|
51503
51541
|
continue;
|
|
51504
51542
|
}
|
|
51505
|
-
const precompressedStats = getStats(
|
|
51543
|
+
const precompressedStats = getStats(path21 + ENCODINGS[encoding]);
|
|
51506
51544
|
if (precompressedStats) {
|
|
51507
51545
|
c.header("Content-Encoding", encoding);
|
|
51508
51546
|
c.header("Vary", "Accept-Encoding", { append: true });
|
|
51509
51547
|
stats = precompressedStats;
|
|
51510
|
-
|
|
51548
|
+
path21 = path21 + ENCODINGS[encoding];
|
|
51511
51549
|
break;
|
|
51512
51550
|
}
|
|
51513
51551
|
}
|
|
@@ -51521,7 +51559,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
51521
51559
|
result = c.body(null);
|
|
51522
51560
|
} else if (!range) {
|
|
51523
51561
|
c.header("Content-Length", size.toString());
|
|
51524
|
-
result = c.body(createStreamBody((0, import_fs15.createReadStream)(
|
|
51562
|
+
result = c.body(createStreamBody((0, import_fs15.createReadStream)(path21)), 200);
|
|
51525
51563
|
} else {
|
|
51526
51564
|
c.header("Accept-Ranges", "bytes");
|
|
51527
51565
|
c.header("Date", stats.birthtime.toUTCString());
|
|
@@ -51532,12 +51570,12 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
51532
51570
|
end = size - 1;
|
|
51533
51571
|
}
|
|
51534
51572
|
const chunksize = end - start + 1;
|
|
51535
|
-
const stream = (0, import_fs15.createReadStream)(
|
|
51573
|
+
const stream = (0, import_fs15.createReadStream)(path21, { start, end });
|
|
51536
51574
|
c.header("Content-Length", chunksize.toString());
|
|
51537
51575
|
c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
|
|
51538
51576
|
result = c.body(createStreamBody(stream), 206);
|
|
51539
51577
|
}
|
|
51540
|
-
await options.onFound?.(
|
|
51578
|
+
await options.onFound?.(path21, c);
|
|
51541
51579
|
return result;
|
|
51542
51580
|
};
|
|
51543
51581
|
};
|
|
@@ -51632,7 +51670,7 @@ var cors = (options) => {
|
|
|
51632
51670
|
|
|
51633
51671
|
// src/server/index.ts
|
|
51634
51672
|
var import_promises13 = require("node:fs/promises");
|
|
51635
|
-
var
|
|
51673
|
+
var import_node_path18 = __toESM(require("node:path"));
|
|
51636
51674
|
|
|
51637
51675
|
// src/git/worktree.ts
|
|
51638
51676
|
var import_child_process2 = require("child_process");
|
|
@@ -53537,7 +53575,25 @@ ${item.dreamContent}` : item.dreamContent).join("\n\n");
|
|
|
53537
53575
|
});
|
|
53538
53576
|
|
|
53539
53577
|
// src/server/routes/tools.ts
|
|
53578
|
+
var import_node_path16 = __toESM(require("node:path"));
|
|
53540
53579
|
var toolRoutes = new Hono2();
|
|
53580
|
+
var listActiveDepartmentSkills = () => {
|
|
53581
|
+
return listDepartments().flatMap(
|
|
53582
|
+
(department) => listDepartmentSkills(department.name).filter((skill) => skill.status === "active").map((skill) => ({
|
|
53583
|
+
name: skill.skillName,
|
|
53584
|
+
description: skill.description,
|
|
53585
|
+
deletable: false,
|
|
53586
|
+
scope: "department",
|
|
53587
|
+
departmentName: department.name,
|
|
53588
|
+
detail: () => {
|
|
53589
|
+
const skillDir = import_node_path16.default.join(getDepartmentWorkSpaceDir(department.name), "skills", skill.skillName);
|
|
53590
|
+
return `Base directory for this skill: ${skillDir}
|
|
53591
|
+
|
|
53592
|
+
${skill.skillMd}`;
|
|
53593
|
+
}
|
|
53594
|
+
}))
|
|
53595
|
+
);
|
|
53596
|
+
};
|
|
53541
53597
|
toolRoutes.get("/tools", (c) => {
|
|
53542
53598
|
try {
|
|
53543
53599
|
const { registry: registry2 } = createDefaultTools();
|
|
@@ -53554,20 +53610,40 @@ toolRoutes.get("/tools", (c) => {
|
|
|
53554
53610
|
toolRoutes.get("/skills", (c) => {
|
|
53555
53611
|
try {
|
|
53556
53612
|
const skills = SkillRegistry_default();
|
|
53557
|
-
|
|
53613
|
+
const departmentSkills = listActiveDepartmentSkills();
|
|
53614
|
+
return c.json([...skills.map((s) => ({
|
|
53558
53615
|
name: s.name,
|
|
53559
53616
|
description: s.description,
|
|
53560
53617
|
deletable: !!s.deletable,
|
|
53561
53618
|
scope: s.scope ?? (s.deletable ? "project" : "global"),
|
|
53562
53619
|
departmentName: s.departmentName
|
|
53563
|
-
})))
|
|
53620
|
+
})), ...departmentSkills.map((s) => ({
|
|
53621
|
+
name: s.name,
|
|
53622
|
+
description: s.description,
|
|
53623
|
+
deletable: s.deletable,
|
|
53624
|
+
scope: s.scope,
|
|
53625
|
+
departmentName: s.departmentName
|
|
53626
|
+
}))]);
|
|
53564
53627
|
} catch (err) {
|
|
53565
53628
|
return c.json({ error: err.message || "Failed to list skills" }, 500);
|
|
53566
53629
|
}
|
|
53567
53630
|
});
|
|
53568
53631
|
toolRoutes.get("/skills/:name", (c) => {
|
|
53569
53632
|
const name = c.req.param("name");
|
|
53633
|
+
const departmentName = c.req.query("departmentName");
|
|
53570
53634
|
try {
|
|
53635
|
+
if (departmentName) {
|
|
53636
|
+
const skill2 = listActiveDepartmentSkills().find((s) => s.name === name && s.departmentName === departmentName);
|
|
53637
|
+
if (!skill2) return c.json({ error: "Skill not found" }, 404);
|
|
53638
|
+
return c.json({
|
|
53639
|
+
name: skill2.name,
|
|
53640
|
+
description: skill2.description,
|
|
53641
|
+
deletable: skill2.deletable,
|
|
53642
|
+
scope: skill2.scope,
|
|
53643
|
+
departmentName: skill2.departmentName,
|
|
53644
|
+
detail: skill2.detail()
|
|
53645
|
+
});
|
|
53646
|
+
}
|
|
53571
53647
|
const skills = SkillRegistry_default();
|
|
53572
53648
|
const skill = skills.find((s) => s.name === name);
|
|
53573
53649
|
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
@@ -53599,7 +53675,7 @@ var systemRoutes = new Hono2();
|
|
|
53599
53675
|
var startTime = Date.now();
|
|
53600
53676
|
systemRoutes.get("/system/info", (c) => {
|
|
53601
53677
|
return c.json({
|
|
53602
|
-
version: true ? "1.9.
|
|
53678
|
+
version: true ? "1.9.11" : "unknown",
|
|
53603
53679
|
uptime: Math.floor((Date.now() - startTime) / 1e3),
|
|
53604
53680
|
env: process.env.NODE_ENV || "development",
|
|
53605
53681
|
nodeVersion: process.version
|
|
@@ -53609,7 +53685,7 @@ systemRoutes.get("/system/info", (c) => {
|
|
|
53609
53685
|
// src/server/routes/mobile.ts
|
|
53610
53686
|
var import_node_crypto16 = require("node:crypto");
|
|
53611
53687
|
var import_promises12 = require("node:fs/promises");
|
|
53612
|
-
var
|
|
53688
|
+
var import_node_path17 = __toESM(require("node:path"));
|
|
53613
53689
|
var mobileRoutes = new Hono2();
|
|
53614
53690
|
var resolveMobileUserId = (body, headerUserId) => {
|
|
53615
53691
|
return body.userId?.trim() || headerUserId?.trim() || "ios:local-user";
|
|
@@ -53651,12 +53727,12 @@ ${goal.tasks.map((task) => `- [${task.status}] ${task.subject}`).join("\n")}` :
|
|
|
53651
53727
|
return lines.join("\n");
|
|
53652
53728
|
};
|
|
53653
53729
|
var sanitizeFileName = (fileName) => {
|
|
53654
|
-
const cleaned =
|
|
53730
|
+
const cleaned = import_node_path17.default.basename(fileName).replace(/[^\w.\-()\u4e00-\u9fa5 ]+/g, "_").trim();
|
|
53655
53731
|
return cleaned || `attachment-${Date.now()}`;
|
|
53656
53732
|
};
|
|
53657
53733
|
var inferAttachmentType2 = (mimeType = "", fileName = "") => {
|
|
53658
53734
|
if (mimeType.startsWith("image/")) return "image";
|
|
53659
|
-
const ext =
|
|
53735
|
+
const ext = import_node_path17.default.extname(fileName).toLowerCase();
|
|
53660
53736
|
if ([".png", ".jpg", ".jpeg", ".gif", ".webp"].includes(ext)) return "image";
|
|
53661
53737
|
return "file";
|
|
53662
53738
|
};
|
|
@@ -53713,9 +53789,9 @@ mobileRoutes.post("/mobile/attachments", async (c) => {
|
|
|
53713
53789
|
const type = inferAttachmentType2(mimeType, fileName);
|
|
53714
53790
|
const attachmentId = (0, import_node_crypto16.randomUUID)();
|
|
53715
53791
|
const buffer = Buffer.from(dataBase64, "base64");
|
|
53716
|
-
const dir =
|
|
53792
|
+
const dir = import_node_path17.default.join(getDuclawWorkspaceDir(), mobileUserId, "mobile", type === "image" ? "images" : "files");
|
|
53717
53793
|
await (0, import_promises12.mkdir)(dir, { recursive: true });
|
|
53718
|
-
const localPath =
|
|
53794
|
+
const localPath = import_node_path17.default.join(dir, `${attachmentId}-${fileName}`);
|
|
53719
53795
|
await (0, import_promises12.writeFile)(localPath, buffer);
|
|
53720
53796
|
const attachment = saveMobileAttachment({
|
|
53721
53797
|
id: attachmentId,
|
|
@@ -53934,7 +54010,7 @@ function createServer() {
|
|
|
53934
54010
|
app.route("/api", mobileRoutes);
|
|
53935
54011
|
app.use("/*", serveStatic({ root: webDistRoot }));
|
|
53936
54012
|
app.get("/*", async (c) => {
|
|
53937
|
-
const indexHtml = await (0, import_promises13.readFile)(
|
|
54013
|
+
const indexHtml = await (0, import_promises13.readFile)(import_node_path18.default.join(webDistRoot, "index.html"), "utf8");
|
|
53938
54014
|
const tenantId = c.req.header("x-tenant-id");
|
|
53939
54015
|
const assetBase = tenantId ? `/t/${tenantId}` : "";
|
|
53940
54016
|
const html = indexHtml.replaceAll('"./', `"${assetBase}/`);
|
|
@@ -53964,7 +54040,7 @@ function shouldStartCoreChannelGateways(env = process.env) {
|
|
|
53964
54040
|
var import_node_fs9 = require("node:fs");
|
|
53965
54041
|
var import_promises14 = require("node:fs/promises");
|
|
53966
54042
|
var import_node_os3 = require("node:os");
|
|
53967
|
-
var
|
|
54043
|
+
var import_node_path19 = __toESM(require("node:path"));
|
|
53968
54044
|
var MAX_CONTEXT_ASSETS = Number(process.env.DUCLAW_SAAS_ASSET_CONTEXT_LIMIT ?? 1e3);
|
|
53969
54045
|
var MAX_SKILL_ASSETS = Number(process.env.DUCLAW_SAAS_ASSET_SKILL_LIMIT ?? 200);
|
|
53970
54046
|
async function restoreSaasRuntimeAssets(reason) {
|
|
@@ -53995,7 +54071,7 @@ async function restoreContextAsset(context, overwrite) {
|
|
|
53995
54071
|
const target = contextPathForSourceKey(context.sourceKey);
|
|
53996
54072
|
if (!target) return false;
|
|
53997
54073
|
if (!overwrite && (0, import_node_fs9.existsSync)(target)) return false;
|
|
53998
|
-
await (0, import_promises14.mkdir)(
|
|
54074
|
+
await (0, import_promises14.mkdir)(import_node_path19.default.dirname(target), { recursive: true });
|
|
53999
54075
|
await (0, import_promises14.writeFile)(target, JSON.stringify(context.payload), "utf8");
|
|
54000
54076
|
return true;
|
|
54001
54077
|
}
|
|
@@ -54004,7 +54080,7 @@ async function restoreSkillAsset(skill, overwrite) {
|
|
|
54004
54080
|
const target = safeSkillTargetPath(skill.sourcePath, skill.skillName);
|
|
54005
54081
|
if (!target) return false;
|
|
54006
54082
|
if (!overwrite && (0, import_node_fs9.existsSync)(target)) return false;
|
|
54007
|
-
await (0, import_promises14.mkdir)(
|
|
54083
|
+
await (0, import_promises14.mkdir)(import_node_path19.default.dirname(target), { recursive: true });
|
|
54008
54084
|
await (0, import_promises14.writeFile)(target, skill.skillMd, "utf8");
|
|
54009
54085
|
return true;
|
|
54010
54086
|
}
|
|
@@ -54037,30 +54113,30 @@ function runtimeAssetClient() {
|
|
|
54037
54113
|
function contextPathForSourceKey(sourceKey) {
|
|
54038
54114
|
if (sourceKey.startsWith("agent:")) {
|
|
54039
54115
|
const logicalKey = sourceKey.slice("agent:".length);
|
|
54040
|
-
return
|
|
54116
|
+
return import_node_path19.default.join(getDuclawDataDir(), "kv", "agent", `${Buffer.from(logicalKey).toString("base64url")}.json`);
|
|
54041
54117
|
}
|
|
54042
54118
|
if (sourceKey.startsWith("goal-context:")) {
|
|
54043
|
-
return
|
|
54119
|
+
return import_node_path19.default.join(getDuclawHomeDir(), "goal-context", `${sourceKey.slice("goal-context:".length)}.json`);
|
|
54044
54120
|
}
|
|
54045
54121
|
if (sourceKey.startsWith("tasks:")) {
|
|
54046
|
-
return
|
|
54122
|
+
return import_node_path19.default.join(getDuclawHomeDir(), "tasks", `${sourceKey.slice("tasks:".length)}.json`);
|
|
54047
54123
|
}
|
|
54048
54124
|
return null;
|
|
54049
54125
|
}
|
|
54050
54126
|
function safeSkillTargetPath(sourcePath, skillName) {
|
|
54051
|
-
const allowedRoots = skillRoots().map((root) =>
|
|
54052
|
-
const normalized =
|
|
54053
|
-
if (allowedRoots.some((root) => normalized ===
|
|
54127
|
+
const allowedRoots = skillRoots().map((root) => import_node_path19.default.resolve(root));
|
|
54128
|
+
const normalized = import_node_path19.default.resolve(sourcePath);
|
|
54129
|
+
if (allowedRoots.some((root) => normalized === import_node_path19.default.join(root, import_node_path19.default.basename(import_node_path19.default.dirname(normalized)), "SKILL.md"))) {
|
|
54054
54130
|
return normalized;
|
|
54055
54131
|
}
|
|
54056
54132
|
const safeName = skillName.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 120) || "imported-skill";
|
|
54057
|
-
return
|
|
54133
|
+
return import_node_path19.default.join("/home/user/app/skills", safeName, "SKILL.md");
|
|
54058
54134
|
}
|
|
54059
54135
|
function skillRoots() {
|
|
54060
54136
|
return [
|
|
54061
54137
|
"/home/user/app/skills",
|
|
54062
|
-
|
|
54063
|
-
|
|
54138
|
+
import_node_path19.default.join(getDuclawHomeDir(), "skills"),
|
|
54139
|
+
import_node_path19.default.join((0, import_node_os3.homedir)(), ".agents", "skills")
|
|
54064
54140
|
];
|
|
54065
54141
|
}
|
|
54066
54142
|
|