@damper/mcp 0.8.3 β 0.8.4
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/formatters.d.ts +12 -2
- package/dist/formatters.js +71 -7
- package/dist/index.js +79 -7
- package/package.json +1 -1
package/dist/formatters.d.ts
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
* Extracted for testability - these pure functions format API responses
|
|
5
5
|
* into user-friendly text output.
|
|
6
6
|
*/
|
|
7
|
+
export interface SelfAssessment {
|
|
8
|
+
missingContext?: string[];
|
|
9
|
+
toolIssues?: string[];
|
|
10
|
+
processGaps?: string[];
|
|
11
|
+
}
|
|
7
12
|
export interface StartTaskResult {
|
|
8
13
|
id: string;
|
|
9
14
|
status: string;
|
|
@@ -39,11 +44,16 @@ export interface AbandonTaskResult {
|
|
|
39
44
|
* Format start_task response
|
|
40
45
|
*/
|
|
41
46
|
export declare function formatStartTaskResponse(result: StartTaskResult): string;
|
|
47
|
+
/**
|
|
48
|
+
* Format self-assessment follow-up actions.
|
|
49
|
+
* Guides the agent to propose improvements to the user with rationale.
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatSelfAssessmentActions(assessment: SelfAssessment): string;
|
|
42
52
|
/**
|
|
43
53
|
* Format complete_task response
|
|
44
54
|
*/
|
|
45
|
-
export declare function formatCompleteTaskResponse(result: CompleteTaskResult): string;
|
|
55
|
+
export declare function formatCompleteTaskResponse(result: CompleteTaskResult, assessment?: SelfAssessment): string;
|
|
46
56
|
/**
|
|
47
57
|
* Format abandon_task response
|
|
48
58
|
*/
|
|
49
|
-
export declare function formatAbandonTaskResponse(result: AbandonTaskResult, hasSummary: boolean): string;
|
|
59
|
+
export declare function formatAbandonTaskResponse(result: AbandonTaskResult, hasSummary: boolean, assessment?: SelfAssessment): string;
|
package/dist/formatters.js
CHANGED
|
@@ -52,18 +52,67 @@ export function formatStartTaskResponse(result) {
|
|
|
52
52
|
lines.push('1. `add_note`: "Session started: <goal>"');
|
|
53
53
|
lines.push('2. Work: use `add_commit` for commits, `add_note` for decisions');
|
|
54
54
|
lines.push('3. `add_note`: "Session end: <summary>"');
|
|
55
|
-
lines.push('4. `complete_task` (with `confirmations`
|
|
55
|
+
lines.push('4. `complete_task` (with `confirmations` and `selfAssessment`) or `abandon_task`');
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Format self-assessment follow-up actions.
|
|
60
|
+
* Guides the agent to propose improvements to the user with rationale.
|
|
61
|
+
*/
|
|
62
|
+
export function formatSelfAssessmentActions(assessment) {
|
|
63
|
+
const lines = [];
|
|
64
|
+
const hasContent = (assessment.missingContext?.length ?? 0) > 0
|
|
65
|
+
|| (assessment.toolIssues?.length ?? 0) > 0
|
|
66
|
+
|| (assessment.processGaps?.length ?? 0) > 0;
|
|
67
|
+
if (!hasContent)
|
|
68
|
+
return '';
|
|
69
|
+
lines.push('\nπ **Self-Assessment β propose these improvements to the user:**');
|
|
70
|
+
lines.push('Explain each finding briefly and why fixing it helps future tasks. Ask for approval before acting.');
|
|
71
|
+
if (assessment.missingContext && assessment.missingContext.length > 0) {
|
|
72
|
+
lines.push('\n**Missing project context:**');
|
|
73
|
+
for (const item of assessment.missingContext) {
|
|
74
|
+
lines.push(` β’ ${item}`);
|
|
75
|
+
}
|
|
76
|
+
lines.push('β Propose calling `update_context_section` to document these β explain that future agents will waste time rediscovering the same things.');
|
|
77
|
+
}
|
|
78
|
+
if (assessment.toolIssues && assessment.toolIssues.length > 0) {
|
|
79
|
+
lines.push('\n**Tool/workflow issues:**');
|
|
80
|
+
for (const item of assessment.toolIssues) {
|
|
81
|
+
lines.push(` β’ ${item}`);
|
|
82
|
+
}
|
|
83
|
+
lines.push('β Propose calling `report_issue` for each β explain what went wrong and how it slowed the task.');
|
|
84
|
+
}
|
|
85
|
+
if (assessment.processGaps && assessment.processGaps.length > 0) {
|
|
86
|
+
lines.push('\n**Process/spec gaps:**');
|
|
87
|
+
for (const item of assessment.processGaps) {
|
|
88
|
+
lines.push(` β’ ${item}`);
|
|
89
|
+
}
|
|
90
|
+
lines.push('β Propose `update_context_section` for doc gaps or `report_issue` for tooling problems β explain the friction it caused.');
|
|
91
|
+
}
|
|
56
92
|
return lines.join('\n');
|
|
57
93
|
}
|
|
58
94
|
/**
|
|
59
95
|
* Format complete_task response
|
|
60
96
|
*/
|
|
61
|
-
export function formatCompleteTaskResponse(result) {
|
|
97
|
+
export function formatCompleteTaskResponse(result, assessment) {
|
|
62
98
|
const lines = [`β
Completed ${result.id}`];
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
99
|
+
// Self-assessment follow-up actions (shown first if provided)
|
|
100
|
+
if (assessment) {
|
|
101
|
+
const actions = formatSelfAssessmentActions(assessment);
|
|
102
|
+
if (actions) {
|
|
103
|
+
lines.push(actions);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!assessment) {
|
|
107
|
+
// No assessment provided β nudge the agent to reflect
|
|
108
|
+
lines.push('\n---');
|
|
109
|
+
lines.push('**π Before you finish β quick self-assessment:**');
|
|
110
|
+
lines.push('Reflect on your session. If you encountered any of these, propose improvements to the user:');
|
|
111
|
+
lines.push('β’ Missing project docs β offer to call `update_context_section`');
|
|
112
|
+
lines.push('β’ Confusing tools β offer to call `report_issue`');
|
|
113
|
+
lines.push('β’ Spec/process gaps β offer to update docs or report');
|
|
114
|
+
lines.push('Explain briefly why each improvement would help future tasks.');
|
|
115
|
+
}
|
|
67
116
|
if (result.documentation) {
|
|
68
117
|
if (result.documentation.affectedSections?.length > 0) {
|
|
69
118
|
lines.push(`\nSections that may need updates: ${result.documentation.affectedSections.join(', ')}`);
|
|
@@ -77,11 +126,26 @@ export function formatCompleteTaskResponse(result) {
|
|
|
77
126
|
/**
|
|
78
127
|
* Format abandon_task response
|
|
79
128
|
*/
|
|
80
|
-
export function formatAbandonTaskResponse(result, hasSummary) {
|
|
129
|
+
export function formatAbandonTaskResponse(result, hasSummary, assessment) {
|
|
81
130
|
const lines = [`βΈοΈ Abandoned ${result.id}: ${result.message}`];
|
|
82
131
|
if (!hasSummary) {
|
|
83
132
|
lines.push('\nβ οΈ Tip: Include a summary next time for better handoff.');
|
|
84
133
|
}
|
|
85
134
|
lines.push('\nπ‘ Task returned to "planned". Notes preserved for next agent.');
|
|
135
|
+
// Self-assessment follow-up actions
|
|
136
|
+
if (assessment) {
|
|
137
|
+
const actions = formatSelfAssessmentActions(assessment);
|
|
138
|
+
if (actions) {
|
|
139
|
+
lines.push(actions);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (!assessment) {
|
|
143
|
+
lines.push('\n---');
|
|
144
|
+
lines.push('**π Before you finish β quick self-assessment:**');
|
|
145
|
+
lines.push('Something caused this task to be abandoned. Propose improvements to the user:');
|
|
146
|
+
lines.push('β’ Missing project docs that would have helped β offer to call `update_context_section`');
|
|
147
|
+
lines.push('β’ Tool issues that blocked progress β offer to call `report_issue`');
|
|
148
|
+
lines.push('Explain briefly why each fix would help the next agent pick this up smoothly.');
|
|
149
|
+
}
|
|
86
150
|
return lines.join('\n');
|
|
87
151
|
}
|
package/dist/index.js
CHANGED
|
@@ -593,6 +593,12 @@ server.registerTool('update_subtask', {
|
|
|
593
593
|
},
|
|
594
594
|
};
|
|
595
595
|
});
|
|
596
|
+
// Self-assessment schema for end-of-task reflection
|
|
597
|
+
const SelfAssessmentSchema = z.object({
|
|
598
|
+
missingContext: z.array(z.string()).optional().describe('Project knowledge that was missing or wrong β things you had to figure out that should be documented for future agents'),
|
|
599
|
+
toolIssues: z.array(z.string()).optional().describe('MCP tools or workflow steps that were confusing, broken, or could be improved'),
|
|
600
|
+
processGaps: z.array(z.string()).optional().describe('Gaps in specs, checklists, or conventions that caused friction or mistakes'),
|
|
601
|
+
});
|
|
596
602
|
// Documentation reminder schema for complete_task response
|
|
597
603
|
const DocumentationSchema = z.object({
|
|
598
604
|
hasContext: z.boolean(),
|
|
@@ -606,6 +612,8 @@ server.registerTool('complete_task', {
|
|
|
606
612
|
'**Before calling:**\n' +
|
|
607
613
|
'1. Push all commits\n' +
|
|
608
614
|
'2. Check if project context docs need updating\n\n' +
|
|
615
|
+
'**Self-assessment:** Reflect on your session β what project knowledge was missing, what tools were confusing, ' +
|
|
616
|
+
'what process gaps caused friction. If you identify improvements, propose them to the user with a brief explanation.\n\n' +
|
|
609
617
|
'**Completion checklist:** If the project has a completion checklist (shown in `start_task` response), ' +
|
|
610
618
|
'you MUST pass `confirmations` β an array of `{item, evidence}` objects. Each confirmation needs the checklist item text ' +
|
|
611
619
|
'and concrete evidence proving you verified it (e.g., test output, build log snippet). ' +
|
|
@@ -615,6 +623,8 @@ server.registerTool('complete_task', {
|
|
|
615
623
|
inputSchema: z.object({
|
|
616
624
|
taskId: z.string(),
|
|
617
625
|
summary: z.string().describe('Brief one-line summary of what was done, written for end users. Focus on the outcome, not the implementation.'),
|
|
626
|
+
selfAssessment: SelfAssessmentSchema.optional().describe('Reflect on your session: what went well, what knowledge was missing, what caused friction. ' +
|
|
627
|
+
'Be honest β this drives project improvements.'),
|
|
618
628
|
commits: z.array(z.object({
|
|
619
629
|
hash: z.string().describe('Commit hash (short or full)'),
|
|
620
630
|
message: z.string().describe('Commit message'),
|
|
@@ -635,11 +645,38 @@ server.registerTool('complete_task', {
|
|
|
635
645
|
idempotentHint: true,
|
|
636
646
|
openWorldHint: false,
|
|
637
647
|
},
|
|
638
|
-
}, async ({ taskId, summary, commits, confirmations }) => {
|
|
648
|
+
}, async ({ taskId, summary, selfAssessment, commits, confirmations }) => {
|
|
639
649
|
try {
|
|
640
650
|
const result = await api('POST', `/api/agent/tasks/${taskId}/complete`, { summary, commits, confirmations });
|
|
651
|
+
// Log self-assessment as a structured note if provided
|
|
652
|
+
if (selfAssessment) {
|
|
653
|
+
const assessmentLines = ['Self-Assessment:'];
|
|
654
|
+
if (selfAssessment.missingContext?.length) {
|
|
655
|
+
assessmentLines.push('Missing context:');
|
|
656
|
+
for (const item of selfAssessment.missingContext)
|
|
657
|
+
assessmentLines.push(` - ${item}`);
|
|
658
|
+
}
|
|
659
|
+
if (selfAssessment.toolIssues?.length) {
|
|
660
|
+
assessmentLines.push('Tool issues:');
|
|
661
|
+
for (const item of selfAssessment.toolIssues)
|
|
662
|
+
assessmentLines.push(` - ${item}`);
|
|
663
|
+
}
|
|
664
|
+
if (selfAssessment.processGaps?.length) {
|
|
665
|
+
assessmentLines.push('Process gaps:');
|
|
666
|
+
for (const item of selfAssessment.processGaps)
|
|
667
|
+
assessmentLines.push(` - ${item}`);
|
|
668
|
+
}
|
|
669
|
+
if (assessmentLines.length > 1) {
|
|
670
|
+
try {
|
|
671
|
+
await api('POST', `/api/agent/tasks/${taskId}/notes`, { note: assessmentLines.join('\n') });
|
|
672
|
+
}
|
|
673
|
+
catch {
|
|
674
|
+
// Don't fail completion if note logging fails
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
641
678
|
return {
|
|
642
|
-
content: [{ type: 'text', text: formatCompleteTaskResponse(result) }],
|
|
679
|
+
content: [{ type: 'text', text: formatCompleteTaskResponse(result, selfAssessment) }],
|
|
643
680
|
structuredContent: result,
|
|
644
681
|
};
|
|
645
682
|
}
|
|
@@ -679,10 +716,14 @@ server.registerTool('abandon_task', {
|
|
|
679
716
|
description: 'Release lock and return task to planned status. Use when stopping work.\n\n' +
|
|
680
717
|
'**Before calling:**\n' +
|
|
681
718
|
'1. Push any WIP commits\n\n' +
|
|
682
|
-
'**Summary parameter:** What was done, what remains, blockers. Helps the next agent
|
|
719
|
+
'**Summary parameter:** What was done, what remains, blockers. Helps the next agent.\n\n' +
|
|
720
|
+
'**Self-assessment:** Especially important when abandoning β reflect on what blocked you ' +
|
|
721
|
+
'or what knowledge was missing so the next agent has a smoother experience.',
|
|
683
722
|
inputSchema: z.object({
|
|
684
723
|
taskId: z.string(),
|
|
685
724
|
summary: z.string().optional().describe('Handoff summary: what was done, what remains, any blockers'),
|
|
725
|
+
selfAssessment: SelfAssessmentSchema.optional().describe('Reflect on your session: what went well, what knowledge was missing, what caused friction. ' +
|
|
726
|
+
'Be honest β this drives project improvements.'),
|
|
686
727
|
}),
|
|
687
728
|
outputSchema: z.object({
|
|
688
729
|
id: z.string(),
|
|
@@ -695,10 +736,37 @@ server.registerTool('abandon_task', {
|
|
|
695
736
|
idempotentHint: true,
|
|
696
737
|
openWorldHint: false,
|
|
697
738
|
},
|
|
698
|
-
}, async ({ taskId, summary }) => {
|
|
739
|
+
}, async ({ taskId, summary, selfAssessment }) => {
|
|
699
740
|
const result = await api('POST', `/api/agent/tasks/${taskId}/abandon`, summary ? { summary } : undefined);
|
|
741
|
+
// Log self-assessment as a structured note if provided
|
|
742
|
+
if (selfAssessment) {
|
|
743
|
+
const assessmentLines = ['Self-Assessment (abandoned):'];
|
|
744
|
+
if (selfAssessment.missingContext?.length) {
|
|
745
|
+
assessmentLines.push('Missing context:');
|
|
746
|
+
for (const item of selfAssessment.missingContext)
|
|
747
|
+
assessmentLines.push(` - ${item}`);
|
|
748
|
+
}
|
|
749
|
+
if (selfAssessment.toolIssues?.length) {
|
|
750
|
+
assessmentLines.push('Tool issues:');
|
|
751
|
+
for (const item of selfAssessment.toolIssues)
|
|
752
|
+
assessmentLines.push(` - ${item}`);
|
|
753
|
+
}
|
|
754
|
+
if (selfAssessment.processGaps?.length) {
|
|
755
|
+
assessmentLines.push('Process gaps:');
|
|
756
|
+
for (const item of selfAssessment.processGaps)
|
|
757
|
+
assessmentLines.push(` - ${item}`);
|
|
758
|
+
}
|
|
759
|
+
if (assessmentLines.length > 1) {
|
|
760
|
+
try {
|
|
761
|
+
await api('POST', `/api/agent/tasks/${taskId}/notes`, { note: assessmentLines.join('\n') });
|
|
762
|
+
}
|
|
763
|
+
catch {
|
|
764
|
+
// Don't fail abandonment if note logging fails
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
700
768
|
return {
|
|
701
|
-
content: [{ type: 'text', text: formatAbandonTaskResponse(result, !!summary) }],
|
|
769
|
+
content: [{ type: 'text', text: formatAbandonTaskResponse(result, !!summary, selfAssessment) }],
|
|
702
770
|
structuredContent: result,
|
|
703
771
|
};
|
|
704
772
|
});
|
|
@@ -748,7 +816,7 @@ server.registerTool('get_agent_instructions', {
|
|
|
748
816
|
openWorldHint: false,
|
|
749
817
|
},
|
|
750
818
|
}, async ({ format = 'section' }) => {
|
|
751
|
-
const lastModified = '2026-02-
|
|
819
|
+
const lastModified = '2026-02-10';
|
|
752
820
|
const section = `## Task Management with Damper MCP
|
|
753
821
|
|
|
754
822
|
> Last updated: ${lastModified}
|
|
@@ -791,7 +859,11 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
|
|
|
791
859
|
2. **Abandon and hand off** - Call \`abandon_task\` with a detailed handoff summary for the next agent.
|
|
792
860
|
- NEVER leave a started task without completing or abandoning it
|
|
793
861
|
- If the project has a **completion checklist** (shown in \`start_task\` response), you MUST pass all items as \`confirmations\` when calling \`complete_task\`
|
|
794
|
-
-
|
|
862
|
+
- **Self-assessment:** Include \`selfAssessment\` when calling \`complete_task\` or \`abandon_task\`. Reflect honestly on:
|
|
863
|
+
- \`missingContext\` β What project knowledge was missing or wrong?
|
|
864
|
+
- \`toolIssues\` β Which tools or workflow steps were confusing or broken?
|
|
865
|
+
- \`processGaps\` β What specs or conventions were missing?
|
|
866
|
+
If you identify improvements, **propose them to the user** β explain briefly what you found and why fixing it helps future tasks. Only act after the user approves.
|
|
795
867
|
|
|
796
868
|
### Content Style Guide
|
|
797
869
|
|