autosnippet 3.2.4 → 3.2.6

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.
Files changed (64) hide show
  1. package/README.md +2 -4
  2. package/bin/cli.js +164 -145
  3. package/config/constitution.yaml +2 -0
  4. package/dashboard/dist/assets/{index-DNOHYBhy.css → index-BaGY7kJI.css} +1 -1
  5. package/dashboard/dist/assets/{index-6itPuGFl.js → index-DfHY_3ln.js} +25 -25
  6. package/dashboard/dist/index.html +2 -2
  7. package/lib/cli/CliLogger.js +78 -0
  8. package/lib/cli/SetupService.js +9 -718
  9. package/lib/cli/UpgradeService.js +23 -398
  10. package/lib/cli/deploy/FileDeployer.js +562 -0
  11. package/lib/cli/deploy/FileManifest.js +272 -0
  12. package/lib/external/mcp/McpServer.js +22 -26
  13. package/lib/external/mcp/autoApproveInjector.js +1 -0
  14. package/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +5 -5
  15. package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +25 -3
  16. package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +6 -6
  17. package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +4 -0
  18. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +5 -5
  19. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +89 -44
  20. package/lib/external/mcp/handlers/consolidated.js +8 -9
  21. package/lib/external/mcp/handlers/dimension-complete-external.js +4 -4
  22. package/lib/external/mcp/handlers/guard.js +283 -5
  23. package/lib/external/mcp/handlers/task.js +183 -9
  24. package/lib/external/mcp/tools.js +32 -81
  25. package/lib/http/routes/task.js +55 -0
  26. package/lib/service/chat/AnalystAgent.js +12 -12
  27. package/lib/service/chat/ChatAgent.js +227 -545
  28. package/lib/service/chat/ChatAgentPrompts.js +9 -11
  29. package/lib/service/chat/ContextWindow.js +2 -296
  30. package/lib/service/chat/EpisodicConsolidator.js +15 -15
  31. package/lib/service/chat/ExplorationTracker.js +1262 -0
  32. package/lib/service/chat/HandoffProtocol.js +8 -9
  33. package/lib/service/chat/Memory.js +4 -0
  34. package/lib/service/chat/ProducerAgent.js +9 -6
  35. package/lib/service/chat/ProjectSemanticMemory.js +4 -0
  36. package/lib/service/chat/ReasoningTrace.js +182 -0
  37. package/lib/service/chat/WorkingMemory.js +4 -0
  38. package/lib/service/chat/memory/ActiveContext.js +910 -0
  39. package/lib/service/chat/memory/MemoryCoordinator.js +662 -0
  40. package/lib/service/chat/memory/PersistentMemory.js +450 -0
  41. package/lib/service/chat/memory/SessionStore.js +896 -0
  42. package/lib/service/chat/memory/index.js +13 -0
  43. package/lib/service/chat/tools/ast-graph.js +17 -16
  44. package/lib/service/cursor/AgentInstructionsGenerator.js +76 -47
  45. package/lib/service/cursor/FileProtection.js +4 -1
  46. package/lib/service/guard/GuardCheckEngine.js +10 -3
  47. package/lib/service/task/TaskGraphService.js +3 -3
  48. package/lib/shared/LanguageService.js +2 -1
  49. package/package.json +1 -1
  50. package/skills/autosnippet-intent/SKILL.md +1 -3
  51. package/skills/autosnippet-recipes/SKILL.md +1 -3
  52. package/templates/claude-code/commands/prime.md +19 -0
  53. package/templates/claude-code/hooks/autosnippet-session.sh +63 -0
  54. package/templates/claude-code/settings.json +21 -0
  55. package/templates/copilot-instructions.md +64 -177
  56. package/templates/cursor-hooks/commands/prime.md +12 -0
  57. package/templates/cursor-hooks/hooks/session-start.sh +10 -0
  58. package/templates/cursor-hooks/hooks.json +11 -0
  59. package/templates/cursor-rules/autosnippet-conventions.mdc +52 -3
  60. package/templates/cursor-rules/autosnippet-workflow.mdc +51 -27
  61. package/lib/external/mcp/handlers/decide.js +0 -109
  62. package/lib/external/mcp/handlers/ready.js +0 -42
  63. package/lib/service/chat/ReasoningLayer.js +0 -888
  64. package/templates/claude-hooks.yaml +0 -19
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Memory Module — 统一导出
3
+ *
4
+ * Phase 2: MemoryCoordinator + legacy module re-exports
5
+ * Phase 3: ActiveContext (合并 WorkingMemory + ReasoningTrace)
6
+ * Phase 4: SessionStore (合并 EpisodicMemory + ToolResultCache)
7
+ * Phase 5: PersistentMemory (继承 ProjectSemanticMemory + 增强)
8
+ */
9
+
10
+ export { MemoryCoordinator } from './MemoryCoordinator.js';
11
+ export { ActiveContext } from './ActiveContext.js';
12
+ export { SessionStore } from './SessionStore.js';
13
+ export { PersistentMemory } from './PersistentMemory.js';
@@ -451,19 +451,18 @@ export const noteFinding = {
451
451
  required: ['finding'],
452
452
  },
453
453
  handler: async (params, ctx) => {
454
- const workingMemory = ctx._workingMemory;
455
- if (!workingMemory) {
456
- return '⚠ 工作记忆未初始化 (仅在 bootstrap 分析期间可用)';
457
- }
458
-
459
- const finding = params.finding || '';
460
- const evidence = params.evidence || '';
461
- const importance = params.importance || 5;
462
- const round = ctx._currentRound || 0;
463
-
464
- workingMemory.noteKeyFinding(finding, evidence, importance, round);
465
-
466
- return `📌 已记录发现 [${importance}/10]: "${finding.substring(0, 80)}" — 当前共 ${workingMemory.scratchpadSize} 条关键发现`;
454
+ // v5.0: 通过 MemoryCoordinator
455
+ const coordinator = ctx._memoryCoordinator;
456
+ if (coordinator) {
457
+ const finding = params.finding || '';
458
+ const evidence = params.evidence || '';
459
+ const importance = params.importance || 5;
460
+ const round = ctx._currentRound || 0;
461
+ const scopeId = ctx._dimensionScopeId || undefined;
462
+ return coordinator.noteFinding(finding, evidence, importance, round, scopeId);
463
+ }
464
+
465
+ return '⚠ 工作记忆未初始化 (仅在 bootstrap 分析期间可用)';
467
466
  },
468
467
  };
469
468
 
@@ -490,12 +489,14 @@ export const getPreviousEvidence = {
490
489
  required: ['query'],
491
490
  },
492
491
  handler: async (params, ctx) => {
493
- const episodicMemory = ctx._episodicMemory;
494
- if (!episodicMemory) {
492
+ // v5.0: 通过 MemoryCoordinator 获取 SessionStore
493
+ const coordinator = ctx._memoryCoordinator;
494
+ const sessionStore = coordinator?.getSessionStore();
495
+ if (!sessionStore) {
495
496
  return '没有前序维度的证据可用。';
496
497
  }
497
498
 
498
- const results = episodicMemory.searchEvidence(params.query, params.dimId || undefined);
499
+ const results = sessionStore.searchEvidence(params.query, params.dimId || undefined);
499
500
 
500
501
  if (results.length === 0) {
501
502
  return `没有找到与 "${params.query}" 相关的前序证据。建议自行搜索。`;
@@ -55,9 +55,7 @@ const MCP_TOOLS_SUMMARY = [
55
55
  { name: 'autosnippet_skill', desc: 'Skill management (list/load/create/update/delete/suggest)' },
56
56
  { name: 'autosnippet_save_document', desc: 'Save development document (auto-publish)' },
57
57
  { name: 'autosnippet_bootstrap', desc: 'Project cold-start & scan (knowledge/refine/scan)' },
58
- { name: 'autosnippet_ready', desc: 'Session entry point loads decisions + ready tasks (call FIRST)' },
59
- { name: 'autosnippet_decide', desc: 'Decision management (record/revise/unpin/list)' },
60
- { name: 'autosnippet_task', desc: 'Task CRUD (create/claim/close/fail/defer/progress/decompose)' },
58
+ { name: 'autosnippet_task', desc: 'Unified task & decision management: prime (session entry, CALL FIRST) / create/claim/close/fail/defer/progress/decompose (task CRUD) / record_decision/revise_decision/unpin_decision/list_decisions (decisions)' },
61
59
  { name: 'autosnippet_health', desc: 'Service health & KB statistics' },
62
60
  { name: 'autosnippet_capabilities', desc: 'List all available MCP tools (self-discovery)' },
63
61
  ];
@@ -89,14 +87,22 @@ export class AgentInstructionsGenerator {
89
87
  // 构建共享内容块
90
88
  const sections = this._buildSections({ rules, patterns, skills });
91
89
 
92
- // 生成 3 个目标文件
93
- const agents = this._writeAgentsMd(sections);
94
- const claude = this._writeClaudeMd(sections);
90
+ // 避免 IDE 上下文重复:
91
+ // - 不自动生成 CLAUDE.md(用户自己维护)
92
+ // - 如果项目已有 CLAUDE.md,跳过 AGENTS.md(避免两份文件同时注入 IDE 上下文)
93
+ const claudePath = path.join(this.projectRoot, 'CLAUDE.md');
94
+ const hasClaudeMd = fs.existsSync(claudePath);
95
+
96
+ const agents = hasClaudeMd
97
+ ? { filePath: path.join(this.projectRoot, 'AGENTS.md'), tokensUsed: 0, skipped: true }
98
+ : this._writeAgentsMd(sections);
99
+ const claude = { filePath: claudePath, tokensUsed: 0, skipped: true }; // 不自动生成
95
100
  const copilot = this._writeCopilotInstructions(sections);
96
101
 
97
102
  const duration = Date.now() - startTime;
98
- const filesWritten = [agents, claude, copilot].filter((r) => !r.skipped).length;
99
- const skippedFiles = [agents, claude, copilot].filter((r) => r.skipped);
103
+ const allResults = [agents, claude, copilot];
104
+ const filesWritten = allResults.filter((r) => !r.skipped).length;
105
+ const skippedFiles = allResults.filter((r) => r.skipped);
100
106
  if (skippedFiles.length > 0) {
101
107
  this.logger.info?.(
102
108
  `[AgentInstructions] Skipped ${skippedFiles.length} file(s) — ` +
@@ -279,24 +285,24 @@ export class AgentInstructionsGenerator {
279
285
  lines.push('');
280
286
 
281
287
  // Key tools highlight for Claude
282
- lines.push('### Recommended Workflow', '');
288
+ lines.push('### Task Workflow', '');
283
289
  lines.push(
284
- '1. **Every message → `autosnippet_ready()`** — Load decisions + tasks + knowledge context (ALWAYS FIRST)'
290
+ '1. **Every message → `autosnippet_task({ operation: "prime" })`** — Load decisions + tasks + knowledge context (ALWAYS FIRST)'
285
291
  );
286
292
  lines.push(
287
- '2. **User agrees/disagrees → `autosnippet_decide(record/revise/unpin)`** Persist decision immediately'
293
+ '2. **Create task for non-trivial work** — ≥2 files OR ≥10 lines → `create` `claim` code → `close`'
288
294
  );
289
295
  lines.push(
290
- '3. **Before writing code**: `autosnippet_search({ query: "<topic>" })` to find relevant patterns'
296
+ '3. **User agrees/disagrees `autosnippet_task({ operation: "record_decision" })`** Persist decision immediately'
291
297
  );
292
298
  lines.push(
293
- '4. **Check compliance**: `autosnippet_guard({ code: "<your code>" })` before committing'
299
+ '4. **Before writing code**: `autosnippet_search({ query: "<topic>" })` to find relevant patterns'
294
300
  );
295
301
  lines.push(
296
- '5. **Complete task**: `autosnippet_task({ operation: "close", id: "<id>" })`'
302
+ '5. **Complete task**: `autosnippet_task({ operation: "close", id: "<id>", reason: "..." })`'
297
303
  );
298
304
  lines.push(
299
- '6. **Guard diagnostics**: Read ruleId `autosnippet_search({ query: "<ruleId>" })` fix'
305
+ '6. **Session end**: Close or defer ALL in_progress tasks zero in_progress on exit'
300
306
  );
301
307
  lines.push('');
302
308
 
@@ -364,12 +370,7 @@ export class AgentInstructionsGenerator {
364
370
  lines.push('');
365
371
 
366
372
  // Workflow
367
- lines.push('## Workflow', '');
368
- lines.push('1. Search before coding: `autosnippet_search({ query: "..." })`');
369
- lines.push('2. Prefer Recipe over raw source code');
370
- lines.push('3. Submit discoveries: `autosnippet_submit_knowledge({ ... })`');
371
- lines.push('4. Do NOT directly modify `AutoSnippet/` or `.autosnippet/` files');
372
- lines.push('');
373
+ lines.push(...this._renderWorkflow());
373
374
 
374
375
  const content = `${lines.join('\n')}\n`;
375
376
  const destDir = path.join(this.projectRoot, '.github');
@@ -391,15 +392,37 @@ export class AgentInstructionsGenerator {
391
392
  */
392
393
  _renderConstraints() {
393
394
  return [
394
- '## Mandatory Constraints',
395
+ '## CRITICAL: You Operate autosnippet_task — The User Doesn\'t',
396
+ '',
397
+ 'You are the task operator. Users speak naturally; you translate to task operations.',
398
+ 'DO NOT tell users to call autosnippet_task. That\'s YOUR job.',
399
+ '',
400
+ '- WRONG: "You can run autosnippet_task({ operation: \'create\' }) to create a task"',
401
+ '- RIGHT: *(you run create yourself and tell the user "Created task asd-42: Fix login bug")*',
402
+ '',
403
+ '## Task Tracking Rules (MANDATORY)',
404
+ '',
405
+ '1. **MUST prime on EVERY message** — `autosnippet_task({ operation: "prime" })` BEFORE anything else. No exceptions.',
406
+ '2. **MUST create task for non-trivial work** — ≥2 files OR ≥10 lines → create BEFORE starting.',
407
+ '3. **MUST claim before coding** — `autosnippet_task({ operation: "claim", id })` then code.',
408
+ '4. **MUST close when done** — `autosnippet_task({ operation: "close", id, reason })` with meaningful reason.',
409
+ '5. **MUST handle unfinished tasks first** — If prime shows in-progress, ask user: Continue, Defer, Abandon? Do NOT auto-resume.',
410
+ '6. **NEVER skip prime** — Even for follow-up messages.',
411
+ '7. **NEVER start new work with open in-progress tasks** — Handle existing first.',
412
+ '8. **NEVER leave tasks in in_progress when session ends** — Close or defer everything.',
413
+ '9. **NEVER tell the user to run task commands** — You are the operator.',
395
414
  '',
396
- '1. **Every message`autosnippet_ready()`** Load latest decisions and task context. Skipping causes contradictions with team agreements.',
397
- '2. **User agrees/disagrees with a plan → `autosnippet_decide(record/revise/unpin)` immediately** — Persist team memory first, then continue execution.',
398
- '3. **Do NOT modify** knowledge base files directly (`AutoSnippet/recipes/`, `.autosnippet/`).',
399
- '4. Create or update knowledge **only** through MCP tools (`autosnippet_submit_knowledge`).',
400
- '5. **Prefer Recipes** as project standards; source code is supplementary.',
401
- '6. Use `autosnippet_search` for knowledge retrieval; do not retry on failure in the same turn.',
402
- '7. Skills handle semantics and workflow; MCP handles capabilities do not hardcode URLs in Skills.',
415
+ 'When in doubtcreate a task. When idle `autosnippet_task({ operation: "ready" })`.',
416
+ '',
417
+ '**When NOT to create**: Quick questions, single-file trivial fixes (<10 lines), code explanation, running tests.',
418
+ '',
419
+ '## Knowledge Rules',
420
+ '',
421
+ '1. **User agrees/disagrees with a plan `autosnippet_task({ operation: "record_decision" })` immediately** Persist team memory first.',
422
+ '2. **Do NOT modify** knowledge base files directly (`AutoSnippet/recipes/`, `.autosnippet/`).',
423
+ '3. **Prefer Recipes** as project standards; source code is supplementary.',
424
+ '4. Use `autosnippet_search` for knowledge retrieval; do not retry on failure in the same turn.',
425
+ '5. Skills handle semantics and workflow; MCP handles capabilities — do not hardcode URLs in Skills.',
403
426
  ];
404
427
  }
405
428
 
@@ -409,29 +432,35 @@ export class AgentInstructionsGenerator {
409
432
  */
410
433
  _renderWorkflow() {
411
434
  return [
412
- '## Recommended Workflow',
435
+ '## User Says → You Run',
436
+ '',
437
+ '| User Says | Your Action |',
438
+ '|---|---|',
439
+ '| "Fix this bug" / "帮我修 bug" | `create` → `claim` → code → `close` |',
440
+ '| "Implement this" / "做功能" | `create` → `claim` → code → `close` |',
441
+ '| "Continue" / "继续" | resume in-progress → code → `close` |',
442
+ '| "Pause" / "先不做了" | `defer(id, reason)` |',
443
+ '| "Abandon" / "不做了" | `fail(id, reason)` |',
444
+ '| "Break it down" / "太大了" | `decompose(id, subtasks)` |',
445
+ '| "What\'s next" / "有什么要做的" | `ready()` → present list |',
446
+ '| "Agreed" / "就这么定了" | `record_decision(...)` |',
447
+ '| Quick question (no code) | No task. Just answer. |',
448
+ '',
449
+ '## Session Closing Protocol',
450
+ '',
451
+ 'Before ending work, you MUST complete this checklist:',
413
452
  '',
414
- '### First Actions (MANDATORY)',
415
- '1. **Every message** `autosnippet_ready()` Load decisions + tasks + knowledge context (never skip)',
416
- '2. **User agrees/disagrees** `autosnippet_decide({ operation: "record" | "revise" | "unpin" })` — Persist decision before continuing',
453
+ '- [ ] Close every claimed task with reason describing what was accomplished',
454
+ '- [ ] Defer any incomplete tasks with notes on why and what remains',
455
+ '- [ ] Verify zero tasks in in_progress state',
456
+ '- [ ] If prime showed ready tasks, mention them to the user for next session',
417
457
  '',
418
- '### Task Lifecycle',
419
- '3. `autosnippet_task({ operation: "claim", id: "asd-xxx" })` — Start working',
420
- '4. `autosnippet_search({ query: "<topic>" })` — Search knowledge before coding',
421
- '5. **CODE** — Write the implementation',
422
- '6. `autosnippet_guard({ code: "<code>" })` — Check compliance',
423
- '7. `autosnippet_task({ operation: "close", id: "asd-xxx" })` — Complete',
458
+ '**Work is not done until all tasks are closed or deferred.**',
424
459
  '',
425
- '### Guard Diagnostics Response',
426
- 'When editor shows diagnostics from "AutoSnippet Guard":',
427
- '1. Read the `ruleId` from the diagnostic message',
428
- '2. `autosnippet_search({ query: "<ruleId>" })` to find the Recipe',
429
- '3. Apply the Recipe\'s `doClause` + `coreCode` to fix',
430
- '4. Save and verify the diagnostic disappears',
460
+ '## Context Pressure',
431
461
  '',
432
- '### Context Pressure',
433
462
  '- `_contextHint: CONTEXT_PRESSURE:WARNING` → Summarize completed work, then continue',
434
- '- `_contextHint: CONTEXT_PRESSURE:CRITICAL` → Call `autosnippet_ready()` immediately',
463
+ '- `_contextHint: CONTEXT_PRESSURE:CRITICAL` → Call `autosnippet_task({ operation: "prime" })` immediately',
435
464
  '',
436
465
  ];
437
466
  }
@@ -17,8 +17,11 @@ import fs from 'node:fs';
17
17
  /**
18
18
  * AutoSnippet 文件签名模式(case-insensitive)
19
19
  * 检查文件前 1024 字节即可——签名总在文件头部
20
+ * 匹配以下任一标记:
21
+ * - "Auto-generated by AutoSnippet" / "Auto-generated by [AutoSnippet]"
22
+ * - "<!-- autosnippet:begin -->" (模板起始标记)
20
23
  */
21
- const SIGNATURE_PATTERN = /auto-generated by (?:\[)?autosnippet(?:\])?/i;
24
+ const SIGNATURE_PATTERN = /auto-generated by (?:\[)?autosnippet(?:\])?|autosnippet:begin/i;
22
25
 
23
26
  /**
24
27
  * 检查文件是否可以被 AutoSnippet 安全写入
@@ -592,7 +592,7 @@ export class GuardCheckEngine {
592
592
  id: g.id || r.id,
593
593
  name: g.name || r.title,
594
594
  message: g.message || r.description || r.title,
595
- languages: r.language ? [r.language] : [],
595
+ languages: r.language ? [r.language, LanguageService.toGuardLangId(r.language)] : [],
596
596
  severity: g.severity || 'warning',
597
597
  dimension: r.scope || 'file',
598
598
  source: 'database',
@@ -647,9 +647,16 @@ export class GuardCheckEngine {
647
647
  }
648
648
  }
649
649
 
650
- // 按语言过滤
650
+ // 按语言过滤(标准化比较:objc == objectivec == objective-c)
651
651
  if (language) {
652
- rules = rules.filter((r) => !r.languages?.length || r.languages.includes(language));
652
+ const langNorm = LanguageService.toGuardLangId(language);
653
+ rules = rules.filter(
654
+ (r) =>
655
+ !r.languages?.length ||
656
+ r.languages.includes(language) ||
657
+ r.languages.includes(langNorm) ||
658
+ r.languages.some((l) => LanguageService.toGuardLangId(l) === langNorm)
659
+ );
653
660
  }
654
661
 
655
662
  // 按 disabledRules 配置过滤
@@ -398,7 +398,7 @@ export class TaskGraphService {
398
398
  }
399
399
 
400
400
  // P1 Result Compaction: compact 模式 — description 截断到 120 chars
401
- // Agent 需要完整内容时调用 autosnippet_decide({ operation: 'list' })
401
+ // Agent 需要完整内容时调用 autosnippet_task({ operation: 'list_decisions' })
402
402
  result.decisions = activeDecisions.map((t) => ({
403
403
  id: t.id,
404
404
  title: t.title,
@@ -424,13 +424,13 @@ export class TaskGraphService {
424
424
 
425
425
  result._decisionHint =
426
426
  'These are team-agreed decisions (compact view). Respect them in your response. ' +
427
- 'Call autosnippet_decide({ operation: "list" }) for full details. ' +
427
+ 'Call autosnippet_task({ operation: "list_decisions" }) for full details. ' +
428
428
  "If the user's request conflicts with a decision, point out the conflict and ask whether to revise_decision.";
429
429
 
430
430
  if (staleDecisions.length > 0) {
431
431
  result._staleHint =
432
432
  `${staleDecisions.length} decision(s) are stale (>${Math.floor(staleThresholdSec / 86400)} days). ` +
433
- 'Consider reviewing with autosnippet_decide({ operation: "list" }) and unpin outdated ones.';
433
+ 'Consider reviewing with autosnippet_task({ operation: "list_decisions" }) and unpin outdated ones.';
434
434
  }
435
435
  }
436
436
 
@@ -386,7 +386,8 @@ export class LanguageService {
386
386
  * @returns {string}
387
387
  */
388
388
  static toGuardLangId(langId) {
389
- return langId === 'objectivec' ? 'objc' : langId;
389
+ const id = (langId || '').toLowerCase().replace(/[_-]/g, '');
390
+ return id === 'objectivec' ? 'objc' : langId;
390
391
  }
391
392
 
392
393
  // ─── 显示名 ────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autosnippet",
3
- "version": "3.2.4",
3
+ "version": "3.2.6",
4
4
  "description": "Extract code patterns into a knowledge base for AI coding assistants",
5
5
  "type": "module",
6
6
  "main": "lib/bootstrap.js",
@@ -46,9 +46,7 @@ Use this skill when the user's intent is unclear or overlaps multiple capabiliti
46
46
  - Guard: `autosnippet_guard` (code 单文件 / files[] 批量)
47
47
  - Bootstrap: `autosnippet_bootstrap` (no params — Mission Briefing) + `autosnippet_dimension_complete`
48
48
  - Wiki: `autosnippet_wiki_plan` (topic planning) + `autosnippet_wiki_finalize` (meta.json + dedup)
49
- - Ready: `autosnippet_ready` (session entry loads decisions + tasks)
50
- - Decide: `autosnippet_decide` (operation: record / revise / unpin / list)
51
- - Task: `autosnippet_task` (operation: create / ready / claim / close / fail / defer / progress / stats / decompose)
49
+ - Task: `autosnippet_task` (operation: prime (session entry) / create / ready / claim / close / fail / defer / progress / stats / decompose / record_decision / revise_decision / unpin_decision / list_decisions)
52
50
  - Skills: `autosnippet_skill` (operation: list / load / create / update / delete / suggest)
53
51
  - Admin: `autosnippet_enrich_candidates`, `autosnippet_knowledge_lifecycle`, `autosnippet_validate_candidate`, `autosnippet_check_duplicate`
54
52
 
@@ -118,9 +118,7 @@ Recipe is the core knowledge unit. V3 uses a unified structured model:
118
118
 
119
119
  | Tool | Description |
120
120
  |------|-------------|
121
- | `autosnippet_ready` | Session entry point loads decisions + ready tasks (call FIRST) |
122
- | `autosnippet_decide` | Decision management (`operation`: record/revise/unpin/list) |
123
- | `autosnippet_task` | Task CRUD (`operation`: create/ready/claim/close/fail/defer/progress/stats/decompose) |
121
+ | `autosnippet_task` | Unified task & decision management (`operation`: prime/create/claim/close/fail/defer/progress/decompose/record_decision/revise_decision/unpin_decision/list_decisions) |
124
122
 
125
123
  ### Skills Management
126
124
 
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: "MANDATORY: Load AutoSnippet project context — decisions, tasks, knowledge"
3
+ allowed-tools: ["mcp__autosnippet__autosnippet_task"]
4
+ ---
5
+
6
+ Call autosnippet_task with `{ "operation": "prime" }` to load the current project context.
7
+
8
+ **You MUST call this on EVERY user message BEFORE doing anything else.**
9
+
10
+ This returns:
11
+ - **Active decisions** — team agreements that must be followed
12
+ - **Ready tasks** — next items to work on
13
+ - **In-progress tasks** — unfinished work (ask user before resuming)
14
+ - **Task rules reminder** — behavioral rules for task management
15
+ - **Project statistics**
16
+
17
+ If there are unfinished tasks, present them to the user and ask: **Continue**, **Defer**, or **Abandon**? Do NOT auto-resume.
18
+
19
+ Call again after long conversations, compaction, or when `_contextHint` shows `CONTEXT_PRESSURE:CRITICAL`.
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ # AutoSnippet session hook for Claude Code
3
+ # SessionStart: full task rules + prime reminder
4
+ # PreCompact (--brief): minimal rules to survive compaction
5
+
6
+ if [[ "$1" == "--brief" ]]; then
7
+ # Brief mode — survives compaction, minimal context
8
+ cat <<'EOF'
9
+ 📋 AutoSnippet Task Rules (MANDATORY):
10
+ • Prime EVERY message: autosnippet_task({ operation: "prime" }) FIRST.
11
+ • Create task for non-trivial work (≥2 files OR ≥10 lines). Claim → code → close.
12
+ • Handle in-progress tasks before new work. Close/defer ALL on session end.
13
+ • You are the task operator — user speaks naturally, you run task operations.
14
+ • User agrees/disagrees → record_decision immediately.
15
+ • "fix bug"/"implement" → create→claim→code→close | "pause" → defer | "abandon" → fail | "next" → ready()
16
+ EOF
17
+ else
18
+ # Full mode — SessionStart
19
+ cat <<'EOF'
20
+ [AutoSnippet Task Rules]
21
+
22
+ ⚡ FIRST: Call autosnippet_task({ "operation": "prime" }) on EVERY message. No exceptions.
23
+
24
+ 🔑 CRITICAL: YOU Operate autosnippet_task — The User Doesn't
25
+ • WRONG: "You can run autosnippet_task to create a task"
26
+ • RIGHT: (you run create yourself and tell the user "Created task asd-42")
27
+
28
+ 📋 MUST:
29
+ • Create task for non-trivial work (≥2 files OR ≥10 lines) BEFORE starting
30
+ • Claim before coding, close when done with meaningful reason
31
+ • Handle unfinished tasks first (ask user: Continue/Defer/Abandon)
32
+ • Close or defer ALL in_progress tasks before session ends
33
+
34
+ 🚫 NEVER:
35
+ • Skip prime
36
+ • Start new work with open in_progress tasks
37
+ • Tell user to run task commands (YOU are the operator)
38
+ • Leave tasks in in_progress when session ends
39
+
40
+ 📖 User Says → You Run:
41
+ • "fix bug" / "implement" → create → claim → code → close
42
+ • "continue" → resume in-progress → code → close
43
+ • "pause" → defer(id, reason)
44
+ • "abandon" → fail(id, reason)
45
+ • "break down" → decompose(id, subtasks)
46
+ • "what's next" → ready() → present list
47
+ • "agreed" → record_decision(...)
48
+ • Quick question → No task. Just answer.
49
+
50
+ 💡 When in doubt → create a task. When idle → autosnippet_task({ operation: "ready" })
51
+
52
+ 📌 User agrees/disagrees with plan → autosnippet_task({ operation: "record_decision" }) immediately
53
+
54
+ ✅ Session end checklist:
55
+ [ ] Close every claimed task with reason
56
+ [ ] Defer incomplete tasks with notes
57
+ [ ] Verify zero in_progress
58
+ [ ] Mention ready tasks for next session
59
+
60
+ 🔎 Search knowledge: autosnippet_search({ query: "..." })
61
+ 📚 Do NOT modify AutoSnippet/recipes/ or .autosnippet/ directly
62
+ EOF
63
+ fi
@@ -0,0 +1,21 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(asd *)",
5
+ "Bash(curl -s * localhost:3000/*)",
6
+ "mcp__autosnippet__*"
7
+ ]
8
+ },
9
+ "hooks": {
10
+ "SessionStart": [
11
+ {
12
+ "command": "bash .claude/hooks/autosnippet-session.sh"
13
+ }
14
+ ],
15
+ "PreCompact": [
16
+ {
17
+ "command": "bash .claude/hooks/autosnippet-session.sh --brief"
18
+ }
19
+ ]
20
+ }
21
+ }