nolo-cli 0.86.0-alpha.1 → 0.87.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{_executeModel-U5FP7ID5.js → _executeModel-TTE5HHOP.js} +11 -11
- package/{agentDeleteCommand-RXZKN7ER.js → agentDeleteCommand-XW2NHDTK.js} +1 -1
- package/{agentEmailCommands-AKELGSE2.js → agentEmailCommands-UI6XIGG7.js} +11 -11
- package/{agentListCommands-ZN75E4YI.js → agentListCommands-3S6LZKWI.js} +1 -1
- package/{agentMachineCommands-UTTHPDUV.js → agentMachineCommands-XUDFW32H.js} +2 -2
- package/{agentRecordCommands-WYII53FP.js → agentRecordCommands-HGTP6T5A.js} +11 -11
- package/{agentRunCommand-NTQPGV6P.js → agentRunCommand-IFXPSZQT.js} +11 -11
- package/{agentRuntimeLocal-CNL444G4.js → agentRuntimeLocal-2W4KJIZE.js} +1 -1
- package/{agentSlice-PZGUYP2L.js → agentSlice-B5JSZNGT.js} +1 -1
- package/{appDeleteCommands-BL4RWG3T.js → appDeleteCommands-NTG4P4DI.js} +1 -1
- package/{appDeployCommands-6OS3RR66.js → appDeployCommands-O7CEHFFG.js} +1 -1
- package/{appDeployStatusCommands-WQFLFSO3.js → appDeployStatusCommands-7OKGI4WA.js} +1 -1
- package/{appGetCommands-FH4CIOJO.js → appGetCommands-F6IO3UMX.js} +1 -1
- package/{appListCommands-Z6XJPYJJ.js → appListCommands-WNGR3Z4G.js} +1 -1
- package/{builtinSkillRegistry-XIXK4XAH.js → builtinSkillRegistry-H3VTDPXU.js} +1 -1
- package/{chatQueueReduxAdapter-SXZ22NDJ.js → chatQueueReduxAdapter-34C6QPMS.js} +2 -2
- package/{chunk-UAWA257T.js → chunk-36VG7O3H.js} +1 -1
- package/{chunk-ICEIW3RB.js → chunk-5S7Q2W6J.js} +2 -2
- package/{chunk-RESMIGAE.js → chunk-6SP2OTHH.js} +6 -6
- package/{chunk-OUYDHPVR.js → chunk-7UQEDGCB.js} +2 -2
- package/{chunk-VIIH2BQP.js → chunk-B3RYNS4I.js} +1 -1
- package/{chunk-GYLJXJ32.js → chunk-BS4DOHEI.js} +3 -3
- package/{chunk-EUHAT445.js → chunk-C3OIYB5O.js} +40 -13
- package/{chunk-BGNHBBI3.js → chunk-C5GYGTUD.js} +4 -4
- package/{chunk-CYSCZQLE.js → chunk-DAWALEPB.js} +2 -2
- package/{chunk-FU3RL7UF.js → chunk-DUXL23YX.js} +128 -17
- package/{chunk-QSDL5Y3K.js → chunk-GNWFC7YT.js} +176 -0
- package/{chunk-TNBEPOJR.js → chunk-IVWFJGEB.js} +12 -10
- package/{chunk-I635TS34.js → chunk-MYYHP5MC.js} +3 -3
- package/{chunk-CWYE43DU.js → chunk-PDPKCLOQ.js} +1 -1
- package/{chunk-I7ZJJVGO.js → chunk-SDDLKP4V.js} +8 -8
- package/{chunk-RZKX733Z.js → chunk-UVSMQBOV.js} +5 -5
- package/{contentThunks-2GNOEECN.js → contentThunks-65VJVF3F.js} +3 -3
- package/{createAgentAutomationAction-3MR5BSTK.js → createAgentAutomationAction-F6TR5V5Z.js} +3 -3
- package/{createDialogAction-E3PALMYX.js → createDialogAction-4PSBOUVA.js} +4 -4
- package/{createPageAction-R2AXAUJK.js → createPageAction-BHEWWPJK.js} +3 -3
- package/{dialogCommands-AAUWSOLU.js → dialogCommands-NL2LL3HN.js} +1 -1
- package/{dialogSlice-CYGOKMXJ.js → dialogSlice-MSNQGQ7M.js} +2 -2
- package/{docCreateCommands-YLDVSLRZ.js → docCreateCommands-TSB6IGNK.js} +1 -1
- package/{docDeleteCommands-3ISHZAEV.js → docDeleteCommands-G7NU7ZDJ.js} +1 -1
- package/{docReadCommands-5COAVOO3.js → docReadCommands-UOBB3US4.js} +1 -1
- package/{docStore-5XXOJADS.js → docStore-32KUMVID.js} +1 -1
- package/{docUpdateCommands-Z2745NT3.js → docUpdateCommands-UWGB4IB7.js} +1 -1
- package/{handleSendMessageAction-HFHRBK3J.js → handleSendMessageAction-JV45R62M.js} +2 -2
- package/index.js +40 -40
- package/{machineCommands-I5KWMVKV.js → machineCommands-KQ23PZ34.js} +11 -11
- package/{machineWsRunDispatch-3UQVJSGJ.js → machineWsRunDispatch-HHQAL54K.js} +11 -11
- package/package.json +1 -1
- package/{readlineWorkspace-DYVLZVQ3.js → readlineWorkspace-IRWDPRMD.js} +11 -11
- package/{runAgentClientLoop-LJBICEE5.js → runAgentClientLoop-V4ZIQNZV.js} +9 -9
- package/{spaceCommands-T2OFTOSA.js → spaceCommands-AYINXM2I.js} +1 -1
- package/{streamAgentChatTurn-GDWIAY3S.js → streamAgentChatTurn-3SB6KVU7.js} +10 -10
- package/{tools-ECH3IW3E.js → tools-CX7EVHKL.js} +7 -7
- package/{updateDialogTitleAction-JOZXFR53.js → updateDialogTitleAction-5SZZXIIK.js} +3 -3
|
@@ -19379,7 +19379,7 @@ function buildLoadSkillExecutor(args2) {
|
|
|
19379
19379
|
const { resolveSkillByName } = await import("./skillDiscovery-CYUCJMAG.js");
|
|
19380
19380
|
const resolved = resolveSkillByName(args2.cwd, name);
|
|
19381
19381
|
if (!resolved) {
|
|
19382
|
-
const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-
|
|
19382
|
+
const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-H3VTDPXU.js");
|
|
19383
19383
|
const builtin = resolveBuiltinSkillByName(name);
|
|
19384
19384
|
if (builtin) {
|
|
19385
19385
|
return {
|
|
@@ -20227,11 +20227,33 @@ function encodeDevinClientMetadata(token) {
|
|
|
20227
20227
|
]);
|
|
20228
20228
|
}
|
|
20229
20229
|
function encodeDevinChatMessage(msg) {
|
|
20230
|
-
const source = msg.role === "assistant" ? 2 : 1;
|
|
20230
|
+
const source = msg.role === "assistant" ? 2 : msg.role === "tool" ? 4 : 1;
|
|
20231
20231
|
return Buffer.concat([
|
|
20232
20232
|
writeStringField(1, randomUUID2()),
|
|
20233
20233
|
writeVarint(2, source),
|
|
20234
|
-
writeStringField(3, msg.text)
|
|
20234
|
+
writeStringField(3, msg.text),
|
|
20235
|
+
...(msg.toolCalls ?? []).map(
|
|
20236
|
+
(toolCall) => writeMessageField(
|
|
20237
|
+
6,
|
|
20238
|
+
Buffer.concat([
|
|
20239
|
+
writeStringField(1, toolCall.id),
|
|
20240
|
+
writeStringField(2, toolCall.function.name),
|
|
20241
|
+
writeStringField(3, toolCall.function.arguments)
|
|
20242
|
+
])
|
|
20243
|
+
)
|
|
20244
|
+
),
|
|
20245
|
+
...msg.toolCallId ? [writeStringField(7, msg.toolCallId)] : []
|
|
20246
|
+
]);
|
|
20247
|
+
}
|
|
20248
|
+
function encodeDevinToolDefinition(tool) {
|
|
20249
|
+
const fn3 = tool.function ?? {};
|
|
20250
|
+
const name = typeof fn3.name === "string" ? fn3.name : "";
|
|
20251
|
+
const description = typeof fn3.description === "string" ? fn3.description : "";
|
|
20252
|
+
const parameters = fn3.parameters ?? {};
|
|
20253
|
+
return Buffer.concat([
|
|
20254
|
+
writeStringField(1, name),
|
|
20255
|
+
writeStringField(2, description.length > 6998 ? `${description.slice(0, 6995)}...` : description),
|
|
20256
|
+
writeStringField(3, JSON.stringify(parameters))
|
|
20235
20257
|
]);
|
|
20236
20258
|
}
|
|
20237
20259
|
function writeFixed64Field(fieldNum, val) {
|
|
@@ -20248,20 +20270,21 @@ function writeFixed64Field(fieldNum, val) {
|
|
|
20248
20270
|
return Buffer.concat([Buffer.from(tagBytes), b]);
|
|
20249
20271
|
}
|
|
20250
20272
|
function buildCompletionConfig(params) {
|
|
20251
|
-
const maxTokens = params?.maxTokens ??
|
|
20273
|
+
const maxTokens = params?.maxTokens ?? 128e3;
|
|
20274
|
+
const maxNewlines = params?.maxNewlines ?? 400;
|
|
20252
20275
|
const temp = params?.temperature ?? 0.4;
|
|
20253
20276
|
const topP = params?.topP ?? 0.95;
|
|
20254
20277
|
return Buffer.concat([
|
|
20255
20278
|
writeVarint(1, 1),
|
|
20256
20279
|
writeVarint(2, maxTokens),
|
|
20257
|
-
writeVarint(3,
|
|
20280
|
+
writeVarint(3, maxNewlines),
|
|
20258
20281
|
writeFixed64Field(5, temp),
|
|
20259
20282
|
writeVarint(7, 40),
|
|
20260
20283
|
writeFixed64Field(8, topP)
|
|
20261
20284
|
]);
|
|
20262
20285
|
}
|
|
20263
20286
|
function buildGetChatMessageRequest(params) {
|
|
20264
|
-
const { token, messages, model } = params;
|
|
20287
|
+
const { token, messages, model, tools = [], temperature } = params;
|
|
20265
20288
|
const metadata = encodeDevinClientMetadata(token);
|
|
20266
20289
|
let systemPrompt = "";
|
|
20267
20290
|
const filteredMessages = [];
|
|
@@ -20271,14 +20294,19 @@ function buildGetChatMessageRequest(params) {
|
|
|
20271
20294
|
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
20272
20295
|
|
|
20273
20296
|
${text}` : text;
|
|
20274
|
-
} else if (m.role === "user" || m.role === "assistant") {
|
|
20275
|
-
filteredMessages.push({
|
|
20297
|
+
} else if (m.role === "user" || m.role === "assistant" || m.role === "tool") {
|
|
20298
|
+
filteredMessages.push({
|
|
20299
|
+
role: m.role,
|
|
20300
|
+
text,
|
|
20301
|
+
...m.tool_call_id ? { toolCallId: m.tool_call_id } : {},
|
|
20302
|
+
...m.tool_calls?.length ? { toolCalls: m.tool_calls } : {}
|
|
20303
|
+
});
|
|
20276
20304
|
}
|
|
20277
20305
|
}
|
|
20278
20306
|
const coalesced = [];
|
|
20279
20307
|
for (const item of filteredMessages) {
|
|
20280
20308
|
const last = coalesced[coalesced.length - 1];
|
|
20281
|
-
if (last && last.role === item.role) {
|
|
20309
|
+
if (last && last.role === item.role && item.role !== "tool" && !last.toolCalls?.length && !item.toolCalls?.length) {
|
|
20282
20310
|
last.text = `${last.text}
|
|
20283
20311
|
|
|
20284
20312
|
${item.text}`;
|
|
@@ -20287,7 +20315,7 @@ ${item.text}`;
|
|
|
20287
20315
|
}
|
|
20288
20316
|
}
|
|
20289
20317
|
const chatMessageBuffers = coalesced.map((m) => encodeDevinChatMessage(m));
|
|
20290
|
-
const completionConfig = buildCompletionConfig();
|
|
20318
|
+
const completionConfig = buildCompletionConfig({ temperature });
|
|
20291
20319
|
const modelConfig = Buffer.concat([
|
|
20292
20320
|
writeStringField(1, randomUUID2()),
|
|
20293
20321
|
writeVarint(2, 1),
|
|
@@ -20299,6 +20327,7 @@ ${item.text}`;
|
|
|
20299
20327
|
...chatMessageBuffers.map((b) => writeMessageField(3, b)),
|
|
20300
20328
|
writeVarint(7, 5),
|
|
20301
20329
|
writeMessageField(8, completionConfig),
|
|
20330
|
+
...tools.map((tool) => writeMessageField(10, encodeDevinToolDefinition(tool))),
|
|
20302
20331
|
writeMessageField(15, modelConfig),
|
|
20303
20332
|
writeStringField(16, randomUUID2()),
|
|
20304
20333
|
writeVarint(20, 1),
|
|
@@ -20371,7 +20400,7 @@ function decodeDevinResponsePayload(payload) {
|
|
|
20371
20400
|
s += 7;
|
|
20372
20401
|
}
|
|
20373
20402
|
if (fieldNum === 5) {
|
|
20374
|
-
finishReason = val ===
|
|
20403
|
+
finishReason = val === 10 ? "tool_calls" : val === 1 || val === 3 ? "length" : "stop";
|
|
20375
20404
|
}
|
|
20376
20405
|
} else if (wireType === 2) {
|
|
20377
20406
|
let len = 0;
|
|
@@ -20392,6 +20421,44 @@ function decodeDevinResponsePayload(payload) {
|
|
|
20392
20421
|
const text = valBytes.toString("utf8");
|
|
20393
20422
|
reasoning += text;
|
|
20394
20423
|
events.push({ type: "reasoning", text });
|
|
20424
|
+
} else if (fieldNum === 6) {
|
|
20425
|
+
let nestedOffset = 0;
|
|
20426
|
+
let id;
|
|
20427
|
+
let name;
|
|
20428
|
+
let argsDelta;
|
|
20429
|
+
while (nestedOffset < valBytes.length) {
|
|
20430
|
+
let nestedTag = 0;
|
|
20431
|
+
let nestedShift = 0;
|
|
20432
|
+
while (nestedOffset < valBytes.length) {
|
|
20433
|
+
const b = valBytes[nestedOffset++];
|
|
20434
|
+
nestedTag |= (b & 127) << nestedShift;
|
|
20435
|
+
if (!(b & 128)) break;
|
|
20436
|
+
nestedShift += 7;
|
|
20437
|
+
}
|
|
20438
|
+
const nestedField = nestedTag >>> 3;
|
|
20439
|
+
const nestedWire = nestedTag & 7;
|
|
20440
|
+
if (nestedWire !== 2) break;
|
|
20441
|
+
let nestedLength = 0;
|
|
20442
|
+
let lengthShift = 0;
|
|
20443
|
+
while (nestedOffset < valBytes.length) {
|
|
20444
|
+
const b = valBytes[nestedOffset++];
|
|
20445
|
+
nestedLength |= (b & 127) << lengthShift;
|
|
20446
|
+
if (!(b & 128)) break;
|
|
20447
|
+
lengthShift += 7;
|
|
20448
|
+
}
|
|
20449
|
+
const nestedValue = valBytes.subarray(nestedOffset, nestedOffset + nestedLength);
|
|
20450
|
+
nestedOffset += nestedLength;
|
|
20451
|
+
const text = nestedValue.toString("utf8");
|
|
20452
|
+
if (nestedField === 1) id = text;
|
|
20453
|
+
else if (nestedField === 2) name = text;
|
|
20454
|
+
else if (nestedField === 3) argsDelta = (argsDelta ?? "") + text;
|
|
20455
|
+
}
|
|
20456
|
+
if (id !== void 0 && name !== void 0) {
|
|
20457
|
+
events.push({ type: "tool-call-start", id, name });
|
|
20458
|
+
}
|
|
20459
|
+
if (argsDelta !== void 0) {
|
|
20460
|
+
events.push({ type: "tool-call-args", argsDelta, ...id ? { id } : {} });
|
|
20461
|
+
}
|
|
20395
20462
|
}
|
|
20396
20463
|
} else {
|
|
20397
20464
|
break;
|
|
@@ -20400,7 +20467,7 @@ function decodeDevinResponsePayload(payload) {
|
|
|
20400
20467
|
return { content, reasoning, finishReason, events };
|
|
20401
20468
|
}
|
|
20402
20469
|
function createDevinProvider(options) {
|
|
20403
|
-
const { token, model = "swe-2", fetchImpl = fetch } = options;
|
|
20470
|
+
const { token, model = "swe-2", fetchImpl = fetch, tools = [], temperature } = options;
|
|
20404
20471
|
return {
|
|
20405
20472
|
model,
|
|
20406
20473
|
async complete(messages, opts) {
|
|
@@ -20408,7 +20475,9 @@ function createDevinProvider(options) {
|
|
|
20408
20475
|
const requestPayload = buildGetChatMessageRequest({
|
|
20409
20476
|
token,
|
|
20410
20477
|
messages,
|
|
20411
|
-
model: selectedModel
|
|
20478
|
+
model: selectedModel,
|
|
20479
|
+
tools,
|
|
20480
|
+
temperature
|
|
20412
20481
|
});
|
|
20413
20482
|
const frame = buildDevinConnectFrame(requestPayload);
|
|
20414
20483
|
const response = await fetchImpl(DEVIN_CONNECT_URL, {
|
|
@@ -20432,6 +20501,10 @@ function createDevinProvider(options) {
|
|
|
20432
20501
|
}
|
|
20433
20502
|
let text = "";
|
|
20434
20503
|
let reasoning = "";
|
|
20504
|
+
let finishReason = null;
|
|
20505
|
+
const toolCallOrder = [];
|
|
20506
|
+
const toolCallById = /* @__PURE__ */ new Map();
|
|
20507
|
+
let currentToolCallId = null;
|
|
20435
20508
|
let buffer3 = Buffer.alloc(0);
|
|
20436
20509
|
let sawTrailer = false;
|
|
20437
20510
|
const reader = response.body.getReader();
|
|
@@ -20455,11 +20528,29 @@ function createDevinProvider(options) {
|
|
|
20455
20528
|
const delta = decodeDevinResponsePayload(f.payload);
|
|
20456
20529
|
text += delta.content;
|
|
20457
20530
|
reasoning += delta.reasoning;
|
|
20531
|
+
if (delta.finishReason) finishReason = delta.finishReason;
|
|
20458
20532
|
for (const event of delta.events) {
|
|
20459
20533
|
if (event.type === "reasoning") {
|
|
20460
20534
|
opts?.onReasoningDelta?.(event.text);
|
|
20461
|
-
} else {
|
|
20535
|
+
} else if (event.type === "content") {
|
|
20462
20536
|
opts?.onTextDelta?.(event.text);
|
|
20537
|
+
} else if (event.type === "tool-call-start") {
|
|
20538
|
+
const existing = toolCallById.get(event.id);
|
|
20539
|
+
if (existing) {
|
|
20540
|
+
existing.name = event.name;
|
|
20541
|
+
} else {
|
|
20542
|
+
toolCallOrder.push(event.id);
|
|
20543
|
+
toolCallById.set(event.id, {
|
|
20544
|
+
id: event.id,
|
|
20545
|
+
name: event.name,
|
|
20546
|
+
argumentsText: ""
|
|
20547
|
+
});
|
|
20548
|
+
}
|
|
20549
|
+
currentToolCallId = event.id;
|
|
20550
|
+
} else {
|
|
20551
|
+
const targetId = event.id ?? currentToolCallId;
|
|
20552
|
+
const target = targetId ? toolCallById.get(targetId) : void 0;
|
|
20553
|
+
if (target) target.argumentsText += event.argsDelta;
|
|
20463
20554
|
}
|
|
20464
20555
|
}
|
|
20465
20556
|
}
|
|
@@ -20473,14 +20564,34 @@ function createDevinProvider(options) {
|
|
|
20473
20564
|
if (!sawTrailer) {
|
|
20474
20565
|
throw new Error("Devin Connect upstream ended before the terminal trailer");
|
|
20475
20566
|
}
|
|
20476
|
-
|
|
20477
|
-
|
|
20567
|
+
const toolCalls = toolCallOrder.map((id) => {
|
|
20568
|
+
const call = toolCallById.get(id);
|
|
20569
|
+
return {
|
|
20570
|
+
id: call.id,
|
|
20571
|
+
type: "function",
|
|
20572
|
+
function: {
|
|
20573
|
+
name: call.name,
|
|
20574
|
+
arguments: call.argumentsText || "{}"
|
|
20575
|
+
}
|
|
20576
|
+
};
|
|
20577
|
+
});
|
|
20578
|
+
if (!text && !reasoning && toolCalls.length === 0) {
|
|
20579
|
+
throw new Error("Devin Connect upstream completed without content or tool calls");
|
|
20478
20580
|
}
|
|
20479
20581
|
return {
|
|
20480
20582
|
content: text,
|
|
20481
20583
|
model: selectedModel,
|
|
20482
20584
|
provider: "devin",
|
|
20483
|
-
reasoning_content: reasoning
|
|
20585
|
+
...reasoning ? { reasoning_content: reasoning } : {},
|
|
20586
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {},
|
|
20587
|
+
// The upstream finish event wins whenever it is present. A tool call
|
|
20588
|
+
// cut off by the length limit has to stay "length" instead of being
|
|
20589
|
+
// relabelled "tool_calls", so probes/telemetry and any downstream
|
|
20590
|
+
// consumer of the final finish_reason no longer see a truncated turn
|
|
20591
|
+
// mislabelled as a normal one. localLoop keeps its own truncation
|
|
20592
|
+
// gates and excludes tool-bearing turns from them.
|
|
20593
|
+
finish_reason: finishReason ?? (toolCalls.length > 0 ? "tool_calls" : "stop"),
|
|
20594
|
+
stream_complete: true
|
|
20484
20595
|
};
|
|
20485
20596
|
}
|
|
20486
20597
|
};
|
|
@@ -1191,6 +1191,154 @@ function buildWorktreeSkillContentBySlug(slug) {
|
|
|
1191
1191
|
});
|
|
1192
1192
|
}
|
|
1193
1193
|
|
|
1194
|
+
// packages/ai/skills/systematicInvestigationSkill.ts
|
|
1195
|
+
var SYSTEMATIC_INVESTIGATION_SKILL_SLUGS = ["systematic-investigation"];
|
|
1196
|
+
function deterministicId7(prefix, seed) {
|
|
1197
|
+
let h = 2166136261;
|
|
1198
|
+
for (let i = 0; i < seed.length; i++) {
|
|
1199
|
+
h ^= seed.charCodeAt(i);
|
|
1200
|
+
h = h * 16777619 >>> 0;
|
|
1201
|
+
}
|
|
1202
|
+
const suffix = h.toString(36).toUpperCase().padStart(14, "0");
|
|
1203
|
+
return (prefix + suffix).slice(0, 26);
|
|
1204
|
+
}
|
|
1205
|
+
function normalizeSkillSeed7(input) {
|
|
1206
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1207
|
+
}
|
|
1208
|
+
function buildSystematicinvestigationSkillId(slug) {
|
|
1209
|
+
return deterministicId7("01SK", normalizeSkillSeed7(slug) || slug);
|
|
1210
|
+
}
|
|
1211
|
+
function buildSystematicinvestigationSkillPageKey(userId, slug) {
|
|
1212
|
+
return `page-${userId}-${buildSystematicinvestigationSkillId(slug)}`;
|
|
1213
|
+
}
|
|
1214
|
+
function buildSystematicinvestigationSkillConfig(slug) {
|
|
1215
|
+
return {
|
|
1216
|
+
version: "0.1",
|
|
1217
|
+
kind: "skill",
|
|
1218
|
+
id: buildSystematicinvestigationSkillId(slug),
|
|
1219
|
+
name: "\u7CFB\u7EDF\u5316\u6392\u67E5\uFF08systematic-investigation\uFF09",
|
|
1220
|
+
triggerMode: "recommended",
|
|
1221
|
+
description: "\u7CFB\u7EDF\u5316\u6392\u67E5\u7EAA\u5F8B\uFF1A\u5148\u6D4B\u91CF\u5B9A\u4F4D\u3001\u518D\u52A8\u624B\u6539\u3002\u56DB\u9636\u6BB5\u6839\u56E0\u8C03\u8BD5\u6CD5\uFF08\u8C03\u67E5\u2192\u6A21\u5F0F\u5206\u6790\u2192\u5047\u8BBE\u6D4B\u8BD5\u2192\u5B9E\u73B0\u4FEE\u590D\uFF09 + \u6570\u636E\u5316\u6027\u80FD\u4F18\u5316 7 \u6B65\uFF08\u5B9A\u4E49\u6307\u6807\u2192\u6253\u6869\u2192baseline\u2192\u5206\u6790\u74F6\u9888\u2192\u4F18\u5316\u2192\u590D\u6D4B\u2192\u5BF9\u6BD4\u62A5\u544A\uFF09\u3002 \u89E6\u53D1\u8BCD\uFF1A\u8C03\u8BD5\u3001bug\u3001\u6839\u56E0\u3001\u6392\u67E5\u3001\u4FEE\u4E0D\u597D\u3001\u53CD\u590D\u5931\u8D25\u3001root cause\u3001\u6027\u80FD\u4F18\u5316\u3001\u6162\u3001latency\u3001 baseline\u3001\u6027\u80FD\u74F6\u9888\u3001perf\u3001\u54CD\u5E94\u6162\u3001\u542F\u52A8\u6162\u3001LCP\u3001hydration\u3002 Do NOT use\uFF1A\u7EAF\u65B0\u529F\u80FD\u5B9E\u73B0\u3001\u6837\u5F0F\u8C03\u6574\u3001\u4E0D\u6D89\u53CA\u6545\u969C\u6392\u67E5\u7684\u67B6\u6784\u8BA8\u8BBA\u3002"
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
function buildSystematicinvestigationSkillContentBySlug(slug) {
|
|
1225
|
+
return buildSkillDocMarkdown({
|
|
1226
|
+
body: '# \u7CFB\u7EDF\u5316\u6392\u67E5\u7EAA\u5F8B\uFF08\u6839\u56E0\u8C03\u8BD5 + \u6570\u636E\u5316\u6027\u80FD\u4F18\u5316\uFF09\n\n**\u5171\u540C\u94C1\u5F8B\uFF1A\u65E0\u6839\u56E0\u8C03\u67E5\u4E0D\u63D0\u4FEE\u590D\uFF0C\u65E0 baseline \u4E0D\u63D0\u4F18\u5316\u3002** \u968F\u673A\u4FEE\u590D\u6D6A\u8D39\u65F6\u95F4\u5E76\u5236\u9020\u65B0 bug\uFF1B\n\u300C\u770B\u8D77\u6765\u6162\u300D\u4E0D\u662F\u4F18\u5316\u7406\u7531\u3002\u8FDD\u53CD\u8FC7\u7A0B\u7684\u5B57\u9762\u5C31\u662F\u8FDD\u53CD\u8FC7\u7A0B\u7684\u7CBE\u795E\u3002\n\n## Part A \u2014 \u56DB\u9636\u6BB5\u6839\u56E0\u8C03\u8BD5\u6CD5\n\n\u6BCF\u9636\u6BB5\u5B8C\u6210\u624D\u80FD\u8FDB\u4E0B\u4E00\u4E2A\uFF1A\n\n1. **\u6839\u56E0\u8C03\u67E5**\uFF1A\u8BFB\u5B8C\u6574\u9519\u8BEF\u4FE1\u606F\u548C\u5806\u6808\uFF08\u542B\u884C\u53F7/\u6587\u4EF6/\u9519\u8BEF\u7801\uFF09\uFF1B\u7A33\u5B9A\u590D\u73B0\uFF08\u4E0D\u80FD\u590D\u73B0\u5C31\u6536\u96C6\u66F4\u591A\u6570\u636E\uFF0C\u4E0D\u731C\uFF09\uFF1B\u68C0\u67E5\u6700\u8FD1\u53D8\u66F4\uFF08git diff/commits/\u4F9D\u8D56/\u914D\u7F6E\uFF09\uFF1B\u591A\u7EC4\u4EF6\u7CFB\u7EDF\u5728\u6BCF\u4E2A\u8FB9\u754C\u52A0\u8BCA\u65AD\u65E5\u5FD7\u5148\u5B9A\u4F4D\u54EA\u5C42\u5931\u8D25\uFF1B\u8FFD\u8E2A\u6570\u636E\u6D41\u5230\u574F\u503C\u7684\u6E90\u5934\u3002\n2. **\u6A21\u5F0F\u5206\u6790**\uFF1A\u627E\u540C\u4ED3\u5E93\u5DE5\u4F5C\u4EE3\u7801\u5BF9\u6BD4\uFF1B\u5B8C\u6574\u8BFB\u53C2\u8003\u5B9E\u73B0\u4E0D skim\uFF1B\u5217\u51FA\u5DE5\u4F5C\u4E0E\u635F\u574F\u7684\u6BCF\u4E2A\u5DEE\u5F02\uFF0C\u518D\u5C0F\u4E5F\u522B\u5047\u8BBE"\u4E0D\u53EF\u80FD"\u3002\n3. **\u5047\u8BBE\u6D4B\u8BD5**\uFF1A\u5355\u4E00\u5047\u8BBE\u5199\u4E0B\u6765\uFF08"\u6211\u8BA4\u4E3A X \u662F\u6839\u56E0\u56E0\u4E3A Y"\uFF09\uFF1B\u6700\u5C0F\u6539\u52A8\u6D4B\u8BD5\uFF1B\u4E00\u6B21\u4E00\u4E2A\u53D8\u91CF\uFF1B\u6CA1\u8FC7\u5C31\u63D0\u65B0\u5047\u8BBE\uFF0C\u4E0D\u52A0\u8865\u4E01\u3002\n4. **\u5B9E\u73B0\u4FEE\u590D**\uFF1A\u5148\u5199\u5931\u8D25\u6D4B\u8BD5\uFF1B\u5355\u4E00\u4FEE\u590D\u4E0D\u505A"\u987A\u4FBF\u6539\u8FDB"\uFF1B\u9A8C\u8BC1\u901A\u8FC7\u4E14\u65E0\u5176\u4ED6\u6D4B\u8BD5\u65AD\u88C2\u3002**3 \u6B21\u4FEE\u590D\u5931\u8D25 \u2192 \u8D28\u7591\u67B6\u6784**\uFF0C\u4E0D\u8BD5\u7B2C 4 \u6B21\uFF1A\u6BCF\u6B21\u4FEE\u590D\u63ED\u793A\u65B0\u4F4D\u7F6E/\u65B0\u8026\u5408 \u2192 \u662F\u67B6\u6784\u95EE\u9898\u4E0D\u662F\u5047\u8BBE\u9519\u8BEF\uFF0C\u627E\u4EBA\u8BA8\u8BBA\u800C\u975E\u7EE7\u7EED\u6253\u8865\u4E01\u3002\n\n### \u7EA2\u65D7\u4FE1\u53F7\u2014\u2014\u53D1\u73B0\u81EA\u5DF1\u5728\u60F3\u8FD9\u4E9B\u5C31\u56DE\u9636\u6BB5 1\n\n- "\u5FEB\u901F\u4FEE\u590D\u5148\u8BD5\u8BD5\uFF0C\u4E4B\u540E\u518D\u67E5"\n- "\u6539 X \u770B\u770B\u884C\u4E0D\u884C"\n- "\u52A0\u51E0\u4E2A\u6539\u52A8\u4E00\u8D77\u8DD1\u6D4B\u8BD5"\n- "\u4E0D\u5199\u6D4B\u8BD5\u4E86\u624B\u52A8\u9A8C\u4E00\u4E0B"\n- "\u5E94\u8BE5\u662F X\uFF0C\u5148\u4FEE\u4E86\u518D\u8BF4"\n- "\u4E00\u6B21\u4FEE\u590D"\uFF08\u5DF2\u7ECF\u8BD5\u4E86 2+ \u6B21\uFF09\n- \u6BCF\u6B21\u4FEE\u590D\u5728\u65B0\u4F4D\u7F6E\u66B4\u9732\u65B0\u95EE\u9898\n\n### \u5E38\u89C1\u501F\u53E3\n\n| \u501F\u53E3 | \u73B0\u5B9E |\n|------|------|\n| "\u95EE\u9898\u7B80\u5355\u4E0D\u9700\u8981\u8FC7\u7A0B" | \u7B80\u5355\u95EE\u9898\u4E5F\u6709\u6839\u56E0\uFF0C\u8FC7\u7A0B\u5BF9\u7B80\u5355 bug \u5F88\u5FEB |\n| "\u7D27\u6025\u6CA1\u65F6\u95F4" | \u7CFB\u7EDF\u5316\u8C03\u8BD5\u6BD4\u4E71\u731C\u91CD\u8BD5\u66F4\u5FEB |\n| "\u5148\u8BD5\u8FD9\u4E2A\u518D\u67E5" | \u7B2C\u4E00\u6B21\u4FEE\u590D\u5B9A\u8C03\uFF0C\u4ECE\u4E00\u5F00\u59CB\u5C31\u505A\u5BF9 |\n| "\u51E0\u4E2A\u4FEE\u590D\u5408\u4E00\u8D77\u7701\u65F6\u95F4" | \u65E0\u6CD5\u9694\u79BB\u54EA\u4E2A\u8D77\u6548\uFF0C\u8FD8\u5236\u9020\u65B0 bug |\n\n## Part B \u2014 \u6570\u636E\u5316\u6027\u80FD\u4F18\u5316 7 \u6B65\n\n\u8986\u76D6\u6570\u636E\u5E93\u3001\u670D\u52A1\u7AEF\u3001\u524D\u7AEF\u3001\u5BA2\u6237\u7AEF\u3001\u684C\u9762/RN\u3001CLI\u3001\u540E\u53F0\u4EFB\u52A1\u3001\u961F\u5217\u3001\u7F13\u5B58\u3001\u540C\u6B65\u3001\u6784\u5EFA\u3001\u542F\u52A8\u548C\u7F51\u7EDC\u94FE\u8DEF\u3002\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u53EA\u505A\u9759\u6001\u5EFA\u8BAE\uFF0C\u5426\u5219\u4E0D\u5F97\u5148\u6539\u4EE3\u7801\u518D\u8865\u89E3\u91CA\u3002\n\n1. **\u5B9A\u4E49\u8DEF\u5F84\u4E0E\u6307\u6807\u3002** \u5199\u6E05\u695A\u7528\u6237\u5165\u53E3\u6216\u7CFB\u7EDF\u5165\u53E3\u3001\u590D\u73B0\u6B65\u9AA4\u3001\u76EE\u6807\u6307\u6807\u548C\u89C2\u5BDF\u7A97\u53E3\u3002\u6309\u5C42\u9009\u62E9\u6307\u6807\uFF1A\u6570\u636E\u5E93 query/scan/lock/row count\uFF0C\u670D\u52A1\u7AEF handler/SSR/RPC/fanout/serialization/cache\uFF0C\u524D\u7AEF render/hydration/LCP/interaction/request waterfall\uFF0C\u5BA2\u6237\u7AEF/\u684C\u9762/RN startup/bridge/native I/O\uFF0CCLI/background job queue/wall time/CPU/memory\uFF0C\u7F51\u7EDC payload bytes/request count/retry\u3002\n2. **\u4F18\u5316\u524D\u5148\u6253\u6869\u3002** \u5148\u6253\u65E5\u5FD7\u6216\u542F\u7528\u73B0\u6709 probes\u3002\u65E5\u5FD7\u5FC5\u987B\u8986\u76D6\u5173\u952E\u9636\u6BB5\u8FB9\u754C\uFF0C\u5305\u542B request/route/job/query/context \u6807\u8BC6\u3001\u5F00\u59CB/\u7ED3\u675F\u65F6\u95F4\u3001duration\u3001count/size/cacheHit \u7B49\u6570\u503C\uFF0C\u5E76\u907F\u514D\u8F93\u51FA token\u3001cookie\u3001API key\u3001\u7528\u6237\u79C1\u5BC6\u6B63\u6587\u6216\u5927 payload\u3002\n3. **\u6536\u96C6 baseline\u3002** \u5728\u672C\u5730\u6216\u6307\u5B9A\u73AF\u5883\u8DD1\u81F3\u5C11\u4E00\u6B21\u5B8C\u6574\u8DEF\u5F84\uFF0C\u4FDD\u5B58\u539F\u59CB\u8F93\u51FA\u4F4D\u7F6E\u6216\u6458\u5F55\u5173\u952E\u6570\u503C\u3002\u82E5\u672C\u5730 runtime/preview \u963B\u585E\uFF0C\u5148\u62A5\u544A\u963B\u585E\u5E76\u4FEE\u6D4B\u91CF\u8DEF\u5F84\uFF0C\u4E0D\u5F97\u8DF3\u5230\u4F18\u5316\u5B9E\u73B0\u3002\n4. **\u5206\u6790\u74F6\u9888\u3002** \u7528\u6570\u636E\u6307\u51FA\u6700\u6162\u9636\u6BB5\u548C\u5360\u6BD4\uFF0C\u5F62\u6210\u53EF\u8BC1\u4F2A\u5047\u8BBE\u3002\u4E0D\u8981\u56E0\u4E3A\u4EE3\u7801\u770B\u8D77\u6765"\u53EF\u80FD\u6162"\u5C31\u76F4\u63A5\u6539\u3002\n5. **\u5E94\u7528\u4E00\u6B21\u8303\u56F4\u9650\u5B9A\u7684\u4F18\u5316\u3002** \u6BCF\u6B21\u53EA\u6539\u4E00\u4E2A\u4E3B\u8981\u74F6\u9888\u6216\u4E00\u7EC4\u5F3A\u76F8\u5173\u74F6\u9888\uFF0C\u4FDD\u7559\u6743\u5A01\u6570\u636E\u6E90\u548C\u7EF4\u62A4\u8DEF\u5F84\uFF0C\u4E0D\u786C\u7F16\u7801\u3001\u590D\u5236\u6216\u5F71\u5B50\u7F13\u5B58\u4E1A\u52A1\u6570\u636E\u3002\n6. **\u91CD\u65B0\u8FD0\u884C\u540C\u4E00\u6D4B\u91CF\u3002** \u4F7F\u7528\u540C\u4E00\u5165\u53E3\u3001\u540C\u4E00\u6570\u636E\u96C6\u3001\u540C\u4E00\u73AF\u5883\u3001\u540C\u4E00 probe/log \u53E3\u5F84\u590D\u6D4B\u3002\u7ED3\u679C\u5FC5\u987B\u80FD\u548C baseline \u5BF9\u9F50\u3002\n7. **\u62A5\u544A\u5BF9\u6BD4\u3002** \u6700\u7EC8\u62A5\u544A\u5FC5\u987B\u5305\u542B before/after \u8868\uFF1A\u9636\u6BB5\u3001baseline\u3001after\u3001delta\u3001\u6837\u672C\u6B21\u6570\u3001\u73AF\u5883\u3001\u547D\u4EE4/\u65E5\u5FD7\u6765\u6E90\u3001\u5269\u4F59\u74F6\u9888\u548C\u672A\u9A8C\u8BC1\u9879\u3002\u6CA1\u6709\u6539\u5584\u6216\u7ED3\u679C\u566A\u58F0\u8FC7\u5927\u65F6\uFF0C\u5982\u5B9E\u62A5\u544A\uFF0C\u4E0D\u5305\u88C5\u6210\u6210\u529F\u3002\n\n### \u8BA1\u5212\u6587\u4EF6\u7ED3\u6784\n\n\u8BA1\u5212\u6587\u4EF6\u4E2D\u7684\u6027\u80FD\u4EFB\u52A1\u5FC5\u987B\u5305\u542B `Measurement plan`\u3001`Baseline results`\u3001`Optimization hypothesis`\u3001`After results`\u3001`Comparison` \u4E94\u6BB5\uFF1B\u6267\u884C\u4E2D\u6BCF\u83B7\u5F97\u4E00\u7EC4\u6570\u636E\u5C31\u66F4\u65B0\u8BA1\u5212\u6587\u4EF6\uFF0C\u786E\u4FDD\u65B0\u4EE3\u7406\u4E0D\u4F9D\u8D56\u804A\u5929\u8BB0\u5FC6\u3002\n\n## Boundaries\n\n- \u805A\u7126\u7CFB\u7EDF\u5316\u8C03\u8BD5\u5FC3\u6CD5\u4E0E\u6027\u80FD\u6D4B\u91CF\u7EAA\u5F8B\uFF0C\u4E0D\u63D0\u4F9B\u4EE3\u7801\u4FEE\u590D\u672C\u8EAB\u3002\n- \u4E0D\u8986\u76D6\u67B6\u6784\u91CD\u8BBE\u8BA1\uFF08\u4FEE\u590D\u5931\u8D25\u8D85 3 \u6B21\u540E\u8F6C\u7ED9 owner\uFF09\uFF1B\u4E0D\u66FF\u4EE3\u5177\u4F53\u5DE5\u5177\uFF08\u65E5\u5FD7\u3001\u6027\u80FD\u5206\u6790\u3001\u7F51\u7EDC\u5305\uFF09\u7684\u5B66\u4E60\u3002\n- \u4E0D\u628A\u6784\u5EFA\u901A\u8FC7\u3001\u4EE3\u7801\u53D8\u5C11\u6216\u4E3B\u89C2\u611F\u89C9\u66F4\u5FEB\u5F53\u6210\u6027\u80FD\u6539\u5584\uFF1B\u5FC5\u987B\u6709\u540C\u53E3\u5F84 before/after \u6570\u636E\u3002\n- \u7528\u6237\u53EA\u8981\u6C42\u9759\u6001\u5EFA\u8BAE\u65F6\u53EF\u4EE5\u4E0D\u6539\u4EE3\u7801\uFF0C\u4F46\u5FC5\u987B\u660E\u786E\u6CA1\u6709\u8FD0\u884C\u65F6\u57FA\u7EBF\u4E0E\u6539\u5584\u8BC1\u636E\u3002',
|
|
1227
|
+
skillConfig: buildSystematicinvestigationSkillConfig(slug)
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// packages/ai/skills/showMeSkill.ts
|
|
1232
|
+
var SHOW_ME_SKILL_SLUGS = ["show-me"];
|
|
1233
|
+
function deterministicId8(prefix, seed) {
|
|
1234
|
+
let h = 2166136261;
|
|
1235
|
+
for (let i = 0; i < seed.length; i++) {
|
|
1236
|
+
h ^= seed.charCodeAt(i);
|
|
1237
|
+
h = h * 16777619 >>> 0;
|
|
1238
|
+
}
|
|
1239
|
+
const suffix = h.toString(36).toUpperCase().padStart(14, "0");
|
|
1240
|
+
return (prefix + suffix).slice(0, 26);
|
|
1241
|
+
}
|
|
1242
|
+
function normalizeSkillSeed8(input) {
|
|
1243
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1244
|
+
}
|
|
1245
|
+
function buildShowmeSkillId(slug) {
|
|
1246
|
+
return deterministicId8("01SK", normalizeSkillSeed8(slug) || slug);
|
|
1247
|
+
}
|
|
1248
|
+
function buildShowmeSkillPageKey(userId, slug) {
|
|
1249
|
+
return `page-${userId}-${buildShowmeSkillId(slug)}`;
|
|
1250
|
+
}
|
|
1251
|
+
function buildShowmeSkillConfig(slug) {
|
|
1252
|
+
return {
|
|
1253
|
+
version: "0.1",
|
|
1254
|
+
kind: "skill",
|
|
1255
|
+
id: buildShowmeSkillId(slug),
|
|
1256
|
+
name: "\u89C6\u89C9\u5316\u89E3\u91CA\uFF08show-me\uFF09",
|
|
1257
|
+
triggerMode: "recommended",
|
|
1258
|
+
description: "\u4EE5\u89C6\u89C9\u76F4\u89C2\u7684\u65B9\u5F0F\uFF08\u7CBE\u70BC\u4F2A\u4EE3\u7801\u3001\u8C03\u7528\u6811\u3001\u7EC4\u4EF6\u6811\u3001Mermaid \u56FE\u8868\u3001\u7ED3\u6784\u5316 Diff \u6216\u72EC\u7ACB HTML \u6E32\u67D3\u5DE5\u4EF6\uFF09\u89E3\u91CA\u590D\u6742\u4E3B\u9898\u3001\u67B6\u6784\u903B\u8F91\u3001\u72B6\u6001\u6D41\u8F6C\u4E0E UI \u7ED3\u6784\u3002\u89E6\u53D1\u8BCD\uFF1A\u753B\u4E2A\u56FE\u3001\u753B\u56FE\u3001\u6D41\u7A0B\u56FE\u3001\u65F6\u5E8F\u56FE\u3001\u53EF\u89C6\u5316\u3001\u600E\u4E48\u8C03\u7528\u7684\u3001\u8C03\u7528\u94FE\u3001\u7EC4\u4EF6\u7ED3\u6784\u3001\u5BF9\u6BD4\u4E00\u4E0B\u3001show me\u3001visualize\u3001diagram\u3001artifact preview\u3002"
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
function buildShowmeSkillContentBySlug(slug) {
|
|
1262
|
+
return buildSkillDocMarkdown({
|
|
1263
|
+
body: "# Show Me (Visual-First \u7ED3\u6784\u5316\u8868\u8FBE\u6307\u5357)\n\n\u5F53\u89E3\u91CA\u590D\u6742\u7CFB\u7EDF\u3001\u6D41\u7A0B\u3001\u67B6\u6784\u8BBE\u8BA1\u3001\u6392\u9519\u6839\u56E0\u6216 UI \u53D8\u52A8\u65F6\uFF0C\u9075\u5FAA **\u201C\u89C6\u89C9\u4F18\u5148\uFF08Visual-First\uFF09\u201D** \u539F\u5219\u3002\n\u8DF3\u8FC7\u5197\u957F\u5F00\u573A\u767D\uFF0C\u4FDD\u6301\u6B63\u6587\u7B80\u660E\u627C\u8981\uFF0C\u9009\u62E9\u80FD\u8BB2\u6E05\u6838\u5FC3\u89C2\u70B9\u7684**\u6700\u5C0F\u5FC5\u8981\u89C6\u56FE\uFF08Smallest View\uFF09**\u3002\n\n---\n\n## \u6838\u5FC3\u53EF\u89C6\u5316\u6A21\u5F0F\n\n### 1. \u903B\u8F91\u4E0E\u7B97\u6CD5\u4F2A\u4EE3\u7801\n\u5C55\u793A\u5173\u952E\u5206\u652F\u5224\u65AD\u3001\u8BA1\u7B97\u987A\u5E8F\u6216\u6838\u5FC3\u7B97\u6CD5\u6B65\u9AA4\uFF1A\n\n```text\non(save)\n if content is unchanged\n return cached result\n write new content\n return fresh result\n```\n\n### 2. \u8FD0\u884C\u65F6\u63A7\u5236\u6D41 / \u8C03\u7528\u6811 (Call Tree)\n\u5C55\u793A\u65B9\u6CD5\u8C03\u7528\u5C42\u7EA7\u4E0E\u6570\u636E\u63A8\u8FDB\u94FE\u8DEF\uFF1A\n\n```text\nsubmitForm\n validateInputs\n createSession\n persistPrompt\n launchAgent\n spawnWorker\n navigateToSession\n```\n\n### 3. \u7EC4\u4EF6\u6811\u4E0E\u72B6\u6001\u8FB9\u754C (Component Tree)\n\u5C55\u793A\u524D\u7AEF UI \u7EC4\u4EF6\u5C42\u7EA7\u3001Props \u4F20\u9012\u4EE5\u53CA\u5C40\u90E8/\u5168\u5C40\u72B6\u6001\u6240\u5C5E\uFF1A\n\n```tsx\n(apps/web/src/pages/WorkspacePage.tsx)\n<WorkspaceProvider> // \u5168\u5C40 workspace context\n <WorkspaceLayout>\n <Sidebar /> // activeNav, unreadBadges\n <MainContent>\n <ChatThread> // threadId, messages\n <MessageList>\n <MessageItem /> // content, sender\n </MessageList>\n <ChatInput /> // draft, isSending\n </ChatThread>\n </MainContent>\n </WorkspaceLayout>\n</WorkspaceProvider>\n```\n\n### 4. \u6D45\u5C42\u6587\u4EF6\u6811 (File Tree)\n\u5C55\u793A\u76EE\u5F55\u7EC4\u7EC7\u3001\u6A21\u5757\u5F52\u5C5E\u6216\u91CD\u6784\u8303\u56F4\uFF08\u4EC5\u4FDD\u7559\u4E0E\u95EE\u9898\u76F4\u63A5\u76F8\u5173\u7684\u5C42\u7EA7\uFF09\uFF1A\n\n```text\npackages/\n client/\n src/\n components/ // UI \u5C55\u793A\u7EC4\u4EF6\n hooks/ // \u6570\u636E\u6D41\u4E0E\u54CD\u5E94\u5F0F\u72B6\u6001\n server/\n src/\n routes/ // API \u8DEF\u7531\u5165\u53E3\n services/ // \u6838\u5FC3\u4E1A\u52A1\u5904\u7406\n```\n\n### 5. \u7ED3\u6784\u5316 Diff\n\u9664\u4E86\u4EE3\u7801\u53D8\u66F4\uFF0C\u8FD8\u53EF\u7528\u4E8E\u76F4\u89C2\u5BF9\u6BD4**\u67B6\u6784\u6F14\u8FDB\u3001\u8C03\u7528\u94FE\u4FEE\u6539\u3001\u6587\u4EF6\u91CD\u6784\u3001\u72B6\u6001\u7ED3\u6784\u53D8\u52A8**\uFF1A\n\n```diff\n submitForm\n validateInputs\n- syncDirectSave\n+ dispatchAsyncJob\n+ queueWorker\n+ pollStatus\n navigateToSession\n```\n\n### 6. Mermaid \u6D41\u7A0B\u56FE / \u65F6\u5E8F\u56FE / \u72B6\u6001\u673A\n\u7528\u4E8E\u8DE8\u670D\u52A1\u901A\u4FE1\u3001\u591A\u7AEF\u4EA4\u4E92\u3001\u751F\u547D\u5468\u671F\u4E0E\u72B6\u6001\u6D41\u8F6C\uFF08Web / Desktop \u5BA2\u6237\u7AEF\u53EF\u76F4\u63A5\u539F\u751F\u6E32\u67D3\uFF09\uFF1A\n\n```mermaid\nsequenceDiagram\n autonumber\n actor User as \u7528\u6237\n participant Client as \u5BA2\u6237\u7AEF (Web/Desktop)\n participant Server as Nolo Server\n participant Agent as Agent Runtime\n\n User->>Client: \u53D1\u9001\u6307\u4EE4\n Client->>Server: POST /api/dialog/message\n Server->>Agent: \u8C03\u5EA6 startAgentThread\n Agent-->>Client: SSE \u6D41\u5F0F\u54CD\u5E94 (Token / Artifact)\n Client-->>User: \u5B9E\u65F6\u754C\u9762\u66F4\u65B0\n```\n\n### 7. \u72EC\u7ACB HTML \u6E32\u67D3\u5DE5\u4EF6 (HTML Artifact)\n\u5F53\u6587\u672C\u3001\u6811\u5F62\u56FE\u6216 Mermaid \u65E0\u6CD5\u5145\u5206\u8868\u8FBE\u4E30\u5BCC\u7684\u4EA4\u4E92\u539F\u578B\u3001\u590D\u6742 UI \u5E03\u5C40\u5BF9\u6BD4\u3001\u4FE1\u606F\u56FE\u8868\u6216\u7B80\u62A5\u65F6\uFF0C\u751F\u6210\u4E00\u4EFD\u81EA\u5305\u542B\u7684\u5355\u4E2A HTML \u6587\u4EF6\u3002\n- \u91C7\u7528\u7B26\u5408\u73B0\u4EE3\u4EA7\u54C1\u6807\u51C6\u7684\u914D\u8272\u3001\u5B57\u4F53\u3001\u95F4\u8DDD\u4E0E\u54CD\u5E94\u5F0F\u5E03\u5C40\u3002\n- \u4F7F\u7528\u771F\u5B9E\u6807\u7B7E\u4E0E\u6A21\u62DF\u6570\u636E\uFF0C\u907F\u514D\u7A7A\u7070\u76D2\u3002\n- \u5199\u5165\u6587\u4EF6\u5E76\u901A\u8FC7\u7CFB\u7EDF\u6216 Browser Connector \u6253\u5F00\u7ED9\u7528\u6237\u9884\u89C8\u3002\n\n---\n\n## \u5B9E\u8DF5\u539F\u5219 (Guidance)\n\n1. **\u56FE\u6587\u5E76\u8302\uFF0C\u56FE\u5728\u6587\u5148**\uFF1A\u8BA9\u7ED3\u6784\u56FE\u7D27\u6328\u7740\u5176\u89E3\u91CA\u7684\u7B80\u8FF0\u6587\u5B57\uFF0C\u5148\u5448\u73B0\u6E05\u6670\u56FE\u8868\uFF0C\u518D\u7528 1~3 \u53E5\u8BDD\u8BF4\u660E\u91CD\u70B9\u3002\n2. **\u514B\u5236\u4E0E\u805A\u7126 (Smallest View)**\uFF1A\u53EA\u4FDD\u7559\u56DE\u7B54\u5F53\u524D\u95EE\u9898\u6240\u5FC5\u9700\u7684\u8C03\u7528\u3001\u5C5E\u6027\u3001\u72B6\u6001\u4E0E\u8FB9\u754C\uFF0C\u4E0D\u8981\u5806\u780C\u65E0\u610F\u4E49\u7684\u5168\u5C40\u5197\u4F59\u4EE3\u7801\u3002\n3. **\u9009\u578B\u6070\u5F53**\uFF1A\u901A\u5E38\u4E00\u6B21\u89E3\u91CA\u9009\u7528 1~2 \u79CD\u6700\u5951\u5408\u7684\u53EF\u89C6\u5316\u5F62\u5F0F\u5373\u53EF\uFF0C\u4E0D\u8981\u628A\u6240\u6709\u56FE\u8868\u90FD\u5806\u5728\u4E00\u8D77\u589E\u52A0\u8BA4\u77E5\u8D1F\u62C5\u3002\n4. **\u5BA2\u6237\u7AEF\u9002\u914D**\uFF1A\n - \u5728 CLI / TUI \u7EC8\u7AEF\u4E2D\uFF0C\u4F18\u5148\u4F7F\u7528\u4F2A\u4EE3\u7801\u3001\u7F29\u8FDB\u8C03\u7528\u6811\u3001Unicode \u5B57\u7B26\u56FE\u4E0E Diff\uFF1B\n - \u5728 Web / Desktop \u56FE\u5F62\u5BA2\u6237\u7AEF\u4E2D\uFF0C\u5145\u5206\u5229\u7528 Mermaid \u6E32\u67D3\u4E0E HTML Artifacts \u9884\u89C8\u3002",
|
|
1264
|
+
skillConfig: buildShowmeSkillConfig(slug)
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// packages/ai/skills/cavemanSkill.ts
|
|
1269
|
+
var CAVEMAN_SKILL_SLUGS = ["caveman"];
|
|
1270
|
+
function deterministicId9(prefix, seed) {
|
|
1271
|
+
let h = 2166136261;
|
|
1272
|
+
for (let i = 0; i < seed.length; i++) {
|
|
1273
|
+
h ^= seed.charCodeAt(i);
|
|
1274
|
+
h = h * 16777619 >>> 0;
|
|
1275
|
+
}
|
|
1276
|
+
const suffix = h.toString(36).toUpperCase().padStart(14, "0");
|
|
1277
|
+
return (prefix + suffix).slice(0, 26);
|
|
1278
|
+
}
|
|
1279
|
+
function normalizeSkillSeed9(input) {
|
|
1280
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1281
|
+
}
|
|
1282
|
+
function buildCavemanSkillId(slug) {
|
|
1283
|
+
return deterministicId9("01SK", normalizeSkillSeed9(slug) || slug);
|
|
1284
|
+
}
|
|
1285
|
+
function buildCavemanSkillPageKey(userId, slug) {
|
|
1286
|
+
return `page-${userId}-${buildCavemanSkillId(slug)}`;
|
|
1287
|
+
}
|
|
1288
|
+
function buildCavemanSkillConfig(slug) {
|
|
1289
|
+
return {
|
|
1290
|
+
version: "0.1",
|
|
1291
|
+
kind: "skill",
|
|
1292
|
+
id: buildCavemanSkillId(slug),
|
|
1293
|
+
name: "\u538B\u7F29\u8868\u8FBE\uFF08caveman\uFF09",
|
|
1294
|
+
triggerMode: "explicit",
|
|
1295
|
+
description: 'Ultra-compressed communication mode. Cuts token usage ~75% by speaking like caveman while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra, wenyan-lite, wenyan-full, wenyan-ultra. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.'
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function buildCavemanSkillContentBySlug(slug) {
|
|
1299
|
+
return buildSkillDocMarkdown({
|
|
1300
|
+
body: 'Respond terse like smart caveman. All technical substance stay. Only fluff die.\n\n## Persistence\n\nACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode".\n\nDefault: **full**. Switch: `/caveman lite|full|ultra`.\n\n## Rules\n\nDrop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). No tool-call narration, no decorative tables/emoji, no dumping long raw error logs unless asked \u2014 quote shortest decisive line. Standard well-known tech acronyms OK (DB/API/HTTP); never invent new abbreviations reader can\'t decode. Technical terms exact. Code blocks unchanged. Errors quoted exact.\n\nPreserve user\'s dominant language. User write Portuguese \u2192 reply Portuguese caveman. User write Spanish \u2192 reply Spanish caveman. Compress the style, not the language. No forced English openings or status phrases. ALWAYS keep technical terms, code, API names, CLI commands, commit-type keywords (feat/fix/...), and exact error strings verbatim \u2014 unless user explicitly ask for translation.\n\nNo self-reference. Never name or announce the style. No "caveman mode on", "me caveman think", no third-person caveman tags. Output caveman-only \u2014 never normal answer plus "Caveman:" recap. Exception: user explicitly ask what the mode is.\n\nPattern: `[thing] [action] [reason]. [next step].`\n\nNot: "Sure! I\'d be happy to help you with that. The issue you\'re experiencing is likely caused by..."\nYes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"\n\n## Intensity\n\n| Level | What change |\n|-------|------------|\n| **lite** | No filler/hedging. Keep articles + full sentences. Professional but tight |\n| **full** | Drop articles, fragments OK, short synonyms. Classic caveman. No tool-call narration, no decorative tables/emoji, no long raw error-log dumps unless asked. Standard acronyms OK; no invented abbreviations |\n| **ultra** | Abbreviate prose words (DB/auth/config/req/res/fn/impl) \u2014 prose words only, never real code symbols/function names. Strip conjunctions, arrows for causality (X \u2192 Y), one word when one word enough. Code symbols, function names, API names, error strings: never abbreviate |\n| **wenyan-lite** | Semi-classical. Drop filler/hedging but keep grammar structure, classical register |\n| **wenyan-full** | Maximum classical terseness. Fully \u6587\u8A00\u6587. 80-90% character reduction. Classical sentence patterns, verbs precede objects, subjects often omitted, classical particles (\u4E4B/\u4E43/\u70BA/\u5176) |\n| **wenyan-ultra** | Extreme abbreviation while keeping classical Chinese feel. Maximum compression, ultra terse |\n\nExample \u2014 "Why React component re-render?"\n- lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`."\n- full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."\n- ultra: "Inline obj prop \u2192 new ref \u2192 re-render. `useMemo`."\n- wenyan-lite: "\u7D44\u4EF6\u983B\u91CD\u7E6A\uFF0C\u4EE5\u6BCF\u7E6A\u65B0\u751F\u5C0D\u8C61\u53C3\u7167\u6545\u3002\u4EE5 useMemo \u5305\u4E4B\u3002"\n- wenyan-full: "\u6BCF\u7E6A\u65B0\u751F\u5C0D\u8C61\u53C3\u7167\uFF0C\u6545\u91CD\u7E6A\uFF1B\u4EE5 useMemo \u5305\u4E4B\u5247\u514D\u3002"\n- wenyan-ultra: "\u65B0\u53C3\u7167\u2192\u91CD\u7E6A\u3002useMemo Wrap\u3002"\n\nExample \u2014 "Explain database connection pooling."\n- lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead."\n- full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."\n- ultra: "Pool = reuse DB conn. Skip handshake \u2192 fast under load."\n- wenyan-full: "\u6C60reuse open connection\u3002\u4E0D\u6BCFreq\u65B0\u958B\u3002skip handshake overhead\u3002"\n- wenyan-ultra: "\u6C60reuse conn\u3002skip handshake \u2192 fast\u3002"\n\n## Auto-Clarity\n\nDrop caveman when:\n- Security warnings\n- Irreversible action confirmations\n- Multi-step sequences where fragment order or omitted conjunctions risk misread\n- Compression itself creates technical ambiguity (e.g., `"migrate table drop column backup first"` \u2014 order unclear without articles/conjunctions)\n- User asks to clarify or repeats question\n\nResume caveman after clear part done.\n\nExample \u2014 destructive op:\n> **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.\n> ```sql\n> DROP TABLE users;\n> ```\n> Caveman resume. Verify backup exist first.\n\n## Boundaries\n\nCode/commits/PRs: write normal. "stop caveman" or "normal mode": revert. Level persist until changed or session end.',
|
|
1301
|
+
skillConfig: buildCavemanSkillConfig(slug)
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// packages/ai/skills/skillCreatorSkill.ts
|
|
1306
|
+
var SKILL_CREATOR_SKILL_SLUGS = ["skill-creator"];
|
|
1307
|
+
function deterministicId10(prefix, seed) {
|
|
1308
|
+
let h = 2166136261;
|
|
1309
|
+
for (let i = 0; i < seed.length; i++) {
|
|
1310
|
+
h ^= seed.charCodeAt(i);
|
|
1311
|
+
h = h * 16777619 >>> 0;
|
|
1312
|
+
}
|
|
1313
|
+
const suffix = h.toString(36).toUpperCase().padStart(14, "0");
|
|
1314
|
+
return (prefix + suffix).slice(0, 26);
|
|
1315
|
+
}
|
|
1316
|
+
function normalizeSkillSeed10(input) {
|
|
1317
|
+
return input.trim().toLowerCase().replace(/[^a-z0-9\u4e00-\u9fa5]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1318
|
+
}
|
|
1319
|
+
function buildSkillCreatorSkillId(slug) {
|
|
1320
|
+
return deterministicId10("01SK", normalizeSkillSeed10(slug) || slug);
|
|
1321
|
+
}
|
|
1322
|
+
function buildSkillCreatorSkillPageKey(userId, slug) {
|
|
1323
|
+
return `page-${userId}-${buildSkillCreatorSkillId(slug)}`;
|
|
1324
|
+
}
|
|
1325
|
+
function buildSkillCreatorSkillConfig(slug) {
|
|
1326
|
+
return {
|
|
1327
|
+
version: "0.1",
|
|
1328
|
+
kind: "skill",
|
|
1329
|
+
id: buildSkillCreatorSkillId(slug),
|
|
1330
|
+
name: "Skill \u7F16\u5199\u65B9\u6CD5\u8BBA\uFF08skill-creator\uFF09",
|
|
1331
|
+
triggerMode: "explicit",
|
|
1332
|
+
description: "\u7F16\u5199\u3001\u6539\u8FDB\u4E0E\u6821\u9A8C Agent Skill\uFF08SKILL.md\uFF09\u7684\u8DE8\u9879\u76EE\u65B9\u6CD5\u8BBA\uFF1A\u6A21\u7CCA\u9700\u6C42\u8BCA\u65AD\u3001\u7ED3\u6784\u6A21\u5F0F\u9009\u578B\u3001frontmatter description \u89E6\u53D1\u8BCD\u8BBE\u8BA1\u3001Boundaries \u8FB9\u754C\u5212\u5B9A\u4E0E\u81EA\u5305\u542B\u6821\u9A8C\u6E05\u5355\u3002\u89E6\u53D1\u8BCD\uFF1A\u65B0\u5EFA skill\u3001\u5199\u4E2A skill\u3001\u6539 skill\u3001\u628A\u5DE5\u4F5C\u6D41\u8F6C\u6210 skill\u3001skill \u89E6\u53D1\u4E0D\u4E86\u3001skill \u4E0D\u89E6\u53D1\u3001SKILL.md\u3001\u6821\u9A8C skill \u683C\u5F0F\u3001skill \u8FB9\u754C\u3002Make sure to use this skill whenever the user mentions skill\u3001SKILL.md\u3001\u6280\u80FD\u521B\u5EFA\u6216\u6280\u80FD\u6539\u9020\u2014\u2014even if they don't explicitly say 'skill-creator'\u3002"
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
function buildSkillCreatorSkillContentBySlug(slug) {
|
|
1336
|
+
return buildSkillDocMarkdown({
|
|
1337
|
+
body: "# Skill Creator (Agent Skill \u7F16\u5199\u65B9\u6CD5\u8BBA)\n\n\u5199 skill \u662F\u7ED9 agent \u5199\u300C\u53EF\u88AB\u8DEF\u7531\u5230\u7684\u5DE5\u4F5C\u8BF4\u660E\u4E66\u300D\uFF0C\u4E0D\u662F\u7ED9\u4EBA\u770B\u7684\u6587\u6863\u3002\u672C skill \u53EA\u8BB2**\u600E\u4E48\u5199 skill**\uFF1B\u8BE5\u4E0D\u8BE5\u65B0\u5EFA\u4E00\u4E2A agent\u3001agent \u7684\u521B\u5EFA\u6D41\u7A0B\u5F52\u5185\u7F6E `agent-creator` \u7BA1\u3002\n\n## Core Principles\n\n### Concise is Key\n\n\u4E0A\u4E0B\u6587\u7A97\u53E3\u662F\u5171\u4EAB\u7684\uFF1Asystem prompt\u3001\u5BF9\u8BDD\u5386\u53F2\u3001\u5176\u4ED6 skill \u7684\u5143\u6570\u636E\u3001\u7528\u6237\u8BF7\u6C42\u90FD\u5728\u91CC\u9762\u3002**\u9ED8\u8BA4\u5047\u8BBE agent \u5DF2\u7ECF\u591F\u806A\u660E**\uFF0C\u53EA\u8865\u5B83\u6CA1\u6709\u7684\u4E0A\u4E0B\u6587\u3002\u6BCF\u53E5\u8BDD\u5148\u8FC7\u4E09\u95EE\uFF1A\u4E0D\u8BF4 agent \u80FD\u4E0D\u80FD\u81EA\u5DF1\u63A8\u51FA\u6765\uFF1F\u2192 \u5220\u3002\u522B\u7684 skill \u91CC\u6709\u6CA1\u6709\uFF1F\u2192 \u5F15\u7528\u5B83\u3002\u662F\u4E0D\u662F\u8BE6\u7EC6\u53C2\u8003\u8D44\u6599\uFF1F\u2192 \u653E `references/` \u6309\u9700\u52A0\u8F7D\u3002\u5B81\u8981\u77ED\u793A\u4F8B\uFF0C\u4E0D\u8981\u957F\u89E3\u91CA\u3002\n\n### Degree of Freedom\n\n\u628A\u8868\u8FF0\u7684\u4E25\u683C\u7A0B\u5EA6\u5339\u914D\u4EFB\u52A1\u7684\u8106\u5F31\u5EA6\uFF1A\n\n- **\u9AD8**\uFF08\u6587\u5B57\u8BF4\u660E\uFF09\u2014\u2014\u591A\u6761\u8DEF\u90FD\u901A\uFF0C\u51B3\u7B56\u4F9D\u8D56\u4E0A\u4E0B\u6587\n- **\u4E2D**\uFF08\u5E26\u53C2\u6570\u7684\u6A21\u677F\u811A\u672C\uFF09\u2014\u2014\u6709\u9996\u9009\u6A21\u5F0F\uFF0C\u5141\u8BB8\u5C11\u91CF\u53D8\u5316\n- **\u4F4E**\uFF08\u5199\u6B7B\u7684\u811A\u672C\u4E0E\u7ED3\u6784\uFF09\u2014\u2014\u64CD\u4F5C\u8106\u5F31\u3001\u4E00\u81F4\u6027\u5173\u952E\n\n### What to Not Include\n\nskill \u91CC\u53EA\u653E\u76F4\u63A5\u652F\u6491\u5B83\u804C\u80FD\u7684\u6587\u4EF6\u3002**\u7EDD\u4E0D\u521B\u5EFA** `README.md`\u3001`INSTALLATION_GUIDE.md`\u3001`CHANGELOG.md` \u6216\u4EFB\u4F55\u8BB2\u8FF0\u300C\u5B83\u662F\u600E\u4E48\u505A\u51FA\u6765\u7684\u300D\u7684\u9644\u5C5E\u6587\u6863\u3002skill \u662F\u7ED9 agent \u5E72\u6D3B\u7684\uFF0C\u4E0D\u662F\u7ED9\u4EBA\u8BFB\u5236\u4F5C\u8FC7\u7A0B\u7684\u3002\n\n## Skill Creation Process\n\n### Step 1: \u4E00\u53E5\u8BDD\u6D4B\u8BD5\n\n\u5148\u7528\u4E00\u53E5\u8BDD\u8BF4\u6E05\u8FD9\u4E2A skill \u5E72\u4EC0\u4E48\u3002\u8BF4\u4E0D\u6E05\u5C31\u505C\u4E0B\u91CD\u60F3\u3002\u300C\u5B83\u5E2E\u5FD9\u505A\u4EE3\u7801\u5BA1\u67E5\u300D\u592A\u6A21\u7CCA\uFF1B\u300C\u5B83\u5BA1\u67E5 TypeScript PR \u7684 bug\u3001\u98CE\u683C\u4E0E\u67B6\u6784\uFF0C\u5E76\u8FD4\u56DE\u5E26 severity \u7B49\u7EA7\u7684\u7ED3\u6784\u5316\u62A5\u544A\u300D\u5408\u683C\u3002\n\n#### 1b. \u8BCA\u65AD\u6A21\u7CCA\u9700\u6C42\n\n\u7528\u6237\u63CF\u8FF0\u7684\u662F\u75DB\u70B9\u800C\u4E0D\u662F skill \u8BF7\u6C42\uFF08\u300C\u6211\u6BCF\u6B21\u90FD\u5F97\u624B\u52A8\u68C0\u67E5 X\u300D\uFF09\u65F6\uFF0C\u5148\u8BCA\u65AD\u518D\u8981\u7ED3\u6784\uFF1A\n\n- \u8FD9\u4EF6\u4E8B\u6700\u9002\u5408\u7684\u662F skill\u3001\u811A\u672C\u3001\u6587\u6863\uFF0C\u8FD8\u662F\u505A\u4E00\u6B21\u5C31\u591F\uFF1F\n- \u82E5\u9002\u5408 skill\uFF0C\u6700\u8F7B\u7684\u5F62\u6001\u662F\u4EC0\u4E48\uFF1Aworkflow\u3001checklist\u3001reference\uFF0C\u8FD8\u662F\u5DE5\u5177\u5C01\u88C5\uFF1F\n- \u6700\u591A\u63A8\u8350\u4E24\u4E2A\u65B9\u5411\uFF0C\u8BF4\u6E05\u5404\u81EA\u9002\u914D\u70B9\u4E0E\u5C40\u9650\u3002\n\n#### 1c. \u95EE\u5BF9\u95EE\u9898\n\n\u52A8\u7B14\u524D\u628A\u6838\u5FC3\u95EE\u6E05\u695A\uFF0C**\u6BCF\u8F6E\u6700\u591A 2-3 \u4E2A\u95EE\u9898**\uFF0C\u4E0D\u8981\u5012\u51FA\u4E00\u5F20\u8868\u5355\u3002\u6838\u5FC3\u95EE\u9898\uFF1A(1) \u8FD9\u4E2A skill \u8981\u63A5\u7BA1\u54EA\u4EF6 recurring \u7684\u6D3B\uFF1F(2) \u522B\u4EBA\u4F1A\u5582\u7ED9\u5B83\u4EC0\u4E48\u771F\u5B9E\u8F93\u5165\uFF1F(3) \u5B83\u8BE5\u8FD4\u56DE\u4EC0\u4E48\u6210\u54C1\uFF1F(4) \u76F8\u90BB\u7684\u54EA\u4E9B\u8BF7\u6C42\u5B83\u8981\u660E\u786E\u62D2\u7EDD\uFF1F\n\n**\u987A\u5E8F\u6709\u8BB2\u7A76**\uFF1A\u5148\u95EE\u8FB9\u754C\uFF08\u300C\u5B83\u4E0D\u8BE5\u505A\u4EC0\u4E48\u300D\uFF09\uFF0C\u518D\u95EE\u4EA7\u51FA\uFF08\u300C\u6210\u529F\u957F\u4EC0\u4E48\u6837\u300D\uFF09\uFF0C\u6700\u540E\u624D\u95EE\u7ED3\u6784\uFF1B\u80FD\u4E00\u53E5\u8BDD\u8BF4\u6E05 skill \u65F6\u5C31\u505C\u6B62\u63D0\u95EE\u3002\n\n#### 1d. \u5BF9\u8BDD\u8BED\u6C14\n\n\u8BED\u6C14\u5339\u914D\u7528\u6237\u72B6\u6001\u800C\u4E0D\u662F\u6A21\u677F\uFF1A\u60F3\u6CD5\u6A21\u7CCA\u65F6\u5148\u5E76\u80A9\u628A\u5B83\u7406\u6E05\uFF0C\u76EE\u6807\u6E05\u6670\u65F6\u76F4\u63A5\u4E0A\u7ED3\u6784\uFF0C\u60F3\u5171\u521B\u5C31\u50CF\u5BF9\u7B49\u8BA8\u8BBA\u5E76\u4ECE\u5BF9\u8BDD\u91CC\u62A0\u8FB9\u754C\u3002\u7B2C\u4E00\u56DE\u590D\u6C38\u8FDC\u4E0D\u8981\u662F\u4E00\u5F20\u51B7\u51B0\u51B0\u7684\u8868\u5355\u95EE\u5377\uFF0C\u4E5F\u4E0D\u8981\u5728\u7406\u89E3\u771F\u5B9E\u804C\u8D23\u4E4B\u524D\u5C31\u7529\u4E00\u5957\u6A21\u677F\u3002\n\n### Step 2: \u89C4\u5212\u7ED3\u6784\n\n\u6309 skill \u6027\u8D28\u9009\u4E00\u79CD\u6A21\u5F0F\uFF1A\n\n**Workflow-based**\u2014\u2014\u6709\u6E05\u6670\u6B65\u9AA4\u7684\u987A\u5E8F\u6D41\u7A0B\uFF1A`## Overview \u2192 ## Workflow \u2192 ## Step 1 \u2192 ## Step 2 ...`\uFF0C\u9002\u5408\u90E8\u7F72\u3001\u53D1\u5E03\u3001\u6392\u9519\u6D41\u7A0B\u3002\n\n**Task-based**\u2014\u2014\u4E00\u7EC4\u76F8\u5173\u64CD\u4F5C\uFF1A`## Overview \u2192 ## Quick Start \u2192 ## Task A \u2192 ## Task B ...`\uFF0C\u9002\u5408 CLI \u53C2\u8003\u3001\u5DE5\u5177\u96C6\u3001API \u6307\u5357\u3002\n\n**Reference-based**\u2014\u2014\u6807\u51C6\u3001schema\u3001\u7B56\u7565\uFF1A`## Overview \u2192 ## Rules \u2192 ## Examples \u2192 ## Boundaries`\uFF0C\u9002\u5408\u4EE3\u7801\u5BA1\u67E5\u89C4\u8303\u3001\u54C1\u724C\u6807\u51C6\u3001\u67B6\u6784\u539F\u5219\u3002\n\n### Step 3: \u521D\u59CB\u5316\n\n\u5EFA\u76EE\u5F55 `<skill-name>/`\uFF0C\u5199 `SKILL.md`\uFF0CYAML frontmatter \u81F3\u5C11\u542B `name`\uFF08kebab-case\uFF09\u4E0E `description`\u3002\u9879\u76EE\u82E5\u81EA\u5E26\u811A\u624B\u67B6\uFF08\u5982 bun-nolo \u7684 `bun scripts/skill/init.ts <name>`\uFF09\u4F18\u5148\u7528\u5B83\uFF0C\u5426\u5219\u624B\u5199\u3002\n\n### Step 4: \u5199 SKILL.md\n\n#### Frontmatter\n\n**\u5148\u5199 `description`**\u2014\u2014\u5B83\u662F agent \u51B3\u5B9A\u52A0\u8F7D\u524D\u552F\u4E00\u80FD\u770B\u5230\u7684\u4E1C\u897F\uFF0C\u4E5F\u662F\u4E3B\u8981\u89E6\u53D1\u673A\u5236\u3002agent \u5929\u7136**\u6B20\u89E6\u53D1**\uFF0C\u8981\u7528\u300Cpushy\u300D\u63AA\u8F9E\u5BF9\u6297\u3002\n\n```yaml\ndescription: >\n [\u5B83\u505A\u4EC0\u4E48]\u3002Use when [\u5177\u4F53\u89E6\u53D1\u8BCD\u3001\u5173\u952E\u8BCD\u3001\u573A\u666F]\u3002\n```\n\n\u89C4\u5219\uFF1A\n\n- \u540C\u65F6\u5199\u300C\u505A\u4EC0\u4E48\u300D\u548C\u300C\u4F55\u65F6\u7528\u300D\uFF1B\u6240\u6709 when-to-use \u4FE1\u606F\u8FDB description\uFF0C\u4E0D\u8FDB\u6B63\u6587\n- \u89E6\u53D1\u8BCD\u8981\u5177\u4F53\uFF08\u6B63\u5F0F\u8BF4\u6CD5\u4E0E\u53E3\u8BED\u90FD\u8BF4\u4E0A\uFF09\uFF0C\u70B9\u540D\u6587\u4EF6\u7C7B\u578B\u3001\u5DE5\u5177\u6216\u573A\u666F\n- \u7528 pushy \u63AA\u8F9E\uFF08\u300CMake sure to use this skill whenever...\u300D\uFF09\n- \u8D1F\u5411\u8FB9\u754C\uFF08\u300C\u4E0D\u505A X\u300D\uFF09\u653E\u6B63\u6587 `## Boundaries`\uFF0C\u4E0D\u8981\u8FDB description\u2014\u2014description \u662F\u53D1\u73B0\u83DC\u5355\uFF0C\u6BCF\u4E2A\u5B57\u90FD\u8BE5\u5E2E agent \u5224\u65AD\u8981\u4E0D\u8981\u52A0\u8F7D\n- \u22641024 \u5B57\u7B26\uFF1B\u4E0D\u542B\u5C16\u62EC\u53F7 `<>`\n\n#### \u6B63\u6587\n\n- \u7528\u7948\u4F7F\u53E5\uFF08\u300C\u8BFB\u8FD9\u4E2A\u6587\u4EF6\u300D\u300C\u68C0\u67E5\u683C\u5F0F\u300D\uFF09\n- \u89E3\u91CA **why** \u800C\u4E0D\u53EA\u662F what\u2014\u2014agent \u591F\u806A\u660E\uFF0C\u80FD\u4ECE\u539F\u5219\u63A8\u7406\n- \u5B81\u8981\u77ED\u793A\u4F8B\uFF0C\u4E0D\u8981\u957F\u89E3\u91CA\n- \u5F15\u7528\u5176\u4ED6 skill \u7528\u53CD\u5F15\u53F7\u5305\u540D\u5B57\n- SKILL.md \u4FDD\u6301\u7CBE\u7B80\uFF0C\u771F\u6B63\u9700\u8981\u65F6\u624D\u62C6 `references/`\n- \u9009\u5B9A\u7ED3\u6784\u6A21\u5F0F\u540E\u5220\u6389\u6A21\u677F\u91CC\u7684\u7ED3\u6784\u6027 HTML \u6CE8\u91CA\n\n\u6BCF\u4E2A skill \u5FC5\u987B\u6709 `## Boundaries` \u4E00\u8282\uFF0C\u5217\u51FA\u5B83\u523B\u610F**\u4E0D**\u505A\u7684\u4E8B\u2014\u2014\u6CA1\u6709\u8FB9\u754C\u7684 skill \u4F1A\u9010\u6E10\u541E\u5E76\u76F8\u90BB\u4EFB\u52A1\u76F4\u5230\u4E0D\u53EF\u9760\uFF1B\u663E\u5F0F\u5217\u51FA\u4E0D\u5904\u7406\u4EC0\u4E48\uFF0C\u662F\u63D0\u5347\u89E6\u53D1\u51C6\u786E\u7387\u6700\u5FEB\u7684\u529E\u6CD5\u3002\n\n### Step 5: \u6821\u9A8C\n\n\u8DD1\u9879\u76EE\u81EA\u5E26\u6821\u9A8C\uFF08\u5982 bun-nolo \u7684 `bun scripts/skill/validate.ts <path>` \u6216 `--all`\uFF09\uFF1B\u6CA1\u6709\u5C31\u6309\u6B64\u6E05\u5355\u81EA\u67E5\uFF1ASKILL.md \u5B58\u5728\uFF1Bfrontmatter \u5408\u6CD5\uFF1B`name` \u662F kebab-case \u4E14 \u226464 \u5B57\u7B26\uFF1B`description` \u5B58\u5728\u3001\u65E0 `<>`\u3001\u22641024 \u5B57\u7B26\u3001\u65E0\u6B8B\u7559 TODO\uFF1B\u6709 `## Boundaries`\u3002\u5168\u8FC7\u624D\u7B97\u5B8C\u6210\u3002\n\n### Step 6: \u8FED\u4EE3\n\n\u7528\u300C\u63D0\u5347\u53EF\u9760\u6027\u5927\u4E8E\u589E\u52A0\u4E0A\u4E0B\u6587\u6210\u672C\u300D\u7684\u6700\u5C0F\u6539\u52A8\u3002\u5305\u66F4\u5927\u53EA\u5728\u8DEF\u7531\u3001\u6267\u884C\u6216\u6CBB\u7406\u660E\u663E\u66F4\u53EF\u9760\u65F6\u624D\u66F4\u4F18\u3002skill \u53CD\u590D\u4EA7\u51FA\u574F\u8F93\u51FA\u65F6\uFF0C\u6839\u56E0\u5F88\u5C11\u662F\u4E00\u6761\u574F\u6307\u4EE4\uFF0C\u901A\u5E38\u662F\u7ED3\u6784\u95EE\u9898\u3002\u52A0\u66F4\u591A\u6587\u5B57\u4E4B\u524D\u5148\u95EE\uFF1A\n\n1. \u8FD9\u4E2A skill **\u62E5\u6709**\u4EC0\u4E48\uFF1F\u8FB9\u754C\u6E05\u4E0D\u6E05\uFF1F\n2. \u4EC0\u4E48**\u53CD\u9988**\u8BF4\u660E\u5B83\u5728\u53D8\u597D\u8FD8\u662F\u5728\u6F02\u79FB\uFF1F\n3. \u54EA\u4E2A\u5931\u6548\u53EA\u6709**\u53CD\u590D\u4F7F\u7528**\u540E\u624D\u4F1A\u51FA\u73B0\uFF1F\n4. \u54EA\u5904\u662F**\u6700\u5C0F\u6539\u52A8\u3001\u6700\u5927\u8D28\u91CF\u6536\u76CA**\uFF1F\n\n## \u8DE8\u5E73\u53F0\u517C\u5BB9\n\nskill \u7CFB\u7EDF\u9075\u5FAA Agent Skills \u5F00\u653E\u6807\u51C6\uFF08Anthropic/OpenAI \u517C\u5BB9\uFF09\uFF1Afrontmatter \u7528 `name`\uFF08kebab-case\uFF0C\u226464 \u5B57\u7B26\uFF09+ `description`\uFF08\u5FC5\u586B\uFF0C\u65E0\u5C16\u62EC\u53F7\uFF09\uFF1B\u53EF\u9009\u5B57\u6BB5 `triggers`\u3001`assertions`\u3001`license`\u3001`metadata`\u3001`compatibility`\u3002\n\n```text\nskill-name/\n\u251C\u2500\u2500 SKILL.md (required)\n\u251C\u2500\u2500 agents/ (optional \u2014 platform-specific metadata)\n\u251C\u2500\u2500 references/ (optional \u2014 docs loaded on demand)\n\u251C\u2500\u2500 scripts/ (optional \u2014 executable code)\n\u2514\u2500\u2500 assets/ (optional \u2014 templates, images, fonts)\n```\n\n## Common Mistakes\n\n| Mistake | Fix |\n|---|---|\n| Description \u6CDB\u6CDB\uFF08\u300Chelps with X\u300D\uFF09 | \u8865\u5177\u4F53\u89E6\u53D1\u8BCD\u4E0E\u573A\u666F |\n| when-to-use \u5199\u5728\u6B63\u6587 | \u632A\u8FDB description |\n| Description \u542B\u5C16\u62EC\u53F7 | \u53BB\u6389 `<>`\uFF08\u7834\u574F XML \u89E3\u6790\uFF09 |\n| skill \u540D\u4E0E\u6CE8\u518C\u8868\u4E0D\u4E00\u81F4 | \u8DD1\u6821\u9A8C\u811A\u672C\u6293\u4E0D\u5339\u914D |\n| \u5EFA\u4E86\u6587\u4EF6\u5FD8\u4E86\u6CE8\u518C | \u7528\u811A\u624B\u67B6\u800C\u4E0D\u662F\u624B\u5EFA |\n| \u6CA1\u6709 Boundaries \u4E00\u8282 | \u81F3\u5C11\u5199\u4E00\u6761\u5B83\u4E0D\u505A\u4EC0\u4E48 |\n| \u6B63\u6587\u8FC7\u957F\uFF08>500 \u884C\uFF09 | \u62C6\u6210 SKILL.md + references/ |\n\n## Boundaries\n\n- \u53EA\u8BB2\u600E\u4E48\u5199 skill\uFF1B\u4E0D\u56DE\u7B54\u5177\u4F53\u4E1A\u52A1\u95EE\u9898\uFF0C\u4E5F\u4E0D\u66FF\u4EE3\u4EFB\u4F55\u5177\u4F53 skill \u672C\u8EAB\n- \u4E0D\u7BA1 agent \u7684\u521B\u5EFA\u4E0E\u751F\u547D\u5468\u671F\u2014\u2014\u90A3\u662F\u5185\u7F6E `agent-creator` \u7684\u804C\u8D23\n- \u4E0D\u4E3A\u4E86\u300C\u770B\u8D77\u6765\u4E13\u4E1A\u300D\u6269\u5199\u957F\u6587\uFF1B\u76EE\u6807\u59CB\u7EC8\u662F\u9AD8\u4FE1\u566A\u6BD4\u3001\u6613\u89E6\u53D1\u3001\u6613\u7EF4\u62A4",
|
|
1338
|
+
skillConfig: buildSkillCreatorSkillConfig(slug)
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1194
1342
|
// packages/ai/skills/builtinSkillRegistry.ts
|
|
1195
1343
|
var codePlannerContentBySlug = /* @__PURE__ */ (() => {
|
|
1196
1344
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -1255,6 +1403,34 @@ var SOURCES = [
|
|
|
1255
1403
|
buildPageKey: buildWorktreeSkillPageKey,
|
|
1256
1404
|
buildConfig: buildWorktreeSkillConfig,
|
|
1257
1405
|
buildContent: buildWorktreeSkillContentBySlug
|
|
1406
|
+
},
|
|
1407
|
+
{
|
|
1408
|
+
slugs: SYSTEMATIC_INVESTIGATION_SKILL_SLUGS,
|
|
1409
|
+
buildSkillId: buildSystematicinvestigationSkillId,
|
|
1410
|
+
buildPageKey: buildSystematicinvestigationSkillPageKey,
|
|
1411
|
+
buildConfig: buildSystematicinvestigationSkillConfig,
|
|
1412
|
+
buildContent: buildSystematicinvestigationSkillContentBySlug
|
|
1413
|
+
},
|
|
1414
|
+
{
|
|
1415
|
+
slugs: SHOW_ME_SKILL_SLUGS,
|
|
1416
|
+
buildSkillId: buildShowmeSkillId,
|
|
1417
|
+
buildPageKey: buildShowmeSkillPageKey,
|
|
1418
|
+
buildConfig: buildShowmeSkillConfig,
|
|
1419
|
+
buildContent: buildShowmeSkillContentBySlug
|
|
1420
|
+
},
|
|
1421
|
+
{
|
|
1422
|
+
slugs: CAVEMAN_SKILL_SLUGS,
|
|
1423
|
+
buildSkillId: buildCavemanSkillId,
|
|
1424
|
+
buildPageKey: buildCavemanSkillPageKey,
|
|
1425
|
+
buildConfig: buildCavemanSkillConfig,
|
|
1426
|
+
buildContent: buildCavemanSkillContentBySlug
|
|
1427
|
+
},
|
|
1428
|
+
{
|
|
1429
|
+
slugs: SKILL_CREATOR_SKILL_SLUGS,
|
|
1430
|
+
buildSkillId: buildSkillCreatorSkillId,
|
|
1431
|
+
buildPageKey: buildSkillCreatorSkillPageKey,
|
|
1432
|
+
buildConfig: buildSkillCreatorSkillConfig,
|
|
1433
|
+
buildContent: buildSkillCreatorSkillContentBySlug
|
|
1258
1434
|
}
|
|
1259
1435
|
];
|
|
1260
1436
|
var buildRegistry = () => {
|
|
@@ -81,10 +81,10 @@ import {
|
|
|
81
81
|
} from "./chunk-VF4K2QE6.js";
|
|
82
82
|
import {
|
|
83
83
|
createDocState
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-7UQEDGCB.js";
|
|
85
85
|
import {
|
|
86
86
|
createDialogAction
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-5S7Q2W6J.js";
|
|
88
88
|
import {
|
|
89
89
|
DEFAULT_COLLAPSED_CATEGORIES,
|
|
90
90
|
addContentToSpace,
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
updateContentCategory,
|
|
103
103
|
updateContentTitle,
|
|
104
104
|
writeStoredCollapsedCategories
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-B3RYNS4I.js";
|
|
106
106
|
import {
|
|
107
107
|
getCurrentSpaceId,
|
|
108
108
|
getCurrentSpaceIdRaw,
|
|
@@ -124,14 +124,14 @@ import {
|
|
|
124
124
|
selectMsgById,
|
|
125
125
|
uiAskChoiceFunc,
|
|
126
126
|
uiAskChoiceFunctionSchema
|
|
127
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-SDDLKP4V.js";
|
|
128
128
|
import {
|
|
129
129
|
createAgent,
|
|
130
130
|
deleteServerSyncedCredential,
|
|
131
131
|
runLlm,
|
|
132
132
|
streamAgentChatTurn,
|
|
133
133
|
updateAgent
|
|
134
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-BS4DOHEI.js";
|
|
135
135
|
import {
|
|
136
136
|
getActiveDialogKey,
|
|
137
137
|
selectCurrentDialogKey,
|
|
@@ -145,7 +145,7 @@ import {
|
|
|
145
145
|
resolveBuiltinCapability,
|
|
146
146
|
resolveBuiltinSkillByName,
|
|
147
147
|
resolveBuiltinSkillEntry
|
|
148
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-GNWFC7YT.js";
|
|
149
149
|
import {
|
|
150
150
|
CAPABILITY_PACKS
|
|
151
151
|
} from "./chunk-SHMFFPY3.js";
|
|
@@ -2106,7 +2106,9 @@ var MODES = [
|
|
|
2106
2106
|
"disabled"
|
|
2107
2107
|
];
|
|
2108
2108
|
var DEFAULT_RECOMMENDED_SKILL_SLUGS = [
|
|
2109
|
-
"worktree-isolation"
|
|
2109
|
+
"worktree-isolation",
|
|
2110
|
+
"systematic-investigation",
|
|
2111
|
+
"show-me"
|
|
2110
2112
|
];
|
|
2111
2113
|
var asMode = (value) => typeof value === "string" && MODES.includes(value) ? value : null;
|
|
2112
2114
|
var resolveAgentSkillConfig = (source) => {
|
|
@@ -3943,7 +3945,7 @@ async function deleteDialogsFunc(args, thunkApi) {
|
|
|
3943
3945
|
const deletedDialogIds = [];
|
|
3944
3946
|
const deletedDialogKeys = [];
|
|
3945
3947
|
const failures = [];
|
|
3946
|
-
const { deleteDialog: deleteDialog2 } = await import("./dialogSlice-
|
|
3948
|
+
const { deleteDialog: deleteDialog2 } = await import("./dialogSlice-MSNQGQ7M.js");
|
|
3947
3949
|
for (const target of targets) {
|
|
3948
3950
|
try {
|
|
3949
3951
|
await thunkApi.dispatch(deleteDialog2(target.dbKey)).unwrap();
|
|
@@ -14817,7 +14819,7 @@ var executeToolRun = createAsyncThunk(
|
|
|
14817
14819
|
if (!executionInput) {
|
|
14818
14820
|
throw new Error(`ToolRun ${id} has no input to execute with.`);
|
|
14819
14821
|
}
|
|
14820
|
-
const { findToolExecutor: findToolExecutor2 } = await import("./tools-
|
|
14822
|
+
const { findToolExecutor: findToolExecutor2 } = await import("./tools-CX7EVHKL.js");
|
|
14821
14823
|
const { executor } = findToolExecutor2(run.toolName);
|
|
14822
14824
|
toolRunStarted({
|
|
14823
14825
|
id: run.id,
|
|
@@ -17324,7 +17326,7 @@ async function updateDocFunc(args, thunkApi) {
|
|
|
17324
17326
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
17325
17327
|
};
|
|
17326
17328
|
await dispatch(write({ data: updatedPageData, customKey: id })).unwrap();
|
|
17327
|
-
const { getDocState, applyExternalDocUpdate } = await import("./docStore-
|
|
17329
|
+
const { getDocState, applyExternalDocUpdate } = await import("./docStore-32KUMVID.js");
|
|
17328
17330
|
if (getDocState().pageKey === id) {
|
|
17329
17331
|
applyExternalDocUpdate({
|
|
17330
17332
|
slateData: finalSlateData,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCliLocalRuntimeAdapter,
|
|
3
3
|
summarizeEndpoint
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-C3OIYB5O.js";
|
|
5
5
|
import {
|
|
6
6
|
clipMultilineText
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IVWFJGEB.js";
|
|
8
8
|
import {
|
|
9
9
|
runLocalAgentTurn
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DUXL23YX.js";
|
|
11
11
|
import {
|
|
12
12
|
applyToolSurfaceConstraints
|
|
13
13
|
} from "./chunk-OKCTLCKS.js";
|