autosnippet 3.2.3 → 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 +3 -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 -719
  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 +75 -40
  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 +66 -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,21 +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', '');
289
+ lines.push(
290
+ '1. **Every message → `autosnippet_task({ operation: "prime" })`** — Load decisions + tasks + knowledge context (ALWAYS FIRST)'
291
+ );
283
292
  lines.push(
284
- '1. **Session start**: `autosnippet_ready()` Restore task context and decisions'
293
+ '2. **Create task for non-trivial work** — ≥2 files OR ≥10 lines → `create` `claim` code `close`'
285
294
  );
286
295
  lines.push(
287
- '2. **Before writing code**: `autosnippet_search({ query: "<topic>" })` to find relevant patterns'
296
+ '3. **User agrees/disagrees `autosnippet_task({ operation: "record_decision" })`** Persist decision immediately'
288
297
  );
289
298
  lines.push(
290
- '3. **Check compliance**: `autosnippet_guard({ code: "<your code>" })` before committing'
299
+ '4. **Before writing code**: `autosnippet_search({ query: "<topic>" })` to find relevant patterns'
291
300
  );
292
301
  lines.push(
293
- '4. **Complete task**: `autosnippet_task({ operation: "close", id: "<id>" })`'
302
+ '5. **Complete task**: `autosnippet_task({ operation: "close", id: "<id>", reason: "..." })`'
294
303
  );
295
304
  lines.push(
296
- '5. **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'
297
306
  );
298
307
  lines.push('');
299
308
 
@@ -361,12 +370,7 @@ export class AgentInstructionsGenerator {
361
370
  lines.push('');
362
371
 
363
372
  // Workflow
364
- lines.push('## Workflow', '');
365
- lines.push('1. Search before coding: `autosnippet_search({ query: "..." })`');
366
- lines.push('2. Prefer Recipe over raw source code');
367
- lines.push('3. Submit discoveries: `autosnippet_submit_knowledge({ ... })`');
368
- lines.push('4. Do NOT directly modify `AutoSnippet/` or `.autosnippet/` files');
369
- lines.push('');
373
+ lines.push(...this._renderWorkflow());
370
374
 
371
375
  const content = `${lines.join('\n')}\n`;
372
376
  const destDir = path.join(this.projectRoot, '.github');
@@ -388,10 +392,34 @@ export class AgentInstructionsGenerator {
388
392
  */
389
393
  _renderConstraints() {
390
394
  return [
391
- '## 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)',
392
404
  '',
393
- '1. **Do NOT modify** knowledge base files directly (`AutoSnippet/recipes/`, `.autosnippet/`).',
394
- '2. Create or update knowledge **only** through MCP tools (`autosnippet_submit_knowledge`).',
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.',
414
+ '',
415
+ 'When in doubt → create 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/`).',
395
423
  '3. **Prefer Recipes** as project standards; source code is supplementary.',
396
424
  '4. Use `autosnippet_search` for knowledge retrieval; do not retry on failure in the same turn.',
397
425
  '5. Skills handle semantics and workflow; MCP handles capabilities — do not hardcode URLs in Skills.',
@@ -404,28 +432,35 @@ export class AgentInstructionsGenerator {
404
432
  */
405
433
  _renderWorkflow() {
406
434
  return [
407
- '## 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:',
408
452
  '',
409
- '### Session Start (ALWAYS)',
410
- '1. `autosnippet_ready()` Restore task context and decisions',
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',
411
457
  '',
412
- '### Task Lifecycle',
413
- '2. `autosnippet_task({ operation: "claim", id: "asd-xxx" })` — Start working',
414
- '3. `autosnippet_search({ query: "<topic>" })` — Search knowledge before coding',
415
- '4. **CODE** — Write the implementation',
416
- '5. `autosnippet_guard({ code: "<code>" })` — Check compliance',
417
- '6. `autosnippet_task({ operation: "close", id: "asd-xxx" })` — Complete',
458
+ '**Work is not done until all tasks are closed or deferred.**',
418
459
  '',
419
- '### Guard Diagnostics Response',
420
- 'When editor shows diagnostics from "AutoSnippet Guard":',
421
- '1. Read the `ruleId` from the diagnostic message',
422
- '2. `autosnippet_search({ query: "<ruleId>" })` to find the Recipe',
423
- '3. Apply the Recipe\'s `doClause` + `coreCode` to fix',
424
- '4. Save and verify the diagnostic disappears',
460
+ '## Context Pressure',
425
461
  '',
426
- '### Context Pressure',
427
462
  '- `_contextHint: CONTEXT_PRESSURE:WARNING` → Summarize completed work, then continue',
428
- '- `_contextHint: CONTEXT_PRESSURE:CRITICAL` → Call `autosnippet_ready()` immediately',
463
+ '- `_contextHint: CONTEXT_PRESSURE:CRITICAL` → Call `autosnippet_task({ operation: "prime" })` immediately',
429
464
  '',
430
465
  ];
431
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.3",
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
+ }