@damper/cli 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { statusCommand } from './commands/status.js';
5
5
  import { cleanupCommand } from './commands/cleanup.js';
6
6
  import { setupCommand } from './commands/setup.js';
7
7
  import { releaseCommand } from './commands/release.js';
8
- const VERSION = '0.6.6';
8
+ const VERSION = '0.6.7';
9
9
  function showHelp() {
10
10
  console.log(`
11
11
  ${pc.bold('@damper/cli')} - Agent orchestration for Damper tasks
@@ -9,6 +9,16 @@ export interface BootstrapResult {
9
9
  taskContextPath: string;
10
10
  claudeMdUpdated: boolean;
11
11
  }
12
+ export interface SectionBlockIndex {
13
+ section: string;
14
+ blocks: Array<{
15
+ id: string;
16
+ heading: string | null;
17
+ level: number;
18
+ charCount: number;
19
+ }>;
20
+ totalChars: number;
21
+ }
12
22
  /**
13
23
  * Fetch all relevant context from Damper and write local files
14
24
  */
@@ -6,6 +6,24 @@ import { generateClaudeAppend } from '../templates/CLAUDE_APPEND.md.js';
6
6
  const TASK_CONTEXT_FILE = 'TASK_CONTEXT.md';
7
7
  const CLAUDE_MD_FILE = 'CLAUDE.md';
8
8
  const TASK_SECTION_MARKER = '## Current Task:';
9
+ /**
10
+ * Fetch block indices for relevant sections.
11
+ * Only fetches the headings/structure - no content.
12
+ * The agent will use get_section_block_content to load what it needs.
13
+ */
14
+ async function fetchBlockIndices(api, relevantSections) {
15
+ const indices = [];
16
+ for (const sectionName of relevantSections) {
17
+ try {
18
+ const blockIndex = await api.getSectionBlocks(sectionName);
19
+ indices.push(blockIndex);
20
+ }
21
+ catch {
22
+ console.log(pc.dim(` Could not fetch blocks for: ${sectionName}`));
23
+ }
24
+ }
25
+ return indices;
26
+ }
9
27
  /**
10
28
  * Fetch all relevant context from Damper and write local files
11
29
  */
@@ -15,26 +33,12 @@ export async function bootstrapContext(options) {
15
33
  const task = await api.getTask(taskId);
16
34
  console.log(pc.dim('Fetching project context...'));
17
35
  const context = await api.getProjectContext(taskId);
18
- // Fetch full content of relevant sections
19
- const sections = [];
36
+ // Fetch block indices (not content) for relevant sections
20
37
  const relevantSections = context.relevantSections || [];
38
+ let blockIndices = [];
21
39
  if (relevantSections.length > 0) {
22
- console.log(pc.dim(`Fetching ${relevantSections.length} relevant context sections...`));
23
- for (const sectionName of relevantSections) {
24
- try {
25
- const result = await api.getContextSection(sectionName);
26
- // Handle both single section and glob pattern responses
27
- if ('pattern' in result && result.sections) {
28
- sections.push(...result.sections);
29
- }
30
- else if ('section' in result && 'content' in result) {
31
- sections.push(result);
32
- }
33
- }
34
- catch (err) {
35
- console.log(pc.dim(` Could not fetch section: ${sectionName}`));
36
- }
37
- }
40
+ console.log(pc.dim(`Fetching block indices for ${relevantSections.length} relevant sections...`));
41
+ blockIndices = await fetchBlockIndices(api, relevantSections);
38
42
  }
39
43
  // Fetch templates
40
44
  console.log(pc.dim('Fetching templates...'));
@@ -51,7 +55,7 @@ export async function bootstrapContext(options) {
51
55
  const taskContext = generateTaskContext({
52
56
  task,
53
57
  criticalRules: context.criticalRules || [],
54
- sections,
58
+ blockIndices,
55
59
  templates,
56
60
  modules,
57
61
  damperInstructions: instructions.content,
@@ -131,6 +131,27 @@ export declare class DamperApi {
131
131
  }>;
132
132
  isEmpty: boolean;
133
133
  }>;
134
+ getSectionBlocks(section: string): Promise<{
135
+ section: string;
136
+ blocks: Array<{
137
+ id: string;
138
+ heading: string | null;
139
+ level: number;
140
+ charCount: number;
141
+ }>;
142
+ totalChars: number;
143
+ }>;
144
+ getSectionBlockContent(section: string, blockIds: string[]): Promise<{
145
+ section: string;
146
+ blocks: Array<{
147
+ id: string;
148
+ heading: string | null;
149
+ level: number;
150
+ content: string;
151
+ charCount: number;
152
+ }>;
153
+ totalChars: number;
154
+ }>;
134
155
  listTemplates(): Promise<{
135
156
  templates: Array<{
136
157
  name: string;
@@ -69,6 +69,16 @@ export class DamperApi {
69
69
  async listContextSections() {
70
70
  return this.request('GET', '/api/agent/context');
71
71
  }
72
+ // Context Blocks
73
+ async getSectionBlocks(section) {
74
+ const encodedSection = encodeURIComponent(section);
75
+ return this.request('GET', `/api/agent/context/${encodedSection}/blocks`);
76
+ }
77
+ async getSectionBlockContent(section, blockIds) {
78
+ const encodedSection = encodeURIComponent(section);
79
+ const encodedBlockIds = blockIds.map(id => encodeURIComponent(id)).join(',');
80
+ return this.request('GET', `/api/agent/context/${encodedSection}/blocks/${encodedBlockIds}`);
81
+ }
72
82
  // Templates
73
83
  async listTemplates() {
74
84
  return this.request('GET', '/api/agent/templates');
@@ -95,7 +105,10 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
95
105
 
96
106
  ### At Session Start (MANDATORY)
97
107
  1. \`get_project_context\` - **READ THIS FIRST.** Contains architecture, conventions, and critical project info.
98
- 2. \`get_context_section\` - Fetch full content for sections relevant to your task
108
+ 2. Load relevant architecture context using blocks (token-efficient):
109
+ - If TASK_CONTEXT.md has an "Available Architecture Context" section, use \`get_section_block_content(section, blockIds)\` to load only the blocks relevant to your task
110
+ - Otherwise, use \`get_section_blocks(section)\` to see what's available, then fetch specific blocks
111
+ - Only fall back to \`get_context_section\` if you need an entire section
99
112
  3. \`list_tasks\` - Check for existing tasks to work on
100
113
  4. If working on a task: \`start_task\` to lock it
101
114
 
@@ -104,6 +117,7 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
104
117
  - \`add_note\` for decisions: "Decision: chose X because Y"
105
118
  - \`update_subtask\` to mark subtask progress
106
119
  - **Follow patterns from project context** - Don't reinvent; use existing conventions
120
+ - When you need architecture context mid-task, use \`get_section_block_content\` to load specific blocks rather than full sections
107
121
 
108
122
  ### Feedback & Changelog Integration
109
123
  - \`link_feedback_to_task\` - Link user feedback IDs to your task (helps track what customer requests led to the feature)
@@ -17,6 +17,12 @@ Read TASK_CONTEXT.md first, then create a plan for user approval. Do NOT write c
17
17
  **IMPORTANT**: Read TASK_CONTEXT.md for full task details and architecture context.
18
18
  If you feel you've lost context, re-read that file.
19
19
  ${planSection}
20
+ **NEVER commit these files** (they are generated by the CLI and gitignored):
21
+ - \`CLAUDE.md\` changes (this task section is temporary)
22
+ - \`TASK_CONTEXT.md\`
23
+ - \`.mcp.json\`
24
+ - \`.claude/settings.local.json\`
25
+
20
26
  **Your responsibilities (via Damper MCP):**
21
27
  1. Use \`add_commit\` after each git commit
22
28
  2. Use \`add_note\` for important decisions
@@ -1,8 +1,9 @@
1
- import type { TaskDetail, ContextSection, Module } from '../services/damper-api.js';
1
+ import type { TaskDetail, Module } from '../services/damper-api.js';
2
+ import type { SectionBlockIndex } from '../services/context-bootstrap.js';
2
3
  interface TaskContextOptions {
3
4
  task: TaskDetail;
4
5
  criticalRules: string[];
5
- sections: ContextSection[];
6
+ blockIndices: SectionBlockIndex[];
6
7
  templates: Array<{
7
8
  name: string;
8
9
  description?: string | null;
@@ -1,5 +1,5 @@
1
1
  export function generateTaskContext(options) {
2
- const { task, criticalRules, sections, templates, modules, damperInstructions } = options;
2
+ const { task, criticalRules, blockIndices, templates, modules, damperInstructions } = options;
3
3
  const typeIcon = task.type === 'bug' ? 'Bug' : task.type === 'feature' ? 'Feature' : task.type === 'improvement' ? 'Improvement' : 'Task';
4
4
  const lines = [];
5
5
  // Header
@@ -80,14 +80,21 @@ export function generateTaskContext(options) {
80
80
  }
81
81
  lines.push('');
82
82
  }
83
- // Project Context Sections
84
- if (sections.length > 0) {
85
- lines.push('## Relevant Architecture');
83
+ // Project Context Block Index (load-on-demand)
84
+ if (blockIndices.length > 0) {
85
+ lines.push('## Available Architecture Context');
86
86
  lines.push('');
87
- for (const section of sections) {
88
- lines.push(`### ${section.section}`);
87
+ lines.push('**BEFORE starting work**, load the blocks relevant to your task using the MCP tool:');
88
+ lines.push('`get_section_block_content(section, blockIds)` — pass the section name and an array of block IDs from the list below.');
89
+ lines.push('Only load what you need to keep token usage low.');
90
+ lines.push('');
91
+ for (const index of blockIndices) {
92
+ lines.push(`### ${index.section} (${index.totalChars} chars)`);
89
93
  lines.push('');
90
- lines.push(section.content);
94
+ for (const block of index.blocks) {
95
+ const heading = block.heading ? block.heading.replace(/^#+\s*/, '') : '(intro)';
96
+ lines.push(`- \`${block.id}\`: ${heading} (${block.charCount} chars)`);
97
+ }
91
98
  lines.push('');
92
99
  }
93
100
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damper/cli",
3
- "version": "0.6.6",
3
+ "version": "0.6.7",
4
4
  "description": "CLI tool for orchestrating Damper task workflows with Claude Code",
5
5
  "author": "Damper <hello@usedamper.com>",
6
6
  "repository": {