prompt-skill-armory 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +3 -3
- package/README.md +3 -3
- package/package.json +1 -1
- package/packages/client-ui-switchblade/lib/client.js +91 -46
- package/packages/client-ui-switchblade/lib/client.js.map +1 -1
- package/packages/client-ui-switchblade/package.json +1 -1
- package/packages/client-ui-switchblade/src/client/SwitchbladeSection.tsx +54 -11
- package/packages/client-ui-switchblade/src/client/conversations.ts +2 -2
- package/packages/switchblade/lib/index.js +164 -20
- package/packages/switchblade/lib/switchblade.js +164 -20
- package/packages/switchblade/package.json +1 -1
- package/packages/switchblade/src/conversations.ts +177 -15
package/README.en.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|--|--|--|--|
|
|
13
13
|
| <img src="docs/preview/preview-6.png" width="220"/> | <img src="docs/preview/preview-7.png" width="220"/> | | |
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|

|
|
17
17
|

|
|
18
18
|

|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
✦ Armory v0.9.
|
|
21
|
+
✦ Armory v0.9.3
|
|
22
22
|
┌─────────┬─────────┬─────┬────────────┬──────┬──────┐
|
|
23
23
|
│ Prompts │ Skills │ MCP │ Wallpaper │ Chat │ Stats│
|
|
24
24
|
│ global │ merged │ hub │ wallpaper │ sync │ usage│
|
|
@@ -111,7 +111,7 @@ Achieved via profile composition (the installer mounts the panel into each profi
|
|
|
111
111
|
|
|
112
112
|
Every time the panel opens it queries npm for the latest `prompt-skill-armory` version; when a newer version exists a banner appears:
|
|
113
113
|
|
|
114
|
-
> New version vX.Y.Z (current v0.9.
|
|
114
|
+
> New version vX.Y.Z (current v0.9.3) [Update now]
|
|
115
115
|
|
|
116
116
|
Clicking "Update now" makes the Host re-run the official installer in place → "Update complete, please restart the client".
|
|
117
117
|
|
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|--|--|--|--|
|
|
13
13
|
| <img src="docs/preview/preview-6.png" width="220"/> | <img src="docs/preview/preview-7.png" width="220"/> | | |
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|

|
|
17
17
|

|
|
18
18
|

|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
✦ Armory v0.9.
|
|
21
|
+
✦ Armory v0.9.3
|
|
22
22
|
┌─────────┬─────────┬─────┬────────────┬──────┬──────┐
|
|
23
23
|
│ 提示词 │ 技能 │ MCP │ Wallpaper │ 对话 │ 统计 │
|
|
24
24
|
│ 全局注入 │ 合并管理 │ 连接 │ 壁纸·特效 │ 导入 │ 用量 │
|
|
@@ -114,7 +114,7 @@ pnpm dsh web
|
|
|
114
114
|
|
|
115
115
|
插件面板每次打开会自动查询 npm 上 `prompt-skill-armory` 的最新版本;发现新版本时顶部显示横幅:
|
|
116
116
|
|
|
117
|
-
> 有新版本 vX.Y.Z(当前 v0.9.
|
|
117
|
+
> 有新版本 vX.Y.Z(当前 v0.9.3) [一键更新]
|
|
118
118
|
|
|
119
119
|
点击「一键更新」→ Host 端运行官方安装器原地重装 → 提示「更新完成,请重启客户端生效」。
|
|
120
120
|
|
package/package.json
CHANGED
|
@@ -521,15 +521,16 @@ window.__ModuleLoader__.load({
|
|
|
521
521
|
return [];
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
-
async function exportConversations(ids) {
|
|
524
|
+
async function exportConversations(ids, projectKey) {
|
|
525
525
|
try {
|
|
526
526
|
const b = await (await fetch("/api/armory/export", {
|
|
527
527
|
method: "POST",
|
|
528
528
|
headers: { "content-type": "application/json" },
|
|
529
529
|
body: JSON.stringify({
|
|
530
530
|
sessionIds: ids,
|
|
531
|
-
|
|
532
|
-
|
|
531
|
+
projectKey,
|
|
532
|
+
includeAttachments: false,
|
|
533
|
+
includeWorkspace: false
|
|
533
534
|
})
|
|
534
535
|
})).json();
|
|
535
536
|
return b.ok && b.name !== void 0 ? b.name : null;
|
|
@@ -946,7 +947,7 @@ window.__ModuleLoader__.load({
|
|
|
946
947
|
});
|
|
947
948
|
}
|
|
948
949
|
/** Bump with every release; keep in sync with package.json version + CHANGELOG. */
|
|
949
|
-
const ARMORY_VERSION = "0.9.
|
|
950
|
+
const ARMORY_VERSION = "0.9.3";
|
|
950
951
|
/** Compact duration: 45.2s / 2m42s / 1h05m. */
|
|
951
952
|
function fmtDuration(ms) {
|
|
952
953
|
const s = ms / 1e3;
|
|
@@ -1278,6 +1279,7 @@ window.__ModuleLoader__.load({
|
|
|
1278
1279
|
const [chatRows, setChatRows] = (0, react.useState)([]);
|
|
1279
1280
|
const [chatSelected, setChatSelected] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
1280
1281
|
const [chatTarget, setChatTarget] = (0, react.useState)("");
|
|
1282
|
+
const [chatProject, setChatProject] = (0, react.useState)("");
|
|
1281
1283
|
const [chatBusy, setChatBusy] = (0, react.useState)(false);
|
|
1282
1284
|
const [chatMsg, setChatMsg] = (0, react.useState)("");
|
|
1283
1285
|
const [latestVer, setLatestVer] = (0, react.useState)("");
|
|
@@ -1311,6 +1313,21 @@ window.__ModuleLoader__.load({
|
|
|
1311
1313
|
return n;
|
|
1312
1314
|
});
|
|
1313
1315
|
};
|
|
1316
|
+
const chatProjects = (0, react.useMemo)(() => {
|
|
1317
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
1318
|
+
for (const row of chatRows) {
|
|
1319
|
+
const name = row.cwd ? row.cwd.split(/[\\/]/).filter(Boolean).pop() ?? row.projectKey : row.projectKey;
|
|
1320
|
+
if (!byKey.has(row.projectKey)) byKey.set(row.projectKey, name);
|
|
1321
|
+
}
|
|
1322
|
+
return [...byKey.entries()].map(([key, name]) => ({
|
|
1323
|
+
key,
|
|
1324
|
+
name
|
|
1325
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
1326
|
+
}, [chatRows]);
|
|
1327
|
+
(0, react.useEffect)(() => {
|
|
1328
|
+
if (chatProject === "" && chatProjects.length > 0) setChatProject(chatProjects[0].key);
|
|
1329
|
+
else if (chatProject !== "" && !chatProjects.some((p) => p.key === chatProject)) setChatProject(chatProjects[0]?.key ?? "");
|
|
1330
|
+
}, [chatProjects, chatProject]);
|
|
1314
1331
|
const doExportChat = async () => {
|
|
1315
1332
|
setChatBusy(true);
|
|
1316
1333
|
setChatMsg("");
|
|
@@ -1324,6 +1341,24 @@ window.__ModuleLoader__.load({
|
|
|
1324
1341
|
setChatMsg(`已导出 ${name}`);
|
|
1325
1342
|
setChatBusy(false);
|
|
1326
1343
|
};
|
|
1344
|
+
const doExportProject = async () => {
|
|
1345
|
+
const key = chatProject.trim();
|
|
1346
|
+
if (key === "") {
|
|
1347
|
+
setChatMsg("请先选择项目工作区");
|
|
1348
|
+
return;
|
|
1349
|
+
}
|
|
1350
|
+
setChatBusy(true);
|
|
1351
|
+
setChatMsg("");
|
|
1352
|
+
const name = await exportConversations([], key);
|
|
1353
|
+
if (name === null) {
|
|
1354
|
+
setChatMsg("导出失败");
|
|
1355
|
+
setChatBusy(false);
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
await downloadExport(name);
|
|
1359
|
+
setChatMsg(`已导出整个项目 ${key} → ${name}`);
|
|
1360
|
+
setChatBusy(false);
|
|
1361
|
+
};
|
|
1327
1362
|
const doUpdate = async () => {
|
|
1328
1363
|
setUpdating(true);
|
|
1329
1364
|
setUpdateMsg("");
|
|
@@ -1564,6 +1599,31 @@ window.__ModuleLoader__.load({
|
|
|
1564
1599
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1565
1600
|
style: CSS.versionBadge,
|
|
1566
1601
|
children: ["v", ARMORY_VERSION]
|
|
1602
|
+
}),
|
|
1603
|
+
latestVer !== "" && isOlder(ARMORY_VERSION, latestVer) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1604
|
+
style: {
|
|
1605
|
+
display: "inline-flex",
|
|
1606
|
+
alignItems: "center",
|
|
1607
|
+
gap: "6px",
|
|
1608
|
+
marginLeft: "8px"
|
|
1609
|
+
},
|
|
1610
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1611
|
+
style: {
|
|
1612
|
+
...CSS.actionBtn,
|
|
1613
|
+
...CSS.badgeEnabled,
|
|
1614
|
+
fontSize: "11px",
|
|
1615
|
+
padding: "2px 8px"
|
|
1616
|
+
},
|
|
1617
|
+
disabled: updating,
|
|
1618
|
+
onClick: () => void doUpdate(),
|
|
1619
|
+
children: updating ? "更新中…" : `↑ v${latestVer} 更新`
|
|
1620
|
+
}), updateMsg !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1621
|
+
style: {
|
|
1622
|
+
...CSS.hint,
|
|
1623
|
+
whiteSpace: "nowrap"
|
|
1624
|
+
},
|
|
1625
|
+
children: updateMsg.slice(0, 60)
|
|
1626
|
+
})]
|
|
1567
1627
|
})
|
|
1568
1628
|
]
|
|
1569
1629
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1581,47 +1641,6 @@ window.__ModuleLoader__.load({
|
|
|
1581
1641
|
state.message
|
|
1582
1642
|
]
|
|
1583
1643
|
}),
|
|
1584
|
-
latestVer !== "" && isOlder(ARMORY_VERSION, latestVer) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1585
|
-
style: {
|
|
1586
|
-
display: "flex",
|
|
1587
|
-
alignItems: "center",
|
|
1588
|
-
gap: "10px",
|
|
1589
|
-
padding: "8px 12px",
|
|
1590
|
-
marginBottom: "10px",
|
|
1591
|
-
borderRadius: "8px",
|
|
1592
|
-
border: "1px solid #58a6ff",
|
|
1593
|
-
background: "rgba(88,166,255,.08)"
|
|
1594
|
-
},
|
|
1595
|
-
children: [
|
|
1596
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1597
|
-
style: {
|
|
1598
|
-
fontSize: "12px",
|
|
1599
|
-
color: "#58a6ff",
|
|
1600
|
-
flex: 1
|
|
1601
|
-
},
|
|
1602
|
-
children: [
|
|
1603
|
-
"有新版本 v",
|
|
1604
|
-
latestVer,
|
|
1605
|
-
"(当前 v",
|
|
1606
|
-
ARMORY_VERSION,
|
|
1607
|
-
")"
|
|
1608
|
-
]
|
|
1609
|
-
}),
|
|
1610
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1611
|
-
style: {
|
|
1612
|
-
...CSS.actionBtn,
|
|
1613
|
-
...CSS.badgeEnabled
|
|
1614
|
-
},
|
|
1615
|
-
disabled: updating,
|
|
1616
|
-
onClick: () => void doUpdate(),
|
|
1617
|
-
children: updating ? "更新中…" : "一键更新"
|
|
1618
|
-
}),
|
|
1619
|
-
updateMsg !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1620
|
-
style: { ...CSS.hint },
|
|
1621
|
-
children: updateMsg
|
|
1622
|
-
})
|
|
1623
|
-
]
|
|
1624
|
-
}),
|
|
1625
1644
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1626
1645
|
style: CSS.tabs,
|
|
1627
1646
|
children: [
|
|
@@ -2484,7 +2503,7 @@ window.__ModuleLoader__.load({
|
|
|
2484
2503
|
...CSS.desc,
|
|
2485
2504
|
lineHeight: "1.5"
|
|
2486
2505
|
},
|
|
2487
|
-
children: "
|
|
2506
|
+
children: "可导出选中的对话,也可下拉选择某个项目工作区整体导出;导入后项目工作区名会尽量与导出端保持一致。"
|
|
2488
2507
|
}),
|
|
2489
2508
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2490
2509
|
style: CSS.actions,
|
|
@@ -2499,6 +2518,32 @@ window.__ModuleLoader__.load({
|
|
|
2499
2518
|
")"
|
|
2500
2519
|
]
|
|
2501
2520
|
}),
|
|
2521
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2522
|
+
style: CSS.actionBtn,
|
|
2523
|
+
disabled: chatBusy || chatProject === "",
|
|
2524
|
+
onClick: () => void doExportProject(),
|
|
2525
|
+
title: "导出该项目工作区下的全部对话,导入后可保留项目名",
|
|
2526
|
+
children: "导出整个项目"
|
|
2527
|
+
}),
|
|
2528
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2529
|
+
style: CSS.input,
|
|
2530
|
+
value: chatProject,
|
|
2531
|
+
onChange: (e) => setChatProject(e.target.value),
|
|
2532
|
+
disabled: chatBusy || chatProjects.length === 0,
|
|
2533
|
+
title: "选择要整体导出的项目工作区",
|
|
2534
|
+
children: [chatProjects.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2535
|
+
value: "",
|
|
2536
|
+
children: "(无项目)"
|
|
2537
|
+
}), chatProjects.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2538
|
+
value: p.key,
|
|
2539
|
+
children: [
|
|
2540
|
+
p.name,
|
|
2541
|
+
"(",
|
|
2542
|
+
chatRows.filter((r) => r.projectKey === p.key).length,
|
|
2543
|
+
" 个对话)"
|
|
2544
|
+
]
|
|
2545
|
+
}, p.key))]
|
|
2546
|
+
}),
|
|
2502
2547
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2503
2548
|
style: {
|
|
2504
2549
|
...CSS.actionBtn,
|