lantern-harness 0.1.2 → 0.1.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/CHANGELOG.md +61 -0
- package/README.md +6 -6
- package/builtin/session/lh-spaces.mjs +102 -0
- package/cli/data-root.mjs +80 -3
- package/cli/lantern.mjs +2 -1
- package/cli/server.mjs +4 -0
- package/cli/spaces.mjs +91 -5
- package/config/app.defaults.json +4 -2
- package/dist/500.html +9 -5
- package/dist/_astro/Base.ByB0D4ZA.css +1 -0
- package/dist/_astro/{Base.astro_astro_type_script_index_0_lang.lxEwQ1R4.js → Base.astro_astro_type_script_index_0_lang.Cg_8YLVA.js} +1 -1
- package/dist/_astro/CaseGenerateApp.BlZyjWEr.js +9 -0
- package/dist/_astro/CasesLibrary.C76La3Xj.js +1 -0
- package/dist/_astro/ChatApp.gfsPLvan.js +269 -0
- package/dist/_astro/ColumnResize.Bs6GL3DJ.js +1 -0
- package/dist/_astro/DatePicker.BdwFRioL.js +1 -0
- package/dist/_astro/{DocsFileBrowser.DkE26UTR.js → DocsFileBrowser.BxAyrkkw.js} +1 -1
- package/dist/_astro/KnowledgeLibrary.Cv488Hot.js +1 -0
- package/dist/_astro/NavLibraries.ALZ9e12z.js +1 -0
- package/dist/_astro/PluginsPage.B2uxCiHL.js +1 -0
- package/dist/_astro/{PluginsPage.BNzpPg2H.js → PluginsPage.DEkyOfQE.js} +2 -2
- package/dist/_astro/PromptsLibrary.BUC1OiCH.js +1 -0
- package/dist/_astro/RequirementsLibrary.D3olQI63.js +1 -0
- package/dist/_astro/{SearchableSelect.DMS2XmXc.js → SearchableSelect.DP74JRWW.js} +1 -1
- package/dist/_astro/SelectDropdown.D2i7-lQC.js +1 -0
- package/dist/_astro/{SettingsDialog.DC0e7580.js → SettingsDialog.CrMDjSLJ.js} +1 -1
- package/dist/_astro/SlideOverDrawer.C7UVeCX1.js +1 -0
- package/dist/_astro/SpaceSwitcher.Wf8EPYUx.js +7 -0
- package/dist/_astro/TasksBoard.2j7rGT9O.js +1 -0
- package/dist/_astro/TemplatesLibrary.J0x7yIcY.js +1 -0
- package/dist/_astro/TodosBoard.BugeB7_7.js +1 -0
- package/dist/_astro/app-config.vqDkEMS3.js +1 -0
- package/dist/_astro/doc-roots.DAJP9Svr.js +1 -0
- package/dist/_astro/i18n.9qZsrs3u.js +7 -0
- package/dist/_astro/{open-docs-in-session.D3JCwMWB.js → open-docs-in-session.fLwnA5qh.js} +1 -1
- package/dist/_astro/plugins.DSUPSizB.js +1 -0
- package/dist/_astro/project-docs.Cd2gKPKh.js +1 -0
- package/dist/_astro/{settings.BoQ0e0m1.js → settings.CkbipdPI.js} +2 -2
- package/dist/_astro/{useListAnim.CnbC_9MC.js → useListAnim.Y3N2budK.js} +1 -1
- package/dist/cases/generate/index.html +10 -6
- package/dist/cases/library/index.html +10 -6
- package/dist/docs/changelog/index.html +69 -6
- package/dist/docs/install/index.html +22 -8
- package/dist/docs/manual/index.html +74 -11
- package/dist/index.html +10 -6
- package/dist/knowledge/index.html +10 -6
- package/dist/knowledge//345/212/237/350/203/275/346/265/213/350/257/225/347/224/250/344/276/213/347/274/226/345/206/231/350/247/204/350/214/203/index.html +9 -5
- package/dist/plugins/index.html +10 -6
- package/dist/prompts/index.html +10 -6
- package/dist/requirements/index.html +10 -6
- package/dist/tasks/index.html +253 -0
- package/dist/templates/index.html +10 -6
- package/dist/templates//345/212/237/350/203/275/346/265/213/350/257/225/346/212/245/345/221/212//345/212/237/350/203/275/346/265/213/350/257/225/346/212/245/345/221/212/346/250/241/346/235/277/index.html +9 -5
- package/dist/templates//346/200/247/350/203/275/346/265/213/350/257/225/346/212/245/345/221/212//346/200/247/350/203/275/346/265/213/350/257/225/346/212/245/345/221/212/346/250/241/346/235/277/index.html +9 -5
- package/dist/templates//346/200/247/350/203/275/346/265/213/350/257/225/347/224/250/344/276/213//346/200/247/350/203/275/346/265/213/350/257/225/347/224/250/344/276/213/346/250/241/346/235/277/index.html +9 -5
- package/dist/templates//346/216/245/345/217/243/346/265/213/350/257/225/346/212/245/345/221/212//346/216/245/345/217/243/346/265/213/350/257/225/346/212/245/345/221/212/346/250/241/346/235/277/index.html +9 -5
- package/dist/templates//350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/347/224/250/344/276/213//350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/347/224/250/344/276/213/346/250/241/346/235/277/index.html +9 -5
- package/dist/todos/index.html +253 -0
- package/docs//345/205/250/345/261/200/346/217/222/344/273/266.md +2 -2
- package/docs//345/256/211/350/243/205/346/211/213/345/206/214.md +10 -8
- package/docs//346/223/215/344/275/234/346/211/213/345/206/214.md +73 -23
- package/lh-plugins/lh-project-docs.mjs +2 -0
- package/lh-plugins/lh-tasks.mjs +223 -0
- package/lh-plugins/lh-todos.mjs +297 -0
- package/lh-plugins/storage-domain.mjs +1 -0
- package/package.json +1 -1
- package/dist/_astro/Base.B9f_iFAZ.css +0 -1
- package/dist/_astro/CaseGenerateApp.Br4uKjun.js +0 -9
- package/dist/_astro/CasesLibrary.CpPoVQ4P.js +0 -1
- package/dist/_astro/ChatApp.CYSPlSNP.js +0 -258
- package/dist/_astro/KnowledgeLibrary.DZinlAWn.js +0 -1
- package/dist/_astro/NavLibraries.EayBsg5g.js +0 -1
- package/dist/_astro/PluginsPage.CY61glLU.js +0 -1
- package/dist/_astro/PromptsLibrary.DfrrCjs7.js +0 -1
- package/dist/_astro/RequirementsLibrary.Dt0Gj6Nr.js +0 -1
- package/dist/_astro/SelectDropdown.Dc7QaPbH.js +0 -1
- package/dist/_astro/SpaceSwitcher.Yy2w8MDF.js +0 -7
- package/dist/_astro/TemplatesLibrary.uK-SjK1z.js +0 -1
- package/dist/_astro/app-config.CpjKWnzM.js +0 -1
- package/dist/_astro/i18n.BVvhz-vw.js +0 -7
- package/dist/_astro/plugins.CrpY8UI9.js +0 -1
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" type="image/png" sizes="32x32" href="/favicon.png"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><title>待办事项 · Lantern Harness</title><script>
|
|
2
|
+
// 尽早禁用滚动恢复,避免整页跳转/切页时停在旧滚动位置造成文字叠影
|
|
3
|
+
try {
|
|
4
|
+
if ('scrollRestoration' in history) history.scrollRestoration = 'manual';
|
|
5
|
+
} catch (e) {}
|
|
6
|
+
</script><script type="module" src="/_astro/Base.astro_astro_type_script_index_0_lang.Cg_8YLVA.js"></script><meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback" content="animate"><script type="module" src="/_astro/ClientRouter.astro_astro_type_script_index_0_lang.CO1cjG9V.js"></script><script>
|
|
7
|
+
(function () {
|
|
8
|
+
try {
|
|
9
|
+
var raw = localStorage.getItem('tw.app.config.v1');
|
|
10
|
+
if (raw) {
|
|
11
|
+
var cfg = JSON.parse(raw);
|
|
12
|
+
var g = (cfg && cfg.general) || {};
|
|
13
|
+
var root = document.documentElement;
|
|
14
|
+
var size = typeof g.sessionFontSize === 'number' ? Math.round(g.sessionFontSize) : 14;
|
|
15
|
+
if (size < 12) size = 12;
|
|
16
|
+
if (size > 22) size = 22;
|
|
17
|
+
var px = size + 'px';
|
|
18
|
+
root.style.setProperty('--tw-ui-font-size', px);
|
|
19
|
+
root.style.setProperty('--tw-session-font-size', px);
|
|
20
|
+
var appearance = g.appearance;
|
|
21
|
+
var theme =
|
|
22
|
+
appearance === 'dark' || appearance === 'light'
|
|
23
|
+
? appearance
|
|
24
|
+
: window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
25
|
+
? 'dark'
|
|
26
|
+
: 'light';
|
|
27
|
+
root.dataset.theme = theme;
|
|
28
|
+
root.style.colorScheme = theme;
|
|
29
|
+
if (g.language === 'en') root.lang = 'en';
|
|
30
|
+
}
|
|
31
|
+
if (localStorage.getItem('tw.nav.collapsed') === '1') {
|
|
32
|
+
document.documentElement.dataset.navCollapsed = '1';
|
|
33
|
+
}
|
|
34
|
+
var spaceId = (
|
|
35
|
+
sessionStorage.getItem('tw.space.active-id') ||
|
|
36
|
+
localStorage.getItem('tw.space.active-id') ||
|
|
37
|
+
''
|
|
38
|
+
).trim();
|
|
39
|
+
var cfgKey = spaceId ? 'tw.app.config.v1::' + spaceId : 'tw.app.config.v1';
|
|
40
|
+
var cfgRaw = localStorage.getItem(cfgKey) || localStorage.getItem('tw.app.config.v1');
|
|
41
|
+
if (cfgRaw) {
|
|
42
|
+
var savedCfg = JSON.parse(cfgRaw) || {};
|
|
43
|
+
var plugins = savedCfg.plugins || {};
|
|
44
|
+
if (plugins.cases === false) document.documentElement.dataset.pluginOffCases = '1';
|
|
45
|
+
if (plugins.todos === false) document.documentElement.dataset.pluginOffTodos = '1';
|
|
46
|
+
if (plugins.tasks === false) document.documentElement.dataset.pluginOffTasks = '1';
|
|
47
|
+
if (plugins.knowledgeLib === false)
|
|
48
|
+
document.documentElement.dataset.pluginOffKnowledgeLib = '1';
|
|
49
|
+
if (plugins.requirements === false)
|
|
50
|
+
document.documentElement.dataset.pluginOffRequirements = '1';
|
|
51
|
+
if (plugins.templates === false)
|
|
52
|
+
document.documentElement.dataset.pluginOffTemplates = '1';
|
|
53
|
+
// 本地已有菜单布局:静态占位(固定顺序平铺)不再亮相,避免闪一下「排序前」
|
|
54
|
+
if (Array.isArray(savedCfg.navGroups) || Array.isArray(savedCfg.navOrder)) {
|
|
55
|
+
document.documentElement.dataset.navCached = '1';
|
|
56
|
+
// 兜底:脚本没跑起来(岛始终为空)时把占位放回来,别让侧栏彻底空着
|
|
57
|
+
window.setTimeout(function () {
|
|
58
|
+
var island = document.querySelector('.tw-nav-libraries astro-island');
|
|
59
|
+
if (!island || !island.querySelector('.tw-nav-item-main')) {
|
|
60
|
+
document.documentElement.removeAttribute('data-nav-cached');
|
|
61
|
+
}
|
|
62
|
+
}, 3000);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} catch (e) {}
|
|
66
|
+
})();
|
|
67
|
+
</script><link rel="stylesheet" href="/_astro/Base.ByB0D4ZA.css"><script type="module" src="/_astro/page.Bx2KSkeL.js"></script><style>[data-astro-transition-scope="astro-bbhp3f5g-3"] { view-transition-name: astro-bbhp3f5g-3; }@layer astro { ::view-transition-old(astro-bbhp3f5g-3) {
|
|
68
|
+
animation-duration: 180ms;
|
|
69
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
70
|
+
animation-fill-mode: both;
|
|
71
|
+
animation-name: astroFadeOut; }::view-transition-new(astro-bbhp3f5g-3) {
|
|
72
|
+
animation-duration: 180ms;
|
|
73
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
74
|
+
animation-fill-mode: both;
|
|
75
|
+
animation-name: astroFadeIn; }[data-astro-transition=back]::view-transition-old(astro-bbhp3f5g-3) {
|
|
76
|
+
animation-duration: 180ms;
|
|
77
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
78
|
+
animation-fill-mode: both;
|
|
79
|
+
animation-name: astroFadeOut; }[data-astro-transition=back]::view-transition-new(astro-bbhp3f5g-3) {
|
|
80
|
+
animation-duration: 180ms;
|
|
81
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
82
|
+
animation-fill-mode: both;
|
|
83
|
+
animation-name: astroFadeIn; } }[data-astro-transition-fallback="old"] [data-astro-transition-scope="astro-bbhp3f5g-3"],
|
|
84
|
+
[data-astro-transition-fallback="old"][data-astro-transition-scope="astro-bbhp3f5g-3"] {
|
|
85
|
+
animation-duration: 180ms;
|
|
86
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
87
|
+
animation-fill-mode: both;
|
|
88
|
+
animation-name: astroFadeOut; }[data-astro-transition-fallback="new"] [data-astro-transition-scope="astro-bbhp3f5g-3"],
|
|
89
|
+
[data-astro-transition-fallback="new"][data-astro-transition-scope="astro-bbhp3f5g-3"] {
|
|
90
|
+
animation-duration: 180ms;
|
|
91
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
92
|
+
animation-fill-mode: both;
|
|
93
|
+
animation-name: astroFadeIn; }[data-astro-transition=back][data-astro-transition-fallback="old"] [data-astro-transition-scope="astro-bbhp3f5g-3"],
|
|
94
|
+
[data-astro-transition=back][data-astro-transition-fallback="old"][data-astro-transition-scope="astro-bbhp3f5g-3"] {
|
|
95
|
+
animation-duration: 180ms;
|
|
96
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
97
|
+
animation-fill-mode: both;
|
|
98
|
+
animation-name: astroFadeOut; }[data-astro-transition=back][data-astro-transition-fallback="new"] [data-astro-transition-scope="astro-bbhp3f5g-3"],
|
|
99
|
+
[data-astro-transition=back][data-astro-transition-fallback="new"][data-astro-transition-scope="astro-bbhp3f5g-3"] {
|
|
100
|
+
animation-duration: 180ms;
|
|
101
|
+
animation-timing-function: cubic-bezier(0.76, 0, 0.24, 1);
|
|
102
|
+
animation-fill-mode: both;
|
|
103
|
+
animation-name: astroFadeIn; }</style></head><body class="tw-body antialiased"><div class="tw-shell min-h-screen"><aside class="tw-nav-aside fixed inset-y-0 left-0 flex flex-col z-45" id="tw-nav-aside"><div class="tw-nav-brand"><div class="tw-nav-brand-row"><a href="/" class="tw-nav-brand-link min-w-0 flex-1"><span class="tw-nav-brand-mark" aria-hidden="true"><img class="tw-nav-brand-mark-img" src="/brand-mark.png" alt="" width="36" height="36"></span><span class="tw-nav-brand-text"><span class="tw-nav-brand-title-row"><span class="tw-nav-brand-title" data-i18n="nav.brand">Lantern Harness</span><span class="tw-nav-brand-ver" data-hint="平台版本 v0.1.2">v0.1.2</span></span></span></a></div></div><div class="tw-nav-space-slot"><div class="tw-nav-space tw-nav-space-ph" id="tw-nav-space-ph" aria-hidden="true"><div class="tw-nav-space-ph-box"><span class="tw-nav-space-ph-ico"></span><span class="tw-nav-space-ph-lines"><span class="tw-nav-space-ph-bar is-cap"></span><span class="tw-nav-space-ph-bar is-name"></span></span></div></div><style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(function(){let e=async e=>{await(await e())()};(self.Astro||(self.Astro={})).only=e,window.dispatchEvent(new Event(`astro:only`))})();</script><script>(function(){function e(t){"@babel/helpers - typeof";return e=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},e(t)}function t(t,n){if(e(t)!=`object`||!t)return t;var r=t[Symbol.toPrimitive];if(r!==void 0){var i=r.call(t,n||`default`);if(e(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(t)}function n(n){var r=t(n,`string`);return e(r)==`symbol`?r:r+``}function r(e,t,r){return(t=n(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}let i=/* @__PURE__ */ new Set([`__proto__`,`constructor`,`prototype`]);{let e={0:e=>a(e),1:e=>n(e),2:e=>new RegExp(e),3:e=>new Date(e),4:e=>new Map(n(e)),5:e=>new Set(n(e)),6:e=>BigInt(e),7:e=>new URL(e),8:e=>new Uint8Array(e),9:e=>new Uint16Array(e),10:e=>new Uint32Array(e),11:e=>1/0*e},t=t=>{let[n,r]=t;return n in e?e[n](r):void 0},n=e=>e.map(t),a=e=>typeof e!=`object`||!e?e:Object.fromEntries(Object.entries(e).map(([e,n])=>[e,t(n)]));class o extends HTMLElement{constructor(...e){super(...e),r(this,`Component`,void 0),r(this,`hydrator`,void 0),r(this,`hydrate`,async()=>{var e;if(!this.hydrator||!this.isConnected)return;let t=(e=this.parentElement)==null?void 0:e.closest(`astro-island[ssr]`);if(t){t.addEventListener(`astro:hydrate`,this.hydrate,{once:!0});return}let n=this.querySelectorAll(`astro-slot`),r={},i=this.querySelectorAll(`template[data-astro-template]`);for(let e of i){let t=e.closest(this.tagName);t!=null&&t.isSameNode(this)&&(r[e.getAttribute(`data-astro-template`)||`default`]=e.innerHTML,e.remove())}for(let e of n){let t=e.closest(this.tagName);t!=null&&t.isSameNode(this)&&(r[e.getAttribute(`name`)||`default`]=e.innerHTML)}let o;try{o=this.hasAttribute(`props`)?a(JSON.parse(this.getAttribute(`props`))):{}}catch(e){let t=this.getAttribute(`component-url`)||`<unknown>`,n=this.getAttribute(`component-export`);throw n&&(t+=` (export ${n})`),console.error(`[hydrate] Error parsing props for component ${t}`,this.getAttribute(`props`),e),e}await this.hydrator(this)(this.Component,o,r,{client:this.getAttribute(`client`)}),this.removeAttribute(`ssr`),this.dispatchEvent(new CustomEvent(`astro:hydrate`))}),r(this,`unmount`,()=>{this.isConnected||this.dispatchEvent(new CustomEvent(`astro:unmount`))})}disconnectedCallback(){document.removeEventListener(`astro:after-swap`,this.unmount),document.addEventListener(`astro:after-swap`,this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute(`await-children`)||document.readyState===`interactive`||document.readyState===`complete`)this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener(`DOMContentLoaded`,e),t.disconnect(),this.childrenConnectedCallback()},t=new MutationObserver(()=>{var t;((t=this.lastChild)==null?void 0:t.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue===`astro:end`&&(this.lastChild.remove(),e())});t.observe(this,{childList:!0}),document.addEventListener(`DOMContentLoaded`,e)}}async childrenConnectedCallback(){let e=this.getAttribute(`before-hydration-url`);e&&await import(e),this.start()}getRetryImportUrl(e){let t=new URL(e,document.baseURI);return t.searchParams.set(`astro-retry`,Date.now().toString()),t.toString()}async importWithRetry(e){try{return await import(e)}catch(t){return await new Promise(e=>setTimeout(e,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let t=this.getAttribute(`component-url`),n=new CustomEvent(`astro:hydration-error`,{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:t}});this.dispatchEvent(n)&&console.error(`[astro-island] Error hydrating ${t}`,e)}async start(){let e=JSON.parse(this.getAttribute(`opts`)),t=this.getAttribute(`client`);if(Astro[t]===void 0)window.addEventListener(`astro:${t}`,()=>this.start(),{once:!0});else try{await Astro[t](async()=>{let e=this.getAttribute(`renderer-url`);try{let[t,{default:n}]=await Promise.all([this.importWithRetry(this.getAttribute(`component-url`)),e?this.importWithRetry(e):Promise.resolve({default:()=>()=>{}})]),r=this.getAttribute(`component-export`)||`default`;if(r.includes(`.`)){this.Component=t;for(let e of r.split(`.`)){if(i.has(e)||!this.Component||typeof this.Component!=`object`&&typeof this.Component!=`function`||!Object.hasOwn(this.Component,e))throw Error(`Invalid component export path: ${r}`);this.Component=this.Component[e]}}else{if(i.has(r))throw Error(`Invalid component export path: ${r}`);this.Component=t[r]}return this.hydrator=n,this.hydrate}catch(e){return this.handleHydrationError(e),()=>{}}},e,this)}catch(e){this.handleHydrationError(e)}}attributeChangedCallback(){this.hydrate()}}r(o,`observedAttributes`,[`props`]),customElements.get(`astro-island`)||customElements.define(`astro-island`,o)}})();</script><astro-island uid="2wH2Dz" component-url="/_astro/SpaceSwitcher.Wf8EPYUx.js" component-export="default" renderer-url="/_astro/client.Be_SakrB.js" props="{"data-astro-transition-persist":[0,"astro-gyrtbwwo-1"]}" ssr client="only" opts="{"name":"SpaceSwitcher","value":"react"}" data-astro-transition-persist="astro-gyrtbwwo-1"></astro-island></div><button type="button" id="tw-nav-toggle" class="tw-nav-toggle" aria-label="收起或展开左侧导航" aria-expanded="true" aria-controls="tw-nav-aside"><svg class="tw-nav-toggle-icon is-collapse" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 6l-6 6 6 6"></path></svg><svg class="tw-nav-toggle-icon is-expand" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 6l6 6-6 6"></path></svg></button><nav class="tw-nav-list flex-1 overflow-y-auto"><a href="/" class="tw-nav-item" data-i18n-hint="nav.home" data-hint="我的工作台"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M3 10.5 12 3l9 7.5"></path><path d="M5 9.5V20h14V9.5"></path></svg><span class="tw-nav-label" data-i18n="nav.home">我的工作台</span></a><div class="tw-nav-libraries"><div class="tw-nav-libraries-ph"><a href="/tasks/" class="tw-nav-item" data-plugin-nav="tasks"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M9 5h10"></path><path d="M9 12h10"></path><path d="M9 19h10"></path><path d="M4 5h.01"></path><path d="M4 12h.01"></path><path d="M4 19h.01"></path></svg><span class="tw-nav-label" data-i18n="nav.tasks">任务管理</span></a><a href="/todos/" class="tw-nav-item is-active font-medium" data-plugin-nav="todos"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M8 6h13"></path><path d="M8 12h13"></path><path d="M8 18h13"></path><path d="M3 6h.01"></path><path d="M3 12h.01"></path><path d="M3 18h.01"></path></svg><span class="tw-nav-label" data-i18n="nav.todos">待办事项</span></a><a href="/cases/library/" class="tw-nav-item" data-plugin-nav="cases"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M9 11l3 3L22 4"></path><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path></svg><span class="tw-nav-label" data-i18n="nav.caseManage">用例管理</span></a><a href="/knowledge/" class="tw-nav-item" data-plugin-nav="knowledgeLib"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg><span class="tw-nav-label" data-i18n="nav.knowledge">知识库管理</span></a><a href="/requirements/" class="tw-nav-item" data-plugin-nav="requirements" data-i18n-hint="nav.requirements"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M14 3v5h5"></path><path d="M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z"></path><path d="M8 13h8"></path><path d="M8 17h6"></path></svg><span class="tw-nav-label" data-i18n="nav.requirements">需求文档库</span></a><a href="/templates/" class="tw-nav-item" data-plugin-nav="templates" data-i18n-hint="nav.templates"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M12 3 3 8l9 5 9-5-9-5z"></path><path d="m3 13 9 5 9-5"></path></svg><span class="tw-nav-label" data-i18n="nav.templates">测试模板库</span></a></div><astro-island uid="Z1lgSd4" component-url="/_astro/NavLibraries.ALZ9e12z.js" component-export="default" renderer-url="/_astro/client.Be_SakrB.js" props="{"data-astro-transition-persist":[0,"astro-iywf7oe7-2"]}" ssr client="only" opts="{"name":"NavLibraries","value":"react"}" data-astro-transition-persist="astro-iywf7oe7-2"></astro-island></div><a href="/prompts/" class="tw-nav-item" data-plugin-nav="prompts" data-pinned-nav="prompts"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M12 20h9"></path><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"></path></svg><span class="tw-nav-label" data-i18n="nav.prompts">提示词管理</span></a><a href="/docs/manual/" class="tw-nav-item" data-hint="帮助中心" data-i18n-hint="nav.helpCenter"><svg class="tw-nav-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><path d="M5 4.5h9.5L19 9v10.5H5V4.5Z" stroke-linejoin="round"></path><path d="M14.5 4.5V9H19" stroke-linejoin="round"></path><path d="M8 13h8M8 16.5h6" stroke-linecap="round"></path></svg><span class="tw-nav-label" data-i18n="nav.helpCenter">帮助中心</span></a></nav><div class="tw-nav-foot"><script>(function(){let e=async e=>{await(await e())()};(self.Astro||(self.Astro={})).load=e,window.dispatchEvent(new Event(`astro:load`))})();</script><astro-island uid="Z12jkyC" prefix="r1" component-url="/_astro/SettingsDialog.CrMDjSLJ.js" component-export="default" renderer-url="/_astro/client.Be_SakrB.js" props="{}" ssr client="load" opts="{"name":"SettingsDialog","value":true}" await-children><div class="tw-nav-foot-row"><button type="button" class="tw-nav-settings-btn" data-hint="设置"><svg class="tw-nav-ico w-4.5 h-4.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" aria-hidden="true"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9c.2.6.7 1 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"></path></svg><span data-i18n="nav.settings">设置</span></button><button type="button" class="tw-nav-provider-chip is-empty" data-hint="未配置模型"><span class="tw-nav-provider-dot" aria-hidden="true"></span><span class="tw-nav-provider-name">未配置</span></button></div><span hidden="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"></span><!--astro:end--></astro-island></div></aside><script data-astro-rerun>
|
|
104
|
+
(function () {
|
|
105
|
+
var root = document.documentElement;
|
|
106
|
+
var btn = document.getElementById('tw-nav-toggle');
|
|
107
|
+
function apply(collapsed) {
|
|
108
|
+
if (collapsed) root.dataset.navCollapsed = '1';
|
|
109
|
+
else delete root.dataset.navCollapsed;
|
|
110
|
+
try {
|
|
111
|
+
localStorage.setItem('tw.nav.collapsed', collapsed ? '1' : '0');
|
|
112
|
+
} catch (e) {}
|
|
113
|
+
if (btn) {
|
|
114
|
+
btn.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
|
|
115
|
+
// 气泡已移除;改为动态更新不可见标签,读屏仍能获知当前动作
|
|
116
|
+
btn.setAttribute('aria-label', collapsed ? '展开导航' : '收起导航');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
apply(root.dataset.navCollapsed === '1');
|
|
120
|
+
if (btn) {
|
|
121
|
+
btn.addEventListener('click', function () {
|
|
122
|
+
apply(root.dataset.navCollapsed !== '1');
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
var raw = localStorage.getItem('tw.app.config.v1');
|
|
128
|
+
if (!raw) return;
|
|
129
|
+
var g = JSON.parse(raw).general || {};
|
|
130
|
+
if (g.language !== 'en') return;
|
|
131
|
+
var en = {
|
|
132
|
+
'nav.brand': 'Lantern Harness',
|
|
133
|
+
'nav.home': 'My Workbench',
|
|
134
|
+
'nav.tasks': 'Tasks',
|
|
135
|
+
'nav.todos': 'Todos',
|
|
136
|
+
'nav.caseManage': 'Test Cases',
|
|
137
|
+
'nav.prompts': 'Prompts',
|
|
138
|
+
'nav.knowledge': 'Knowledge Mgmt',
|
|
139
|
+
'nav.plugins': 'My Plugins',
|
|
140
|
+
'nav.docs': 'Documents',
|
|
141
|
+
'nav.requirements': 'Requirements',
|
|
142
|
+
'nav.templates': 'Test Templates',
|
|
143
|
+
'nav.settings': 'Settings',
|
|
144
|
+
'nav.changelog': 'Changelog',
|
|
145
|
+
'nav.changelogShort': 'Changelog',
|
|
146
|
+
'nav.helpCenter': 'Help Center',
|
|
147
|
+
'docs.nav.title': 'Docs',
|
|
148
|
+
'docs.nav.changelog': 'Changelog',
|
|
149
|
+
'docs.nav.manual': 'User Guide',
|
|
150
|
+
'docs.nav.install': 'Install Guide',
|
|
151
|
+
'nav.repo': 'GitHub',
|
|
152
|
+
'nav.repoShort': 'Repo',
|
|
153
|
+
'nav.npm': 'npm package',
|
|
154
|
+
'nav.npmShort': 'npm',
|
|
155
|
+
'nav.site': 'Yycy Docs',
|
|
156
|
+
'nav.siteShort': 'Site',
|
|
157
|
+
'nav.board': 'Questions & suggestions',
|
|
158
|
+
'nav.boardShort': 'Suggestions',
|
|
159
|
+
};
|
|
160
|
+
document.querySelectorAll('[data-i18n]').forEach(function (el) {
|
|
161
|
+
var key = el.getAttribute('data-i18n');
|
|
162
|
+
if (key && en[key]) el.textContent = en[key];
|
|
163
|
+
});
|
|
164
|
+
document.querySelectorAll('[data-i18n-hint]').forEach(function (el) {
|
|
165
|
+
var key = el.getAttribute('data-i18n-hint');
|
|
166
|
+
if (key && en[key]) el.setAttribute('data-hint', en[key]);
|
|
167
|
+
});
|
|
168
|
+
} catch (e) {}
|
|
169
|
+
})();
|
|
170
|
+
</script><main data-astro-transition-scope="astro-bbhp3f5g-3" class="tw-main min-h-screen"><div id="tw-route-loading" class="tw-route-loading is-hidden" role="status" aria-live="polite" aria-label="页面加载中"><span class="tw-route-loading-spin" aria-hidden="true"></span></div><div class="tw-library-page tw-library-wide px-8 py-8"><header class="mb-6 shrink-0"><h1 class="text-2xl font-bold text-stone-900">待办事项</h1><p class="mt-2 text-sm text-stone-500">按状态与紧急程度跟踪待办;工作台会话里也能让 AI 直接记录、更新同一份待办。</p></header><astro-island uid="7kN3O" component-url="/_astro/TodosBoard.BugeB7_7.js" component-export="default" renderer-url="/_astro/client.Be_SakrB.js" props="{}" ssr client="only" opts="{"name":"TodosBoard","value":"react"}"></astro-island></div></main></div><script>
|
|
171
|
+
(function () {
|
|
172
|
+
/**
|
|
173
|
+
* 切页滚回顶部。
|
|
174
|
+
* 只在「换页后」重置:若在 before-preparation(点击瞬间)就重置,
|
|
175
|
+
* 当前页面会先跳回顶部、再等新页到达,用户看到的就是「打开时还在滚动」。
|
|
176
|
+
* 带锚点(#)时交给浏览器定位,不强制回顶。
|
|
177
|
+
*/
|
|
178
|
+
try {
|
|
179
|
+
if ('scrollRestoration' in history) history.scrollRestoration = 'manual';
|
|
180
|
+
} catch (e) {}
|
|
181
|
+
function twScrollTop() {
|
|
182
|
+
if (location.hash) return;
|
|
183
|
+
if (window.scrollY === 0 && document.documentElement.scrollTop === 0) return;
|
|
184
|
+
try {
|
|
185
|
+
// instant:不受将来可能加入的 scroll-behavior: smooth 影响
|
|
186
|
+
window.scrollTo({ top: 0, left: 0, behavior: 'instant' });
|
|
187
|
+
} catch (e) {
|
|
188
|
+
// 旧浏览器不认 instant,会抛 TypeError,退回普通写法
|
|
189
|
+
window.scrollTo(0, 0);
|
|
190
|
+
}
|
|
191
|
+
document.documentElement.scrollTop = 0;
|
|
192
|
+
document.body.scrollTop = 0;
|
|
193
|
+
var main = document.querySelector('.tw-main');
|
|
194
|
+
if (main) main.scrollTop = 0;
|
|
195
|
+
}
|
|
196
|
+
document.addEventListener('astro:after-swap', twScrollTop);
|
|
197
|
+
document.addEventListener('astro:page-load', twScrollTop);
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* 软导航「闪白」修复。
|
|
201
|
+
* ClientRouter 交换文档时,会用新文档 <html> 的属性整体替换当前 <html>,
|
|
202
|
+
* 于是 data-theme 连同 style 里的 color-scheme 一起被清空;在主题属性
|
|
203
|
+
* 恢复之前,color-scheme 回落到 normal,画布变白 —— 深色主题下就是
|
|
204
|
+
* 切页瞬间的闪白(与具体页面无关,所有路由都受影响)。
|
|
205
|
+
* 在交换前把主题 / 语言写进新文档的 <html>,交换完成时即已带上,不留空档。
|
|
206
|
+
*/
|
|
207
|
+
document.addEventListener('astro:before-swap', function (e) {
|
|
208
|
+
var next = e.newDocument;
|
|
209
|
+
if (!next || !next.documentElement) return;
|
|
210
|
+
var cur = document.documentElement;
|
|
211
|
+
var nextRoot = next.documentElement;
|
|
212
|
+
var theme = cur.dataset.theme;
|
|
213
|
+
if (theme) {
|
|
214
|
+
nextRoot.dataset.theme = theme;
|
|
215
|
+
nextRoot.style.colorScheme = theme;
|
|
216
|
+
}
|
|
217
|
+
if (cur.lang) nextRoot.lang = cur.lang;
|
|
218
|
+
// 新文档是「解析」出来的:head 里的内联脚本在解析阶段不会执行,
|
|
219
|
+
// 于是所有运行期写在 <html> 上的状态都不会自带。主题 / 语言之外,
|
|
220
|
+
// 侧栏收起状态与空间服务可用性同样要显式搬过去,否则每次软导航都会丢
|
|
221
|
+
// (表现为侧栏自己弹开、骨架又冒出来)。
|
|
222
|
+
if (cur.dataset.navCollapsed === '1') nextRoot.dataset.navCollapsed = '1';
|
|
223
|
+
if (cur.dataset.spaceService) nextRoot.dataset.spaceService = cur.dataset.spaceService;
|
|
224
|
+
// 插件开关同理:不搬过去会先亮出被隐藏的侧栏入口,等 page-load 再收起
|
|
225
|
+
[
|
|
226
|
+
'pluginOffTasks',
|
|
227
|
+
'pluginOffTodos',
|
|
228
|
+
'pluginOffCases',
|
|
229
|
+
'pluginOffKnowledgeLib',
|
|
230
|
+
'pluginOffRequirements',
|
|
231
|
+
'pluginOffTemplates',
|
|
232
|
+
].forEach(function (key) {
|
|
233
|
+
if (cur.dataset[key]) nextRoot.dataset[key] = cur.dataset[key];
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
/** 版本日志「查看更多」:委托绑定,兼容 View Transitions 软导航 */
|
|
238
|
+
document.addEventListener('click', function (e) {
|
|
239
|
+
var t = e.target;
|
|
240
|
+
if (!(t instanceof Element)) return;
|
|
241
|
+
var btn = t.closest('.tw-changelog-toggle');
|
|
242
|
+
if (!(btn instanceof HTMLButtonElement)) return;
|
|
243
|
+
var card = btn.closest('.tw-changelog-card');
|
|
244
|
+
if (!(card instanceof HTMLElement)) return;
|
|
245
|
+
e.preventDefault();
|
|
246
|
+
var next = card.getAttribute('data-open') !== 'true';
|
|
247
|
+
card.setAttribute('data-open', next ? 'true' : 'false');
|
|
248
|
+
btn.setAttribute('aria-expanded', next ? 'true' : 'false');
|
|
249
|
+
var label = btn.querySelector('.tw-changelog-toggle-label');
|
|
250
|
+
if (label) label.textContent = next ? '收起' : '查看更多';
|
|
251
|
+
});
|
|
252
|
+
})();
|
|
253
|
+
</script></body></html>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- **策略**:平台默认能力目录;插件页「全局」Tab 展示,多数无用户开关。
|
|
6
6
|
- **实现层**:本文件为规格说明;**不等于**已全部实现。与扩展/`tb-*` 有重叠的在「Lantern Harness 映射」注明。
|
|
7
|
-
- **扩展插件**(可开关,另见 `plugins.ts`):`cases` / `prompts` / `knowledgeLib` / `requirements` / `templates`(侧栏库入口与内容根)以及 `caseGen` / `promptGen` / `knowledgeGen` / `knowledge` / `memory` / `pluginDev` — 对应 `lh-kb`、`lh-memory`、`lh-project-docs` 等,不在本全局清单逐条重复产品开关逻辑。
|
|
7
|
+
- **扩展插件**(可开关,另见 `plugins.ts`):`cases` / `prompts` / `knowledgeLib` / `requirements` / `templates`(侧栏库入口与内容根)以及 `caseGen` / `promptGen` / `knowledgeGen` / `knowledge` / `memory` / `todos` / `tasks` / `pluginDev` — 对应 `lh-kb`、`lh-memory`、`lh-project-docs`、`lh-todos`、`lh-tasks` 等,不在本全局清单逐条重复产品开关逻辑。
|
|
8
8
|
|
|
9
9
|
## 目录
|
|
10
10
|
|
|
@@ -316,7 +316,7 @@
|
|
|
316
316
|
- **状态**:部分就绪
|
|
317
317
|
- **Lantern Harness 映射**:[`storage-domain.mjs`](../lh-plugins/storage-domain.mjs) → `GET /__tb_config/storage-domains`
|
|
318
318
|
|
|
319
|
-
**行为**:列举 `.local` 下已知域(sessions / jsonl / checkpoints / schedules / spill / memories 等)及存在性与体积。
|
|
319
|
+
**行为**:列举 `.local` 下已知域(sessions / jsonl / checkpoints / schedules / spill / memories / todos 等)及存在性与体积。
|
|
320
320
|
|
|
321
321
|
**说明**:只读清单,非通用 domain KV API;不含密钥明文。
|
|
322
322
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 安装手册
|
|
2
2
|
|
|
3
|
-
要求本地已安装 [Node.js](https://nodejs.org/)(需 22.22
|
|
3
|
+
要求本地已安装 [Node.js](https://nodejs.org/)(需 22.22 及以上)。装好后在侧栏「设置」里配置模型 API Key(自带密钥,仅存本机);默认地址 `http://127.0.0.1:4321/`。
|
|
4
4
|
|
|
5
5
|
## 方式一:本地服务(推荐)
|
|
6
6
|
|
|
@@ -69,14 +69,16 @@ lantern acp # 进阶:以 ACP 子集供外部编排驱动无 UI Agen
|
|
|
69
69
|
|
|
70
70
|
### 5. 首次进入看到什么
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
新建空间默认开启「提示词管理」,其余插件默认关闭,所以侧栏只有「我的工作台」「提示词管理」「帮助中心」三项。每个空间都会自动带上自己的「默认提示词.md」,可随时在「提示词管理」或「空间管理 → 编辑」中修改。需要用例 / 知识库 / 任务 / 待办 / 记忆 / 插件开发等入口时,进入「插件」页在「扩展插件」里按分类开启:
|
|
73
73
|
|
|
74
|
-
| 分类 | 插件
|
|
75
|
-
| ---------- |
|
|
76
|
-
| 内容库 |
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
74
|
+
| 分类 | 插件 | 新建空间默认 |
|
|
75
|
+
| ---------- | -------------------------------------------- | ------------ |
|
|
76
|
+
| 内容库 | 用例管理、知识库管理、需求文档库、测试模板库 | 关 |
|
|
77
|
+
| 内容库 | 提示词管理 | 开(内置) |
|
|
78
|
+
| 生成能力 | 生成测试用例、生成提示词、生成知识库 | 关 |
|
|
79
|
+
| 记忆与检索 | 知识库检索、会话记忆 | 关 |
|
|
80
|
+
| 待办与效率 | 任务管理、待办事项 | 关 |
|
|
81
|
+
| 开发工具 | 插件开发 | 关 |
|
|
80
82
|
|
|
81
83
|
## 方式二:源码启动
|
|
82
84
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
界面从左到右为:左侧导航(功能入口)→ 中间内容区(工作台 / 内容库)→ 底部「设置」。首次使用请先完成模型配置。
|
|
4
4
|
|
|
5
|
-
| 区域 | 内容
|
|
6
|
-
| -------- |
|
|
7
|
-
| 左侧导航 |
|
|
8
|
-
| 底部设置 | 通用设置与模型(BYOK)配置
|
|
9
|
-
| 帮助中心 | 版本日志 / 操作手册 / 安装手册,以及「问题与建议」外链
|
|
5
|
+
| 区域 | 内容 |
|
|
6
|
+
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| 左侧导航 | 新建空间默认有「我的工作台」「提示词管理」「帮助中心」;提示词管理固定在帮助中心上方、不参与分组排序,其余内容库开启插件后才出现用例管理 / 知识库管理 / 需求文档库 / 测试模板库(可自行建分组) |
|
|
8
|
+
| 底部设置 | 通用设置与模型(BYOK)配置 |
|
|
9
|
+
| 帮助中心 | 版本日志 / 操作手册 / 安装手册,以及「问题与建议」外链 |
|
|
10
10
|
|
|
11
11
|
## 模型配置(BYOK,自带密钥)
|
|
12
12
|
|
|
@@ -91,7 +91,9 @@
|
|
|
91
91
|
| `知识库管理/` | 规范 / 方法论 / 环境约定 |
|
|
92
92
|
| `测试模板库/` | 用例与报告模板 |
|
|
93
93
|
|
|
94
|
-
> 目录**按插件开关懒建**:新建 / 首次选中的数据空间只有隐藏的 `.lantern/` 元数据,启用对应内容库插件后才出现上表目录并补入种子文件;旧版本留下的空目录(只有 `.gitkeep
|
|
94
|
+
> 目录**按插件开关懒建**:新建 / 首次选中的数据空间只有隐藏的 `.lantern/` 元数据,启用对应内容库插件后才出现上表目录并补入种子文件;旧版本留下的空目录(只有 `.gitkeep`)会自动收起,已有文件的目录不动。**`提示词管理/` 是唯一例外**:每个空间都有默认提示词,因此该目录与 `默认提示词.md` 会始终铺好。
|
|
95
|
+
|
|
96
|
+
> 「空间管理」默认展示全部空间:右上角「+ 新增空间」新建并立即写入默认提示词;每行的「编辑」可修改空间名称、提示词要求与默认提示词正文,保存后工作台立即生效。
|
|
95
97
|
|
|
96
98
|
> 旧版英文目录(`requirements/` / `cases/` / `prompts/` / `knowledge/` / `templates/`)在启动时**自动改名**为上述中文目录,无需手工迁移;若目标目录已存在则不覆盖。
|
|
97
99
|
|
|
@@ -99,6 +101,14 @@
|
|
|
99
101
|
|
|
100
102
|
把一份空间文件夹(带 `.lantern/space.json` 清单)整体拷进数据目录后,在「空间管理」点「扫描文件夹」,即可纳入列表:名称以目录名为准,清单里的 id 与已有空间撞车时自动换新。
|
|
101
103
|
|
|
104
|
+
「空间管理」里的「复制」是另一种做法:在数据目录内**逐文件复制**出一个新空间(含 `.lantern/local` 下的待办、任务、会话、记忆与配置),新空间直接出现在列表里、不需要再扫描。
|
|
105
|
+
|
|
106
|
+
- 复制会跳过 `node_modules` / `.git` / `.astro` / `dist` 与 `.DS_Store`;也会跳过可重建的派生缓存(`.lantern/local/session-query.sqlite` 及其 `-wal` / `-shm`、`.lantern/local/spill/`),避免拷到写了一半的文件。
|
|
107
|
+
- 复制品里的工作区注册表会被改指新目录,所以新空间的「工作区」停在自己身上,而不是被复制的那个空间。
|
|
108
|
+
- 有会话正在运行时不允许复制(与切换空间一致,先停止再操作)。
|
|
109
|
+
- 复制**不会**自动切过去;切到新空间时页面会重载,待办 / 任务等按新空间的数据重新加载。
|
|
110
|
+
- 浏览器本地存储里按空间 id 记的界面偏好(列宽、侧栏展开状态等)不会跟着复制,新空间用默认值。
|
|
111
|
+
|
|
102
112
|
同一目录里其它**不是空间**的文件夹会在扫描后列出来,勾选并确认才纳入:
|
|
103
113
|
|
|
104
114
|
- 纳入只把文件夹登记进列表,**不写入 `.lantern/space.json`,也不铺内容目录、不播种子**,文件夹内容保持原样。
|
|
@@ -177,23 +187,63 @@ version: '1.0' # 可选
|
|
|
177
187
|
工作台会话栏「新会话」下方点「插件」进入:
|
|
178
188
|
|
|
179
189
|
- **我的插件**(`/plugins/`):分「扩展插件 / 会话插件 / 全局插件」三个 Tab(默认打开扩展插件),Tab 标题带数量;点击卡片展开详情。扩展为可配置项,可开关;开关状态存本机。插件随仓库代码发布,不提供远程安装 / 更新。
|
|
180
|
-
- 扩展插件按「内容库 / 生成能力 / 记忆与检索 /
|
|
181
|
-
|
|
182
|
-
| 分类 | 插件 | 新建空间默认 | 说明
|
|
183
|
-
| ---------- | ------------ | ------------ |
|
|
184
|
-
| 内容库 | 用例管理 | 关 | 侧栏进入用例库;关闭后入口隐藏,「生成测试用例」一并关闭;磁盘文件仍保留
|
|
185
|
-
| 内容库 | 提示词管理 |
|
|
186
|
-
| 内容库 | 知识库管理 | 关 | 侧栏进入知识库;关闭后入口隐藏,「生成知识库」一并关闭;磁盘文件仍保留
|
|
187
|
-
| 内容库 | 需求文档库 | 关 | 侧栏进入需求文档库;关闭后入口隐藏,生成用例时不再引用需求文档;磁盘文件仍保留
|
|
188
|
-
| 内容库 | 测试模板库 | 关 | 侧栏进入测试模板库;关闭后入口隐藏,生成用例时不再选用模板;磁盘文件仍保留
|
|
189
|
-
| 生成能力 | 生成测试用例 | 关 | 配置类型 / 输出格式 / 需求 / 模板 / 提示词后对话生成用例,写入 `用例管理/`(需本地服务落盘)
|
|
190
|
-
| 生成能力 | 生成提示词 | 关 | 配置类型后对话生成提示词,质检通过写入 `提示词管理/`(需本地服务)
|
|
191
|
-
| 生成能力 | 生成知识库 | 关 | 配置分类后对话生成规范 / 方法论等,质检通过写入 `知识库管理/`(需本地服务)
|
|
192
|
-
| 记忆与检索 | 知识库检索 | 关 | 工作台输入 `@` 引用 `知识库管理/`、`测试模板库/` 与工作区文档
|
|
193
|
-
| 记忆与检索 | 会话记忆 | 关 | 长期记忆 / 项目关键 / 项目日志等记忆轨 + 待确认队列;`.lantern/local/memories/`(需本地服务)
|
|
194
|
-
|
|
|
195
|
-
|
|
196
|
-
|
|
190
|
+
- 扩展插件按「内容库 / 生成能力 / 记忆与检索 / 待办与效率 / 开发工具」五类分组展示,分类标题带数量,可点击折叠 / 展开;分类与插件注册表的 `category` 字段一致。
|
|
191
|
+
|
|
192
|
+
| 分类 | 插件 | 新建空间默认 | 说明 |
|
|
193
|
+
| ---------- | ------------ | ------------ | ----------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| 内容库 | 用例管理 | 关 | 侧栏进入用例库;关闭后入口隐藏,「生成测试用例」一并关闭;磁盘文件仍保留 |
|
|
195
|
+
| 内容库 | 提示词管理 | 开(内置) | 侧栏进入提示词库,并维护当前空间的「默认提示词」;每个空间都需要,因此常开不可关闭 |
|
|
196
|
+
| 内容库 | 知识库管理 | 关 | 侧栏进入知识库;关闭后入口隐藏,「生成知识库」一并关闭;磁盘文件仍保留 |
|
|
197
|
+
| 内容库 | 需求文档库 | 关 | 侧栏进入需求文档库;关闭后入口隐藏,生成用例时不再引用需求文档;磁盘文件仍保留 |
|
|
198
|
+
| 内容库 | 测试模板库 | 关 | 侧栏进入测试模板库;关闭后入口隐藏,生成用例时不再选用模板;磁盘文件仍保留 |
|
|
199
|
+
| 生成能力 | 生成测试用例 | 关 | 配置类型 / 输出格式 / 需求 / 模板 / 提示词后对话生成用例,写入 `用例管理/`(需本地服务落盘) |
|
|
200
|
+
| 生成能力 | 生成提示词 | 关 | 配置类型后对话生成提示词,质检通过写入 `提示词管理/`(需本地服务) |
|
|
201
|
+
| 生成能力 | 生成知识库 | 关 | 配置分类后对话生成规范 / 方法论等,质检通过写入 `知识库管理/`(需本地服务) |
|
|
202
|
+
| 记忆与检索 | 知识库检索 | 关 | 工作台输入 `@` 引用 `知识库管理/`、`测试模板库/` 与工作区文档 |
|
|
203
|
+
| 记忆与检索 | 会话记忆 | 关 | 长期记忆 / 项目关键 / 项目日志等记忆轨 + 待确认队列;`.lantern/local/memories/`(需本地服务) |
|
|
204
|
+
| 待办与效率 | 任务管理 | 关 | 侧栏进入任务列表:任务池 / 进行中 / 已完成 / 已关闭,自动汇总任务下待办的数量与完成进度(需本地服务) |
|
|
205
|
+
| 待办与效率 | 待办事项 | 关 | 侧栏进入待办列表:筛选、行内改状态、手动增删改;工作台会话可用工具记录同一份待办(需本地服务) |
|
|
206
|
+
| 开发工具 | 插件开发 | 关 | 固定提示词开发扩展插件:先评估并用选项确认,确认后才改代码,完成后并入「扩展插件」(需本地服务) |
|
|
207
|
+
|
|
208
|
+
> **新建空间默认开启「提示词管理」,其余插件默认关闭**:每个空间都会带上自己的「默认提示词.md」,因此提示词管理是内置常开项;其余入口与「生成」能力仍要在「我的插件」里按分类手动开启,已有空间也保持原开关。种子文件(默认提示词、模板)不会让其它插件自动打开,只有用户自己放进空间的内容才会触发首次识别。
|
|
209
|
+
|
|
210
|
+
### 待办事项
|
|
211
|
+
|
|
212
|
+
「我的插件」→「待办与效率」→「待办事项」开启后,侧栏出现「待办事项」入口(`/todos/`)。
|
|
213
|
+
|
|
214
|
+
- 数据落在当前数据空间的 `.lantern/local/todos.json`,随空间走、不进 git;切换空间后看到的是各空间自己的待办。
|
|
215
|
+
- 字段:待办名称、待办状态(待开始 / 进行中 / 已完成 / 已取消)、紧急程度(重要紧急 / 重要不紧急 / 紧急不重要 / 普通)、所属任务、开始日期、截止日期、结束日期、备注。
|
|
216
|
+
- **结束日期是只读派生值**:状态改为「已完成 / 已取消」时自动记为当天(再改其他字段不会刷新);状态改回「待开始 / 进行中」时清空,界面上显示「待办未完成」。表格行内、抽屉、AI 工具(`todo_update`)改状态都按同一规则处理。
|
|
217
|
+
- 新建待办(抽屉与「+ 新增记录」)的**开始日期 / 截止日期默认是当天**,可直接改。
|
|
218
|
+
- 「所属任务」从「任务管理」里选(需同时开启该插件),选中后写回任务 id 与任务名称;**已关闭的任务不出现在选项里**。待办关联任务时,任务会从「任务池 / 已完成」被拉回「进行中」(已关闭的不动);打开待办页时也会对「仍有未完成待办」的已关联任务做同样处理。任务管理开启时,旧数据里只存了任务名的待办会按名称自动补上关联,任务管理关闭时该列显示「任务管理插件未启用」,原任务名不会丢。
|
|
219
|
+
- 「待办周期」与「剩余天数」由日期自动算出(含首尾);未完成且过了截止日期显示「已延期」,存储状态不变。
|
|
220
|
+
- 表格按飞书多维表格的方式展示:默认按「待办状态」分组(进行中 / 待开始 / 已延期 / 已完成 / 已取消),每组标题带记录数,点标题可折叠;顶部的分组下拉可切换为「按紧急程度分组」或「不分组」。
|
|
221
|
+
- 单元格直接改:点名称 / 所属任务 / 日期 / 备注即可编辑,回车或点空白处保存,Esc 放弃;状态下拉与紧急程度下拉在行内改完立即生效(改状态后会自动换到对应分组)。
|
|
222
|
+
- 日期格不再显示系统小日历图标:点一下弹出白色卡片日历(可翻月,底部「清除 / 今天」),选完立即保存。
|
|
223
|
+
- 工具栏与单元格里的下拉都是卡片菜单(白底圆角),状态 / 紧急程度用颜色点和选中底色区分,不显示对钩,不会弹出系统原生下拉。
|
|
224
|
+
- 每组底部有「+ 新增记录」(手动新增入口):点开后在组内展开一行,包含全部列(名称 / 状态 / 紧急程度 / 所属任务 / 开始日期 / 截止日期 / 备注;结束日期随状态自动生成,不在这里填);没有单独的保存 / 取消按钮——填好名称后回车,或直接点页面空白处即自动保存,完全没填内容时点空白处则自动收起,Esc 放弃。顶部「新建待办」会从右侧滑出记录抽屉,按顺序填写名称、状态、任务详情、日期与备注后保存;没有数据时只保留右上角的「新建待办」按钮。
|
|
225
|
+
- 抽屉里的「待办状态」整行都可点:点击范围一直延伸到「待办名称」输入框的右边界,胶囊只是选中值的样子,点行的任意位置都会展开状态选项。
|
|
226
|
+
- 行尾的展开按钮可用同一个抽屉回看 / 修改整条记录;抽屉里的「待办周期」「剩余天数」是只读派生值,会随日期即时计算。
|
|
227
|
+
- 顶部可搜索,并按紧急程度筛选;支持批量删除,行尾「操作」列可删除单条,都会二次弹窗确认;表格右侧列较多时可横向滚动。
|
|
228
|
+
- 列宽可拖:把鼠标放到表头字段的右边缘,出现竖线后左右拖即可调整;默认宽度就是设计稿宽度。调过的列宽存在浏览器本地(localStorage),刷新、切换页面后保持,不会写进数据空间。
|
|
229
|
+
- 新增行没有任何内容时,点页面其它位置会自动收起;已经填了名称则点空白处(或回车)即自动保存,不再有单独的 ✓ / ✕ 按钮。
|
|
230
|
+
- 「我的工作台」对话上方的 Tab 里有「待办」(待办插件开启时,排在「回合」右侧):默认「全部待办」,按 已逾期 / 今天截止 / 接下来 / 没有截止日期 / 已完成 分桶(今日与其它待办都在里面);也可只看「未完成」或「已完成」。每行显示待办名称、紧急程度,以及第二行的截止日期、剩余天数(逾期会标红)和所属任务;点左侧圆圈即可标记完成 / 恢复,右上角「打开待办页」跳到完整表格。停在 Tab 上每 15 秒自动刷新,AI 在会话里写入后不用手动刷。
|
|
231
|
+
- 输入框左侧「+」→「计划」下面会按插件开关给出「待办」「任务」两个手动入口(对应插件关闭时入口直接隐藏,不会触发新增):点开后弹出同一张确认卡片,手动入口的最后一个按钮是「提交」。待办分两页:第一页填待办自身字段(名称 / 状态 / 紧急程度 / 开始日期 / 截止日期 / 备注,开始 / 截止默认今天),第二页选「所属任务」并只读展示该任务的名称、状态、紧急程度与起止日期;选中任务后,任务有值的开始日期 / 截止日期 / 紧急程度会自动带到第一页(紧急程度仅在待办未设置时带出),仍可再改。任务没有所属任务,一页填完(名称 / 状态 / 紧急程度 / 开始日期 / 截止日期 / 备注)。填好「提交」直接落库,不经过模型;点「取消」或点卡片外面任意位置(包括切到别的 Tab)只会播放收起动画并放弃这次新增,不会写入待办 / 任务。
|
|
232
|
+
- 工作台里直接说「记一条待办:周五前提交测试报告」,AI 会调用 `todo_add`;写入前聊天区会弹出确认卡片,同样分两页(第一页待办字段,第二页选所属任务并带出任务的日期与紧急程度),点「确认新增」才落库;点「取消」或点卡片外面会收起卡片、不写任何数据。查进度用 `todo_list`,完成用 `todo_update`。停在该页时会定时刷新,AI 在会话里写入后不用手动刷新。
|
|
233
|
+
|
|
234
|
+
### 任务管理
|
|
235
|
+
|
|
236
|
+
「我的插件」→「待办与效率」→「任务管理」开启后,侧栏出现「任务管理」入口(`/tasks/`)。
|
|
237
|
+
|
|
238
|
+
- 数据落在当前数据空间的 `.lantern/local/tasks.json`;切换空间后看到各空间自己的任务。
|
|
239
|
+
- 顶部六张统计卡片:全部任务、任务池、进行中、已完成、已关闭、需要紧急(重要紧急 + 紧急不重要)。
|
|
240
|
+
- 列表字段:任务描述、任务状态、紧急程度、开始日期、截止日期、任务周期、待办数量、完成进度、备注。
|
|
241
|
+
- 新建任务的开始日期 / 截止日期默认是当天,可直接改。
|
|
242
|
+
- 「任务周期」由开始 / 截止日期算出;「待办数量」与「完成进度」按待办里的「所属任务」实时汇总(待办完成状态变化后自动刷新)。待办事项插件关闭时,这两列显示「待办事项未启用」。
|
|
243
|
+
- 状态 / 紧急程度在行内用卡片菜单改;日期点开卡片日历;点任务名称或用行尾展开按钮打开右侧抽屉,可改名称、日期与备注,并看到该任务下已关联的待办。
|
|
244
|
+
- 工作台里也可以让 AI 建任务:说「新建一个任务:…」会调用 `task_add`,同样先弹确认卡片(一页:名称 / 状态 / 紧急程度 / 开始 / 截止日期 / 备注),确认后才创建;点「取消」或点卡片外面不会写入。查询用 `task_list`、改字段用 `task_update`、删除用 `task_delete`。
|
|
245
|
+
- 删除任务不会删待办,只是解除关联(待办里的「所属任务」变为未关联)。
|
|
246
|
+
- 列宽同样可拖表头右边缘调整,与待办页一致;表头、行高、状态胶囊、行尾展开 / 删除按钮的样式也与待办页保持同一套。
|
|
197
247
|
|
|
198
248
|
### 插件开发
|
|
199
249
|
|
|
@@ -718,6 +718,8 @@ function readJsonOr(fp, fallback) {
|
|
|
718
718
|
* @param {string} dirName 中文内容目录名
|
|
719
719
|
*/
|
|
720
720
|
export function isContentRootEnabled(spaceDir, dirName) {
|
|
721
|
+
// 提示词管理是内置常开项:每个空间都要有「默认提示词」,不受插件开关影响
|
|
722
|
+
if (dirName === DOC_ROOT_DIRS.prompts.dirName) return true;
|
|
721
723
|
const key = Object.keys(DOC_ROOT_DIRS).find((k) => DOC_ROOT_DIRS[k].dirName === dirName);
|
|
722
724
|
if (!key) return false;
|
|
723
725
|
const pluginId = CONTENT_ROOT_PLUGINS[key];
|