diff --git a/paperforge/plugin/main.js b/paperforge/plugin/main.js
index ef4f11d6..67083316 100644
--- a/paperforge/plugin/main.js
+++ b/paperforge/plugin/main.js
@@ -1460,11 +1460,20 @@ class PaperForgeStatusView extends ItemView {
const truncated = extracted.length > 200 ? extracted.slice(0, 200) + '...' : extracted;
excerptEl.setText(truncated);
if (extracted.length > 200) {
- const expandBtn = body.createEl('button', { cls: 'paperforge-paper-overview-expand', text: '展开' });
+ const expandContainer = body.createEl('div', { cls: 'paperforge-expand-container' });
+ const expandBtn = expandContainer.createEl('button', { cls: 'paperforge-expand-icon', title: '展开/收起' });
+
+ // Insert arrow SVG
+ expandBtn.innerHTML = '';
+
let expanded = false;
- expandBtn.addEventListener('click', () => {
+
+ // Make the whole container clickable
+ expandContainer.addEventListener('click', () => {
excerptEl.setText(expanded ? truncated : extracted);
- expandBtn.setText(expanded ? '展开' : '收起');
+ expandBtn.innerHTML = expanded
+ ? ''
+ : '';
expanded = !expanded;
});
}
@@ -1556,14 +1565,23 @@ class PaperForgeStatusView extends ItemView {
: (qa.answer || '');
aEl.createEl('span', { cls: 'paperforge-discussion-a-text', text: '解答:' + shortAnswer });
if (qa.answer && qa.answer.length > 150) {
- const expandLink = aEl.createEl('button', { cls: 'paperforge-discussion-expand', text: '展开' });
+ const expandContainer = aEl.createEl('div', { cls: 'paperforge-expand-container' });
+ const expandBtn = expandContainer.createEl('button', { cls: 'paperforge-expand-icon', title: '展开/收起' });
+
+ // Insert arrow SVG
+ expandBtn.innerHTML = '';
+
let expanded = false;
- expandLink.addEventListener('click', () => {
+
+ // Make the whole container clickable
+ expandContainer.addEventListener('click', () => {
const textSpan = aEl.querySelector('.paperforge-discussion-a-text');
if (textSpan) {
textSpan.setText(expanded ? ('解答:' + shortAnswer) : ('解答:' + qa.answer));
}
- expandLink.setText(expanded ? '展开' : '收起');
+ expandBtn.innerHTML = expanded
+ ? ''
+ : '';
expanded = !expanded;
});
}
@@ -1692,9 +1710,19 @@ class PaperForgeStatusView extends ItemView {
});
// Show "Run in [agent_platform]" label below the button (DASH-02)
- const platform = this.app.plugins.plugins['paperforge']?.settings?.agent_platform || 'opencode';
+ const platformKey = this.app.plugins.plugins['paperforge']?.settings?.agent_platform || 'opencode';
+ const AGENTS = {
+ 'opencode': 'OpenCode',
+ 'claude': 'Claude Code',
+ 'cursor': 'Cursor',
+ 'github_copilot': 'GitHub Copilot',
+ 'windsurf': 'Windsurf',
+ 'codex': 'Codex',
+ 'cline': 'Cline'
+ };
+ const platformName = AGENTS[platformKey] || platformKey;
const labelEl = card.createEl('div', { cls: 'paperforge-agent-platform-label' });
- labelEl.setText(t('run_in_agent').replace('{0}', platform));
+ labelEl.setText(t('run_in_agent').replace('{0}', platformName));
} else if (nextStep === 'ready') {
const trigger = card.createEl('button', { cls: 'paperforge-next-step-trigger' });
trigger.createEl('span', { text: '✓ ' + info.label });
@@ -1806,7 +1834,7 @@ class PaperForgeStatusView extends ItemView {
{ cls: 'pending', value: ocrPending, label: 'Pending' },
{ cls: 'active', value: ocrProcessing, label: 'Processing' },
{ cls: 'done', value: ocrDone, label: 'Done' },
- { cls: 'failed', value: ocrFailed, label: 'Needs Attention' },
+ { cls: 'failed', value: ocrFailed, label: 'Attention' },
];
for (const l of ocrLabels) {
const cnt = ocrCounts.createEl('div', { cls: 'paperforge-ocr-count' });
diff --git a/paperforge/plugin/styles.css b/paperforge/plugin/styles.css
index 842b8a35..f861ef3a 100644
--- a/paperforge/plugin/styles.css
+++ b/paperforge/plugin/styles.css
@@ -8,18 +8,25 @@
font-family: inherit;
font-size: 14px;
color: var(--text-normal);
- padding: 14px;
+ padding: 14px 14px 56px 14px;
height: 100%;
overflow-y: auto;
+ scrollbar-gutter: stable;
display: flex;
flex-direction: column;
gap: 12px;
+ container-type: inline-size;
+ container-name: pfpanel;
--pf-surface: var(--background-secondary);
--pf-surface-alt: var(--background-primary-alt);
--pf-border: var(--background-modifier-border);
--pf-border-hover: var(--background-modifier-border-hover);
--pf-accent: var(--interactive-accent);
--pf-radius: var(--radius-m);
+ --pf-paper-accent: #6f8780;
+ --pf-collection-accent: #9a6b52;
+ --pf-global-accent: #5f7180;
+ --pf-warm-line: #a28a5d;
}
/* ── Typography tokens ── */
@@ -343,7 +350,11 @@
}
.paperforge-progress-seg.pending {
- background: var(--text-faint);
+ background: #e2d9c8;
+}
+
+.theme-dark .paperforge-progress-seg.pending {
+ background: #4a4135;
}
.paperforge-progress-seg.active {
@@ -352,7 +363,11 @@
}
.paperforge-progress-seg.done {
- background: var(--color-green);
+ background: #3e5a47;
+}
+
+.theme-dark .paperforge-progress-seg.done {
+ background: #4f735b;
}
.paperforge-progress-seg.failed {
@@ -380,8 +395,8 @@
}
.paperforge-ocr-count-value {
- font-size: var(--font-ui-medium);
- font-weight: var(--font-bold);
+ font-size: 18px;
+ font-weight: 600;
color: var(--text-normal);
line-height: 1.2;
}
@@ -1203,6 +1218,7 @@
font-weight: var(--font-semibold);
padding: 2px 8px;
border-radius: 10px;
+ border: 1px solid transparent;
text-transform: uppercase;
letter-spacing: 0.5px;
line-height: 1.4;
@@ -1210,18 +1226,21 @@
}
.paperforge-mode-badge.global {
- background: var(--interactive-accent);
- color: var(--text-on-accent);
+ background: color-mix(in srgb, var(--pf-global-accent) 12%, var(--background-secondary));
+ border-color: color-mix(in srgb, var(--pf-global-accent) 28%, var(--pf-border));
+ color: var(--pf-global-accent);
}
.paperforge-mode-badge.paper {
- background: var(--color-cyan);
- color: var(--text-on-accent);
+ background: color-mix(in srgb, var(--pf-paper-accent) 12%, var(--background-secondary));
+ border-color: color-mix(in srgb, var(--pf-paper-accent) 28%, var(--pf-border));
+ color: var(--pf-paper-accent);
}
.paperforge-mode-badge.collection {
- background: var(--color-purple);
- color: var(--text-on-accent);
+ background: color-mix(in srgb, var(--pf-collection-accent) 12%, var(--background-secondary));
+ border-color: color-mix(in srgb, var(--pf-collection-accent) 28%, var(--pf-border));
+ color: var(--pf-collection-accent);
}
.paperforge-mode-name {
@@ -1294,36 +1313,6 @@
flex-wrap: wrap;
}
-.paperforge-contextual-btn {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- padding: 6px 14px;
- font-size: var(--font-ui-small);
- font-weight: var(--font-semibold);
- color: var(--text-normal);
- background: var(--background-secondary-alt);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- cursor: pointer;
- transition: background 0.15s, color 0.15s;
- user-select: none;
-}
-
-.paperforge-contextual-btn:hover {
- background: var(--background-modifier-hover);
- color: var(--text-accent);
-}
-
-.paperforge-contextual-btn:active {
- transform: scale(0.97);
-}
-
-.paperforge-contextual-btn-icon {
- font-size: 14px;
- line-height: 1;
-}
-
/* ==========================================================================
SECTION 16 — Next-Step Recommendation Card
========================================================================== */
@@ -1393,6 +1382,8 @@
display: flex;
flex-direction: column;
gap: 24px;
+ max-width: 800px;
+ margin: 0 auto;
}
.paperforge-collection-metrics {
@@ -1687,65 +1678,170 @@
}
/* ==========================================================================
- SECTION 39 — Shared Components (Native Light Surface Design)
+ SECTION 39 — Dashboard Visual System
========================================================================== */
-/* ── Section Label ── */
+/* Shared tokens */
.paperforge-section-label {
font-size: 12px;
font-weight: 600;
color: var(--text-muted);
+ margin: 0 0 10px 0;
+ padding-left: 10px;
+ border-left: 3px solid var(--pf-warm-line);
text-transform: uppercase;
- letter-spacing: 0.04em;
- margin-bottom: 6px;
+ letter-spacing: 0.06em;
+ line-height: 1.3;
+}
+
+.paperforge-contextual-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 5px;
+ padding: 5px 12px;
+ background: var(--background-secondary);
+ border: 1px solid var(--pf-border);
+ border-radius: var(--radius-s);
+ color: var(--text-muted);
+ font-size: 12px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s, border-color 0.15s, color 0.15s;
+ white-space: nowrap;
+ user-select: none;
+}
+
+.paperforge-contextual-btn:hover {
+ background: var(--background-modifier-hover);
+ border-color: color-mix(in srgb, var(--pf-warm-line) 52%, var(--pf-border-hover));
+ color: var(--text-normal);
+}
+
+.paperforge-contextual-btn.running {
+ opacity: 0.6;
+ pointer-events: none;
+}
+
+.paperforge-contextual-btn:active {
+ transform: scale(0.97);
+}
+
+.paperforge-contextual-btn:focus-visible {
+ outline: 2px solid color-mix(in srgb, var(--interactive-accent) 62%, white 38%);
+ outline-offset: 2px;
+}
+
+.paperforge-contextual-btn-icon {
+ font-size: 14px;
+ line-height: 1;
}
-/* ── Status Pill ── */
.paperforge-status-pill {
display: inline-flex;
align-items: center;
gap: 4px;
- padding: 2px 8px;
+ padding: 2px 10px;
+ border: 1px solid var(--pf-border);
border-radius: 999px;
- background: var(--background-primary-alt);
- color: var(--text-muted);
font-size: 12px;
font-weight: 500;
- line-height: 1.4;
-}
-
-.paperforge-status-pill-icon { font-size: 11px; line-height: 1; }
-
-.paperforge-status-pill.ok { color: var(--text-success); }
-.paperforge-status-pill.fail { color: var(--text-error); }
-.paperforge-status-pill.pending { color: var(--text-muted); }
-
-/* ── Cards (only primary content modules) ── */
-.paperforge-paper-overview,
-.paperforge-discussion-card {
- margin: 8px 0;
- padding: 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
-}
-
-/* ── Paper Overview ── */
-.paperforge-paper-overview-header { margin-bottom: 6px; }
-
-.paperforge-paper-overview-title {
- font-size: 12px;
- font-weight: 600;
+ line-height: 1.5;
+ background: var(--background-primary-alt);
color: var(--text-muted);
+}
+
+.paperforge-status-pill.pending {
+ background: color-mix(in srgb, var(--pf-paper-accent) 9%, var(--background-primary));
+ border-color: color-mix(in srgb, var(--pf-paper-accent) 20%, var(--pf-border));
+ color: var(--pf-paper-accent);
+}
+
+.paperforge-status-pill.ok {
+ background: rgba(var(--background-modifier-success-rgb, 0, 200, 100), 0.12);
+ border-color: rgba(var(--background-modifier-success-rgb, 0, 200, 100), 0.2);
+ color: var(--text-success, var(--color-green));
+}
+
+.paperforge-status-pill.fail {
+ background: rgba(var(--background-modifier-error-rgb, 255, 80, 80), 0.12);
+ border-color: rgba(var(--background-modifier-error-rgb, 255, 80, 80), 0.22);
+ color: var(--text-error);
+}
+
+.paperforge-status-pill-icon {
+ font-size: 11px;
+ line-height: 1;
+}
+
+.paperforge-library-snapshot,
+.paperforge-system-status,
+.paperforge-global-actions {
+ padding: 20px;
+ background: color-mix(in srgb, var(--background-primary) 92%, var(--background-secondary) 8%);
+ border: 1px solid color-mix(in srgb, var(--pf-warm-line) 20%, var(--pf-border));
+ border-radius: calc(var(--pf-radius) + 2px);
+ box-shadow: 0 1px 2px rgba(20, 18, 14, 0.04), 0 10px 24px rgba(20, 18, 14, 0.04);
+ transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
+}
+
+.paperforge-library-snapshot:hover,
+.paperforge-system-status:hover,
+.paperforge-global-actions:hover {
+ border-color: color-mix(in srgb, var(--pf-warm-line) 42%, var(--pf-border));
+ box-shadow: 0 2px 10px rgba(20, 18, 14, 0.08), 0 14px 28px rgba(20, 18, 14, 0.06);
+}
+
+/* Paper mode */
+.paperforge-status-strip {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 10px;
+ padding: 10px 0 8px;
+ margin: 4px 0 6px;
+}
+
+.paperforge-status-strip-left,
+.paperforge-status-strip-right {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ flex-wrap: wrap;
+}
+
+.paperforge-paper-overview {
+ margin: 10px 0;
+ padding: 18px;
+ background: var(--background-primary);
+ border: 1px solid color-mix(in srgb, var(--pf-warm-line) 18%, var(--pf-border));
+ border-radius: calc(var(--pf-radius) + 2px);
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 16%, transparent);
+ transition: border-color 0.2s, box-shadow 0.2s;
+}
+
+.paperforge-paper-overview:hover {
+ border-color: color-mix(in srgb, var(--pf-warm-line) 34%, var(--pf-border));
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 22%, transparent), 0 2px 8px rgba(0, 0, 0, 0.06);
+}
+
+.paperforge-paper-overview-header {
+ margin-bottom: 8px;
+}
+
+.paperforge-paper-overview-title,
+.paperforge-discussion-title {
+ font-size: 12px;
+ font-weight: 700;
+ color: var(--pf-paper-accent);
text-transform: uppercase;
- letter-spacing: 0.04em;
+ letter-spacing: 0.06em;
}
.paperforge-paper-overview-body {
font-size: 14px;
- font-weight: 400;
- color: var(--text-muted);
- line-height: 1.55;
+ color: var(--text-normal);
+ line-height: 1.72;
}
.paperforge-paper-overview-excerpt {
@@ -1753,38 +1849,74 @@
word-break: break-word;
}
-.paperforge-paper-overview-expand {
- display: inline-block;
- margin-top: 4px;
- padding: 2px 0;
- background: none;
- border: none;
- color: var(--text-accent);
- font-size: 13px;
- font-weight: 400;
- cursor: pointer;
- transition: color 0.15s;
+.paperforge-expand-container,
+.paperforge-discussion-viewall {
+ color: var(--pf-paper-accent);
}
-.paperforge-paper-overview-expand:hover {
+.paperforge-expand-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ margin-top: 8px;
+ padding: 4px 0;
+ cursor: pointer;
+ transition: background-color 0.2s ease, color 0.2s ease;
+ border-radius: var(--pf-radius);
+ background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--pf-surface-alt) 50%, transparent));
+}
+
+.paperforge-expand-icon {
+ background: none;
+ border: none;
+ padding: 0;
+ margin: 0;
+ color: inherit;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ pointer-events: none; /* Let container handle clicks */
+ opacity: 0.6;
+ transition: opacity 0.2s ease;
+}
+
+.paperforge-expand-container:hover,
+.paperforge-discussion-viewall:hover {
color: var(--interactive-accent-hover);
}
-/* ── Discussion Card ── */
-.paperforge-discussion-header { margin-bottom: 8px; }
+.paperforge-expand-container:hover {
+ background: color-mix(in srgb, var(--pf-surface-alt) 80%, transparent);
+}
-.paperforge-discussion-title {
- font-size: 12px;
- font-weight: 600;
- color: var(--text-muted);
- text-transform: uppercase;
- letter-spacing: 0.04em;
+.paperforge-expand-container:hover .paperforge-expand-icon {
+ opacity: 1;
+}
+
+.paperforge-discussion-header {
+ margin-bottom: 10px;
+}
+
+.paperforge-discussion-card {
+ margin: 10px 0;
+ padding: 18px;
+ background: var(--background-primary);
+ border: 1px solid color-mix(in srgb, var(--pf-warm-line) 18%, var(--pf-border));
+ border-radius: calc(var(--pf-radius) + 2px);
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 11%, transparent);
+ transition: border-color 0.2s, box-shadow 0.2s;
+}
+
+.paperforge-discussion-card:hover {
+ border-color: color-mix(in srgb, var(--pf-warm-line) 34%, var(--pf-border));
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 16%, transparent), 0 2px 8px rgba(0, 0, 0, 0.06);
}
.paperforge-discussion-item {
- margin-bottom: 8px;
- padding-bottom: 8px;
- border-bottom: 1px solid var(--background-modifier-border);
+ margin-bottom: 10px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid var(--pf-border);
}
.paperforge-discussion-item:last-child {
@@ -1803,82 +1935,92 @@
.paperforge-discussion-a {
font-size: 14px;
- font-weight: 400;
- color: var(--text-muted);
- line-height: 1.55;
+ color: var(--text-normal);
+ line-height: 1.68;
}
-.paperforge-discussion-expand {
- display: inline;
- padding: 0;
- margin-left: 4px;
- background: none;
- border: none;
- color: var(--text-accent);
- font-size: 13px;
- font-weight: 400;
- cursor: pointer;
- transition: color 0.15s;
-}
-.paperforge-discussion-expand:hover { color: var(--interactive-accent-hover); }
.paperforge-discussion-viewall {
display: block;
text-align: right;
- margin-top: 4px;
- font-size: 13px;
- font-weight: 400;
- color: var(--text-accent);
+ margin-top: 6px;
+ font-size: 12px;
+ font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: color 0.15s;
}
-.paperforge-discussion-viewall:hover { color: var(--interactive-accent-hover); }
-
-/* ── Complete state row ── */
-.paperforge-complete-row {
- display: flex;
- align-items: center;
- gap: 6px;
- color: var(--text-success);
- font-size: 13px;
- font-weight: 400;
- line-height: 1.4;
- padding: 4px 0;
+.paperforge-discussion-viewall:hover {
+ text-decoration: underline;
+}
+
+.paperforge-paper-files {
+ display: flex;
+ gap: 8px;
+ margin: 10px 0;
+}
+
+.paperforge-status-strip-right .paperforge-contextual-btn {
+ min-height: 34px;
+ padding: 7px 12px;
+ background: color-mix(in srgb, var(--background-secondary) 78%, var(--background-primary));
+ border-color: color-mix(in srgb, var(--pf-border) 88%, var(--pf-warm-line));
+ color: var(--text-muted);
+}
+
+.paperforge-status-strip-right .paperforge-contextual-btn:hover {
+ background: color-mix(in srgb, var(--background-modifier-hover) 78%, var(--background-primary));
+ border-color: color-mix(in srgb, var(--pf-border-hover) 82%, var(--pf-warm-line));
+ color: var(--text-normal);
}
-/* ── Technical Details disclosure ── */
.paperforge-technical-details {
- margin: 4px 0;
+ margin: 8px 0 4px;
}
.paperforge-technical-details-toggle {
- display: inline-block;
- padding: 4px 0;
+ width: 100%;
+ min-height: 34px;
+ padding: 8px 0;
background: none;
border: none;
+ border-radius: 0;
color: var(--text-muted);
- font-size: 13px;
- font-weight: 400;
+ font-size: 12px;
+ font-weight: 600;
cursor: pointer;
- user-select: none;
+ text-align: left;
+ letter-spacing: 0.02em;
transition: color 0.15s;
}
-.paperforge-technical-details-toggle:hover { color: var(--text-normal); }
+.paperforge-technical-details-toggle:hover {
+ background: none;
+ border-color: transparent;
+ color: var(--text-normal);
+}
.paperforge-technical-details-body {
- padding: 6px 0 2px 0;
+ margin-top: 0;
+ padding: 8px 0 0;
+ background: none;
+ border: none;
+ border-radius: 0;
font-size: 12px;
- color: var(--text-faint);
}
.paperforge-technical-row {
display: flex;
justify-content: space-between;
- padding: 2px 0;
+ gap: 12px;
+ padding: 6px 0;
+ border-bottom: 1px solid color-mix(in srgb, var(--pf-border) 72%, transparent);
+}
+
+.paperforge-technical-row:last-child {
+ border-bottom: none;
}
.paperforge-technical-label {
@@ -1896,87 +2038,27 @@
text-align: right;
}
-/* ── Contextual buttons ── */
-.paperforge-contextual-btn {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- padding: 3px 8px;
- background: var(--interactive-normal);
- border: 1px solid var(--background-modifier-border);
- color: var(--text-normal);
- border-radius: var(--button-radius, 4px);
- font-size: 12px;
- font-weight: 400;
- cursor: pointer;
- transition: background 0.15s;
- white-space: nowrap;
-}
-
-.paperforge-contextual-btn:hover {
- background: var(--interactive-hover);
- border-color: var(--background-modifier-border-hover);
-}
-
-.paperforge-contextual-btn.running {
- opacity: 0.6;
- pointer-events: none;
-}
-
-.paperforge-contextual-btn-icon {
- font-size: 14px;
- line-height: 1;
-}
-
-.paperforge-contextual-btn.primary {
- background: var(--interactive-accent);
- color: var(--text-on-accent);
- border-color: var(--interactive-accent);
- font-weight: 500;
-}
-
-.paperforge-contextual-btn.primary:hover {
- opacity: 0.85;
-}
-
-/* ==========================================================================
- SECTION 40 — Per-Paper View
- ========================================================================== */
-
-/* ── Status Strip + Files Row (merged) ── */
-.paperforge-status-strip {
- display: flex;
- align-items: center;
- justify-content: space-between;
- flex-wrap: wrap;
- gap: 8px;
- padding: 6px 0;
- margin: 4px 0;
-}
-
-.paperforge-status-strip-left {
- display: flex;
- align-items: center;
- gap: 6px;
-}
-
-.paperforge-status-strip-right {
- display: flex;
- align-items: center;
- gap: 6px;
-}
-
-/* ── Workflow Toggles (inline, not a card) ── */
.paperforge-workflow-toggles {
display: flex;
+ flex-wrap: wrap;
gap: 14px;
- padding: 6px 0;
+ margin: 0 0 10px;
+ padding: 0 0 10px;
+ background: none;
+ border: none;
+ border-bottom: 1px solid color-mix(in srgb, var(--pf-border) 72%, transparent);
+ border-radius: 0;
}
.paperforge-workflow-toggle {
display: flex;
align-items: center;
gap: 6px;
+ min-height: 34px;
+ padding: 6px 10px;
+ background: color-mix(in srgb, var(--background-primary-alt) 88%, var(--background-primary));
+ border: 1px solid color-mix(in srgb, var(--pf-border) 82%, var(--pf-paper-accent));
+ border-radius: 999px;
cursor: pointer;
font-size: 13px;
color: var(--text-muted);
@@ -1992,28 +2074,25 @@
}
.paperforge-workflow-toggle-label {
- font-weight: 500;
+ font-weight: 600;
color: var(--text-normal);
}
.paperforge-workflow-toggle-hint {
color: var(--text-faint);
- font-size: 12px;
+ font-size: 11px;
}
-/* ==========================================================================
- SECTION 41 — Collection / Base View
- ========================================================================== */
-
+/* Collection mode */
.paperforge-collection-header {
- margin-bottom: 8px;
+ margin-bottom: 10px;
}
.paperforge-collection-title {
font-size: 16px;
font-weight: 600;
color: var(--text-normal);
- line-height: 1.35;
+ line-height: 1.3;
}
.paperforge-collection-count {
@@ -2022,629 +2101,87 @@
margin-top: 2px;
}
+.paperforge-global-view {
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.paperforge-global-view .paperforge-section-label,
+.paperforge-workflow-overview .paperforge-section-label {
+ margin-bottom: 12px;
+}
+
.paperforge-workflow-overview {
- margin: 8px 0;
- padding: 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
+ margin: 10px 0;
+ padding: 18px;
+ background: color-mix(in srgb, var(--background-primary) 94%, var(--background-primary-alt) 6%);
+ border: 1px solid color-mix(in srgb, var(--pf-warm-line) 20%, var(--pf-border));
+ border-radius: calc(var(--pf-radius) + 2px);
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-collection-accent) 12%, transparent);
+ transition: border-color 0.2s, box-shadow 0.2s;
+}
+
+.paperforge-workflow-overview:hover {
+ border-color: color-mix(in srgb, var(--pf-warm-line) 42%, var(--pf-border));
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-collection-accent) 17%, transparent), 0 2px 10px rgba(20, 18, 14, 0.08);
}
.paperforge-workflow-funnel {
- display: flex;
+ display: grid;
+ grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;
+ gap: 8px 6px;
align-items: center;
- gap: 3px;
- flex-wrap: wrap;
- justify-content: center;
+}
+
+@container pfpanel (max-width: 380px) {
+ .paperforge-workflow-funnel {
+ grid-template-columns: 1fr auto 1fr;
+ }
+ .paperforge-workflow-funnel > div:nth-child(4) {
+ display: none;
+ }
+}
+
+@container pfpanel (max-width: 220px) {
+ .paperforge-workflow-funnel {
+ grid-template-columns: 1fr;
+ }
+ .paperforge-workflow-arrow {
+ display: none;
+ }
}
.paperforge-workflow-stage {
display: flex;
flex-direction: column;
align-items: center;
- padding: 6px 12px;
- background: var(--background-primary-alt);
- border-radius: 6px;
- min-width: 52px;
-}
-
-.paperforge-workflow-stage-value {
- font-size: 18px;
- font-weight: 600;
- color: var(--text-normal);
- line-height: 1.2;
-}
-
-.paperforge-workflow-stage-label {
- font-size: 11px;
- color: var(--text-muted);
- text-transform: uppercase;
- letter-spacing: 0.04em;
- margin-top: 2px;
- text-align: center;
-}
-
-.paperforge-workflow-arrow {
- color: var(--text-faint);
- font-size: 12px;
- flex-shrink: 0;
-}
-
-.paperforge-collection-ocr-header {
- display: flex;
- align-items: center;
- gap: 10px;
- margin-bottom: 14px;
-}
-
-.paperforge-issue-summary {
- margin: 8px 0;
- padding: 10px 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-left: 3px solid var(--color-orange, #e67e22);
- border-radius: var(--radius-m);
-}
-
-.paperforge-issue-summary .paperforge-section-label {
- color: var(--color-orange, #e67e22);
-}
-
-.paperforge-issue-list {
- margin: 4px 0 6px 0;
-}
-
-.paperforge-issue-item {
- font-size: 14px;
- color: var(--text-muted);
- padding: 2px 0;
-}
-
-.paperforge-issue-actions {
- display: flex;
- gap: 8px;
- margin-top: 8px;
-}
-
-.paperforge-collection-actions {
- display: flex;
- gap: 8px;
- margin-top: 8px;
- padding-top: 8px;
- border-top: 1px solid var(--background-modifier-border);
-}
-
-/* ==========================================================================
- SECTION 42 — Global / Home View
- ========================================================================== */
-
-.paperforge-library-snapshot {
- padding: 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
-}
-
-.paperforge-snapshot-pills {
- display: flex;
- gap: 8px;
- flex-wrap: wrap;
-}
-
-.paperforge-snapshot-pill {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 8px 14px;
- background: var(--background-primary-alt);
- border-radius: 6px;
- min-width: 56px;
- flex: 1;
-}
-
-.paperforge-snapshot-value {
- font-size: 18px;
- font-weight: 600;
- color: var(--text-normal);
- line-height: 1.2;
-}
-
-.paperforge-snapshot-label {
- font-size: 11px;
- color: var(--text-muted);
- text-transform: uppercase;
- letter-spacing: 0.04em;
- margin-top: 2px;
- text-align: center;
-}
-
-.paperforge-system-status {
- padding: 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
-}
-
-.paperforge-status-grid {
- display: flex;
- flex-direction: column;
- gap: 1px;
-}
-
-.paperforge-status-row {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 3px 0;
-}
-
-.paperforge-status-dot {
- width: 7px;
- height: 7px;
- border-radius: 50%;
- flex-shrink: 0;
- background: var(--background-modifier-border);
- transition: background 0.3s;
-}
-
-.paperforge-status-dot.ok { background: var(--text-success); }
-.paperforge-status-dot.fail { background: var(--text-error); }
-
-.paperforge-status-label {
- font-size: 14px;
- color: var(--text-muted);
- min-width: 85px;
-}
-
-.paperforge-status-detail {
- font-size: 13px;
- color: var(--text-faint);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.paperforge-global-actions {
- padding: 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
-}
-
-.paperforge-global-actions-row {
- display: flex;
- gap: 8px;
-}
-
-/* ==========================================================================
- SECTION 43 — Dark Theme
- ========================================================================== */
-
-.theme-dark .paperforge-status-pill {
- background: var(--background-primary-alt);
-}
-
-.theme-dark .paperforge-status-pill.ok {
- color: var(--text-success);
-}
-
-.theme-dark .paperforge-status-pill.fail {
- color: var(--text-error);
-}
-
-/* ==========================================================================
- SECTION 39 — Dashboard Redesign: Shared Components
- ========================================================================== */
-
-/* ── Section Label ── */
-.paperforge-section-label {
- font-size: 11px;
- font-weight: 600;
- color: var(--text-muted);
- margin: 0 0 10px 0;
- padding-left: 10px;
- border-left: 3px solid var(--interactive-accent);
- text-transform: uppercase;
- letter-spacing: 0.06em;
- line-height: 1.3;
-}
-
-/* ── Contextual Button ── */
-.paperforge-contextual-btn {
- display: inline-flex;
- align-items: center;
- gap: 5px;
- padding: 5px 12px;
- background: var(--background-secondary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-s);
- color: var(--text-muted);
- font-size: 12px;
- font-weight: 500;
- cursor: pointer;
- transition: background 0.15s, border-color 0.15s, color 0.15s;
- white-space: nowrap;
-}
-
-.paperforge-contextual-btn:hover {
- background: var(--background-modifier-hover);
- border-color: var(--interactive-accent);
- color: var(--text-normal);
-}
-
-.paperforge-contextual-btn.running {
- opacity: 0.6;
- pointer-events: none;
-}
-
-.paperforge-contextual-btn-icon {
- font-size: 14px;
- line-height: 1;
-}
-
-/* ==========================================================================
- SECTION 40 — Per-Paper View (Reading Companion)
- ========================================================================== */
-
-/* ── Status Strip ── */
-.paperforge-status-strip {
- display: flex;
- gap: 6px;
- padding: 8px 0;
- margin: 6px 0;
-}
-
-.paperforge-status-pill {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- padding: 2px 10px;
- border-radius: 4px;
- font-size: 12px;
- font-weight: 500;
- line-height: 1.5;
- background: var(--background-primary-alt);
- color: var(--text-muted);
-}
-
-.paperforge-status-pill.ok {
- background: rgba(var(--background-modifier-success-rgb, 0, 200, 100), 0.12);
- color: var(--text-success, var(--color-green));
-}
-
-.paperforge-status-pill.fail {
- background: rgba(var(--background-modifier-error-rgb, 255, 80, 80), 0.12);
- color: var(--text-error);
-}
-
-.paperforge-status-pill.pending {
- background: var(--background-primary-alt);
- color: var(--text-muted);
-}
-
-.paperforge-status-pill-icon {
- font-size: 11px;
- line-height: 1;
-}
-
-/* Theme dark: softer pill backgrounds */
-.theme-dark .paperforge-status-pill.ok {
- background: rgba(100, 200, 120, 0.15);
-}
-.theme-dark .paperforge-status-pill.fail {
- background: rgba(255, 100, 100, 0.15);
-}
-
-/* ── Paper Overview Card ── */
-.paperforge-paper-overview {
- margin: 10px 0;
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-paper-overview::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-paper-overview:hover::before {
- opacity: 1;
-}
-
-.paperforge-paper-overview-header {
- margin-bottom: 8px;
-}
-
-.paperforge-paper-overview-title {
- font-size: 11px;
- font-weight: 700;
- color: var(--text-accent);
- text-transform: uppercase;
- letter-spacing: 0.06em;
-}
-
-.paperforge-paper-overview-body {
- font-size: 13.5px;
- color: var(--text-muted);
- line-height: 1.65;
-}
-
-.paperforge-paper-overview-excerpt {
- white-space: pre-wrap;
- word-break: break-word;
-}
-
-.paperforge-paper-overview-expand {
- display: inline-block;
- margin-top: 6px;
- padding: 3px 0;
- background: none;
- border: none;
- border-bottom: 1px dashed var(--text-accent);
- color: var(--text-accent);
- font-size: 12px;
- font-weight: 500;
- cursor: pointer;
- transition: color 0.15s, border-color 0.15s;
-}
-
-.paperforge-paper-overview-expand:hover {
- color: var(--interactive-accent-hover);
- border-color: var(--interactive-accent-hover);
-}
-
-/* ── Discussion Card ── */
-.paperforge-discussion-card {
- margin: 10px 0;
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-discussion-card::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-discussion-card:hover::before {
- opacity: 1;
-}
-
-.paperforge-discussion-header {
- margin-bottom: 10px;
-}
-
-.paperforge-discussion-title {
- font-size: 11px;
- font-weight: 700;
- color: var(--text-accent);
- text-transform: uppercase;
- letter-spacing: 0.06em;
-}
-
-.paperforge-discussion-item {
- margin-bottom: 10px;
- padding-bottom: 10px;
- border-bottom: 1px solid var(--background-modifier-border);
-}
-
-.paperforge-discussion-item:last-child {
- border-bottom: none;
- margin-bottom: 0;
- padding-bottom: 0;
-}
-
-.paperforge-discussion-q {
- font-size: 13.5px;
- font-weight: 600;
- color: var(--text-normal);
- margin-bottom: 4px;
- line-height: 1.5;
-}
-
-.paperforge-discussion-a {
- font-size: 13.5px;
- color: var(--text-muted);
- line-height: 1.6;
-}
-
-.paperforge-discussion-expand {
- display: inline;
- padding: 0;
- margin-left: 4px;
- background: none;
- border: none;
- border-bottom: 1px dashed var(--text-accent);
- color: var(--text-accent);
- font-size: 12px;
- font-weight: 500;
- cursor: pointer;
- transition: color 0.15s;
-}
-
-.paperforge-discussion-expand:hover {
- color: var(--interactive-accent-hover);
-}
-
-.paperforge-discussion-viewall {
- display: block;
- text-align: right;
- margin-top: 6px;
- font-size: 12px;
- font-weight: 500;
- color: var(--text-accent);
- cursor: pointer;
- text-decoration: none;
- transition: color 0.15s;
-}
-
-.paperforge-discussion-viewall:hover {
- color: var(--interactive-accent-hover);
- text-decoration: underline;
-}
-
-/* ── Paper Files Row ── */
-.paperforge-paper-files {
- display: flex;
- gap: 8px;
- margin: 10px 0;
-}
-
-/* ── Technical Details ── */
-.paperforge-technical-details {
- margin: 6px 0;
-}
-
-.paperforge-technical-details-toggle {
+ padding: 12px 6px;
+ background: color-mix(in srgb, var(--background-primary-alt) 88%, var(--background-primary) 12%);
+ border: 1px solid color-mix(in srgb, var(--pf-collection-accent) 22%, var(--pf-border));
+ border-radius: 8px;
+ min-width: 0;
width: 100%;
- padding: 6px 12px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-s);
- color: var(--text-faint);
- font-size: 11px;
- font-weight: 500;
- cursor: pointer;
- text-align: left;
- transition: background 0.15s, border-color 0.15s, color 0.15s;
-}
-
-.paperforge-technical-details-toggle:hover {
- background: var(--background-modifier-hover);
- border-color: var(--background-modifier-border-hover);
- color: var(--text-muted);
-}
-
-.paperforge-technical-details-body {
- margin-top: 4px;
- padding: 8px 12px;
- background: var(--background-primary-alt);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-s);
- font-size: 11px;
-}
-
-.paperforge-technical-row {
- display: flex;
- justify-content: space-between;
- padding: 2px 0;
-}
-
-.paperforge-technical-label {
- color: var(--text-faint);
- flex-shrink: 0;
- margin-right: 12px;
-}
-
-.paperforge-technical-value {
- color: var(--text-muted);
- max-width: 60%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- text-align: right;
-}
-
-/* ==========================================================================
- SECTION 41 — Collection / Base View (Batch Workspace)
- ========================================================================== */
-
-/* ── Collection Header ── */
-.paperforge-collection-header {
- margin-bottom: 10px;
-}
-
-.paperforge-collection-title {
- font-size: 16px;
- font-weight: 600;
- color: var(--text-normal);
- line-height: 1.3;
-}
-
-.paperforge-collection-count {
- font-size: 12px;
- color: var(--text-muted);
- margin-top: 2px;
-}
-
-/* ── Workflow Overview ── */
-.paperforge-workflow-overview {
- margin: 10px 0;
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-workflow-overview::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-workflow-overview:hover::before {
- opacity: 1;
-}
-
-.paperforge-workflow-funnel {
- display: flex;
- align-items: center;
- gap: 3px;
- flex-wrap: wrap;
- justify-content: center;
-}
-
-.paperforge-workflow-stage {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 8px 12px;
- background: var(--background-primary-alt);
- border-radius: 6px;
- min-width: 56px;
}
.paperforge-workflow-stage-value {
- font-size: 20px;
+ font-size: 26px;
font-weight: 700;
- color: var(--text-accent);
+ color: var(--pf-collection-accent);
line-height: 1.2;
- letter-spacing: -0.3px;
+ letter-spacing: -0.5px;
}
.paperforge-workflow-stage-label {
- font-size: 10px;
+ font-size: 11px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.3px;
- margin-top: 2px;
+ margin-top: 4px;
text-align: center;
+ word-break: break-word;
}
.paperforge-workflow-arrow {
@@ -2653,7 +2190,6 @@
flex-shrink: 0;
}
-/* ── OCR Pipeline in Base ── */
.paperforge-collection-ocr-header {
display: flex;
align-items: center;
@@ -2661,77 +2197,60 @@
margin-bottom: 14px;
}
-/* ── Issue Summary (serious blockers only) ── */
.paperforge-issue-summary {
margin: 10px 0;
padding: 12px 14px;
background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-left: 3px solid var(--color-orange);
- border-radius: var(--radius-m);
+ border: 1px solid var(--pf-border);
+ border-left: 3px solid var(--pf-warm-line);
+ border-radius: var(--pf-radius);
}
.paperforge-issue-summary .paperforge-section-label {
- color: var(--color-orange);
+ border-left-color: var(--pf-warm-line);
+ color: var(--text-normal);
}
.paperforge-issue-list {
- margin: 4px 0 6px 0;
+ margin: 8px 0 12px 0;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
}
.paperforge-issue-item {
font-size: 13px;
- color: var(--text-muted);
- padding: 2px 0;
-}
-
-.paperforge-issue-actions {
+ font-weight: 500;
+ color: var(--text-normal);
+ padding: 6px 10px;
+ background: color-mix(in srgb, var(--background-secondary) 50%, transparent);
+ border-radius: calc(var(--pf-radius) - 2px);
display: flex;
- gap: 8px;
- margin-top: 8px;
+ align-items: center;
}
-/* ── Collection Actions ── */
+.paperforge-issue-actions,
.paperforge-collection-actions {
display: flex;
gap: 8px;
- margin-top: 10px;
- padding-top: 10px;
- border-top: 1px solid var(--background-modifier-border);
}
-/* ==========================================================================
- SECTION 42 — Global / Home View (System Homepage)
- ========================================================================== */
-
-/* ── Library Snapshot ── */
-.paperforge-library-snapshot {
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
+.paperforge-issue-actions {
+ margin-top: 8px;
}
-.paperforge-library-snapshot::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-library-snapshot:hover::before {
- opacity: 1;
+.paperforge-collection-actions {
+ align-items: center;
+ flex-wrap: wrap;
+ margin-top: 8px;
+ padding-top: 8px;
+ border-top: 1px solid color-mix(in srgb, var(--pf-border) 82%, var(--pf-warm-line));
}
+/* Global mode */
.paperforge-snapshot-pills {
display: flex;
- gap: 8px;
+ gap: 10px;
flex-wrap: wrap;
}
@@ -2739,55 +2258,32 @@
display: flex;
flex-direction: column;
align-items: center;
- padding: 10px 14px;
- background: var(--background-primary-alt);
- border-radius: 6px;
- min-width: 60px;
+ justify-content: center;
+ padding: 14px 16px;
+ background: color-mix(in srgb, var(--background-primary-alt) 86%, var(--background-primary) 14%);
+ border: 1px solid color-mix(in srgb, var(--pf-global-accent) 22%, var(--pf-border));
+ border-radius: 8px;
+ min-width: 72px;
flex: 1;
}
.paperforge-snapshot-value {
- font-size: 20px;
+ font-size: 26px;
font-weight: 700;
- color: var(--text-accent);
+ color: var(--pf-global-accent);
line-height: 1.2;
- letter-spacing: -0.3px;
+ letter-spacing: -0.5px;
}
.paperforge-snapshot-label {
- font-size: 10px;
+ font-size: 11px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.3px;
- margin-top: 2px;
+ margin-top: 4px;
text-align: center;
}
-/* ── System Status ── */
-.paperforge-system-status {
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-system-status::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-system-status:hover::before {
- opacity: 1;
-}
-
.paperforge-status-grid {
display: flex;
flex-direction: column;
@@ -2797,8 +2293,8 @@
.paperforge-status-row {
display: flex;
align-items: center;
- gap: 8px;
- padding: 4px 0;
+ gap: 10px;
+ padding: 6px 0;
}
.paperforge-status-dot {
@@ -2806,12 +2302,12 @@
height: 7px;
border-radius: 50%;
flex-shrink: 0;
- background: var(--background-modifier-border);
+ background: var(--pf-border);
transition: background 0.3s;
}
.paperforge-status-dot.ok {
- background: var(--color-green);
+ background: var(--text-success);
}
.paperforge-status-dot.fail {
@@ -2825,123 +2321,89 @@
}
.paperforge-status-detail {
- font-size: 12px;
+ font-size: 13px;
color: var(--text-faint);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
-/* ── Global Actions ── */
-.paperforge-global-actions {
- padding: 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-global-actions::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-global-actions:hover::before {
- opacity: 1;
-}
-
.paperforge-global-actions-row {
display: flex;
gap: 8px;
+ flex-wrap: wrap;
}
-/* ==========================================================================
- SECTION 43 — Workflow Toggle Checkboxes (per-paper)
- ========================================================================== */
-
-.paperforge-workflow-toggles {
- display: flex;
- gap: 14px;
- padding: 12px 16px;
- background: var(--background-primary);
- border: 1px solid var(--background-modifier-border);
- border-radius: var(--radius-m);
- margin: 10px 0;
- transition: border-color 0.2s, box-shadow 0.2s;
- position: relative;
-}
-
-.paperforge-workflow-toggles::before {
- content: '';
- position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
- transition: opacity 0.2s;
- pointer-events: none;
-}
-
-.paperforge-workflow-toggles:hover::before {
- opacity: 1;
-}
-
-.paperforge-workflow-toggle {
- display: flex;
- align-items: center;
- gap: 6px;
- cursor: pointer;
+.paperforge-collection-actions .paperforge-contextual-btn,
+.paperforge-global-actions-row .paperforge-contextual-btn {
+ min-height: 36px;
+ padding: 8px 14px;
font-size: 13px;
- color: var(--text-muted);
- user-select: none;
-}
-
-.paperforge-workflow-checkbox {
- width: 15px;
- height: 15px;
- margin: 0;
- cursor: pointer;
- accent-color: var(--interactive-accent);
-}
-
-.paperforge-workflow-toggle-label {
font-weight: 600;
- color: var(--text-normal);
}
-.paperforge-workflow-toggle-hint {
- color: var(--text-faint);
+.paperforge-global-actions-row .paperforge-contextual-btn.primary {
+ background: color-mix(in srgb, var(--pf-global-accent) 86%, black 14%);
+ border-color: color-mix(in srgb, var(--pf-global-accent) 90%, black 10%);
+ color: var(--text-on-accent);
+}
+
+.paperforge-collection-actions .paperforge-contextual-btn.primary {
+ background: color-mix(in srgb, var(--pf-collection-accent) 84%, black 16%);
+ border-color: color-mix(in srgb, var(--pf-collection-accent) 88%, black 12%);
+ color: var(--text-on-accent);
+}
+
+.paperforge-global-actions-row .paperforge-contextual-btn.primary:hover {
+ background: color-mix(in srgb, var(--pf-global-accent) 78%, black 22%);
+ border-color: color-mix(in srgb, var(--pf-global-accent) 82%, black 18%);
+}
+
+.paperforge-collection-actions .paperforge-contextual-btn.primary:hover {
+ background: color-mix(in srgb, var(--pf-collection-accent) 76%, black 24%);
+ border-color: color-mix(in srgb, var(--pf-collection-accent) 80%, black 20%);
+}
+
+.paperforge-collection-view .paperforge-ocr-section {
+ padding: 18px 18px 16px;
+ background: color-mix(in srgb, var(--background-secondary) 90%, var(--background-primary) 10%);
+ border-color: color-mix(in srgb, var(--pf-warm-line) 20%, var(--background-modifier-border));
+ box-shadow: 0 1px 2px rgba(20, 18, 14, 0.04), 0 8px 20px rgba(20, 18, 14, 0.04);
+}
+
+.paperforge-collection-view .paperforge-ocr-count-label {
font-size: 11px;
}
-/* ==========================================================================
- SECTION 44 — Dark Theme Specific Overrides
- ========================================================================== */
-
-.theme-dark .paperforge-paper-overview,
-.theme-dark .paperforge-discussion-card,
-.theme-dark .paperforge-workflow-overview,
+.theme-dark .paperforge-collection-view .paperforge-ocr-section,
.theme-dark .paperforge-library-snapshot,
.theme-dark .paperforge-system-status,
.theme-dark .paperforge-global-actions,
-.theme-dark .paperforge-workflow-toggles {
- background: var(--background-primary);
- border-color: var(--background-modifier-border);
+.theme-dark .paperforge-workflow-overview {
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
}
-.theme-dark .paperforge-paper-overview::before,
-.theme-dark .paperforge-discussion-card::before,
-.theme-dark .paperforge-workflow-overview::before,
-.theme-dark .paperforge-library-snapshot::before,
-.theme-dark .paperforge-system-status::before,
-.theme-dark .paperforge-global-actions::before,
-.theme-dark .paperforge-workflow-toggles::before {
- box-shadow: 0 2px 12px rgba(0,0,0,0.3);
+/* Dark theme overrides */
+.theme-dark .paperforge-status-pill.ok {
+ background: rgba(100, 200, 120, 0.15);
+}
+
+.theme-dark .paperforge-status-pill.fail {
+ background: rgba(255, 100, 100, 0.15);
+}
+
+.theme-dark .paperforge-library-snapshot:hover,
+.theme-dark .paperforge-system-status:hover,
+.theme-dark .paperforge-global-actions:hover,
+.theme-dark .paperforge-workflow-overview:hover,
+.theme-dark .paperforge-workflow-toggles:hover {
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
+}
+
+.theme-dark .paperforge-paper-overview:hover {
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 22%, transparent), 0 2px 12px rgba(0, 0, 0, 0.3);
+}
+
+.theme-dark .paperforge-discussion-card:hover {
+ box-shadow: inset 3px 0 0 color-mix(in srgb, var(--pf-paper-accent) 16%, transparent), 0 2px 12px rgba(0, 0, 0, 0.3);
}
diff --git a/paperforge/setup_wizard.py b/paperforge/setup_wizard.py
index f6f58a8a..6bd28b01 100644
--- a/paperforge/setup_wizard.py
+++ b/paperforge/setup_wizard.py
@@ -1012,7 +1012,7 @@ def headless_setup(
"OCR dir": (pf_path / "ocr").exists(),
"paperforge.json": pf_json.exists(),
"Obsidian plugin": (vault / ".obsidian" / "plugins" / "paperforge" / "main.js").exists(),
- "AGENTS.md": True if not agents_src.exists() else agents_dst.exists(),
+ "AGENTS.md": (vault / "AGENTS.md").exists(),
}
failed = [k for k, v in checks.items() if not v]
if failed:
diff --git a/paperforge/skills/literature-qa/SKILL.md b/paperforge/skills/literature-qa/SKILL.md
new file mode 100644
index 00000000..2ad91877
--- /dev/null
+++ b/paperforge/skills/literature-qa/SKILL.md
@@ -0,0 +1,80 @@
+---
+name: literature-qa
+description: >
+ 学术文献精读与问答。MUST trigger when user types /pf-deep, /pf-paper, /pf-end,
+ or says "精读", "深度阅读", "读一下", "查一下这篇论文", "帮我看看这篇文章",
+ "这篇文章讲了什么", "保存讨论", "结束讨论", "做这篇文献的问答",
+ or any phrase about reading/analyzing papers in their Zotero library.
+ 支持 Zotero key, DOI, 标题, 作者/年份, 自然语言描述定位论文.
+license: Apache-2.0
+compatibility: opencode
+---
+
+# Literature QA — 学术文献精读与问答
+
+## 路由表
+
+Agent 读到本文件后,首先根据用户意图路由到对应的 reference 文件:
+
+| 用户意图 | 典型输入 | 加载文件 |
+|---------|---------|---------|
+| 三阶段精读(指定论文) | `/pf-deep `, `pf-deep `, "精读 XXX", "深度阅读 XXX" | [references/deep-reading.md](references/deep-reading.md) |
+| 三阶段精读(查看队列) | `/pf-deep`(无参数), "精读队列", "有哪些该读了" | [references/deep-reading.md](references/deep-reading.md) |
+| 论文问答 | `/pf-paper `, `pf-paper `, "做这篇的问答", "帮我看看 XXX" | [references/paper-qa.md](references/paper-qa.md) |
+| 保存讨论记录 | `/pf-end`, `pf-end`, "保存", "结束讨论", "完成讨论" | [references/save-session.md](references/save-session.md) |
+
+> **重要:** 加载 reference 文件后,严格按照该文件的流程执行。不要跳过任何步骤。
+
+## 论文定位(所有路由共用,先执行)
+
+详见 [references/paper-resolution.md](references/paper-resolution.md)。
+
+**核心原则:二路定位。Python 干确定的活,Agent 干理解的活。路径全在环境变量里,零硬编码。**
+
+### 第零步:加载环境变量(每条路由启动时跑一次)
+
+```pwsh
+python -m paperforge.worker.paper_resolver env --vault . --shell pwsh | Invoke-Expression
+```
+
+此后所有路径用环境变量引用,不再拼接:
+
+| 变量 | 含义 |
+| ------------------ | --------------------------- |
+| `$env:PF_VAULT` | vault 根目录 |
+| `$env:PF_INDEX_PATH` | formal-library.json 路径 |
+| `$env:PF_LITERATURE_DIR` | formal notes 目录 |
+| `$env:PF_OCR_DIR` | OCR 结果目录 |
+
+### 第一步:判断输入类型,选择路径
+
+| 输入特征 | 执行命令 |
+|---------|---------|
+| 8位 key | `python -m paperforge.worker.paper_resolver resolve-key --vault "$env:PF_VAULT"` |
+| DOI | `python -m paperforge.worker.paper_resolver resolve-doi "" --vault "$env:PF_VAULT"` |
+| 标题片段 | `python -m paperforge.worker.paper_resolver search --title "..." --vault "$env:PF_VAULT"` |
+| 作者+年份 | `python -m paperforge.worker.paper_resolver search --author "Smith" --year 2024 --vault "$env:PF_VAULT"` |
+| 自然语言 | Agent 读 `$env:PF_INDEX_PATH` 指向的 formal-library.json |
+
+### 第二步:处理结果
+
+- **Python 返回匹配:** 直接使用返回的 workspace(`formal_note_path` 等由 config 动态计算)
+- **Python 搜不到:** Agent grep fallback:`rg -l "zotero_key:.*ABC" "$env:PF_LITERATURE_DIR/"`
+- **自然语言搜不到:** 告知用户 "未找到,请确认或先运行 `paperforge sync`"
+- **命中多篇:** 列出候选清单让用户选
+
+## 文件结构
+
+```
+literature-qa/
+├── SKILL.md ← 本文件(路由入口)
+├── references/
+│ ├── deep-reading.md ← 精读工作流
+│ ├── paper-qa.md ← 问答工作流
+│ ├── save-session.md ← 保存记录工作流
+│ ├── paper-resolution.md ← 论文定位详细协议
+│ ├── deep-subagent.md ← 子代理提示词模板
+│ └── chart-reading/ ← 19 个图表类型阅读指南
+└── scripts/
+ └── ld_deep.py ← 精读引擎(Python)
+```
diff --git a/paperforge/skills/literature-qa/chart-reading/GSEA富集图.md b/paperforge/skills/literature-qa/references/chart-reading/GSEA富集图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/GSEA富集图.md
rename to paperforge/skills/literature-qa/references/chart-reading/GSEA富集图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/INDEX.md b/paperforge/skills/literature-qa/references/chart-reading/INDEX.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/INDEX.md
rename to paperforge/skills/literature-qa/references/chart-reading/INDEX.md
diff --git a/paperforge/skills/literature-qa/chart-reading/ROC与PR曲线.md b/paperforge/skills/literature-qa/references/chart-reading/ROC与PR曲线.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/ROC与PR曲线.md
rename to paperforge/skills/literature-qa/references/chart-reading/ROC与PR曲线.md
diff --git a/paperforge/skills/literature-qa/chart-reading/Western Blot条带图.md b/paperforge/skills/literature-qa/references/chart-reading/Western Blot条带图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/Western Blot条带图.md
rename to paperforge/skills/literature-qa/references/chart-reading/Western Blot条带图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/免疫荧光定量图.md b/paperforge/skills/literature-qa/references/chart-reading/免疫荧光定量图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/免疫荧光定量图.md
rename to paperforge/skills/literature-qa/references/chart-reading/免疫荧光定量图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/折线图与时间序列.md b/paperforge/skills/literature-qa/references/chart-reading/折线图与时间序列.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/折线图与时间序列.md
rename to paperforge/skills/literature-qa/references/chart-reading/折线图与时间序列.md
diff --git a/paperforge/skills/literature-qa/chart-reading/散点图与气泡图.md b/paperforge/skills/literature-qa/references/chart-reading/散点图与气泡图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/散点图与气泡图.md
rename to paperforge/skills/literature-qa/references/chart-reading/散点图与气泡图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/显微照片与SEM图.md b/paperforge/skills/literature-qa/references/chart-reading/显微照片与SEM图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/显微照片与SEM图.md
rename to paperforge/skills/literature-qa/references/chart-reading/显微照片与SEM图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/条形图与误差棒.md b/paperforge/skills/literature-qa/references/chart-reading/条形图与误差棒.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/条形图与误差棒.md
rename to paperforge/skills/literature-qa/references/chart-reading/条形图与误差棒.md
diff --git a/paperforge/skills/literature-qa/chart-reading/桑基图与弦图.md b/paperforge/skills/literature-qa/references/chart-reading/桑基图与弦图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/桑基图与弦图.md
rename to paperforge/skills/literature-qa/references/chart-reading/桑基图与弦图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/森林图与Meta分析.md b/paperforge/skills/literature-qa/references/chart-reading/森林图与Meta分析.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/森林图与Meta分析.md
rename to paperforge/skills/literature-qa/references/chart-reading/森林图与Meta分析.md
diff --git a/paperforge/skills/literature-qa/chart-reading/火山图与曼哈顿图.md b/paperforge/skills/literature-qa/references/chart-reading/火山图与曼哈顿图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/火山图与曼哈顿图.md
rename to paperforge/skills/literature-qa/references/chart-reading/火山图与曼哈顿图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/热图与聚类图.md b/paperforge/skills/literature-qa/references/chart-reading/热图与聚类图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/热图与聚类图.md
rename to paperforge/skills/literature-qa/references/chart-reading/热图与聚类图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/生存曲线.md b/paperforge/skills/literature-qa/references/chart-reading/生存曲线.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/生存曲线.md
rename to paperforge/skills/literature-qa/references/chart-reading/生存曲线.md
diff --git a/paperforge/skills/literature-qa/chart-reading/箱式图与小提琴图.md b/paperforge/skills/literature-qa/references/chart-reading/箱式图与小提琴图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/箱式图与小提琴图.md
rename to paperforge/skills/literature-qa/references/chart-reading/箱式图与小提琴图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/组织学半定量图.md b/paperforge/skills/literature-qa/references/chart-reading/组织学半定量图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/组织学半定量图.md
rename to paperforge/skills/literature-qa/references/chart-reading/组织学半定量图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/网络图与通路图.md b/paperforge/skills/literature-qa/references/chart-reading/网络图与通路图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/网络图与通路图.md
rename to paperforge/skills/literature-qa/references/chart-reading/网络图与通路图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/蛋白质结构图.md b/paperforge/skills/literature-qa/references/chart-reading/蛋白质结构图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/蛋白质结构图.md
rename to paperforge/skills/literature-qa/references/chart-reading/蛋白质结构图.md
diff --git a/paperforge/skills/literature-qa/chart-reading/降维图(PCA-tSNE-UMAP).md b/paperforge/skills/literature-qa/references/chart-reading/降维图(PCA-tSNE-UMAP).md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/降维图(PCA-tSNE-UMAP).md
rename to paperforge/skills/literature-qa/references/chart-reading/降维图(PCA-tSNE-UMAP).md
diff --git a/paperforge/skills/literature-qa/chart-reading/雷达图与漏斗图.md b/paperforge/skills/literature-qa/references/chart-reading/雷达图与漏斗图.md
similarity index 100%
rename from paperforge/skills/literature-qa/chart-reading/雷达图与漏斗图.md
rename to paperforge/skills/literature-qa/references/chart-reading/雷达图与漏斗图.md
diff --git a/paperforge/skills/literature-qa/references/deep-reading.md b/paperforge/skills/literature-qa/references/deep-reading.md
new file mode 100644
index 00000000..3563a5d7
--- /dev/null
+++ b/paperforge/skills/literature-qa/references/deep-reading.md
@@ -0,0 +1,171 @@
+# 三阶段精读
+
+Keshav 三阶段组会式精读。触发后执行以下工作流。
+
+> **路径说明:** 本文件中的 `scripts/ld_deep.py` 相对于本 skill 目录。Agent 运行时 skill 目录由平台注入(通常为 `/paperforge/skills/literature-qa/`)。如不确定,AI 应从 SKILL.md 所在目录推断。
+
+---
+
+## 前置条件检查
+
+执行前确认:
+- [ ] 已完成论文定位(参考 [paper-resolution.md](paper-resolution.md)),拿到 zotero_key 和 workspace
+- [ ] `analyze: true`(在 formal note frontmatter 中,resolver 返回的 workspace 里可查到)
+- [ ] `ocr_status: done`(在 resolver 返回的 workspace 里可查到)
+
+如果前置条件不满足,告知用户并停止。
+
+---
+
+## 执行流程
+
+### Step 1: Prepare(机械操作,跑脚本)
+
+```bash
+python scripts/ld_deep.py prepare --vault . --key
+```
+
+返回 JSON 解析:
+- `status: "ok"` → 继续
+- `status: "error"` → 报告 `message` 给用户,停止
+
+Prepare 做的事情(Agent 不需要关心细节):
+- 检查 analyze 和 ocr_status
+- 生成 figure-map.json 和 chart-type-map.json
+- 在 formal note 中插入 `## 🔍 精读` 骨架
+
+读 formal note 确认骨架已插入。
+
+---
+
+### Step 2: Pass 1 — 概览
+
+只填 `### Pass 1: 概览` 区域。不碰 Pass 2/3。
+
+**填写内容:**
+
+- **一句话总览**:论文类型 + 核心发现,一句话。
+- **5 Cs 快速评估**:
+ - **Category**(类型):RCT / 队列研究 / 病例对照 / 综述 / 基础研究 / ...
+ - **Context**(上下文):该领域当前共识,本文要解决什么问题
+ - **Correctness**(合理性初判):初步直觉,逻辑是否有明显漏洞
+ - **Contributions**(贡献):1-3 条
+ - **Clarity**(清晰度):写作质量,图表可读性
+- **Figure 导读**(基于 fulltext.md 浏览各图 caption):
+ - 关键主图:列出并一句话概括每个主图要证明什么
+ - 证据转折点:哪个 figure 是叙事的关键转折
+ - 需要重点展开的 supplementary:如果有
+ - 关键表格:列出
+
+填完立即保存 formal note。
+
+---
+
+### Step 3: Pass 2 — 精读还原
+
+填 `### Pass 2: 精读还原` 区域。**按 figure 顺序逐个处理。**
+
+#### 图表类型定位(两步)
+
+**Step A: Python 给建议(快速初筛)**
+```bash
+python scripts/ld_deep.py chart-type-scan --vault . --key
+```
+输出每个 figure 的关键词命中结果。这只是建议,Agent 不要盲信。
+
+**Step B: Agent 读 caption 做最终判断**
+
+对每个 figure:
+1. 读该 figure 的 caption(来自 fulltext.md 或 figure-map.json)
+2. 根据 caption 内容,对照 [chart-reading/INDEX.md](chart-reading/INDEX.md) 判断图表类型
+3. 如果 Python 建议和 Agent 判断不一致 → 以 Agent 判断为准
+4. 如果无法确定类型 → 跳过 chart guide,按通用 figure 结构分析
+5. 确定类型后,读对应的 chart-reading 指南(如 `chart-reading/条形图与误差棒.md`),按指南中的检查清单分析
+
+#### 每张 Figure 的子标题(固定,不可少)
+
+按以下格式填入 formal note 中该 figure 的 callout block:
+
+```
+**图像定位与核心问题**:页码 + 要回答什么问题
+**方法与结果**:实验设计/数据来源/技术手段。核心数据、趋势、对比。
+**图表质量审查**:按 chart-reading 指南检查坐标轴、单位、误差棒、统计标注等。
+**作者解释**:作者在正文中对该图的解读
+**我的理解**:自己的理解(区分于作者解释)
+**疑点/局限**:读图时发现的疑问,用 `> [!warning]` 突出
+```
+
+#### 每张 Table 的子标题
+
+```
+回答什么问题、关键字段/分组、主要结果、我的理解、疑点/局限
+```
+
+#### 每张 figure 填完立即保存,再处理下一张。
+
+#### 所有 figure/table 处理完后,填:
+
+**关键方法补课**:简要解释不熟悉的实验技术(1-2 项即可)
+
+**主要发现与新意**:
+- 发现 1:...(来源:Figure X)
+- 发现 2:...(来源:Figure Y / Table Z)
+
+保存。
+
+---
+
+### Step 4: Postprocess(跑校验脚本,修正问题)
+
+```bash
+python scripts/ld_deep.py postprocess-pass2 --figures --format text
+```
+
+- 输出 `OK` → 继续
+- 输出错误 → 按错误提示修正(包含行号),修正后重新跑
+- 最多 3 轮修正。3 轮后仍失败 → 报告剩余错误给用户
+
+---
+
+### Step 5: Pass 3 — 深度理解
+
+填 `### Pass 3: 深度理解` 区域。基于 Pass 1/2 已写的内容。
+
+**填写内容:**
+
+- **假设挑战与隐藏缺陷**:隐含假设;如果放宽某个假设结论还成立吗;缺少哪些关键引用;实验/分析技术潜在问题
+- **哪些结论扎实,哪些仍存疑**:
+ - **较扎实**:...
+ - **仍存疑**:...(用 `> [!warning]`)
+- **Discussion 与 Conclusion 怎么读**:作者真正完成了什么;哪些地方有拔高;哪些是推测
+- **对我的启发**:研究设计上;figure 组织上;方法组合上;未来工作想法
+- **遗留问题**:...(用 `> [!question]`)
+
+保存。
+
+---
+
+### Step 6: Final Validation
+
+```bash
+python scripts/ld_deep.py validate-note --fulltext
+```
+
+- 输出 `OK` → 告知用户精读完成
+- 输出错误 → 修正缺失项,不报告成功直到通过
+
+---
+
+## Callout 格式规则
+
+- `> [!important]`:每个 main finding
+- `> [!warning]`:疑问、局限、证据边界、仍存疑条目
+- `> [!question]`:遗留问题
+- **间距:** 相邻 callout block 之间必须有空行,否则 Obsidian 会合并
+ - 正确:`> [!important] A\n\n> [!important] B`
+ - 错误:`> [!important] A\n> [!important] B`
+
+## Supplementary 规则
+
+- 默认不逐张展开 supplementary figure/table
+- 仅在以下情况纳入:对主结论形成关键支撑、补足方法可信度、限制主文结论解释范围、作者在正文中明显依赖该补充材料
diff --git a/paperforge/skills/literature-qa/prompt_deep_subagent.md b/paperforge/skills/literature-qa/references/deep-subagent.md
similarity index 100%
rename from paperforge/skills/literature-qa/prompt_deep_subagent.md
rename to paperforge/skills/literature-qa/references/deep-subagent.md
diff --git a/paperforge/skills/literature-qa/references/paper-qa.md b/paperforge/skills/literature-qa/references/paper-qa.md
new file mode 100644
index 00000000..626f23e0
--- /dev/null
+++ b/paperforge/skills/literature-qa/references/paper-qa.md
@@ -0,0 +1,61 @@
+# 论文问答
+
+交互式论文 Q&A 工作台。不强制要求 OCR,但 OCR 完成后回答更准确。
+
+---
+
+## 前置条件
+
+- [ ] 已完成论文定位(参考 [paper-resolution.md](paper-resolution.md)),拿到 zotero_key 和 workspace
+- [ ] OCR 完成(推荐但非强制)
+
+---
+
+## 执行流程
+
+### Step 1: 加载论文
+
+1. 确认 workspace 路径
+2. 读 `fulltext.md`(如果存在)作为主要回答依据
+3. 读 formal note frontmatter 获取元数据(标题、作者、期刊、年份)
+4. 如果 fulltext.md 不存在,告知用户 "OCR 文本不可用,回答将基于元数据和公开信息"
+
+### Step 2: 显示论文信息
+
+```
+已加载论文: [title] ([year], [journal])
+作者: [authors]
+Zotero Key: [key]
+领域: [domain]
+OCR 状态: [done / 不可用]
+结束对话时说 "保存" 即可保存讨论。
+请问有什么问题?
+```
+
+### Step 3: 进入 Q&A 模式
+
+- 等待用户提问
+- 每次回答后等待下一个问题
+- 持续到用户说 "保存"、"结束"、"完成" 等关键词
+
+---
+
+## 回答原则
+
+- **严格基于** fulltext.md 中的文本内容回答
+- 引用原文时标注来源页码/章节(如 "第 3 页,Methods 部分")
+- 用中文(简体中文)回答
+- 论文中未提及的内容,明确说明 "论文中未提及该内容"
+- 需要结合论文以外知识的问题,说明 "该问题需要结合论文以外的知识"
+
+---
+
+## 切换模式
+
+用户在当前对话中可以说 "精读这篇文章" 切换到 deep-reading 模式。此时加载 [deep-reading.md](deep-reading.md) 执行精读流程。
+
+---
+
+## 保存记录
+
+用户说 "保存"、"结束"、"完成"、"保存讨论" 时,加载 [save-session.md](save-session.md) 执行保存。不要自动保存。
diff --git a/paperforge/skills/literature-qa/references/paper-resolution.md b/paperforge/skills/literature-qa/references/paper-resolution.md
new file mode 100644
index 00000000..763425eb
--- /dev/null
+++ b/paperforge/skills/literature-qa/references/paper-resolution.md
@@ -0,0 +1,173 @@
+# 论文定位协议
+
+本文件定义如何将用户输入(key / DOI / 标题 / 作者年份 / 自然语言)解析为论文 workspace。所有子流程(deep-reading, paper-qa, save-session)共用此协议。
+
+## 核心原则
+
+1. **确定性输入走 Python。** key、DOI、标题片段、作者+年份 —— 这些是机器能精确处理的。
+2. **自然语言走 Agent。** "关于骨再生的那篇"、"去年那篇Nature" —— 需要 AI 理解语义。
+3. **Python 搜不到时 Agent 兜底。** 不是报错,是换个方式再试一次。
+4. **所有路径从环境变量获取。** 每条路由启动时先跑 `python -m paperforge.worker.paper_resolver env --vault . --shell pwsh | Invoke-Expression`。此后 `$env:PF_VAULT`、`$env:PF_LITERATURE_DIR`、`$env:PF_OCR_DIR`、`$env:PF_INDEX_PATH` 全程可用。不写死任何目录名。
+
+---
+
+## 前置:获取 vault 路径配置(每个路由启动时跑一次)
+
+```bash
+python -m paperforge.worker.paper_resolver paths --vault .
+```
+
+返回示例(所有路径均由 `paperforge.json` 动态计算):
+```json
+{
+ "ok": true,
+ "data": {
+ "vault_root": "/path/to/vault",
+ "index_path": "/PaperForge/indexes/formal-library.json",
+ "literature_dir": "/",
+ "ocr_dir": "/PaperForge/ocr"
+ }
+}
+```
+
+**后续所有路径操作使用此输出中的值,不要自己拼接。**
+
+---
+
+## 输入类型判断
+
+### 类型 1: Zotero Key(8位字符)
+
+**识别规则:** 8位字母数字组合,如 `XGT9Z257`、`ABC12345`
+
+**执行命令:**
+```bash
+python -m paperforge.worker.paper_resolver resolve-key --vault .
+```
+
+**返回示例(路径由 paperforge.json 配置决定,不固定):**
+```json
+{
+ "ok": true,
+ "data": {
+ "match": {
+ "key": "ABC12345",
+ "title": "TGF-beta in Bone Regeneration",
+ "domain": "骨科",
+ "formal_note_path": "...",
+ "ocr_path": "...",
+ "fulltext_path": "...",
+ "ocr_status": "done"
+ }
+ }
+}
+```
+
+**返回 `"match": null` 时:** Agent fallback — 用 `paths` 命令获取的 `literature_dir` 路径 grep frontmatter:
+```bash
+rg -l "zotero_key:.*ABC12345" /
+```
+
+---
+
+### 类型 2: DOI
+
+**识别规则:** 以 `10.` 开头的标准 DOI 格式,可能带 URL 前缀
+
+**执行命令:**
+```bash
+python -m paperforge.worker.paper_resolver resolve-doi "10.1016/j.jse.2018.01.001" --vault .
+```
+
+**返回格式同类型1。** 返回的路径直接使用,不自己拼接。
+
+---
+
+### 类型 3: 标题片段
+
+**识别规则:** 看起来像论文标题的文本(含学术关键词,非自然语言问句)
+
+**执行命令:**
+```bash
+python -m paperforge.worker.paper_resolver search --title "Predictive findings on MRI" --vault .
+```
+
+**返回示例:**
+```json
+{
+ "ok": true,
+ "data": {
+ "matches": [{ "key": "...", "title": "...", "formal_note_path": "...", ... }],
+ "count": 3
+ }
+}
+```
+
+---
+
+### 类型 4: 作者 + 年份
+
+**识别规则:** 包含作者名(英文姓)和年份
+
+**执行命令:**
+```bash
+python -m paperforge.worker.paper_resolver search --author "Smith" --year 2024 --vault .
+```
+
+---
+
+### 类型 5: 自然语言
+
+**识别规则:** 中文自然语言描述,如 "关于骨再生的那篇"、"去年Nature上那篇讲TGF的"
+
+**Agent 操作:**
+1. 用 `paths` 命令获取的 `index_path` 读 `formal-library.json`
+2. 理解用户意图中的关键信息:主题词、年份、期刊、领域
+3. 在 JSON 的 `title`、`domain`、`journal`、`abstract` 字段中搜索匹配
+4. 如果 formal-library.json 无结果,用 `paths` 命令获取的 `literature_dir` grep formal notes:
+ ```bash
+ rg -i -l "骨再生|bone regeneration" / --include "*.md" -g "!*.canvas"
+ ```
+5. 读匹配的 frontmatter 确认是目标论文
+
+---
+
+## 多篇匹配处理
+
+当搜索返回多个匹配时,Agent 必须列出候选清单,让用户选择:
+
+```
+找到 3 篇匹配的论文:
+
+[1] ABC12345 — TGF-beta in Bone Regeneration (2024, 骨科, OCR: done)
+[2] DEF67890 — Bone Healing After Fracture (2023, 骨科, OCR: pending)
+[3] GHI11111 — Scaffold Design for Bone Repair (2024, 骨科, OCR: done)
+
+请输入编号选择,或 refine 搜索词。
+```
+
+**格式要求:**
+- 编号 + key + title + (year, domain, ocr_status)
+- 不要只列标题或只列 key
+
+---
+
+## Fallback 顺序
+
+```
+输入
+ │
+ ├── 看起来像 key/DOI/标题/作者年份?
+ │ └── YES → Python paper_resolver
+ │ ├── 有结果 → 使用
+ │ └── 无结果 → Agent grep fallback
+ │ ├── 有结果 → 使用
+ │ └── 无结果 → 告知用户
+ │
+ └── 看起来像自然语言?
+ └── Agent 读 formal-library.json
+ ├── 有结果 → 列出/使用
+ └── 无结果 → Agent grep fallback
+ ├── 有结果 → 使用
+ └── 无结果 → 告知用户
+```
diff --git a/paperforge/skills/literature-qa/references/save-session.md b/paperforge/skills/literature-qa/references/save-session.md
new file mode 100644
index 00000000..de023e21
--- /dev/null
+++ b/paperforge/skills/literature-qa/references/save-session.md
@@ -0,0 +1,55 @@
+# 保存讨论记录
+
+将 paper-qa 会话中的 Q&A 记录持久化到论文工作区。
+
+---
+
+## 触发条件
+
+- 用户显式说 "保存"、"保存记录"、"结束"、"完成讨论"、"save"
+- 或显式输入 `/pf-end`
+- 不要自动触发
+
+---
+
+## 执行
+
+### Step 1: 收集 Q&A 对
+
+汇总本次 paper-qa 会话中所有 Q&A,序列化为 JSON 数组:
+
+```json
+[
+ {
+ "question": "用户的问题",
+ "answer": "Agent 的回答",
+ "source": "user_question",
+ "timestamp": "2026-05-10T12:00:00+08:00"
+ }
+]
+```
+
+`source` 为 `"user_question"`(用户提问)或 `"agent_analysis"`(Agent 主动分析)。
+
+### Step 2: 调用 discussion 模块
+
+```bash
+python -m paperforge.worker.discussion record \
+ --vault . \
+ --agent pf-paper \
+ --model "" \
+ --qa-pairs ''
+```
+
+### Step 3: 确认结果
+
+CLI 返回 `{"status": "ok", ...}` → 告知用户记录已保存。
+
+返回 `{"status": "error"}` → 记录错误,重试一次。仍失败则告知用户。
+
+---
+
+## 注意事项
+
+- 仅 paper-qa 会话需要记录。deep-reading 的内容直接写入 formal note,不需要通过本文件。
+- 如果无法从 formal-library.json 找到论文 domain/title,记录失败不应影响用户使用。
diff --git a/paperforge/skills/literature-qa/scripts/pf-deep.md b/paperforge/skills/literature-qa/scripts/pf-deep.md
deleted file mode 100644
index 3d2af01c..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-deep.md
+++ /dev/null
@@ -1,237 +0,0 @@
----
-name: pf-deep
-description: Complete three-pass deep reading of an academic paper (Keshav method). Requires OCR fulltext. Searches by Zotero key, title, DOI, or PMID.
-allowed-tools: [Read, Bash, Edit]
----
-
-# pf-deep
-
-## Purpose
-
-基于单篇论文的组会式精读入口。
-
-1. 解析 `pf-deep ` 中的查询词
-2. 支持 Zotero key、标题片段、DOI、PMID、关键词
-3. 优先搜索本地 Zotero 并锁定单篇论文
-4. 绑定该论文对应的:
- - `/PaperForge/ocr//fulltext.md`
- - `/PaperForge/ocr//meta.json`
- - `//.../KEY - Title.md`
-5. 在正式文献卡片中检查或创建 `## 精读`
-6. 以"研究思路 + figure-by-figure"方式一次性完成精读写回
-
-## CLI Equivalent
-
-```bash
-# 准备阶段(间接)
-python .opencode/skills/pf-deep/scripts/ld_deep.py prepare --vault "" --key
-# 返回 JSON:{status, formal_note, fulltext_md, figures, tables}
-```
-
-> `pf-deep` 是 **Agent 层命令**,通过 Python 代码自动检测论文状态,无需先行 CLI 准备。
-
-## Detection(自动检测,无需手动 sync)
-
-启动时,Agent 执行以下 Python 检测命令,代码会自动判断是否需要精读:
-
-```bash
-python .opencode/skills/pf-deep/scripts/ld_deep.py prepare --vault "" --key
-```
-
-返回 JSON:
-- `status: "ok"` → 就绪,可以开始精读
-- `status: "error"` → 被阻塞(`message` 说明原因:analyze=false / OCR 未完成 / 未找到论文)
-
-Agent 根据返回的 `status` 决定是否进入精读流程,不自行读取 frontmatter。
-
-**队列模式**(无参数时自动检测):Agent 运行:
-```bash
-python .opencode/skills/pf-deep/scripts/ld_deep.py queue --vault ""
-```
-代码自动扫描 canonical index 中 `analyze=true` 且 `deep_reading_status=pending` 的论文,按 OCR 状态分组。
-
-## Arguments
-
-| 参数 | 必需 | 说明 |
-|------|------|------|
-| `` | 是(queue 模式除外) | Zotero key、标题片段、DOI、PMID 或关键词 |
-| `queue` | 否 | 启动批量精读队列模式 |
-
-### 参数说明
-
-1. 如果输入看起来像 8 位 Zotero key,则直接按 key 解析。
-2. 否则先在本地 Zotero 中搜索标题/摘要。
-3. 若命中唯一结果或明显最佳结果,则直接载入。
-4. 若存在多个合理候选,则先列候选清单再让用户选。
-5. 不要强迫用户先知道 Zotero key。
-
-## Example
-
-### 单篇精读(已知 key)
-
-```bash
-pf-deep XGT9Z257
-pf-deep Predictive findings on magnetic resonance imaging
-pf-deep 10.1016/j.jse.2018.01.001
-```
-
-### 无参数:自动检测队列
-
-```bash
-pf-deep
-```
-
-当不提供具体 key/标题时,agent 自动检测精读队列:
-
-1. 运行 `python .opencode/skills/pf-deep/scripts/ld_deep.py queue --vault ""` 扫描队列
-2. 解析输出的 JSON,按 OCR 状态分组展示
-3. 由用户选择篇目
-
-无需先跑 `paperforge sync`。
-
-## Output
-
-Agent 在正式笔记中创建或更新 `## 精读` 区域,包含:
-
-- **Pass 1: 概览** — 一句话总览、5 Cs 快速评估、Figure 导读
-- **Pass 2: 精读还原** — Figure-by-Figure 解析、Table-by-Table 解析、关键方法补课、主要发现与新意
-- **Pass 3: 深度理解** — 假设挑战与隐藏缺陷、结论扎实性评估、Discussion 解读、个人启发、遗留问题
-
-## Error Handling
-
-### OCR 未完成
-- **表现**:Agent 提示 `ocr_status` 不是 `done`
-- **解决**:先运行 `paperforge ocr`,确认 `meta.json` 中 `ocr_status` 变为 `done`
-
-### 内容已存在(覆盖确认)
-- **表现**:正式笔记中已存在 `## 精读` 区域且包含非占位符的实质内容
-- **处理**:Agent **必须**询问用户:追加 / 覆盖 / 跳过
-
-### 未找到论文
-- **表现**:Zotero key 无效或搜索无结果
-- **解决**:确认 key 正确,或尝试用标题片段搜索
-
-## 精读结构参考
-
-### 执行原则
-
-- `pf-deep` 对用户来说是一次触发直接完成。
-- 内部逻辑分两步:
- 1. 先生成 `## 精读` 骨架和 figure 标题位
- 2. 再补全所有空段
-- 后续再次运行时(用户选择追加):
- - 只补空段,不覆盖已有内容
-
-### 精读定位
-
-这不是综述提取,也不是信息摘录。目标是模拟高水平博士/博士后组会讲解单篇论文的学习型精读。
-
-主线必须是:
-
-1. 文章整体研究思路
-2. 主文 figure 逐张解析
-3. 关键方法补课
-4. 主要发现、新意、疑点与启发
-
-### Supplementary 规则
-
-- 默认不逐张展开 supplementary figure/table。
-- 仅在以下情况下纳入:
- - 对主结论形成关键支撑
- - 补足方法可信度
- - 限制主文结论的解释范围
- - 作者在正文中明显依赖该补充材料
-
-### 标准骨架
-
-```md
-## 精读
-
-**证据边界**:区分三层信息:`论文结果`、`作者解释`、`我的理解/推断`。
-
-### Pass 1: 概览
-
-**一句话总览**
-(待补充)
-
-**5 Cs 快速评估**
-- **Category**(类型):
-- **Context**(上下文):
-- **Correctness**(合理性初判):
-- **Contributions**(贡献):
-- **Clarity**(清晰度):
-
-**Figure 导读**
-- 关键主图:
-- 证据转折点:
-- 需要重点展开的 supplementary:
-- 关键表格:
-
-### Pass 2: 精读还原
-
-#### Figure-by-Figure 解析
-(每张 figure 下方按以下顺序填写)
-- **图像定位与核心问题**:页码 + 要回答什么问题
-- **方法与结果**:方法 + 结果
-- **作者解释**:作者对该图的解读
-- **我的理解**:自己的理解(区分于作者解释)
-- **在全文中的作用**:该图在整体故事线中的位置
-- **疑点 / 局限**:读图时发现的疑问
-
-#### Table-by-Table 解析
-(如有重要表格,按同样结构展开)
-
-#### 关键方法补课
-- 方法 1:
-- 方法 2:
-
-#### 主要发现与新意
-**主要发现**
-- 发现 1:
-- 发现 2:
-
-### Pass 3: 深度理解
-
-#### 假设挑战与隐藏缺陷
-- 隐含假设:
-- 如果放宽某个假设,结论还成立吗?
-- 缺少哪些关键引用?
-- 实验/分析技术的潜在问题:
-
-#### 哪些结论扎实,哪些仍存疑
-**较扎实**
--
-
-**仍存疑**
--
-
-#### Discussion 与 Conclusion 怎么读
-- 作者真正完成了什么:
-- 哪些地方有拔高:
-- 哪些地方是推测:
-
-#### 对我的启发
-- 研究设计上:
-- figure 组织上:
-- 方法组合上:
-- 未来工作想法:
-
-#### 遗留问题
-**遗留问题**
--
-```
-
-### Figure 节要求
-
-每个 figure 小节按以下顺序填写:
-
-- **图像定位与核心问题**:页码 + 要回答什么问题
-- **方法与结果**:方法 + 结果
-- **作者解释**:作者对该图的解读
-- **我的理解**:自己的理解(区分于作者解释)
-- **在全文中的作用**:该图在整体故事线中的位置
-- **疑点 / 局限**:读图时发现的疑问(可酌情用 `> [!warning]` 突出)
-
-## See Also
-
-- [pf-paper](pf-paper.md) — 快速摘要与问答
diff --git a/paperforge/skills/literature-qa/scripts/pf-end.md b/paperforge/skills/literature-qa/scripts/pf-end.md
deleted file mode 100644
index 0f3a0f04..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-end.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-name: pf-end
-description: Save the paper Q&A discussion record. Triggered when user says "保存" "结束" "save" or types $pf-end. Summarizes all Q&A pairs and writes them to the paper's ai/discussion directory via the discussion module.
-allowed-tools: [Read, Bash]
----
-
-# pf-end
-
-## Purpose
-
-结束当前论文对话并保存讨论记录。需要用户**显式要求**时才执行,不自动触发。
-
-1. 汇总本次对话中所有 Q&A 对
-2. 通过 `discussion.record_session()` 写入论文工作区的 `ai/` 目录
-3. 告知用户记录已保存
-
-## Trigger
-
-用户说以下任一关键词时执行(全平台通用):
-- `保存` / `记录` / `保存记录`
-- `结束` / `完成`
-- `save discussion` / `save` / `done`
-
-也可以显式指定 key:
-- `{prefix}pf-end `(OpenCode)
-- `保存 `(全平台)
-
-如果未指定 key,则使用当前已加载的论文 key。
-
-## Save Format
-
-将会话期间的所有 Q&A 序列化为 JSON 数组:
-
-```json
-{
- "question": "用户的问题",
- "answer": "Agent 的回答",
- "source": "user_question",
- "timestamp": "2026-05-06T12:00:00+08:00"
-}
-```
-
-`source` 为 `"user_question"`(用户提问)或 `"agent_analysis"`(Agent 主动分析)。
-
-## Command
-
-```bash
-python -m paperforge.worker.discussion record \
- --vault "" \
- --agent pf-paper \
- --model "" \
- --qa-pairs ''
-```
-
-## Verification
-
-CLI 返回:
-```json
-{"status": "ok", "json_path": "Literature/{domain}/{key} - {title}/ai/discussion.json", "md_path": "..."}
-```
-
-如果 `status` 为 `"error"`,记录错误信息并重试,不要跳过。
-
-## See Also
-
-- [pf-paper](pf-paper.md) — 论文 Q&A 工作台
-- [pf-deep](pf-deep.md) — 完整三阶段精读
diff --git a/paperforge/skills/literature-qa/scripts/pf-ocr.md b/paperforge/skills/literature-qa/scripts/pf-ocr.md
deleted file mode 100644
index 000611a3..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-ocr.md
+++ /dev/null
@@ -1,102 +0,0 @@
----
-name: pf-ocr
-description: Process the PDF OCR queue for formal notes marked do_ocr: true. Uploads PDFs to PaddleOCR API and extracts fulltext with figures.
-allowed-tools: [Bash]
----
-
-# /pf-ocr
-
-## Purpose
-
-处理正式笔记 frontmatter 中 `do_ocr: true` 的 PDF OCR 队列。
-
-`paperforge ocr` 会自动读取 `paperforge.json` 定位 ocr 目录和 worker 脚本,运行 OCR 并自动诊断结果。
-
-## CLI Equivalent
-
-```bash
-paperforge ocr
-```
-
-## Prerequisites
-
-- [ ] formal note frontmatter 中 `do_ocr: true` 已设置
-- [ ] PDF 附件存在(`has_pdf: true`)
-- [ ] PaddleOCR API Key 已配置(`.env` 中 `PADDLEOCR_API_TOKEN`)
-- [ ] 网络连接正常(可访问 PaddleOCR 服务)
-
-## Arguments
-
-| 参数 | 必需 | 说明 |
-|------|------|------|
-| `--diagnose` | 否 | 仅诊断配置,不上传 PDF |
-| `--key ` | 否 | 仅处理指定 Zotero key 的文献 |
-| `--vault ` | 否 | 指定 Vault 根目录(默认当前目录) |
-| `--live` | 否 | 与 `--diagnose` 联用,执行实时 PDF 测试 |
-
-### 诊断等级
-
-| 等级 | 检查项 | 失败含义 |
-|------|--------|---------|
-| L1 | API token 存在性 | `PADDLEOCR_API_TOKEN` 缺失或为空 |
-| L2 | URL 可达性 | 无法连接 PaddleOCR 服务 |
-| L3 | API 格式验证 | 服务可达但响应格式异常 |
-| L4 | 实时 PDF 往返 | 完整提交和结果获取失败 |
-
-> Exit code `0` = 所有检查通过。Exit code `1` = 至少一项检查失败。
-
-## Example
-
-```bash
-# 处理所有标记 do_ocr: true 的文献
-paperforge ocr
-
-# 仅处理指定文献
-paperforge ocr --key ABCDEFG
-
-# 诊断模式(不实际运行)
-paperforge ocr --diagnose
-
-# 完整诊断(含实时测试)
-paperforge ocr --diagnose --live
-
-# 指定 Vault 目录
-paperforge ocr --vault /path/to/vault
-```
-
-## Output
-
-OCR 完成后,每个文献生成以下文件:
-
-```
-/PaperForge/ocr//
-├── fulltext.md # 提取的全文(含 分页标记)
-├── images/ # 自动切割的图表图片
-├── meta.json # OCR 元数据(含 ocr_status)
-└── figure-map.json # 图表索引(自动生成)
-```
-
-`meta.json` 中的 `ocr_status` 字段:
-- `pending` — 等待处理
-- `processing` — 正在处理
-- `done` — 完成
-- `failed` — 失败
-
-## Error Handling
-
-### API Token 缺失(L1 失败)
-- `PADDLEOCR_API_TOKEN` 未设置 → 在 `.env` 文件中添加
-
-### 服务不可达(L2 失败)
-- 无法连接 PaddleOCR → 检查网络连接
-
-### PDF 上传失败(L4 失败)
-- PDF 提交后未返回结果 → 检查 PDF 文件是否损坏
-
-### OCR 状态卡住
-- `ocr_status` 长期显示 `processing` → 重新设置 `do_ocr: true` 后再次运行
-
-## See Also
-
-- [pf-sync](pf-sync.md) — 文献同步(生成正式笔记)
-- [pf-deep](pf-deep.md) — 深度精读(依赖 OCR 结果)
diff --git a/paperforge/skills/literature-qa/scripts/pf-paper.md b/paperforge/skills/literature-qa/scripts/pf-paper.md
deleted file mode 100644
index aa3e032b..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-paper.md
+++ /dev/null
@@ -1,107 +0,0 @@
----
-name: pf-paper
-description: Quick paper Q&A workbench. Load a paper by Zotero key, title, DOI, or PMID and answer questions. Does not require OCR.
-allowed-tools: [Read, Bash]
----
-
-# pf-paper
-
-## Purpose
-
-基于 Zotero OCR 文本的单篇论文工作台入口。
-
-1. 解析 `pf-paper ` 中的查询词
-2. 支持 Zotero key、标题片段、DOI、PMID、关键词
-3. 优先搜索本地 Zotero,解析到单篇目标论文
-4. 根据 Vault 根目录的 `paperforge.json` 加载 `/PaperForge/ocr//fulltext.md` 作为主文本
-5. 读取 `meta.json` 显示论文标题、作者、期刊、年份
-6. 进入 Q&A 模式,用中文回答用户关于该论文的问题
-7. 在当前论文上下文中,用户可再说"精读这篇文章"切换到 deep 层
-
-## CLI Equivalent
-
-```bash
-# 准备阶段(间接)
-paperforge sync # 生成正式笔记
-```
-
-> `pf-paper` 是 **Agent 层命令**,无直接 CLI 等效命令。
-
-## Prerequisites
-
-- [ ] 正式笔记已生成(`paperforge sync` 生成)
-- [ ] `fulltext.md` 存在(推荐,用于基于原文回答;如不存在则基于元数据回答)
-- [ ] discussion.py 模块可用(`python -m paperforge.worker.discussion --help` 可执行)
-
-> **注意**:与 `/pf-deep` 不同,`pf-paper` **不强制要求** OCR 完成。没有 OCR 时基于论文元数据和公开信息回答。
-
-## Arguments
-
-| 参数 | 必需 | 说明 |
-|------|------|------|
-| `` | 是 | Zotero key、标题片段、DOI、PMID 或关键词 |
-| ` ...` | 否 | 可同时加载多篇论文 |
-
-### 解析规则
-
-1. 如果输入看起来像 8 位 Zotero key,则直接按 key 解析。
-2. 否则先在本地 Zotero 中搜索标题/摘要。
-3. 若命中唯一结果或明显最佳结果,则直接载入。
-4. 若存在多个合理候选,则先列候选清单再让用户选。
-5. 不要强迫用户先知道 Zotero key。
-
-## Example
-
-```bash
-pf-paper XGT9Z257
-pf-paper Predictive findings on magnetic resonance imaging
-pf-paper 10.1016/j.jse.2018.01.001
-pf-paper XGT9Z257 PQR8KLM
-```
-
-## Output
-
-加载成功后显示:
-
-```
-已加载论文: [title] ([year], [journal])
-Zotero Key: [key]
-结束对话时说"保存记录"即可保存讨论。
-请问有什么问题?
-```
-
-### 回答原则
-
-- **严格基于** `fulltext.md` 中的文本内容回答
-- 引用原文时标注来源页码/章节
-- 用中文(简体中文)回答
-- 论文中未提及的内容,明确说明"论文中未提及该内容"
-- 需要结合论文以外知识的问题,说明"该问题需要结合论文以外的知识回答"
-
-## Error Handling
-
-### 论文未找到
-- **表现**:Zotero key 无效或搜索无结果
-- **解决**:确认 key 正确,或尝试用标题片段搜索
-
-### 多个候选结果
-- **表现**:搜索返回多个匹配的论文
-- **处理**:Agent 列出候选清单,让用户选择目标论文
-
-### OCR 文件缺失
-- **表现**:`fulltext.md` 不存在
-- **处理**:Agent 基于元数据和公开信息回答,并告知用户"OCR 文本不可用,回答基于元数据"
-
-## Saving Discussion Record
-
-当用户说"保存"、"结束"、"完成"等关键词时(或显式输入 `{prefix}pf-end `),必须执行记录保存。具体步骤见 [pf-end](pf-end.md)。
-
-### 注意事项
-
-- 仅 `/pf-paper` Q&A 需要记录。`/pf-deep` 不记录(精读内容已写入正式笔记)。
-- 如果无法从 formal-library.json 找到论文 domain/title,记录失败不应影响用户使用。
-
-## See Also
-
-- [pf-end](pf-end.md) — 结束对话并保存记录
-- [pf-deep](pf-deep.md) — 完整三阶段精读
diff --git a/paperforge/skills/literature-qa/scripts/pf-status.md b/paperforge/skills/literature-qa/scripts/pf-status.md
deleted file mode 100644
index 67d22f94..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-status.md
+++ /dev/null
@@ -1,94 +0,0 @@
----
-name: pf-status
-description: Check PaperForge installation and runtime status. Verifies configuration, paths, and data integrity.
-allowed-tools: [Bash]
----
-
-# /pf-status
-
-## Purpose
-
-查看 PaperForge 当前安装与运行状态。
-
-`paperforge status` 会检查:
-
-- 安装完整性(Python 包、依赖)
-- 配置文件(`paperforge.json`、`.env`)
-- 路径连通性(exports、ocr、literature 目录)
-- Zotero 数据目录链接状态
-- Better BibTeX 导出文件状态
-
-## CLI Equivalent
-
-```bash
-paperforge status
-```
-
-## Prerequisites
-
-无特殊前置条件。此命令用于诊断安装问题,即使在配置不完整时也会尽量输出可用信息。
-
-## Arguments
-
-| 参数 | 必需 | 说明 |
-|------|------|------|
-| `--vault ` | 否 | 指定 Vault 根目录(默认当前目录) |
-
-## Example
-
-```bash
-# 检查当前目录的 Vault 状态
-paperforge status
-
-# 检查指定 Vault 的状态
-paperforge status --vault /path/to/vault
-```
-
-## Output
-
-典型输出示例:
-
-```
-PaperForge Lite v1.2
-====================
-
-[安装检查]
-✓ Python 包: paperforge v1.2.0
-✓ 依赖: requests, pymupdf, pillow
-
-[配置检查]
-✓ paperforge.json: 存在且有效
-✓ .env: 存在
-✓ PADDLEOCR_API_TOKEN: 已设置
-
-[路径检查]
-✓ exports: /PaperForge/exports/
-✓ ocr: /PaperForge/ocr/
-✓ literature: //
-✓ Zotero: /Zotero/
-
-[数据检查]
-✓ library.json: 存在,包含 150 条文献
-✓ 正式笔记: 150 篇
-
-状态: 一切正常 ✅
-```
-
-## Error Handling
-
-### 配置缺失
-- `✗ paperforge.json: 未找到` → 运行 `paperforge doctor` 或重新执行安装
-
-### 路径错误
-- `✗ Zotero: 目录不存在或不是有效链接` → 创建 junction/symlink 到 Zotero 数据目录
-
-### 依赖缺失
-- `✗ 依赖: requests 未安装` → `pip install requests pymupdf pillow`
-
-### API Key 未设置
-- `✗ PADDLEOCR_API_TOKEN: 未设置` → 在 `.env` 文件中添加 API token
-
-## See Also
-
-- [pf-sync](pf-sync.md) — 文献同步
-- [pf-ocr](pf-ocr.md) — OCR 提取
diff --git a/paperforge/skills/literature-qa/scripts/pf-sync.md b/paperforge/skills/literature-qa/scripts/pf-sync.md
deleted file mode 100644
index 02dedf87..00000000
--- a/paperforge/skills/literature-qa/scripts/pf-sync.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-name: pf-sync
-description: Sync Zotero Better BibTeX JSON export and generate/update formal literature notes.
-allowed-tools: [Bash]
----
-
-# /pf-sync
-
-## Purpose
-
-同步 Zotero Better BibTeX JSON 导出并生成/更新正式文献笔记。
-
-`paperforge sync` 读取 Zotero JSON 中的新条目,直接生成正式文献笔记。
-
-自动读取 `paperforge.json` 定位 exports 目录和 literature 目录。
-
-## CLI Equivalent
-
-```bash
-paperforge sync
-```
-
-## Prerequisites
-
-- [ ] Zotero 已安装且 Better BibTeX 插件已启用
-- [ ] Better BibTeX 已配置自动导出 JSON
-- [ ] JSON 导出文件存在(`/PaperForge/exports/library.json`)
-- [ ] `paperforge.json` 配置正确(Vault 根目录下)
-
-## Arguments
-
-| 参数 | 必需 | 说明 |
-|------|------|------|
-| `--dry-run` | 否 | 预览变更,不实际写入文件 |
-| `--domain ` | 否 | 仅同步指定领域(如 `骨科`) |
-| `--selection` | 否 | (已废弃)仅保留以兼容旧版 |
-| `--index` | 否 | (已废弃)仅保留以兼容旧版 |
-| `--vault ` | 否 | 指定 Vault 根目录(默认当前目录) |
-
-### 选项
-
-```bash
-paperforge sync --dry-run # 预览同步结果
-paperforge sync --domain 骨科 # 按领域过滤同步
-```
-
-## Example
-
-```bash
-# 同步 Zotero 并生成正式笔记
-paperforge sync
-
-# 预览模式
-paperforge sync --dry-run
-
-# 仅同步特定领域
-paperforge sync --domain 骨科
-
-# 指定 Vault 目录
-paperforge sync --vault /path/to/vault
-```
-
-## Output
-
-```
-[INFO] Found 5 new items
-[INFO] Created 骨科/XXXXXXX.md
-[INFO] Generated 5 formal notes
-[INFO] Output: //骨科/XXXXXXX - Title.md
-```
-
-生成文件:`/// - .md`
-
-## Error Handling
-
-### JSON 文件不存在
-- `[ERROR] library.json not found` → 检查 Better BibTeX 导出路径
-
-### 空 JSON 导出
-- `[INFO] Found 0 new items` → 确认 Zotero 中有带 citation key 的文献,Better BibTeX 已启用"Keep updated"
-
-## See Also
-
-- [pf-ocr](pf-ocr.md) — OCR 提取(下一步操作)
-- [pf-status](pf-status.md) — 检查系统状态