skill-forge-hub 1.1.0 → 1.2.0
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/CHANGELOG.en.md +10 -0
- package/CHANGELOG.md +10 -0
- package/README.en.md +3 -1
- package/README.md +3 -1
- package/SKILLS_CATALOG.md +119 -0
- package/annual-report/SKILL.md +3 -3
- package/annual-report/resources/reference.html +2 -2
- package/annual-report/resources/skillforge-guide.html +1 -0
- package/annual-report/resources/skillforge-guide.txt +1 -0
- package/annual-report/user-config.md +1 -1
- package/article-to-html/SKILL.md +1 -1
- package/article-to-html/resources/skillforge-guide.html +1 -0
- package/article-to-html/resources/skillforge-guide.txt +1 -0
- package/article-to-html/user-config.md +1 -1
- package/cli.js +54 -14
- package/commit-heatmap/SKILL.md +2 -2
- package/commit-heatmap/resources/skillforge-guide.html +1 -0
- package/commit-heatmap/resources/skillforge-guide.txt +1 -0
- package/commit-heatmap/user-config.md +1 -1
- package/daily-report/SKILL.md +2 -2
- package/daily-report/resources/skillforge-guide.html +1 -0
- package/daily-report/resources/skillforge-guide.txt +1 -0
- package/daily-report/user-config.md +1 -1
- package/data-prepper/SKILL.md +2 -2
- package/data-prepper/resources/skillforge-guide.html +1 -0
- package/data-prepper/resources/skillforge-guide.txt +1 -0
- package/data-prepper/user-config.md +1 -1
- package/decision-log/SKILL.md +2 -2
- package/decision-log/resources/skillforge-guide.html +1 -0
- package/decision-log/resources/skillforge-guide.txt +1 -0
- package/decision-log/user-config.md +1 -1
- package/deck-stage/SKILL.md +3 -10
- package/deck-stage/resources/skillforge-guide.html +1 -0
- package/deck-stage/resources/skillforge-guide.txt +1 -0
- package/docs/articles/ai-daily-report-correct-pose.md +39 -0
- package/docs/articles/ai-prompt-management-skill-pouch.md +37 -0
- package/docs/directory-submission.md +106 -0
- package/docs/install.en.md +3 -3
- package/docs/install.md +3 -3
- package/docs/usage-examples.en.md +1 -1
- package/docs/usage-examples.md +1 -1
- package/magic-deck/SKILL.md +4 -5
- package/magic-deck/resources/skillforge-guide.html +1 -0
- package/magic-deck/resources/skillforge-guide.txt +1 -0
- package/magic-deck/user-config.md +1 -1
- package/meeting-minutes/SKILL.md +1 -1
- package/meeting-minutes/resources/skillforge-guide.html +1 -0
- package/meeting-minutes/resources/skillforge-guide.txt +1 -0
- package/meeting-minutes/user-config.md +1 -1
- package/meta-forge/SKILL.md +2 -2
- package/meta-forge/resources/skillforge-guide.html +1 -0
- package/meta-forge/resources/skillforge-guide.txt +1 -0
- package/meta-forge/user-config.md +1 -1
- package/monthly-report/SKILL.md +1 -1
- package/monthly-report/resources/skillforge-guide.html +1 -0
- package/monthly-report/resources/skillforge-guide.txt +1 -0
- package/monthly-report/user-config.md +1 -1
- package/one-pager/SKILL.md +20 -8
- package/one-pager/resources/design-process.md +117 -0
- package/one-pager/resources/generate.md +19 -7
- package/one-pager/resources/html-rules.md +55 -10
- package/one-pager/resources/reference.html +1192 -111
- package/one-pager/resources/skillforge-guide.html +1 -0
- package/one-pager/resources/skillforge-guide.txt +1 -0
- package/one-pager/resources/usage-guide.md +18 -4
- package/one-pager/resources/user-template-example.html +63 -0
- package/one-pager/user-config.md +7 -4
- package/package.json +3 -2
- package/prompt-pouch/SKILL.md +4 -15
- package/prompt-pouch/resources/reference.html +180 -42
- package/prompt-pouch/resources/skillforge-guide.html +1 -0
- package/prompt-pouch/resources/skillforge-guide.txt +1 -0
- package/prompt-pouch/resources/usage-guide.md +3 -3
- package/quarterly-report/SKILL.md +1 -1
- package/quarterly-report/resources/skillforge-guide.html +1 -0
- package/quarterly-report/resources/skillforge-guide.txt +1 -0
- package/quarterly-report/user-config.md +1 -1
- package/release-notes/SKILL.md +2 -2
- package/release-notes/resources/skillforge-guide.html +1 -0
- package/release-notes/resources/skillforge-guide.txt +1 -0
- package/release-notes/user-config.md +1 -1
- package/skill-doctor/SKILL.md +2 -2
- package/skill-doctor/resources/skillforge-guide.html +1 -0
- package/skill-doctor/resources/skillforge-guide.txt +1 -0
- package/skill-doctor/user-config.md +1 -1
- package/spec-doc2spec/SKILL.md +3 -9
- package/spec-doc2spec/resources/skillforge-guide.html +1 -0
- package/spec-doc2spec/resources/skillforge-guide.txt +1 -0
- package/spec-doc2spec/user-config.md +1 -1
- package/spec-spec2doc/SKILL.md +3 -12
- package/spec-spec2doc/resources/skillforge-guide.html +1 -0
- package/spec-spec2doc/resources/skillforge-guide.txt +1 -0
- package/spec-spec2doc/user-config.md +1 -1
- package/team-report-collector/SKILL.md +2 -2
- package/team-report-collector/resources/skillforge-guide.html +1 -0
- package/team-report-collector/resources/skillforge-guide.txt +1 -0
- package/team-report-collector/user-config.md +1 -1
- package/template/SKILL.md +2 -2
- package/template/user-config.md +1 -1
- package/twin-docs/SKILL.md +2 -2
- package/twin-docs/resources/skillforge-guide.html +1 -0
- package/twin-docs/resources/skillforge-guide.txt +1 -0
- package/twin-docs/user-config.md +1 -1
- package/weekly-report/SKILL.md +2 -2
- package/weekly-report/resources/skillforge-guide.html +1 -0
- package/weekly-report/resources/skillforge-guide.txt +1 -0
- package/weekly-report/user-config.md +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<meta name="sf-template" content="prompt-pouch@
|
|
6
|
+
<meta name="sf-template" content="prompt-pouch@9">
|
|
7
7
|
<meta name="pouch-id" content="REF-POUCH-0000">
|
|
8
8
|
<title>锦囊 Prompt Pouch — 提示词管理台</title>
|
|
9
9
|
<style>
|
|
@@ -200,12 +200,13 @@ header{
|
|
|
200
200
|
/* 侧栏 */
|
|
201
201
|
aside{ width:200px; flex:0 0 auto;
|
|
202
202
|
display:flex; flex-direction:column;
|
|
203
|
-
|
|
204
|
-
height:calc(100vh - 100px);
|
|
203
|
+
align-self:flex-start; /* 自然流式随页面整体滚动:说明卡完整展示,页面滚到底即可读完 */
|
|
205
204
|
}
|
|
206
|
-
/* 侧栏分组滚动区:收藏 +
|
|
205
|
+
/* 侧栏分组滚动区:收藏 + 分组局部滚动——滚动区最大高度 = 视口高度减去顶栏、「全部」行与底部「锦囊用法」说明卡(完整展示不裁剪),分组再多说明卡也完整可见;窄滚动条 */
|
|
207
206
|
.nav-scroll{
|
|
208
|
-
flex:
|
|
207
|
+
flex:0 0 auto; min-height:0;
|
|
208
|
+
max-height:calc(100vh - 360px);
|
|
209
|
+
overflow-y:auto;
|
|
209
210
|
margin:0 -4px 0 0; padding-right:4px;
|
|
210
211
|
scrollbar-width:thin; scrollbar-color:var(--border) transparent;
|
|
211
212
|
}
|
|
@@ -231,8 +232,8 @@ aside{ width:200px; flex:0 0 auto;
|
|
|
231
232
|
}
|
|
232
233
|
.nav-item.on .cnt{ color:var(--gold); background:var(--gold-dim); }
|
|
233
234
|
.side-tip{
|
|
234
|
-
flex:0 0 auto;
|
|
235
|
-
margin:
|
|
235
|
+
flex:0 0 auto; /* 完整展示不裁剪:分组滚动区为其留出空间,侧栏随页面整体滚动即可读完 */
|
|
236
|
+
margin:12px 0 0 0; padding:12px 14px 14px; border-radius:10px;
|
|
236
237
|
border:1px dashed var(--border); font-size:11px; line-height:1.9; color:var(--muted);
|
|
237
238
|
}
|
|
238
239
|
.side-tip b{ color:var(--gold); font-weight:700; }
|
|
@@ -246,13 +247,38 @@ main{ flex:1; min-width:0; }
|
|
|
246
247
|
font-weight:900;
|
|
247
248
|
}
|
|
248
249
|
.bar .total{ font-size:12px; color:var(--muted); }
|
|
249
|
-
.sort-box{ margin-left:auto; display:flex; align-items:center; gap:6px; font-size:11px; color:var(--muted); }
|
|
250
|
-
.sort-
|
|
250
|
+
.sort-box{ margin-left:auto; display:flex; align-items:center; gap:6px; font-size:11px; color:var(--muted); position:relative; }
|
|
251
|
+
.sort-sel{
|
|
252
|
+
display:flex; align-items:center; gap:7px;
|
|
251
253
|
background:var(--panel2); border:1px solid var(--border); color:var(--text);
|
|
252
254
|
font-family:inherit; font-size:12px; letter-spacing:1px;
|
|
253
|
-
border-radius:999px; padding:5px
|
|
254
|
-
|
|
255
|
-
|
|
255
|
+
border-radius:999px; padding:5px 13px; outline:none; cursor:pointer;
|
|
256
|
+
transition:border-color .15s ease;
|
|
257
|
+
}
|
|
258
|
+
.sort-sel:hover,.sort-sel.open{ border-color:var(--gold); }
|
|
259
|
+
.sort-arrow{ font-size:9px; color:var(--gold); line-height:1; transition:transform .2s ease; }
|
|
260
|
+
.sort-sel.open .sort-arrow{ transform:rotate(180deg); }
|
|
261
|
+
.sort-menu{
|
|
262
|
+
position:absolute; top:calc(100% + 6px); right:0; z-index:130;
|
|
263
|
+
display:flex; flex-direction:column; gap:2px; min-width:136px;
|
|
264
|
+
background:var(--panel2); border:1px solid var(--border); border-radius:12px;
|
|
265
|
+
padding:5px; box-shadow:0 12px 32px rgba(0,0,0,.45);
|
|
266
|
+
animation:sortMenuIn .16s ease;
|
|
267
|
+
}
|
|
268
|
+
.sort-menu[hidden]{ display:none; }
|
|
269
|
+
@keyframes sortMenuIn{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:none; } }
|
|
270
|
+
.sort-opt{
|
|
271
|
+
display:flex; align-items:center; gap:8px; width:100%;
|
|
272
|
+
background:transparent; border:none; border-radius:8px;
|
|
273
|
+
color:var(--text); font-family:inherit; font-size:12px; letter-spacing:1px;
|
|
274
|
+
padding:7px 10px; cursor:pointer; text-align:left;
|
|
275
|
+
transition:background .12s ease,color .12s ease;
|
|
276
|
+
}
|
|
277
|
+
.sort-opt:hover{ background:var(--gold-dim); color:var(--gold); }
|
|
278
|
+
.sort-check{ width:14px; font-size:11px; color:var(--gold); opacity:0; flex:0 0 auto; }
|
|
279
|
+
.sort-opt.on{ color:var(--gold); font-weight:600; }
|
|
280
|
+
.sort-opt.on .sort-check{ opacity:1; }
|
|
281
|
+
[data-theme="light"] .sort-menu{ box-shadow:0 10px 28px rgba(30,31,34,.16); }
|
|
256
282
|
.sort-status{
|
|
257
283
|
font-size:12px; color:var(--muted);
|
|
258
284
|
display:flex; align-items:center; gap:10px;
|
|
@@ -521,9 +547,10 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
521
547
|
}
|
|
522
548
|
/* 页面直写:侧栏分组管理 / 提示词表单 / toast */
|
|
523
549
|
.nav-add{
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
550
|
+
flex:0 0 auto; /* 「全部」行右侧迷你 + 图标(新建分组),行内不占独立高度 */
|
|
551
|
+
width:22px; height:22px; margin-left:6px;
|
|
552
|
+
display:flex; align-items:center; justify-content:center;
|
|
553
|
+
border-radius:6px; cursor:pointer; font-size:14px; line-height:1; color:var(--gold);
|
|
527
554
|
border:1px dashed var(--border); background:var(--gold-dim);
|
|
528
555
|
transition:all .18s ease; user-select:none;
|
|
529
556
|
}
|
|
@@ -636,13 +663,16 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
636
663
|
<span class="tag-filter" id="tagFilterChip" style="display:none"><span class="tf-ico">🏷</span><b id="tagFilterName"></b><button class="tf-x" id="tagFilterClear" title="清除标签过滤">✕</button></span>
|
|
637
664
|
<button class="btn primary" id="btnAddItem">+ 新增提示词</button>
|
|
638
665
|
<div class="sort-box">
|
|
639
|
-
<label
|
|
640
|
-
<
|
|
641
|
-
<
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
<
|
|
645
|
-
|
|
666
|
+
<label>排序</label>
|
|
667
|
+
<button class="sort-sel" id="sortSel" type="button" title="切换卡片排序方式">
|
|
668
|
+
<span class="sort-sel-txt" id="sortTxt">最新添加</span><span class="sort-arrow">▾</span>
|
|
669
|
+
</button>
|
|
670
|
+
<div class="sort-menu" id="sortMenu" hidden>
|
|
671
|
+
<button class="sort-opt on" data-mode="added" type="button"><span class="sort-check">✓</span>最新添加</button>
|
|
672
|
+
<button class="sort-opt" data-mode="recent" type="button"><span class="sort-check">✓</span>最近使用</button>
|
|
673
|
+
<button class="sort-opt" data-mode="freq" type="button"><span class="sort-check">✓</span>使用频率</button>
|
|
674
|
+
<button class="sort-opt" data-mode="manual" type="button"><span class="sort-check">✓</span>手动顺序</button>
|
|
675
|
+
</div>
|
|
646
676
|
</div>
|
|
647
677
|
<div class="sort-status" id="sortStatus">
|
|
648
678
|
<button class="btn" id="btnSortCmd" disabled>📋 复制变更指令</button>
|
|
@@ -812,6 +842,9 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
812
842
|
var searchClear = document.getElementById('searchClear');
|
|
813
843
|
var sortStatus = document.getElementById('sortStatus');
|
|
814
844
|
var sortSel = document.getElementById('sortSel');
|
|
845
|
+
var sortMenu = document.getElementById('sortMenu');
|
|
846
|
+
var sortTxt = document.getElementById('sortTxt');
|
|
847
|
+
var SORT_LABELS = { added:'最新添加', recent:'最近使用', freq:'使用频率', manual:'手动顺序' };
|
|
815
848
|
var btnSortCmd = document.getElementById('btnSortCmd');
|
|
816
849
|
var btnMarkSaved = document.getElementById('btnMarkSaved');
|
|
817
850
|
var bkStatus = document.getElementById('bkStatus');
|
|
@@ -944,16 +977,15 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
944
977
|
var html = '';
|
|
945
978
|
var all = state.data.prompts.length;
|
|
946
979
|
var favN = state.data.prompts.filter(function(p){ return p.favorite; }).length;
|
|
947
|
-
html += '<div class="nav-item' + (state.curGroup==='all'?' on':'') + '" data-g="all"><span class="icon">🗂️</span>全部<span class="cnt">' + all + '</span></div>';
|
|
980
|
+
html += '<div class="nav-item' + (state.curGroup==='all'?' on':'') + '" data-g="all"><span class="icon">🗂️</span>全部<span class="cnt">' + all + '</span><span class="nav-add" id="navAdd" title="新建分组">+</span></div>';
|
|
948
981
|
html += '<div class="nav-scroll">';
|
|
949
982
|
html += '<div class="nav-item' + (state.curGroup==='fav'?' on':'') + '" data-g="fav"><span class="icon">⭐</span>收藏<span class="cnt">' + favN + '</span></div>';
|
|
950
983
|
state.data.groups.forEach(function(g){
|
|
951
984
|
var n = state.data.prompts.filter(function(p){ return p.group === g.id; }).length;
|
|
952
985
|
html += '<div class="nav-item' + (state.curGroup===g.id?' on':'') + '" data-g="' + g.id + '" draggable="true" title="拖拽调整分组顺序"><span class="icon">' + g.icon + '</span><span class="g-name">' + escapeHtml(g.name) + '</span><span class="cnt">' + n + '</span><span class="g-ops"><button class="g-edit" title="编辑分组">✎</button><button class="g-del" title="删除分组">🗑</button></span></div>';
|
|
953
986
|
});
|
|
954
|
-
html += '<div class="nav-add" id="navAdd">+ 新建分组</div>';
|
|
955
|
-
html += '<div class="side-tip"><b>锦囊用法</b><br>· 页面直接增删改:+ 新建分组 / + 新增提示词 / ✎ 编辑 / 🗑 删除(授权目录即写即存)<br>· 也可对 AI 说「把 XX 加到写作输出分组」<br>· 顶栏切换排序;⇄ 移组、拖卡片排序自动保存;拖分组条调整分组顺序<br>· 点卡片标签按标签筛选(再点取消);标签悬停 ✕ 删 / + 加;⤓ 导出 / ⤒ 导入 JSON 备份<br>· ⭐ 收藏常用 · 复制次数在卡片右上角</div>';
|
|
956
987
|
html += '</div>';
|
|
988
|
+
html += '<div class="side-tip"><b>锦囊用法</b><br>· 页面直接增删改:+ 新建分组 / + 新增提示词 / ✎ 编辑 / 🗑 删除(授权目录即写即存)<br>· 也可对 AI 说「把 XX 加到写作输出分组」<br>· 顶栏切换排序;⇄ 移组、拖卡片排序自动保存;拖分组条调整分组顺序<br>· 点卡片标签按标签筛选(再点取消);标签悬停 ✕ 删 / + 加;⤓ 导出 / ⤒ 导入 JSON 备份<br>· ⭐ 收藏常用 · 复制次数在卡片右上角</div>';
|
|
957
989
|
sideNav.innerHTML = html;
|
|
958
990
|
sideNav.querySelectorAll('.nav-item').forEach(function(el){
|
|
959
991
|
el.addEventListener('click', function(){
|
|
@@ -1001,7 +1033,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1001
1033
|
});
|
|
1002
1034
|
});
|
|
1003
1035
|
var addBtn = sideNav.querySelector('#navAdd');
|
|
1004
|
-
if (addBtn) addBtn.addEventListener('click', function(){ openGroupForm(null); });
|
|
1036
|
+
if (addBtn) addBtn.addEventListener('click', function(e){ e.stopPropagation(); openGroupForm(null); });
|
|
1005
1037
|
}
|
|
1006
1038
|
|
|
1007
1039
|
function render(){
|
|
@@ -1198,7 +1230,12 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1198
1230
|
persistUserState();
|
|
1199
1231
|
scheduleBackup();
|
|
1200
1232
|
}
|
|
1201
|
-
function syncSortUI(){
|
|
1233
|
+
function syncSortUI(){
|
|
1234
|
+
if (sortTxt) sortTxt.textContent = SORT_LABELS[state.sortMode] || SORT_LABELS.added;
|
|
1235
|
+
if (sortMenu) sortMenu.querySelectorAll('.sort-opt').forEach(function(o){
|
|
1236
|
+
o.classList.toggle('on', o.getAttribute('data-mode') === state.sortMode);
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1202
1239
|
function ensureManual(){
|
|
1203
1240
|
if (state.sortMode === 'manual') return;
|
|
1204
1241
|
state.sortMode = 'manual';
|
|
@@ -1279,10 +1316,30 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1279
1316
|
if (!gpopEl.contains(e.target) && !onAnchor){ closeGpop(); }
|
|
1280
1317
|
}
|
|
1281
1318
|
});
|
|
1282
|
-
|
|
1283
|
-
|
|
1319
|
+
function toggleSortMenu(force){
|
|
1320
|
+
if (!sortMenu) return;
|
|
1321
|
+
var willOpen = (force !== undefined) ? force : sortMenu.hidden;
|
|
1322
|
+
sortMenu.hidden = !willOpen;
|
|
1323
|
+
sortSel.classList.toggle('open', willOpen);
|
|
1324
|
+
}
|
|
1325
|
+
sortSel.addEventListener('click', function(e){
|
|
1326
|
+
e.stopPropagation();
|
|
1327
|
+
toggleSortMenu();
|
|
1328
|
+
});
|
|
1329
|
+
sortMenu.addEventListener('click', function(e){
|
|
1330
|
+
var opt = e.target.closest('.sort-opt');
|
|
1331
|
+
if (!opt) return;
|
|
1332
|
+
state.sortMode = opt.getAttribute('data-mode');
|
|
1284
1333
|
persistUserState();
|
|
1285
1334
|
render();
|
|
1335
|
+
syncSortUI();
|
|
1336
|
+
toggleSortMenu(false);
|
|
1337
|
+
});
|
|
1338
|
+
document.addEventListener('click', function(e){
|
|
1339
|
+
if (!sortMenu.hidden){
|
|
1340
|
+
var onSel = e.target.closest && e.target.closest('#sortSel');
|
|
1341
|
+
if (!sortMenu.contains(e.target) && !onSel){ toggleSortMenu(false); }
|
|
1342
|
+
}
|
|
1286
1343
|
});
|
|
1287
1344
|
|
|
1288
1345
|
/* ---------- 模板插值({{变量}} / {变量}) ---------- */
|
|
@@ -1448,6 +1505,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1448
1505
|
if (next === null) return false;
|
|
1449
1506
|
return bkWrite('prompts.json', 'data', JSON.stringify(next, null, 2)).then(function(){
|
|
1450
1507
|
state.data = next;
|
|
1508
|
+
syncMirror(next);
|
|
1451
1509
|
applyUserState();
|
|
1452
1510
|
state.dirty = false; state.moves = [];
|
|
1453
1511
|
persistUserState(); refreshDirtyUI();
|
|
@@ -1484,6 +1542,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1484
1542
|
});
|
|
1485
1543
|
return bkWrite('prompts.json', 'data', JSON.stringify(latest, null, 2)).then(function(){
|
|
1486
1544
|
state.data = latest;
|
|
1545
|
+
syncMirror(latest);
|
|
1487
1546
|
applyUserState();
|
|
1488
1547
|
state.dirty = false; state.moves = [];
|
|
1489
1548
|
persistUserState(); refreshDirtyUI();
|
|
@@ -1868,6 +1927,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
|
|
|
1868
1927
|
if (e.key === 'Escape'){
|
|
1869
1928
|
closeFillPanel();
|
|
1870
1929
|
closeGpop();
|
|
1930
|
+
toggleSortMenu(false);
|
|
1871
1931
|
closeItemForm();
|
|
1872
1932
|
closeGroupForm();
|
|
1873
1933
|
document.getElementById('bkMask').classList.remove('open');
|
|
@@ -2030,6 +2090,19 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2030
2090
|
});
|
|
2031
2091
|
});
|
|
2032
2092
|
}
|
|
2093
|
+
/* 数据镜像:localStorage 存全量数据快照(file:// 下 IndexedDB 偶发不可用时兜底恢复,键按 pouch-id 隔离) */
|
|
2094
|
+
function syncMirror(data){
|
|
2095
|
+
try{ localStorage.setItem(SF_NS + '-mirror', JSON.stringify(data)); }catch(e){}
|
|
2096
|
+
}
|
|
2097
|
+
function readMirror(){
|
|
2098
|
+
try{
|
|
2099
|
+
var raw = localStorage.getItem(SF_NS + '-mirror');
|
|
2100
|
+
if (!raw) return null;
|
|
2101
|
+
var d = JSON.parse(raw);
|
|
2102
|
+
if (d && d.groups && d.prompts) return d;
|
|
2103
|
+
}catch(e){}
|
|
2104
|
+
return null;
|
|
2105
|
+
}
|
|
2033
2106
|
/* 备份文件读:backup/ 优先,读不到回退根目录旧文件(旧目录结构兼容) */
|
|
2034
2107
|
function readBk(name){
|
|
2035
2108
|
return bkRead(name, 'backup').then(function(text){
|
|
@@ -2122,6 +2195,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2122
2195
|
try{ localStorage.removeItem(SF_NS + '-bk-declined'); }catch(e){}
|
|
2123
2196
|
idbSet('bkHandle', bkDirHandle);
|
|
2124
2197
|
updateBkUI();
|
|
2198
|
+
reloadFromDirIfNeeded();
|
|
2125
2199
|
return true;
|
|
2126
2200
|
})
|
|
2127
2201
|
.catch(function(){ pendingAuth = false; updateBkUI(); return false; });
|
|
@@ -2168,6 +2242,43 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2168
2242
|
pendingAuth = false;
|
|
2169
2243
|
}).catch(function(){});
|
|
2170
2244
|
}
|
|
2245
|
+
/* file:// 直开补洞:fetch 被浏览器拦截读不到数据文件时,授权目录后直读 data/prompts.json 替换示例/快照 */
|
|
2246
|
+
function reloadFromDirIfNeeded(){
|
|
2247
|
+
if (!bkDirHandle || bootMode === 'live') return;
|
|
2248
|
+
readPouch().then(function(text){
|
|
2249
|
+
if (text === null) return;
|
|
2250
|
+
var data = JSON.parse(text);
|
|
2251
|
+
state.data = data;
|
|
2252
|
+
idbSet('lastData', data);
|
|
2253
|
+
syncMirror(data);
|
|
2254
|
+
bootMode = 'live';
|
|
2255
|
+
cacheBadge.style.display = 'none';
|
|
2256
|
+
applyUserState();
|
|
2257
|
+
renderNav(); render();
|
|
2258
|
+
toast('✓ 已直读 data/prompts.json,你的分组与提示词已载入');
|
|
2259
|
+
}).catch(function(){});
|
|
2260
|
+
}
|
|
2261
|
+
/* 「🔓 恢复数据」:已授权过目录但刷新后权限需重新确认(file:// 权限不跨会话持久)→ 一键 requestPermission 后直读,免重新选目录 */
|
|
2262
|
+
function restoreAuth(){
|
|
2263
|
+
if (!bkDirHandle || typeof bkDirHandle.requestPermission !== 'function') return;
|
|
2264
|
+
bkDirHandle.requestPermission({ mode: 'readwrite' }).then(function(st){
|
|
2265
|
+
if (st === 'granted'){
|
|
2266
|
+
pendingAuth = false; updateBkUI();
|
|
2267
|
+
reloadFromDirIfNeeded();
|
|
2268
|
+
} else {
|
|
2269
|
+
toast('未获授权:点「💾 授权目录」重新选择目录', true);
|
|
2270
|
+
}
|
|
2271
|
+
}).catch(function(){ toast('权限恢复失败,请重新授权目录', true); });
|
|
2272
|
+
}
|
|
2273
|
+
function updateBootBadge(){
|
|
2274
|
+
if (bootMode === 'live' || !bkDirHandle || !bootRendered) return;
|
|
2275
|
+
var link = ' <a id="bootRestore" style="cursor:pointer;text-decoration:underline">🔓 恢复数据</a>';
|
|
2276
|
+
cacheBadge.innerHTML = (bootMode === 'cache'
|
|
2277
|
+
? '⚠️ 快照模式:当前显示上次快照,目录权限需确认后直读最新数据'
|
|
2278
|
+
: '📌 示例模式:检测到曾授权过目录,点击确认权限即可载入你的数据') + link;
|
|
2279
|
+
cacheBadge.style.display = '';
|
|
2280
|
+
document.getElementById('bootRestore').addEventListener('click', restoreAuth);
|
|
2281
|
+
}
|
|
2171
2282
|
btnBkEnable.addEventListener('click', function(){
|
|
2172
2283
|
if (bkDirHandle && !pendingAuth){
|
|
2173
2284
|
writeBackupNow().then(function(ok){ toast(ok ? '✓ 备份完成 · backup/pouch-backup.json' : '备份失败,请重新授权目录', !ok); });
|
|
@@ -2179,7 +2290,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2179
2290
|
}
|
|
2180
2291
|
if (bkDirHandle && pendingAuth){
|
|
2181
2292
|
bkDirHandle.requestPermission({ mode: 'readwrite' }).then(function(st){
|
|
2182
|
-
if (st === 'granted'){ pendingAuth = false; updateBkUI(); writeBackupNow(); }
|
|
2293
|
+
if (st === 'granted'){ pendingAuth = false; updateBkUI(); writeBackupNow(); reloadFromDirIfNeeded(); }
|
|
2183
2294
|
else bkStatus.textContent = '未获授权,备份暂停';
|
|
2184
2295
|
}).catch(function(){});
|
|
2185
2296
|
return;
|
|
@@ -2191,6 +2302,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2191
2302
|
idbSet('bkHandle', bkDirHandle);
|
|
2192
2303
|
updateBkUI();
|
|
2193
2304
|
writeBackupNow();
|
|
2305
|
+
reloadFromDirIfNeeded();
|
|
2194
2306
|
})
|
|
2195
2307
|
.catch(function(){});
|
|
2196
2308
|
});
|
|
@@ -2204,6 +2316,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2204
2316
|
idbSet('bkHandle', bkDirHandle);
|
|
2205
2317
|
updateBkUI();
|
|
2206
2318
|
writeBackupNow();
|
|
2319
|
+
reloadFromDirIfNeeded();
|
|
2207
2320
|
})
|
|
2208
2321
|
.catch(function(){});
|
|
2209
2322
|
});
|
|
@@ -2267,6 +2380,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2267
2380
|
// 先把当前状态固化进备份(目录备份滚入 .prev.json / 快照环记一份),再应用所选备份
|
|
2268
2381
|
(bkDirHandle ? writeBackupNow() : writeSnapNow()).then(function(){
|
|
2269
2382
|
state.data = snap.data;
|
|
2383
|
+
syncMirror(snap.data);
|
|
2270
2384
|
applyUserStateFrom(snap.userState || {});
|
|
2271
2385
|
state.dirty = false; state.moves = [];
|
|
2272
2386
|
persistUserState();
|
|
@@ -2303,7 +2417,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2303
2417
|
render();
|
|
2304
2418
|
if (bootMode === 'cache') cacheBadge.style.display = '';
|
|
2305
2419
|
if (bootMode === 'demo'){
|
|
2306
|
-
cacheBadge.textContent = '📌 示例模式:未读到 data/prompts.json
|
|
2420
|
+
cacheBadge.textContent = '📌 示例模式:未读到 data/prompts.json,当前展示系统自带示例。若你有自己的数据文件:点顶部「💾 授权目录」选 prompt-pouch.html 所在文件夹即可直读载入;或经 HTTP 打开页面(file:// 直开会被浏览器拦截文件读取)。';
|
|
2307
2421
|
cacheBadge.style.display = '';
|
|
2308
2422
|
}
|
|
2309
2423
|
}
|
|
@@ -2319,26 +2433,49 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2319
2433
|
.then(function(data){
|
|
2320
2434
|
state.data = data;
|
|
2321
2435
|
idbSet('lastData', data);
|
|
2436
|
+
syncMirror(data);
|
|
2322
2437
|
bootMode = 'live';
|
|
2323
2438
|
firstRender();
|
|
2324
2439
|
})
|
|
2325
2440
|
.catch(function(){
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2441
|
+
// file:// 场景:fetch 被浏览器拦截 → 已授权目录则直读 data/prompts.json(File System Access API)
|
|
2442
|
+
return dirHandleReady.then(function(){
|
|
2443
|
+
return readPouch().then(function(text){
|
|
2444
|
+
if (text !== null) return JSON.parse(text);
|
|
2445
|
+
throw new Error('no-fs');
|
|
2446
|
+
});
|
|
2447
|
+
}).then(function(data){
|
|
2448
|
+
state.data = data;
|
|
2449
|
+
idbSet('lastData', data);
|
|
2450
|
+
syncMirror(data);
|
|
2451
|
+
bootMode = 'live';
|
|
2452
|
+
firstRender();
|
|
2453
|
+
}).catch(function(){
|
|
2454
|
+
idbGet('lastData').then(function(cached){
|
|
2455
|
+
if (cached){
|
|
2456
|
+
state.data = cached;
|
|
2457
|
+
bootMode = 'cache';
|
|
2458
|
+
firstRender();
|
|
2459
|
+
} else {
|
|
2460
|
+
var mirror = readMirror();
|
|
2461
|
+
if (mirror){
|
|
2462
|
+
state.data = mirror;
|
|
2463
|
+
bootMode = 'cache';
|
|
2464
|
+
firstRender();
|
|
2465
|
+
} else {
|
|
2466
|
+
state.data = DEFAULT_POUCH;
|
|
2467
|
+
bootMode = 'demo';
|
|
2468
|
+
firstRender();
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
});
|
|
2336
2472
|
});
|
|
2337
2473
|
});
|
|
2338
2474
|
// 本地态并行:可用则应用收藏与排序并刷新备份区(不阻塞数据展示)
|
|
2475
|
+
var dirHandleReady = idbOpen().then(function(){ return loadDirHandle(); }).catch(function(){});
|
|
2339
2476
|
idbOpen()
|
|
2340
2477
|
.then(loadLocalState)
|
|
2341
|
-
.then(
|
|
2478
|
+
.then(function(){ return dirHandleReady; })
|
|
2342
2479
|
.catch(function(){})
|
|
2343
2480
|
.then(function(){
|
|
2344
2481
|
applyUserState();
|
|
@@ -2346,6 +2483,7 @@ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUC
|
|
|
2346
2483
|
refreshDirtyUI();
|
|
2347
2484
|
if (bootRendered){ renderNav(); render(); }
|
|
2348
2485
|
updateBkUI();
|
|
2486
|
+
updateBootBadge();
|
|
2349
2487
|
});
|
|
2350
2488
|
})();
|
|
2351
2489
|
|
|
@@ -361,6 +361,7 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
|
|
|
361
361
|
<tr><td>查全部命令</td><td><span class="cmd-in">skill-forge --help</span></td></tr>
|
|
362
362
|
<tr><td>问单个技能用法</td><td>直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出</td></tr>
|
|
363
363
|
<tr><td>问 SkillForge 本身</td><td>问「skillforge 怎么用」,AI 朗读本指引并打开排版页</td></tr>
|
|
364
|
+
<tr><td>查技能双语简介 / 实操文章</td><td><span class="cmd-in">SKILLS_CATALOG.md</span>(21 技能逐条中英简介)/ <span class="cmd-in">docs/articles/</span>(实操文章)/ <span class="cmd-in">docs/directory-submission.md</span>(目录收录素材)</td></tr>
|
|
364
365
|
</table>
|
|
365
366
|
<div class="faq">
|
|
366
367
|
<div class="faq-title">常见问题</div>
|
|
@@ -122,6 +122,7 @@ skill-forge init --skills daily-report,weekly-report --yes
|
|
|
122
122
|
| 查全部命令 | skill-forge --help |
|
|
123
123
|
| 问单个技能用法 | 直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出 |
|
|
124
124
|
| 问 SkillForge 本身 | 问「skillforge 怎么用」,AI 朗读本指引并打开排版页 |
|
|
125
|
+
| 查技能双语简介 / 实操文章 | SKILLS_CATALOG.md(21 技能逐条中英简介)/ docs/articles/(实操文章)/ docs/directory-submission.md(目录收录素材) |
|
|
125
126
|
|
|
126
127
|
## 六、常见问题
|
|
127
128
|
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## 怎么用
|
|
6
6
|
|
|
7
|
-
1. **打开页面**:对 AI 说「打开锦囊」即可(自动起服务并打开浏览器);手动方式:`cd <目录> && python3 -m http.server 8933`(Windows 用 `py -m http.server`),浏览器访问 `http://localhost:8933/prompt-pouch.html`(HTTP
|
|
7
|
+
1. **打开页面**:对 AI 说「打开锦囊」即可(自动起服务并打开浏览器);手动方式:`cd <目录> && python3 -m http.server 8933`(Windows 用 `py -m http.server`),浏览器访问 `http://localhost:8933/prompt-pouch.html`(HTTP 方式自动读 data/prompts.json;file:// 直开时浏览器会拦截文件读取——已授权目录则刷新自动直读 data/prompts.json,权限需重新确认时点徽标「🔓 恢复数据」一键续权(免重新选目录),读不到则回退本地快照/镜像、再回退内置示例,点页面「💾 授权目录」即可载入你的数据,但仍推荐 HTTP 打开)
|
|
8
8
|
2. **添加提示词**:页面点「+ 新增提示词」填表保存(已授权目录即写即存);或对 AI 说「把 XX 加到锦囊的写作输出分组」(不说分组也行,AI 会列出现有分组让你选;分组不存在时会问你是否新建)
|
|
9
9
|
3. **查看与修改**:卡片正文超长只显示前三行,点「👁 详情」弹窗看全文(超长限高滚动),弹窗内可直接「⧉ 复制」或「✎ 修改」,并附时间线——创建时间、上次修改时间(修改过才显示)、最近使用时间(用过才显示);卡片上也能直接点「✎」改完保存;或对 AI 说「修改锦囊里『日报速写』的内容」,改后刷新
|
|
10
10
|
4. **删除**:页面点卡片「🗑」;或对 AI 说「删掉锦囊里『XX』这条」
|
|
11
11
|
5. **排序与移组**:顶栏「排序」切换四种方式——最新添加(默认)/ 最近使用 / 使用频率 / 手动顺序;想手动排时拖动卡片或点 ▲▼(自动切回手动),点卡片 ⇄ 可把提示词移到其它分组;已授权目录时排序/移组 2 秒内自动保存,未授权时点「📋 复制变更指令」把指令发给 AI 落盘;复制过提示词后卡片右上角会显示「⧉ N 次 · 最近时间」(最近使用/使用频率排序即按复制统计);AI 落盘后回页面点「✓ 已落盘」清除未保存标记
|
|
12
12
|
6. **收藏**:卡片右上角星标,收藏/取消收藏指令由 AI 同步到数据文件
|
|
13
|
-
7.
|
|
13
|
+
7. **分组管理**:「全部」行右侧「+」小图标新建分组;悬停分组名出现「✎ 改名 / 🗑 删除」(组内还有提示词时不允许删,先移出或删条目);重名分组会提示;新建/编辑分组时图标输入框下方有快捷 emoji 面板(点击即填入、选中高亮,输入框仍可手输/粘贴任意 emoji)
|
|
14
14
|
8. **标签全交互**:点卡片标签立即按标签筛选(顶栏出现「🏷 标签」胶囊,点 ✕ 或再点同标签取消,切分组自动清除,与搜索叠加);标签悬停出「✕」点它直接删除该标签;标签不满 3 个时悬停出「+」快速加标签(多个用逗号分隔)——已授权目录即写即存,未授权时操作指令复制给 AI 落盘
|
|
15
15
|
9. **分组排序**:左侧分组条可直接拖拽调整顺序(已授权目录即写即存,未授权时指令自动复制给 AI 落盘)
|
|
16
16
|
10. **导入 / 导出**:顶栏「⤓ 导出」把当前全部数据下载为 JSON 备份文件(文件名带时间戳);「⤒ 导入」选择 JSON 文件整库覆盖现有数据(导入前自动备份,可从「↩ 恢复」回滚;未授权目录时导出仍可用、导入需先授权)
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- **自动备份(默认开启)**:数据一有变更 2 秒内自动备份——首次变更会请求授权写入 prompt-pouch.html 所在目录(弹窗选同目录即可,选一次后浏览器记住),写 backup/pouch-backup.json 并滚动保留上一版 .prev.json;未授权或浏览器不支持时自动降级为本地快照(浏览器内保留最近 5 份),页内「↩ 恢复」均可一键回滚;顶栏「📂 换目录」可随时重新配置备份目录
|
|
23
23
|
- **详情弹窗**:点卡片「👁 详情」弹出全文查看(超长内容限高 52vh 内滚动),带复制与修改入口,附时间线(创建 / 上次修改 / 最近使用);含 {变量} 的模板会在弹窗里标出变量清单,复制时自动进入填充面板
|
|
24
24
|
- **页面直写(双笔)**:页面增删改直接写入 data/prompts.json(与自动备份共用同一目录授权);未授权时自动降级——生成操作指令复制到剪贴板,粘贴给 AI 落盘
|
|
25
|
-
- **侧栏局部滚动**:分组较多时,左侧「收藏 +
|
|
25
|
+
- **侧栏局部滚动**:分组较多时,左侧「收藏 + 分组列表」区域独立滚动(窄滚动条,滚动区最大高度 = 屏幕高度减去顶栏、「全部」行与底部说明卡),「+ 新建分组」在「全部」行右侧不随滚动、「全部」固定不滚;底部「锦囊用法」说明卡完整展示不裁剪,侧栏随页面整体滚动即可读完;窄屏下自动恢复平铺排列
|
|
26
26
|
- **批量整理入囊**:把一堆文字/文件交给 AI,或说「把最近对话框内容整理进锦囊」——两段确认:先定条目(AI 默认智能打标——每条自动配 1-3 个语义标签,可改可删;含具体词的可泛化为 {变量} 插值,附改写示例)→ 再定分组(归组理由 + 装不下的推荐新分组名),都确认后一次性写入;条目少(≤3 条)两段合一
|
|
27
27
|
- **标签全交互**:点标签即筛选(顶栏胶囊一键清除,再点取消,切分组自动清除,与搜索叠加);标签悬停「✕」删、「+」加(最多 3 个),授权目录即写即存,未授权指令交 AI
|
|
28
28
|
- **导入 / 导出 JSON**:顶栏「⤓ 导出」一键下载全量数据为 JSON 备份文件(文件名带时间戳);「⤒ 导入」选择 JSON 文件整库覆盖(导入前自动备份、可恢复);未授权目录时导出仍可用、导入需先授权
|
|
@@ -34,7 +34,7 @@ disable-model-invocation: false
|
|
|
34
34
|
|
|
35
35
|
## 配置版本机制(升级保护)
|
|
36
36
|
|
|
37
|
-
本 skill 当前配置版本为 `3`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明的当前版本不一致:先将旧 user-config.md 备份为 `user-config.md
|
|
37
|
+
本 skill 当前配置版本为 `3`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明的当前版本不一致:先将旧 user-config.md 备份为 `user-config.bak-<时间戳>.md`(同目录,绝不删除旧值)→ 按本节「当前版本变更记录」迁移字段(新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认)→ 更新 CONFIG_VERSION 为当前版本 → 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」。禁止在未声明版本变更的情况下静默修改配置语义。
|
|
38
38
|
|
|
39
39
|
**无法迁移项处理**(值域失效 / 语义漂移 / 数据不兼容):三情形——①旧值不在新值域(如旧模板/主题名已移除)②同名键含义变化(单位/枚举变更)③数据文件 schema 不兼容。三绝不:绝不静默(无法迁移项停下问,不猜值)、绝不丢失(旧值永远在 .bak-时间戳)、一次说清(升级报告三段式:⚠️ 版本与备份路径 → ✅ 已自动迁移清单 → 🟡 无法迁移项逐条附原因+影响+建议替代);随后 AskUserQuestion 三选项(A 用建议值 / B 用户给新值 / C 保持旧配置——不更新 CONFIG_VERSION,每次执行再提醒);报告必附回滚一句话。
|
|
40
40
|
|
|
@@ -361,6 +361,7 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
|
|
|
361
361
|
<tr><td>查全部命令</td><td><span class="cmd-in">skill-forge --help</span></td></tr>
|
|
362
362
|
<tr><td>问单个技能用法</td><td>直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出</td></tr>
|
|
363
363
|
<tr><td>问 SkillForge 本身</td><td>问「skillforge 怎么用」,AI 朗读本指引并打开排版页</td></tr>
|
|
364
|
+
<tr><td>查技能双语简介 / 实操文章</td><td><span class="cmd-in">SKILLS_CATALOG.md</span>(21 技能逐条中英简介)/ <span class="cmd-in">docs/articles/</span>(实操文章)/ <span class="cmd-in">docs/directory-submission.md</span>(目录收录素材)</td></tr>
|
|
364
365
|
</table>
|
|
365
366
|
<div class="faq">
|
|
366
367
|
<div class="faq-title">常见问题</div>
|
|
@@ -122,6 +122,7 @@ skill-forge init --skills daily-report,weekly-report --yes
|
|
|
122
122
|
| 查全部命令 | skill-forge --help |
|
|
123
123
|
| 问单个技能用法 | 直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出 |
|
|
124
124
|
| 问 SkillForge 本身 | 问「skillforge 怎么用」,AI 朗读本指引并打开排版页 |
|
|
125
|
+
| 查技能双语简介 / 实操文章 | SKILLS_CATALOG.md(21 技能逐条中英简介)/ docs/articles/(实操文章)/ docs/directory-submission.md(目录收录素材) |
|
|
125
126
|
|
|
126
127
|
## 六、常见问题
|
|
127
128
|
|
package/release-notes/SKILL.md
CHANGED
|
@@ -20,13 +20,13 @@ disable-model-invocation: false
|
|
|
20
20
|
|
|
21
21
|
## ⚙️ 配置与自定义
|
|
22
22
|
|
|
23
|
-
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(REPO/LANG/CHANGELOG_FILE/REL_DIR/STATS/SCOPE_HINT)都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.md
|
|
23
|
+
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(REPO/LANG/CHANGELOG_FILE/REL_DIR/STATS/SCOPE_HINT)都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.upstream.md` 对照文件,可按需手动合并新配置点。
|
|
24
24
|
|
|
25
25
|
## 配置版本机制(升级保护)
|
|
26
26
|
|
|
27
27
|
本 skill 当前配置版本为 `1`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明不一致:
|
|
28
28
|
|
|
29
|
-
1. 先将旧 user-config.md 备份为 `user-config.md
|
|
29
|
+
1. 先将旧 user-config.md 备份为 `user-config.bak-<时间戳>.md`(同目录,绝不删除旧值)
|
|
30
30
|
2. 按本节「配置升级规则」迁移字段:新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认
|
|
31
31
|
3. 更新 CONFIG_VERSION 为当前版本
|
|
32
32
|
4. 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」
|
|
@@ -361,6 +361,7 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
|
|
|
361
361
|
<tr><td>查全部命令</td><td><span class="cmd-in">skill-forge --help</span></td></tr>
|
|
362
362
|
<tr><td>问单个技能用法</td><td>直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出</td></tr>
|
|
363
363
|
<tr><td>问 SkillForge 本身</td><td>问「skillforge 怎么用」,AI 朗读本指引并打开排版页</td></tr>
|
|
364
|
+
<tr><td>查技能双语简介 / 实操文章</td><td><span class="cmd-in">SKILLS_CATALOG.md</span>(21 技能逐条中英简介)/ <span class="cmd-in">docs/articles/</span>(实操文章)/ <span class="cmd-in">docs/directory-submission.md</span>(目录收录素材)</td></tr>
|
|
364
365
|
</table>
|
|
365
366
|
<div class="faq">
|
|
366
367
|
<div class="faq-title">常见问题</div>
|
|
@@ -122,6 +122,7 @@ skill-forge init --skills daily-report,weekly-report --yes
|
|
|
122
122
|
| 查全部命令 | skill-forge --help |
|
|
123
123
|
| 问单个技能用法 | 直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出 |
|
|
124
124
|
| 问 SkillForge 本身 | 问「skillforge 怎么用」,AI 朗读本指引并打开排版页 |
|
|
125
|
+
| 查技能双语简介 / 实操文章 | SKILLS_CATALOG.md(21 技能逐条中英简介)/ docs/articles/(实操文章)/ docs/directory-submission.md(目录收录素材) |
|
|
125
126
|
|
|
126
127
|
## 六、常见问题
|
|
127
128
|
|
package/skill-doctor/SKILL.md
CHANGED
|
@@ -19,13 +19,13 @@ disable-model-invocation: false
|
|
|
19
19
|
|
|
20
20
|
## ⚙️ 配置与自定义
|
|
21
21
|
|
|
22
|
-
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(TARGET/CHECKS/FIX)都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.md
|
|
22
|
+
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(TARGET/CHECKS/FIX)都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.upstream.md` 对照文件,可按需手动合并新配置点。
|
|
23
23
|
|
|
24
24
|
## 配置版本机制(升级保护)
|
|
25
25
|
|
|
26
26
|
本 skill 当前配置版本为 `1`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明不一致:
|
|
27
27
|
|
|
28
|
-
1. 先将旧 user-config.md 备份为 `user-config.md
|
|
28
|
+
1. 先将旧 user-config.md 备份为 `user-config.bak-<时间戳>.md`(同目录,绝不删除旧值)
|
|
29
29
|
2. 按本节「配置升级规则」迁移字段:新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认
|
|
30
30
|
3. 更新 CONFIG_VERSION 为当前版本
|
|
31
31
|
4. 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」
|
|
@@ -361,6 +361,7 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
|
|
|
361
361
|
<tr><td>查全部命令</td><td><span class="cmd-in">skill-forge --help</span></td></tr>
|
|
362
362
|
<tr><td>问单个技能用法</td><td>直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出</td></tr>
|
|
363
363
|
<tr><td>问 SkillForge 本身</td><td>问「skillforge 怎么用」,AI 朗读本指引并打开排版页</td></tr>
|
|
364
|
+
<tr><td>查技能双语简介 / 实操文章</td><td><span class="cmd-in">SKILLS_CATALOG.md</span>(21 技能逐条中英简介)/ <span class="cmd-in">docs/articles/</span>(实操文章)/ <span class="cmd-in">docs/directory-submission.md</span>(目录收录素材)</td></tr>
|
|
364
365
|
</table>
|
|
365
366
|
<div class="faq">
|
|
366
367
|
<div class="faq-title">常见问题</div>
|
|
@@ -122,6 +122,7 @@ skill-forge init --skills daily-report,weekly-report --yes
|
|
|
122
122
|
| 查全部命令 | skill-forge --help |
|
|
123
123
|
| 问单个技能用法 | 直接问「XX 技能怎么用」,AI 会读该技能的使用说明输出 |
|
|
124
124
|
| 问 SkillForge 本身 | 问「skillforge 怎么用」,AI 朗读本指引并打开排版页 |
|
|
125
|
+
| 查技能双语简介 / 实操文章 | SKILLS_CATALOG.md(21 技能逐条中英简介)/ docs/articles/(实操文章)/ docs/directory-submission.md(目录收录素材) |
|
|
125
126
|
|
|
126
127
|
## 六、常见问题
|
|
127
128
|
|
package/spec-doc2spec/SKILL.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-doc2spec
|
|
3
|
-
description:
|
|
4
|
-
文档转高质量 Markdown Skill(doc2spec)。把 Word / PDF / Markdown 文档转成结构化 Markdown——Pandoc 负责机械转换,AI 全程校对防错(量化校验断言、双通道完整性比对、表格列表修复、图片提取与 EMF/WMF 自动转 PNG、乱码与修订痕清理),转换后整理成干净的正文稿落盘。
|
|
5
|
-
可选「需求加工档」:用户要求整理成需求规格时,另出需求点+验收标准与功能单元切片。
|
|
6
|
-
图片自动提取到 assets/images(可配置 IMG_DIR);输出默认源文档同目录下 {文档名}-spec/ 子目录,可配置 OUTPUT_DIR(绝对路径同样按文档名建子目录,多文档互不覆盖)。
|
|
7
|
-
跨系统适配 macOS / Windows / Linux(Pandoc 安装、EMF 转换工具链探测)。支持 .docx(Pandoc 转换)/ .md(直接读取)/ .pdf(LibreOffice 转 docx 优先保留图片版式,降级 pdftotext 纯文本)。
|
|
8
|
-
不处理一般性的文档内容讨论(如「帮我看看这份文档讲了什么」),只处理「文档 → Markdown / 需求规格」的转换任务。
|
|
9
|
-
用户询问用法(doc2spec 怎么用/使用说明/能干什么)时走使用说明应答:读 resources/usage-guide.md 原样输出(首行标题改为「doc2spec 使用指南」),不执行任何转换命令。
|
|
3
|
+
description: 文档转高质量 Markdown Skill(doc2spec)。把 Word / PDF / Markdown 文档转成结构化 Markdown——Pandoc 负责机械转换,AI 全程校对防错(量化校验断言、双通道完整性比对、表格列表修复、图片提取与 EMF/WMF 自动转 PNG、乱码与修订痕清理),转换后整理成干净的正文稿落盘。 可选「需求加工档」:用户要求整理成需求规格时,另出需求点+验收标准与功能单元切片。 图片自动提取到 assets/images(可配置 IMG_DIR);输出默认源文档同目录下 {文档名}-spec/ 子目录,可配置 OUTPUT_DIR(绝对路径同样按文档名建子目录,多文档互不覆盖)。 跨系统适配 macOS / Windows / Linux(Pandoc 安装、EMF 转换工具链探测)。支持 .docx(Pandoc 转换)/ .md(直接读取)/ .pdf(LibreOffice 转 docx 优先保留图片版式,降级 pdftotext 纯文本)。 不处理一般性的文档内容讨论(如「帮我看看这份文档讲了什么」),只处理「文档 → Markdown / 需求规格」的转换任务。 用户询问用法(doc2spec 怎么用/使用说明/能干什么)时走使用说明应答:读 resources/usage-guide.md 原样输出(首行标题改为「doc2spec 使用指南」),不执行任何转换命令。
|
|
10
4
|
allowed-tools: ["Bash", "Read", "Write", "Edit"]
|
|
11
5
|
disable-model-invocation: false
|
|
12
6
|
---
|
|
@@ -28,13 +22,13 @@ disable-model-invocation: false
|
|
|
28
22
|
|
|
29
23
|
## ⚙️ 配置与自定义
|
|
30
24
|
|
|
31
|
-
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(OUTPUT_DIR/IMG_DIR/EMF_POLICY/CONFIRM/CONFIG_VERSION)与临时口头要求说明都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.md
|
|
25
|
+
**执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(OUTPUT_DIR/IMG_DIR/EMF_POLICY/CONFIRM/CONFIG_VERSION)与临时口头要求说明都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留;官方更新配置时另存 `user-config.upstream.md` 对照文件,可按需手动合并新配置点。
|
|
32
26
|
|
|
33
27
|
## 配置版本机制(升级保护)
|
|
34
28
|
|
|
35
29
|
本 skill 当前配置版本为 `2`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明的当前版本不一致:
|
|
36
30
|
|
|
37
|
-
1. 先将旧 user-config.md 备份为 `user-config.md
|
|
31
|
+
1. 先将旧 user-config.md 备份为 `user-config.bak-<时间戳>.md`(同目录,绝不删除旧值)
|
|
38
32
|
2. 按本节「配置升级规则」迁移字段:新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认
|
|
39
33
|
3. 更新 CONFIG_VERSION 为当前版本
|
|
40
34
|
4. 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」
|