pulse-framework-cli 0.4.1
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/commands/checkpoint.d.ts +2 -0
- package/dist/commands/checkpoint.js +129 -0
- package/dist/commands/correct.d.ts +2 -0
- package/dist/commands/correct.js +77 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +183 -0
- package/dist/commands/escalate.d.ts +2 -0
- package/dist/commands/escalate.js +226 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +570 -0
- package/dist/commands/learn.d.ts +2 -0
- package/dist/commands/learn.js +137 -0
- package/dist/commands/profile.d.ts +2 -0
- package/dist/commands/profile.js +39 -0
- package/dist/commands/reset.d.ts +2 -0
- package/dist/commands/reset.js +130 -0
- package/dist/commands/review.d.ts +2 -0
- package/dist/commands/review.js +129 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +272 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.js +196 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +239 -0
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.js +98 -0
- package/dist/hooks/install.d.ts +1 -0
- package/dist/hooks/install.js +89 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +40 -0
- package/dist/lib/artifacts.d.ts +7 -0
- package/dist/lib/artifacts.js +52 -0
- package/dist/lib/briefing.d.ts +77 -0
- package/dist/lib/briefing.js +231 -0
- package/dist/lib/clipboard.d.ts +9 -0
- package/dist/lib/clipboard.js +116 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.js +167 -0
- package/dist/lib/context-export.d.ts +30 -0
- package/dist/lib/context-export.js +149 -0
- package/dist/lib/exec.d.ts +9 -0
- package/dist/lib/exec.js +23 -0
- package/dist/lib/git.d.ts +24 -0
- package/dist/lib/git.js +74 -0
- package/dist/lib/input.d.ts +15 -0
- package/dist/lib/input.js +80 -0
- package/dist/lib/notifications.d.ts +2 -0
- package/dist/lib/notifications.js +25 -0
- package/dist/lib/paths.d.ts +4 -0
- package/dist/lib/paths.js +39 -0
- package/dist/lib/prompts.d.ts +43 -0
- package/dist/lib/prompts.js +270 -0
- package/dist/lib/scanner.d.ts +37 -0
- package/dist/lib/scanner.js +413 -0
- package/dist/lib/types.d.ts +37 -0
- package/dist/lib/types.js +2 -0
- package/package.json +42 -0
- package/templates/.cursorrules +159 -0
- package/templates/AGENTS.md +198 -0
- package/templates/cursor/mcp.json +9 -0
- package/templates/cursor/pulse.mdc +144 -0
- package/templates/roles/architect.cursorrules +15 -0
- package/templates/roles/backend.cursorrules +12 -0
- package/templates/roles/frontend.cursorrules +12 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROMPT_TEMPLATES = void 0;
|
|
4
|
+
exports.renderSixElementPrompt = renderSixElementPrompt;
|
|
5
|
+
exports.renderIstSollPrompt = renderIstSollPrompt;
|
|
6
|
+
exports.renderEscalationPrompt = renderEscalationPrompt;
|
|
7
|
+
exports.countProvidedElements = countProvidedElements;
|
|
8
|
+
exports.validateOneAction = validateOneAction;
|
|
9
|
+
exports.getTemplateById = getTemplateById;
|
|
10
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// TEMPLATE 1: 6-Element Prompt (from PULSE Framework Documentation)
|
|
12
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
13
|
+
/**
|
|
14
|
+
* Generates a 6-Element prompt exactly as specified in the PULSE Framework.
|
|
15
|
+
* This is the core template that should be copy-pasted into AI tools.
|
|
16
|
+
*/
|
|
17
|
+
function renderSixElementPrompt(layer, el) {
|
|
18
|
+
const layerHint = getLayerHint(layer);
|
|
19
|
+
const lines = [];
|
|
20
|
+
// Header with layer context
|
|
21
|
+
lines.push(`# PULSE: ${layerHint.title}`);
|
|
22
|
+
lines.push("");
|
|
23
|
+
lines.push(layerHint.hint);
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push("---");
|
|
26
|
+
lines.push("");
|
|
27
|
+
// ┌─────────────────────────────────────────────────────────────────────────
|
|
28
|
+
// │ 6-ELEMENTS (exactly as documented in Framework)
|
|
29
|
+
// └─────────────────────────────────────────────────────────────────────────
|
|
30
|
+
// 1. ROLE
|
|
31
|
+
lines.push("**ROLE:** " + (el.role?.trim() || "[Who should the AI be? Senior Dev, Architect, Code-Reviewer?]"));
|
|
32
|
+
lines.push("");
|
|
33
|
+
// 2. CONTEXT
|
|
34
|
+
lines.push("**CONTEXT:** " + (el.context?.trim() || "[Where are you? What happened? Which project?]"));
|
|
35
|
+
lines.push("");
|
|
36
|
+
// 3. INPUT
|
|
37
|
+
lines.push("**INPUT:** " + (el.input?.trim() || "[What is given? Code, Screenshot, Error, Concept?]"));
|
|
38
|
+
lines.push("");
|
|
39
|
+
// 4. OUTPUT
|
|
40
|
+
lines.push("**OUTPUT:** " + (el.output?.trim() || "[What should be the result? Code, Docs, Explanation, File?]"));
|
|
41
|
+
lines.push("");
|
|
42
|
+
// 5. ACTION
|
|
43
|
+
lines.push("**ACTION:** " + (el.action?.trim() || "[What should the AI do? Build, analyze, fix, explain?]"));
|
|
44
|
+
lines.push("");
|
|
45
|
+
// 6. EXAMPLES
|
|
46
|
+
if (el.examples?.trim()) {
|
|
47
|
+
lines.push("**EXAMPLES:**");
|
|
48
|
+
lines.push("✅ How it should be: " + el.examples.trim());
|
|
49
|
+
lines.push("❌ How it should NOT be: [Negative Example]");
|
|
50
|
+
lines.push("");
|
|
51
|
+
}
|
|
52
|
+
// ┌─────────────────────────────────────────────────────────────────────────
|
|
53
|
+
// │ SAFEGUARDS (from .cursorrules)
|
|
54
|
+
// └─────────────────────────────────────────────────────────────────────────
|
|
55
|
+
if (layer === "build") {
|
|
56
|
+
lines.push("---");
|
|
57
|
+
lines.push("");
|
|
58
|
+
lines.push("⚠️ **SAFEGUARDS** (non-negotiable):");
|
|
59
|
+
lines.push("- ⏱️ MAX 30 min autonomous, then STOP + ask user");
|
|
60
|
+
lines.push("- 🗑️ NO DELETE without confirmation");
|
|
61
|
+
lines.push("- 📤 NO PUSH without confirmation");
|
|
62
|
+
lines.push("- 🔐 NO Secrets in code");
|
|
63
|
+
lines.push("- 📋 Git commit every 5-10 min");
|
|
64
|
+
lines.push("");
|
|
65
|
+
}
|
|
66
|
+
lines.push("---");
|
|
67
|
+
lines.push("Did you understand? Then let's proceed step by step.");
|
|
68
|
+
return lines.join("\n");
|
|
69
|
+
}
|
|
70
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
71
|
+
// TEMPLATE 2: AS-IS/TO-BE Prompt (for quick bug fixes)
|
|
72
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
73
|
+
function renderIstSollPrompt(options) {
|
|
74
|
+
const lines = [];
|
|
75
|
+
lines.push("# AS-IS/TO-BE Bug Fix");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("**AS-IS:** " + options.ist.trim());
|
|
78
|
+
lines.push("");
|
|
79
|
+
lines.push("**TO-BE:** " + options.soll.trim());
|
|
80
|
+
lines.push("");
|
|
81
|
+
if (options.error?.trim()) {
|
|
82
|
+
lines.push("**ERROR Log:**");
|
|
83
|
+
lines.push("```");
|
|
84
|
+
lines.push(options.error.trim());
|
|
85
|
+
lines.push("```");
|
|
86
|
+
lines.push("");
|
|
87
|
+
}
|
|
88
|
+
if (options.context?.trim()) {
|
|
89
|
+
lines.push("**CONTEXT:** " + options.context.trim());
|
|
90
|
+
lines.push("");
|
|
91
|
+
}
|
|
92
|
+
lines.push("---");
|
|
93
|
+
lines.push("⚠️ Safeguards: No delete without confirmation, commit after fix.");
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
96
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
97
|
+
// TEMPLATE 3: Escalation Prompt (for external models like GPT-5/Opus)
|
|
98
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
99
|
+
function renderEscalationPrompt(options) {
|
|
100
|
+
const lines = [];
|
|
101
|
+
lines.push("# Escalation: Cursor is stuck");
|
|
102
|
+
lines.push("");
|
|
103
|
+
lines.push("My developer (Cursor) is stuck on the following problem:");
|
|
104
|
+
lines.push("");
|
|
105
|
+
lines.push("**Problem Description:**");
|
|
106
|
+
lines.push(options.cursorExplanation.trim() || "[Cursor's explanation of the problem here]");
|
|
107
|
+
lines.push("");
|
|
108
|
+
// What Cursor tried
|
|
109
|
+
lines.push("**What Cursor tried:**");
|
|
110
|
+
if (options.attempts && options.attempts.length > 0) {
|
|
111
|
+
options.attempts.forEach((attempt, i) => {
|
|
112
|
+
lines.push(`• ${attempt}`);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
lines.push("• (Not documented)");
|
|
117
|
+
}
|
|
118
|
+
lines.push("");
|
|
119
|
+
// Error logs
|
|
120
|
+
if (options.errorText?.trim()) {
|
|
121
|
+
lines.push("**Error Message:**");
|
|
122
|
+
lines.push("```");
|
|
123
|
+
lines.push(options.errorText.trim());
|
|
124
|
+
lines.push("```");
|
|
125
|
+
lines.push("");
|
|
126
|
+
}
|
|
127
|
+
// Code Context
|
|
128
|
+
if (options.codeSnippets?.trim()) {
|
|
129
|
+
lines.push("**Code Context:**");
|
|
130
|
+
lines.push("```");
|
|
131
|
+
lines.push(options.codeSnippets.trim());
|
|
132
|
+
lines.push("```");
|
|
133
|
+
lines.push("");
|
|
134
|
+
}
|
|
135
|
+
// Git Context
|
|
136
|
+
if (options.gitLog?.trim()) {
|
|
137
|
+
lines.push("**Git Log (recent commits):**");
|
|
138
|
+
lines.push("```");
|
|
139
|
+
lines.push(options.gitLog.trim());
|
|
140
|
+
lines.push("```");
|
|
141
|
+
lines.push("");
|
|
142
|
+
}
|
|
143
|
+
if (options.gitDiff?.trim()) {
|
|
144
|
+
lines.push("**Git Diff:**");
|
|
145
|
+
lines.push("```");
|
|
146
|
+
lines.push(options.gitDiff.trim());
|
|
147
|
+
lines.push("```");
|
|
148
|
+
lines.push("");
|
|
149
|
+
}
|
|
150
|
+
// Call to action
|
|
151
|
+
lines.push("---");
|
|
152
|
+
lines.push("");
|
|
153
|
+
lines.push("**My Question:** " + (options.question.trim() || "What is the root cause and how do I fix it?"));
|
|
154
|
+
lines.push("");
|
|
155
|
+
lines.push("**Give me a solution that I can provide to my developer (Cursor) as instructions.**");
|
|
156
|
+
lines.push("");
|
|
157
|
+
lines.push("Format:");
|
|
158
|
+
lines.push("1. Root Cause (one line)");
|
|
159
|
+
lines.push("2. Step-by-step instructions for Cursor");
|
|
160
|
+
lines.push("3. Code snippet if needed");
|
|
161
|
+
return lines.join("\n");
|
|
162
|
+
}
|
|
163
|
+
exports.PROMPT_TEMPLATES = [
|
|
164
|
+
{
|
|
165
|
+
id: "feature",
|
|
166
|
+
name: "🚀 Build Feature",
|
|
167
|
+
description: "Implement new feature",
|
|
168
|
+
layer: "build",
|
|
169
|
+
defaults: {
|
|
170
|
+
role: "Senior Full-Stack Developer",
|
|
171
|
+
output: "Working implementation with tests",
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "bugfix",
|
|
176
|
+
name: "🐛 Fix Bug",
|
|
177
|
+
description: "Analyze and fix error",
|
|
178
|
+
layer: "build",
|
|
179
|
+
defaults: {
|
|
180
|
+
role: "Experienced Debugger and Code Analyst",
|
|
181
|
+
output: "1. Root Cause\n2. Fix\n3. Test that it works",
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "refactor",
|
|
186
|
+
name: "♻️ Refactoring",
|
|
187
|
+
description: "Improve code without changing functionality",
|
|
188
|
+
layer: "build",
|
|
189
|
+
defaults: {
|
|
190
|
+
role: "Code Quality Expert",
|
|
191
|
+
output: "Clean, maintainable code. Same functionality.",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: "concept",
|
|
196
|
+
name: "📋 Create Concept",
|
|
197
|
+
description: "Plan first, then build",
|
|
198
|
+
layer: "concept",
|
|
199
|
+
defaults: {
|
|
200
|
+
role: "Software Architect",
|
|
201
|
+
output: "Markdown document with plan, architecture, risks",
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "analyze",
|
|
206
|
+
name: "🔍 Analyze Code",
|
|
207
|
+
description: "Understand and document project",
|
|
208
|
+
layer: "concept",
|
|
209
|
+
defaults: {
|
|
210
|
+
role: "Senior Developer onboarding to the project",
|
|
211
|
+
output: "Structured analysis: What exists, how it works, what is missing",
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: "review",
|
|
216
|
+
name: "👀 Code Review",
|
|
217
|
+
description: "Review changes",
|
|
218
|
+
layer: "concept",
|
|
219
|
+
defaults: {
|
|
220
|
+
role: "Code Reviewer with Security focus",
|
|
221
|
+
output: "List of findings: Critical, High, Medium, Low",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
];
|
|
225
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
226
|
+
// HELPER FUNCTIONS
|
|
227
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
228
|
+
function getLayerHint(layer) {
|
|
229
|
+
switch (layer) {
|
|
230
|
+
case "concept":
|
|
231
|
+
return {
|
|
232
|
+
title: "CONCEPT MODE",
|
|
233
|
+
hint: "🧠 You are in Concept Mode. NO CODE. Only analysis, planning, documentation.",
|
|
234
|
+
};
|
|
235
|
+
case "build":
|
|
236
|
+
return {
|
|
237
|
+
title: "BUILD MODE",
|
|
238
|
+
hint: "🔨 You are in Build Mode. Implement EXACTLY what is requested. No more, no less.",
|
|
239
|
+
};
|
|
240
|
+
case "escalation":
|
|
241
|
+
return {
|
|
242
|
+
title: "ESCALATION MODE",
|
|
243
|
+
hint: "🚨 Escalation active. Analyze the problem and provide instructions for the builder.",
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function countProvidedElements(el) {
|
|
248
|
+
return Object.values(el).filter((v) => typeof v === "string" && v.trim().length > 0).length;
|
|
249
|
+
}
|
|
250
|
+
function validateOneAction(action) {
|
|
251
|
+
const a = (action ?? "").trim();
|
|
252
|
+
if (!a)
|
|
253
|
+
return "Missing [ACTION].";
|
|
254
|
+
// Heuristic: multiple bullet lines = likely multiple actions
|
|
255
|
+
const bulletLines = a.split("\n").filter((l) => /^\s*[-*]\s+/.test(l)).length;
|
|
256
|
+
if (bulletLines >= 3) {
|
|
257
|
+
return "⚠️ ACTION contains multiple points. Better: One action per Pulse.";
|
|
258
|
+
}
|
|
259
|
+
const andCount = (a.match(/\b(und|and)\b/gi) ?? []).length;
|
|
260
|
+
if (andCount >= 2) {
|
|
261
|
+
return "⚠️ ACTION contains multiple 'and'. Better: Split into milestones.";
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get template by ID
|
|
267
|
+
*/
|
|
268
|
+
function getTemplateById(id) {
|
|
269
|
+
return exports.PROMPT_TEMPLATES.find((t) => t.id === id);
|
|
270
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { PulseConfig } from "./types.js";
|
|
2
|
+
export type FindingSeverity = "critical" | "warn" | "info";
|
|
3
|
+
export type Finding = {
|
|
4
|
+
severity: FindingSeverity;
|
|
5
|
+
code: "SECRETS" | "PROD_URL" | "MASS_DELETE" | "BIG_CHANGESET" | "UNKNOWN_DEPS" | "CONSOLE_LOG" | "COMMENTED_CODE" | "TODO_NO_ISSUE" | "LOOP_SIGNAL";
|
|
6
|
+
message: string;
|
|
7
|
+
details?: string;
|
|
8
|
+
};
|
|
9
|
+
export type ScanInput = {
|
|
10
|
+
diffText: string;
|
|
11
|
+
diffStat: string;
|
|
12
|
+
diffNumstat: string;
|
|
13
|
+
diffNameStatus: string;
|
|
14
|
+
};
|
|
15
|
+
export type ScanResult = {
|
|
16
|
+
findings: Finding[];
|
|
17
|
+
stats: {
|
|
18
|
+
filesChanged: number;
|
|
19
|
+
linesAdded: number;
|
|
20
|
+
linesDeleted: number;
|
|
21
|
+
deletedFiles: string[];
|
|
22
|
+
touchedFiles: string[];
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export declare function scanDiff(config: PulseConfig, input: ScanInput): ScanResult;
|
|
26
|
+
export type LoopSignal = {
|
|
27
|
+
type: "fix_chain" | "revert" | "churn" | "pendeln" | "fix_no_test";
|
|
28
|
+
severity: FindingSeverity;
|
|
29
|
+
message: string;
|
|
30
|
+
details?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Analyze git log for loop signals
|
|
34
|
+
* @param gitLog Output from `git log --oneline -n 15`
|
|
35
|
+
* @param gitLogWithFiles Output from `git log --name-only --oneline -n 15`
|
|
36
|
+
*/
|
|
37
|
+
export declare function detectLoopSignals(gitLog: string, gitLogWithFiles?: string): LoopSignal[];
|