@geminilight/mindos 0.5.40 → 0.5.42

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.
@@ -1,6 +1,6 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync, statSync, renameSync, unlinkSync, openSync, readSync, closeSync } from 'node:fs';
3
- import { resolve } from 'node:path';
3
+ import { resolve, dirname } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
5
  import { MINDOS_DIR, LOG_PATH, CLI_PATH, NODE_BIN, CONFIG_PATH } from './constants.js';
6
6
  import { green, red, dim, cyan, yellow } from './colors.js';
@@ -8,6 +8,41 @@ import { isPortInUse } from './port.js';
8
8
 
9
9
  // ── Helpers ──────────────────────────────────────────────────────────────────
10
10
 
11
+ /**
12
+ * Dynamically resolve the current mindos CLI path.
13
+ * This is needed because CLI_PATH is evaluated at module load time,
14
+ * but after `npm install -g @geminilight/mindos@latest`, the path may have changed.
15
+ */
16
+ function getCurrentCliPath() {
17
+ try {
18
+ // Try to find mindos in PATH
19
+ const mindosBin = execSync('which mindos', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
20
+ if (mindosBin) {
21
+ // mindos is usually a symlink, resolve it
22
+ try {
23
+ const realPath = execSync(`readlink -f "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
24
+ if (realPath && existsSync(realPath)) {
25
+ return realPath;
26
+ }
27
+ } catch {
28
+ // readlink -f not available on macOS, fallback to realpath
29
+ try {
30
+ const realPath = execSync(`realpath "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
31
+ if (realPath && existsSync(realPath)) {
32
+ return realPath;
33
+ }
34
+ } catch {}
35
+ }
36
+ // Fallback: use the symlink target itself
37
+ if (existsSync(mindosBin)) {
38
+ return mindosBin;
39
+ }
40
+ }
41
+ } catch {}
42
+ // Fallback to static CLI_PATH if dynamic resolution fails
43
+ return CLI_PATH;
44
+ }
45
+
11
46
  /** Rotate log file when it exceeds 2 MB. Keeps at most one .old backup. */
12
47
  function rotateLogs() {
13
48
  try {
@@ -169,6 +204,7 @@ const systemd = {
169
204
  ensureMindosDir();
170
205
  rotateLogs();
171
206
  const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
207
+ const cliPath = getCurrentCliPath();
172
208
  const unit = [
173
209
  '[Unit]',
174
210
  'Description=MindOS app + MCP server',
@@ -176,7 +212,7 @@ const systemd = {
176
212
  '',
177
213
  '[Service]',
178
214
  'Type=simple',
179
- `ExecStart=${NODE_BIN} ${CLI_PATH} start`,
215
+ `ExecStart=${NODE_BIN} ${cliPath} start`,
180
216
  'Restart=on-failure',
181
217
  'RestartSec=3',
182
218
  `Environment=HOME=${homedir()}`,
@@ -253,6 +289,7 @@ const launchd = {
253
289
  ensureMindosDir();
254
290
  rotateLogs();
255
291
  const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
292
+ const cliPath = getCurrentCliPath();
256
293
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
257
294
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
258
295
  <plist version="1.0">
@@ -261,7 +298,7 @@ const launchd = {
261
298
  <key>ProgramArguments</key>
262
299
  <array>
263
300
  <string>${NODE_BIN}</string>
264
- <string>${CLI_PATH}</string>
301
+ <string>${cliPath}</string>
265
302
  <string>start</string>
266
303
  </array>
267
304
  <key>RunAtLoad</key><true/>
@@ -0,0 +1,133 @@
1
+ import { existsSync, readFileSync, copyFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { createInterface } from 'node:readline';
5
+ import { ROOT } from './constants.js';
6
+ import { bold, dim, cyan, green, yellow, isTTY } from './colors.js';
7
+
8
+ const SKILLS = ['mindos', 'mindos-zh'];
9
+ const INSTALLED_BASE = resolve(homedir(), '.agents', 'skills');
10
+
11
+ /**
12
+ * Simple semver "a > b" comparison (major.minor.patch only).
13
+ * Intentionally inlined (same as update-check.js) to keep this module
14
+ * self-contained — no cross-module dependency for a 10-line function.
15
+ */
16
+ function semverGt(a, b) {
17
+ const pa = a.split('.').map(Number);
18
+ const pb = b.split('.').map(Number);
19
+ for (let i = 0; i < 3; i++) {
20
+ if ((pa[i] || 0) > (pb[i] || 0)) return true;
21
+ if ((pa[i] || 0) < (pb[i] || 0)) return false;
22
+ }
23
+ return false;
24
+ }
25
+
26
+ /**
27
+ * Extract version from `<!-- version: X.Y.Z -->` comment in a file.
28
+ * Returns null if file doesn't exist or has no version tag.
29
+ */
30
+ export function extractSkillVersion(filePath) {
31
+ try {
32
+ const content = readFileSync(filePath, 'utf-8');
33
+ const match = content.match(/<!--\s*version:\s*([\d.]+)\s*-->/);
34
+ return match ? match[1] : null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Compare installed vs bundled skill versions.
42
+ * @param {string} [root] — package root to read bundled skills from.
43
+ * Defaults to the static ROOT (fine for startup). Pass the post-update
44
+ * root when called from `mindos update` so we read the NEW package's skills.
45
+ * Returns array of mismatches where bundled > installed.
46
+ */
47
+ export function checkSkillVersions(root) {
48
+ const base = root || ROOT;
49
+ const mismatches = [];
50
+ for (const name of SKILLS) {
51
+ const installPath = resolve(INSTALLED_BASE, name, 'SKILL.md');
52
+ const bundledPath = resolve(base, 'skills', name, 'SKILL.md');
53
+
54
+ if (!existsSync(installPath)) continue;
55
+ if (!existsSync(bundledPath)) continue;
56
+
57
+ const installed = extractSkillVersion(installPath);
58
+ const bundled = extractSkillVersion(bundledPath);
59
+
60
+ if (!installed || !bundled) continue;
61
+ if (semverGt(bundled, installed)) {
62
+ mismatches.push({ name, installed, bundled, installPath, bundledPath });
63
+ }
64
+ }
65
+ return mismatches;
66
+ }
67
+
68
+ /**
69
+ * Copy bundled SKILL.md over the installed version.
70
+ */
71
+ export function updateSkill(bundledPath, installPath) {
72
+ copyFileSync(bundledPath, installPath);
73
+ }
74
+
75
+ /**
76
+ * Print skill update hints and optionally prompt user to update.
77
+ *
78
+ * - TTY + not daemon: interactive readline prompt (default Y)
79
+ * - Non-TTY / daemon / MINDOS_NO_SKILL_CHECK=1: one-line hint, no block
80
+ */
81
+ export async function promptSkillUpdate(mismatches) {
82
+ if (!mismatches || mismatches.length === 0) return;
83
+
84
+ // Print mismatch info
85
+ for (const m of mismatches) {
86
+ console.log(`\n ${yellow('⬆')} Skill ${bold(m.name)}: ${dim(`v${m.installed}`)} → ${cyan(`v${m.bundled}`)}`);
87
+ }
88
+
89
+ // Non-interactive mode: just print hint
90
+ if (!isTTY || process.env.LAUNCHED_BY_LAUNCHD === '1' || process.env.INVOCATION_ID) {
91
+ console.log(` ${dim('Run `mindos start` in a terminal to update interactively.')}`);
92
+ return;
93
+ }
94
+
95
+ // Interactive prompt (10s timeout to avoid blocking startup indefinitely)
96
+ return new Promise((res) => {
97
+ let done = false;
98
+ const finish = () => { if (!done) { done = true; res(); } };
99
+
100
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
101
+ const timer = setTimeout(() => { rl.close(); finish(); }, 10_000);
102
+
103
+ rl.on('close', finish); // handles broken pipe / EOF
104
+
105
+ rl.question(` Update skill${mismatches.length > 1 ? 's' : ''}? ${dim('(Y/n)')} `, (answer) => {
106
+ clearTimeout(timer);
107
+ rl.close();
108
+ const yes = !answer || answer.trim().toLowerCase() !== 'n';
109
+ if (yes) {
110
+ for (const m of mismatches) {
111
+ try {
112
+ updateSkill(m.bundledPath, m.installPath);
113
+ console.log(` ${green('✓')} ${dim(`Updated ${m.name} → v${m.bundled}`)}`);
114
+ } catch (err) {
115
+ console.log(` ${yellow('!')} ${dim(`Failed to update ${m.name}: ${err.message}`)}`);
116
+ }
117
+ }
118
+ }
119
+ finish();
120
+ });
121
+ });
122
+ }
123
+
124
+ /**
125
+ * Main entry: check + prompt. Best-effort, never throws.
126
+ */
127
+ export async function runSkillCheck() {
128
+ if (process.env.MINDOS_NO_SKILL_CHECK === '1') return;
129
+ try {
130
+ const mismatches = checkSkillVersions();
131
+ await promptSkillUpdate(mismatches);
132
+ } catch { /* best-effort, don't block startup */ }
133
+ }
@@ -4,6 +4,7 @@ import { CONFIG_PATH } from './constants.js';
4
4
  import { bold, dim, cyan, green, yellow } from './colors.js';
5
5
  import { getSyncStatus } from './sync.js';
6
6
  import { checkForUpdate, printUpdateHint } from './update-check.js';
7
+ import { runSkillCheck } from './skill-check.js';
7
8
 
8
9
  export function getLocalIP() {
9
10
  try {
@@ -71,5 +72,8 @@ export async function printStartupInfo(webPort, mcpPort) {
71
72
  ]);
72
73
  if (latestVersion) printUpdateHint(latestVersion);
73
74
 
75
+ // Skill version check (best-effort, non-blocking)
76
+ await runSkillCheck();
77
+
74
78
  console.log(`${'─'.repeat(53)}\n`);
75
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.5.40",
3
+ "version": "0.5.42",
4
4
  "description": "MindOS — Human-Agent Collaborative Mind System. Local-first knowledge base that syncs your mind to all AI Agents via MCP.",
5
5
  "keywords": [
6
6
  "mindos",
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Fix nested postcss dependencies inside next/node_modules.
3
+ *
4
+ * Next.js 16 bundles postcss@8.4.31 which depends on nanoid@^3,
5
+ * picocolors, and source-map-js. When the app's top-level nanoid
6
+ * is v5 (major mismatch), npm's hoisting fails to place nanoid@3
7
+ * where postcss can find it. This script installs the missing
8
+ * sub-dependencies directly into postcss's node_modules.
9
+ *
10
+ * Runs as postinstall — skips silently if postcss is already OK
11
+ * or if next/node_modules/postcss doesn't exist.
12
+ */
13
+
14
+ const { existsSync } = require('fs');
15
+ const { join } = require('path');
16
+ const { execSync } = require('child_process');
17
+
18
+ const postcssDir = join('node_modules', 'next', 'node_modules', 'postcss');
19
+ const depsDir = join(postcssDir, 'node_modules');
20
+
21
+ if (existsSync(postcssDir) && !existsSync(depsDir)) {
22
+ try {
23
+ execSync('npm install --no-save --install-strategy=nested', {
24
+ cwd: postcssDir,
25
+ stdio: 'ignore',
26
+ });
27
+ } catch {
28
+ // Best-effort — build will report the real error if deps are still missing
29
+ }
30
+ }
@@ -20,7 +20,7 @@ context automatically when present. User rules override default rules on conflic
20
20
 
21
21
  ---
22
22
 
23
- <!-- version: 1.0.0 -->
23
+ <!-- version: 1.1.0 -->
24
24
  # MindOS Operating Rules
25
25
 
26
26
  ## Core Principles
@@ -47,7 +47,13 @@ Run this sequence before substantive edits:
47
47
  - Read nearby `README.md` / `INSTRUCTION.md` when present.
48
48
  - Follow local conventions over global assumptions.
49
49
 
50
- 4. Execute edits.
50
+ 4. Match existing SOPs.
51
+ - If the task is procedural (multi-step, repeatable, or matches a known workflow category):
52
+ search Workflows/ directory with `mindos_search_notes(scope: "Workflows/")` using task keywords.
53
+ - If a matching SOP is found, read it and follow its steps (adapting as needed).
54
+ - If the SOP's steps diverge from actual execution, propose updating the SOP after task completion.
55
+
56
+ 5. Execute edits.
51
57
 
52
58
  If required context is missing, continue with best effort and state assumptions explicitly.
53
59
 
@@ -135,7 +141,39 @@ Before finishing any operation, verify:
135
141
 
136
142
  ## Preference Capture
137
143
 
138
- When the user expresses a preference correction during operations (e.g., "don't do X in the future", "next time remember to...", "this should go in... not in..."), append it as a structured rule to `user-skill-rules.md` in the knowledge base root under the appropriate section. Confirm to the user: "Preference recorded."
144
+ ### When to capture
145
+ The user expresses a preference correction (e.g., "don't do X", "next time remember to...", "this should go in... not in...").
146
+
147
+ ### Confirm-then-write flow
148
+ 1. **First occurrence of a new preference**: propose the rule and target file before writing.
149
+ - "Record this preference to `user-skill-rules.md`? Rule: _{summary}_"
150
+ - Write only after user confirms.
151
+ 2. **Repeated confirmation on similar category**: after the user confirms the same category of preference 3+ times, auto-write future rules in that category without asking. Add an `auto-confirm: true` flag to the category header in `user-skill-rules.md`.
152
+ 3. **User explicitly grants blanket permission** (e.g., "just record preferences directly"): set a top-level `auto-confirm-all: true` flag and skip confirmation for all future captures.
153
+
154
+ ### File location
155
+ - Target: `user-skill-rules.md` in the knowledge base root (read by `mindos_bootstrap` automatically).
156
+ - If the file does not exist, create it with the template below on first confirmed write.
157
+
158
+ ### File template
159
+ ```markdown
160
+ # User Skill Rules
161
+ <!-- auto-confirm-all: false -->
162
+
163
+ ## Preferences
164
+ <!-- Group by category. Mark auto-confirm: true on categories confirmed 3+ times. -->
165
+
166
+ ## Suppressed Hooks
167
+ <!-- List post-task hooks the user has opted out of. -->
168
+ ```
169
+
170
+ ### Rule format
171
+ Each rule is a bullet under its category:
172
+ ```markdown
173
+ ### {Category}
174
+ <!-- auto-confirm: false -->
175
+ - {Rule description} — _{date captured}_
176
+ ```
139
177
 
140
178
  ---
141
179
 
@@ -179,7 +217,7 @@ For unstructured inputs (meeting notes, braindumps, chat exports) that belong in
179
217
  | SOP/workflow execution | Read doc fully -> execute stepwise -> update only affected section |
180
218
  | Cross-agent handoff | Read task state + decisions -> continue without re-discovery -> write back progress |
181
219
  | Knowledge conflict resolution | Multi-term search for old info -> list all affected files -> present change plan -> update after approval |
182
- | Distill experience into SOP | Extract procedure -> generalize -> create under Workflows/ with prerequisites, steps, pitfalls |
220
+ | Distill experience into SOP | Extract procedure generalize create under Workflows/ using the **SOP template** (see below) with keywords metadata, scenarios, branching steps, exit conditions, and pitfalls |
183
221
  | Periodic review/summary | `get_recent`/`get_history` -> read changed files -> categorize -> structured summary |
184
222
  | Handoff document synthesis | Identify sources -> read -> synthesize (background, decisions, status, open items) -> place in project dir |
185
223
  | Relationship management | Extract updates from notes -> update contact records -> generate next-step strategy |
@@ -188,6 +226,37 @@ For unstructured inputs (meeting notes, braindumps, chat exports) that belong in
188
226
  | Code review | Read review standards -> check naming/security/performance -> output actionable findings |
189
227
  | Distill cross-agent discussion | Confirm decisions with user -> structure as problem/decision/rationale/next-actions -> minimal write-back |
190
228
 
229
+ ### SOP Template
230
+
231
+ When creating a new SOP via "Distill experience into SOP", the file **must** follow this structure:
232
+
233
+ ```markdown
234
+ # SOP: {Title}
235
+ <!-- keywords: {3-5 trigger keywords, English and Chinese} -->
236
+ <!-- last-used: {ISO date} -->
237
+ <!-- created: {ISO date} -->
238
+
239
+ ## Applicable Scenarios
240
+ When to use this SOP. List trigger conditions and prerequisites.
241
+
242
+ ## Steps
243
+ Each step includes:
244
+ 1. **Action** — concrete operation
245
+ 2. **Branch** — if X do A, if Y do B (mark "none" if no branching)
246
+ 3. **Failure handling** — what can go wrong and how to respond
247
+
248
+ ## Exit Conditions
249
+ When is the task complete. When to abort or escalate.
250
+
251
+ ## Pitfall Log
252
+ Known edge cases and lessons learned. Append new entries each time the SOP is executed and a new issue is encountered.
253
+ ```
254
+
255
+ Metadata rules:
256
+ - `keywords` — used by SOP recall search in Startup Protocol step 4. Include both English and Chinese terms.
257
+ - `last-used` — update to today's date each time the SOP is followed.
258
+ - `created` — set once at creation time.
259
+
191
260
  ## Interaction Rules
192
261
 
193
262
  - **When a request is ambiguous or too broad (e.g., "help me organize things"), always ask for clarification before acting.** Propose specific options based on what you see in the knowledge base (recent changes, directory structure), but do not start reorganizing or rewriting without understanding the user's intent and scope.
@@ -230,6 +299,11 @@ After completing a task, check the conditions below. If one matches, make a one-
230
299
  - Condition: 3+ structurally similar operations in the current session.
231
300
  - Propose: "This operation repeated multiple times — create an SOP?"
232
301
 
302
+ ### SOP drift (priority: medium)
303
+ - Condition: task was executed following an existing SOP, but actual steps diverged from documented steps.
304
+ - Propose: "Execution diverged from {SOP file} — update the SOP?"
305
+ - Action: update divergent steps, append new pitfalls, set `<!-- last-used: -->` to today.
306
+
233
307
  ### Conversation retrospective (priority: low)
234
308
  - Condition: session >10 turns and involved decisions, trade-offs, or lessons.
235
309
  - Propose: "This conversation had some decisions worth capturing — do a retrospective?"
@@ -18,7 +18,7 @@ description: >
18
18
 
19
19
  ---
20
20
 
21
- <!-- version: 1.0.0 -->
21
+ <!-- version: 1.1.0 -->
22
22
  # MindOS 操作规则
23
23
 
24
24
  ## 核心原则
@@ -45,7 +45,13 @@ description: >
45
45
  - 若存在,读取就近 `README.md` / `INSTRUCTION.md`。
46
46
  - 优先遵循局部约定,而非全局假设。
47
47
 
48
- 4. 再执行编辑。
48
+ 4. 匹配已有 SOP。
49
+ - 若任务是流程性的(多步骤、可重复、或匹配已知工作流类别):
50
+ 用任务关键词搜索 Workflows/ 目录 `mindos_search_notes(scope: "Workflows/")`。
51
+ - 若找到匹配的 SOP,读取并按其步骤执行(按需调整)。
52
+ - 若 SOP 步骤与实际执行产生偏差,任务完成后提议更新该 SOP。
53
+
54
+ 5. 再执行编辑。
49
55
 
50
56
  若关键上下文缺失,按最佳努力继续,并明确写出假设。
51
57
 
@@ -133,7 +139,39 @@ description: >
133
139
 
134
140
  ## 偏好捕获
135
141
 
136
- 当用户在操作过程中表达偏好修正(如"以后不要…""下次记得…""这个应该放在…而不是…"),将偏好以结构化规则追加到知识库根目录的 `user-skill-rules.md` 的对应分区。追加后告知用户"已记录偏好"。
142
+ ### 何时捕获
143
+ 用户在操作过程中表达偏好修正(如"以后不要…""下次记得…""这个应该放在…而不是…")。
144
+
145
+ ### 确认后写入流程
146
+ 1. **某类偏好首次出现**:先提议,用户确认后再写入。
147
+ - "记录此偏好到 `user-skill-rules.md`?规则:_{摘要}_"
148
+ - 仅在用户确认后写入。
149
+ 2. **同类偏好确认 3 次以上**:该类别标记 `auto-confirm: true`,后续同类偏好自动写入,不再询问。
150
+ 3. **用户明确授权**(如"偏好直接记就行"):设置顶层 `auto-confirm-all: true`,所有偏好跳过确认直接写入。
151
+
152
+ ### 文件位置
153
+ - 目标:知识库根目录的 `user-skill-rules.md`(`mindos_bootstrap` 启动时自动读取)。
154
+ - 若文件不存在,在首次确认写入时按以下模板创建。
155
+
156
+ ### 文件模板
157
+ ```markdown
158
+ # User Skill Rules
159
+ <!-- auto-confirm-all: false -->
160
+
161
+ ## Preferences
162
+ <!-- 按类别分组。确认 3 次以上的类别标记 auto-confirm: true。 -->
163
+
164
+ ## Suppressed Hooks
165
+ <!-- 列出用户已关闭的 Post-Task Hooks。 -->
166
+ ```
167
+
168
+ ### 规则格式
169
+ 每条规则以列表项写在对应类别下:
170
+ ```markdown
171
+ ### {类别名}
172
+ <!-- auto-confirm: false -->
173
+ - {规则描述} — _{记录日期}_
174
+ ```
137
175
 
138
176
  ---
139
177
 
@@ -177,7 +215,7 @@ description: >
177
215
  | SOP/工作流执行 | 完整读取 → 分步执行 → 仅更新过时章节 |
178
216
  | 跨 Agent 接力 | 读任务状态+决策 → 无需重复探索直接接续 → 回写进度 |
179
217
  | 知识冲突联动 | 多关键词搜索旧信息 → 列出受影响文件 → 展示变更计划 → 确认后更新 |
180
- | 经验提炼 SOP | 提取步骤 → 泛化 → 在 Workflows/ 下创建含前置条件、步骤、踩坑的 SOP |
218
+ | 经验提炼 SOP | 提取步骤 → 泛化 → 在 Workflows/ 下按 **SOP 模板**(见下方)创建,包含关键词元数据、适用场景、分支步骤、退出条件和踩坑记录 |
181
219
  | 周期性回顾 | `get_recent`/`get_history` → 读变动文件 → 分类 → 结构化总结 |
182
220
  | 交接文档合成 | 识别来源 → 读取 → 合成(背景、决策、状态、待办)→ 放项目目录 |
183
221
  | 关系维护与跟进 | 从纪要提取更新 → 更新联系人记录 → 生成跟进策略 |
@@ -186,6 +224,37 @@ description: >
186
224
  | 代码审查 | 读审查规范 → 检查命名/安全/性能 → 输出可执行建议 |
187
225
  | 沉淀跨 Agent 讨论 | 与用户确认决策 → 结构化为问题/决策/理由/下一步 → 最小化写回 |
188
226
 
227
+ ### SOP 模板
228
+
229
+ 通过"经验提炼 SOP"创建新 SOP 时,文件**必须**遵循以下结构:
230
+
231
+ ```markdown
232
+ # SOP: {标题}
233
+ <!-- keywords: {3-5 个触发关键词,中英文} -->
234
+ <!-- last-used: {ISO date} -->
235
+ <!-- created: {ISO date} -->
236
+
237
+ ## 适用场景
238
+ 什么情况下该用这个 SOP。列出触发条件和前置依赖。
239
+
240
+ ## 步骤
241
+ 每步包含:
242
+ 1. **做什么** — 具体操作
243
+ 2. **判断分支** — 遇到 X 走 A,遇到 Y 走 B(无分支则标注"无")
244
+ 3. **失败处理** — 这步可能失败的情况和应对
245
+
246
+ ## 退出条件
247
+ 什么时候算完成,什么时候该放弃或升级。
248
+
249
+ ## 踩坑记录
250
+ 已知的边界 case 和教训。每次执行遇到新坑时追加。
251
+ ```
252
+
253
+ 元数据规则:
254
+ - `keywords` — 供启动协议步骤 4 的 SOP 召回搜索使用。同时包含中英文关键词。
255
+ - `last-used` — 每次按 SOP 执行后更新为当天日期。
256
+ - `created` — 创建时设置一次。
257
+
189
258
  ## 交互规则
190
259
 
191
260
  - **当请求模糊或范围过大时(如"帮我整理一下"),先问清楚再动手。** 基于知识库现状(近期变动、目录结构)提出具体选项,但不要在理解用户意图和范围之前就开始重组或重写。
@@ -228,6 +297,11 @@ description: >
228
297
  - 条件:当前会话中 3+ 次结构相似的操作
229
298
  - 提议:"这个操作重复了多次,要整理成 SOP 吗?"
230
299
 
300
+ ### SOP 偏差(优先级:中)
301
+ - 条件:任务按已有 SOP 执行,但实际步骤与文档步骤产生偏差
302
+ - 提议:"执行过程与 {SOP 文件} 有偏差,要更新这个 SOP 吗?"
303
+ - 动作:更新偏差步骤、追加新踩坑记录、将 `<!-- last-used: -->` 设为今天。
304
+
231
305
  ### 对话复盘(优先级:低)
232
306
  - 条件:会话 >10 轮且涉及决策、权衡或经验教训
233
307
  - 提议:"这段对话有些决策值得沉淀,要做个复盘吗?"
@@ -0,0 +1,8 @@
1
+ # Drafts
2
+
3
+ Work-in-progress notes that are not ready to share or publish.
4
+
5
+ ## Usage
6
+
7
+ - Store unfinished writing, incomplete ideas, or content pending revision.
8
+ - When ready, move to the appropriate folder or finalize for sharing.
@@ -9,6 +9,7 @@ Quick capture and lightweight notes.
9
9
  ├── README.md
10
10
  ├── INSTRUCTION.md
11
11
  ├── Inbox/
12
+ ├── Drafts/
12
13
  ├── Waiting/
13
14
  ├── Meetings/
14
15
  └── Ideas/
@@ -17,6 +18,7 @@ Quick capture and lightweight notes.
17
18
  ## Usage
18
19
 
19
20
  - `Inbox/`: quick capture for unprocessed notes.
21
+ - `Drafts/`: work-in-progress content not yet ready to share or publish.
20
22
  - `Waiting/`: items blocked by external dependency or feedback.
21
23
  - `Meetings/`: meeting notes, decisions, and action items.
22
24
  - `Ideas/`: idea pool for product concepts, topics, and experiments.
@@ -9,6 +9,7 @@
9
9
  ├── README.md
10
10
  ├── INSTRUCTION.md
11
11
  ├── 收件箱/
12
+ ├── 草稿/
12
13
  ├── 待反馈/
13
14
  ├── 会议/
14
15
  └── 想法/
@@ -17,6 +18,7 @@
17
18
  ## 💡 使用说明
18
19
 
19
20
  - `收件箱/`:临时速记入口,未整理内容先落这里。
21
+ - `草稿/`:未完成、尚未准备好分享或发布的内容。
20
22
  - `待反馈/`:需要他人反馈或外部依赖的事项。
21
23
  - `会议/`:会议纪要、决策点与行动项。
22
24
  - `想法/`:灵感池,沉淀产品点子、选题与实验想法。
@@ -0,0 +1,8 @@
1
+ # 草稿
2
+
3
+ 存放未完成、尚未准备好分享或发布的内容。
4
+
5
+ ## 使用说明
6
+
7
+ - 用于保存未写完的文章、不成熟的想法或待修改的内容。
8
+ - 完稿后迁移到对应目录,或整理后对外分享。