claude-setup 1.1.7 → 1.1.9
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/README.md +88 -107
- package/dist/builder.d.ts +6 -0
- package/dist/builder.js +143 -80
- package/dist/commands/init.js +8 -1
- package/dist/commands/sync.js +76 -12
- package/dist/marketplace.d.ts +24 -19
- package/dist/marketplace.js +429 -86
- package/dist/os.d.ts +33 -4
- package/dist/os.js +238 -3
- package/package.json +1 -1
- package/templates/add.md +57 -10
- package/templates/sync.md +6 -2
package/dist/commands/sync.js
CHANGED
|
@@ -46,6 +46,25 @@ function truncate(content, maxChars) {
|
|
|
46
46
|
return content;
|
|
47
47
|
return content.slice(0, maxChars) + "\n[... truncated for sync diff]";
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Compute a simple line-level diff between two strings.
|
|
51
|
+
* Returns added lines (green) and removed lines (red).
|
|
52
|
+
*/
|
|
53
|
+
function computeLineDiff(oldContent, newContent, maxLines = 20) {
|
|
54
|
+
const oldLines = oldContent.split("\n");
|
|
55
|
+
const newLines = newContent.split("\n");
|
|
56
|
+
const oldSet = new Set(oldLines);
|
|
57
|
+
const newSet = new Set(newLines);
|
|
58
|
+
const added = newLines.filter(l => !oldSet.has(l) && l.trim() !== "");
|
|
59
|
+
const removed = oldLines.filter(l => !newSet.has(l) && l.trim() !== "");
|
|
60
|
+
const totalChanges = added.length + removed.length;
|
|
61
|
+
const summary = `+${added.length} lines, -${removed.length} lines`;
|
|
62
|
+
return {
|
|
63
|
+
added: added.slice(0, maxLines),
|
|
64
|
+
removed: removed.slice(0, maxLines),
|
|
65
|
+
summary,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
49
68
|
/**
|
|
50
69
|
* Legacy diff — compares manifest hashes against collected files.
|
|
51
70
|
* Only used when no snapshot data is available (e.g., old projects).
|
|
@@ -96,6 +115,7 @@ function computeLegacyDiff(snapshot, collected, cwd) {
|
|
|
96
115
|
/**
|
|
97
116
|
* Full-scan diff — compares every file on disk against a reference snapshot.
|
|
98
117
|
* This is the authoritative diff: catches ALL file changes, no sampling.
|
|
118
|
+
* Now includes line-level diffs for modified files.
|
|
99
119
|
*/
|
|
100
120
|
function computeFullDiff(currentFiles, referenceFiles) {
|
|
101
121
|
const added = [];
|
|
@@ -111,7 +131,13 @@ function computeFullDiff(currentFiles, referenceFiles) {
|
|
|
111
131
|
const currentHash = sha256(f.content);
|
|
112
132
|
const refHash = sha256(referenceFiles[f.path]);
|
|
113
133
|
if (currentHash !== refHash) {
|
|
114
|
-
|
|
134
|
+
const lineDiff = computeLineDiff(referenceFiles[f.path], f.content);
|
|
135
|
+
changed.push({
|
|
136
|
+
path: f.path,
|
|
137
|
+
current: truncate(f.content, 2000),
|
|
138
|
+
previous: truncate(referenceFiles[f.path], 2000),
|
|
139
|
+
lineDiff,
|
|
140
|
+
});
|
|
115
141
|
}
|
|
116
142
|
}
|
|
117
143
|
}
|
|
@@ -198,18 +224,22 @@ export async function runSync(opts = {}) {
|
|
|
198
224
|
console.log(c.bold("[DRY RUN] Changes detected:\n"));
|
|
199
225
|
if (diff.added.length) {
|
|
200
226
|
console.log(c.green(` +${diff.added.length} added`));
|
|
201
|
-
for (const f of diff.added)
|
|
202
|
-
|
|
227
|
+
for (const f of diff.added) {
|
|
228
|
+
const lineCount = f.content.split("\n").length;
|
|
229
|
+
console.log(c.green(` + ${f.path}`) + c.dim(` (${lineCount} lines)`));
|
|
230
|
+
}
|
|
203
231
|
}
|
|
204
232
|
if (diff.changed.length) {
|
|
205
233
|
console.log(c.yellow(` ~${diff.changed.length} modified`));
|
|
206
|
-
for (const f of diff.changed)
|
|
207
|
-
|
|
234
|
+
for (const f of diff.changed) {
|
|
235
|
+
const diffInfo = f.lineDiff ? ` (${f.lineDiff.summary})` : "";
|
|
236
|
+
console.log(c.yellow(` ~ ${f.path}`) + c.dim(diffInfo));
|
|
237
|
+
}
|
|
208
238
|
}
|
|
209
239
|
if (diff.deleted.length) {
|
|
210
240
|
console.log(c.red(` -${diff.deleted.length} deleted`));
|
|
211
241
|
for (const f of diff.deleted)
|
|
212
|
-
console.log(` ${f}`);
|
|
242
|
+
console.log(c.red(` - ${f}`));
|
|
213
243
|
}
|
|
214
244
|
console.log(`\n Would write: .claude/commands/stack-sync.md (~${tokens.toLocaleString()} tokens)`);
|
|
215
245
|
section("Token cost estimate");
|
|
@@ -225,10 +255,44 @@ export async function runSync(opts = {}) {
|
|
|
225
255
|
createSnapshot(cwd, "sync", currentFiles, {
|
|
226
256
|
summary: `+${diff.added.length} added, ~${diff.changed.length} modified, -${diff.deleted.length} deleted`,
|
|
227
257
|
});
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
${c.green(`+${diff.added.length}`)} added ${c.yellow(`~${diff.changed.length}`)} modified ${c.red(`-${diff.deleted.length}`)} deleted
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
258
|
+
// --- Detailed diff output ---
|
|
259
|
+
console.log(`\nChanges since ${c.dim(lastRun.at)}:`);
|
|
260
|
+
console.log(` ${c.green(`+${diff.added.length}`)} added ${c.yellow(`~${diff.changed.length}`)} modified ${c.red(`-${diff.deleted.length}`)} deleted\n`);
|
|
261
|
+
if (diff.added.length > 0) {
|
|
262
|
+
console.log(c.green(c.bold(" Added files:")));
|
|
263
|
+
for (const f of diff.added) {
|
|
264
|
+
const lineCount = f.content.split("\n").length;
|
|
265
|
+
console.log(c.green(` + ${f.path}`) + c.dim(` (${lineCount} lines)`));
|
|
266
|
+
}
|
|
267
|
+
console.log("");
|
|
268
|
+
}
|
|
269
|
+
if (diff.changed.length > 0) {
|
|
270
|
+
console.log(c.yellow(c.bold(" Modified files:")));
|
|
271
|
+
for (const f of diff.changed) {
|
|
272
|
+
const diffInfo = f.lineDiff ? ` (${f.lineDiff.summary})` : "";
|
|
273
|
+
console.log(c.yellow(` ~ ${f.path}`) + c.dim(diffInfo));
|
|
274
|
+
if (f.lineDiff) {
|
|
275
|
+
for (const line of f.lineDiff.removed.slice(0, 3)) {
|
|
276
|
+
console.log(c.red(` - ${line.trim().slice(0, 80)}`));
|
|
277
|
+
}
|
|
278
|
+
for (const line of f.lineDiff.added.slice(0, 3)) {
|
|
279
|
+
console.log(c.green(` + ${line.trim().slice(0, 80)}`));
|
|
280
|
+
}
|
|
281
|
+
const totalShown = Math.min(f.lineDiff.removed.length, 3) + Math.min(f.lineDiff.added.length, 3);
|
|
282
|
+
const totalChanges = f.lineDiff.removed.length + f.lineDiff.added.length;
|
|
283
|
+
if (totalChanges > totalShown) {
|
|
284
|
+
console.log(c.dim(` ... +${totalChanges - totalShown} more changes`));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
console.log("");
|
|
289
|
+
}
|
|
290
|
+
if (diff.deleted.length > 0) {
|
|
291
|
+
console.log(c.red(c.bold(" Deleted files:")));
|
|
292
|
+
for (const f of diff.deleted) {
|
|
293
|
+
console.log(c.red(` - ${f}`));
|
|
294
|
+
}
|
|
295
|
+
console.log("");
|
|
296
|
+
}
|
|
297
|
+
console.log(`${c.green("✅")} Run ${c.cyan("/stack-sync")} in Claude Code to apply.\n`);
|
|
234
298
|
}
|
package/dist/marketplace.d.ts
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Marketplace intelligence — provides catalog info and decision logic
|
|
3
|
-
* for the add command to suggest plugins, skills,
|
|
3
|
+
* for the add command to suggest plugins, skills, MCP servers, and agents.
|
|
4
|
+
*
|
|
5
|
+
* Implements the 4-catalog exhaustion pipeline (Rule 6) with 3-stage
|
|
6
|
+
* fetch resolution (Rule 7): find entry → navigate directory → download content.
|
|
4
7
|
*
|
|
5
8
|
* Zero API calls at import time. Catalog is fetched only when needed.
|
|
6
9
|
*/
|
|
10
|
+
export declare const VOLTAGENT_SUBAGENTS_REPO = "VoltAgent/awesome-claude-code-subagents";
|
|
11
|
+
export declare const VOLTAGENT_SUBAGENTS_API = "https://api.github.com/repos/VoltAgent/awesome-claude-code-subagents/contents/categories";
|
|
12
|
+
export declare const VOLTAGENT_SUBAGENTS_RAW = "https://raw.githubusercontent.com/VoltAgent/awesome-claude-code-subagents/main/categories";
|
|
13
|
+
export declare const VOLTAGENT_CATEGORIES: readonly ["01-core-development", "02-language-specialists", "03-infrastructure", "04-quality-security", "05-data-ai", "06-developer-experience", "07-specialized-domains", "08-business-product", "09-meta-orchestration", "10-research-analysis"];
|
|
7
14
|
export declare const MARKETPLACE_REPO = "jeremylongshore/claude-code-plugins-plus-skills";
|
|
8
15
|
export declare const MARKETPLACE_CATALOG_URL = "https://raw.githubusercontent.com/jeremylongshore/claude-code-plugins-plus-skills/main/.claude-plugin/marketplace.extended.json";
|
|
9
|
-
|
|
10
|
-
export declare const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
readonly note: "No marketplace add needed — available by default";
|
|
15
|
-
}, {
|
|
16
|
-
readonly name: "awesome-claude-code";
|
|
17
|
-
readonly description: "Community collection of Claude Code skills and workflows";
|
|
18
|
-
readonly catalogUrl: "https://raw.githubusercontent.com/hesreallyhim/awesome-claude-code/main/catalog.json";
|
|
19
|
-
readonly installPrefix: null;
|
|
20
|
-
readonly note: "Browse and manually install skills";
|
|
21
|
-
}];
|
|
16
|
+
export declare const VOLTAGENT_SKILLS_REPO = "VoltAgent/awesome-agent-skills";
|
|
17
|
+
export declare const VOLTAGENT_SKILLS_API = "https://api.github.com/repos/VoltAgent/awesome-agent-skills/contents";
|
|
18
|
+
export declare const COMPOSIO_REPO = "ComposioHQ/awesome-claude-skills";
|
|
19
|
+
export declare const COMPOSIO_API = "https://api.github.com/repos/ComposioHQ/awesome-claude-skills/contents";
|
|
20
|
+
export declare const COMPOSIO_RAW = "https://raw.githubusercontent.com/ComposioHQ/awesome-claude-skills/master";
|
|
22
21
|
/** The 20 skill categories in the marketplace */
|
|
23
22
|
export declare const SKILL_CATEGORIES: readonly ["01-code-quality", "02-testing", "03-security", "04-devops", "05-api-development", "06-database", "07-frontend", "08-backend", "09-mobile", "10-data-science", "11-documentation", "12-project-management", "13-communication", "14-research", "15-content-creation", "16-business", "17-finance", "18-visual-content", "19-legal", "20-productivity"];
|
|
24
23
|
/** SaaS packs available in the marketplace */
|
|
25
24
|
export declare const SAAS_PACKS: readonly ["Supabase", "Vercel", "OpenRouter", "GitHub", "Azure", "MongoDB", "Playwright", "Tavily", "Stripe", "Slack", "Linear", "Notion"];
|
|
26
|
-
/** Keyword-to-category mapping for classifying
|
|
25
|
+
/** Keyword-to-category mapping for classifying skill requests */
|
|
27
26
|
export declare const KEYWORD_CATEGORY_MAP: Record<string, string>;
|
|
28
|
-
|
|
29
|
-
export declare function classifyRequest(input: string): {
|
|
27
|
+
export interface ClassificationResult {
|
|
30
28
|
categories: string[];
|
|
31
29
|
saasMatches: string[];
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
isAgent: boolean;
|
|
31
|
+
agentCategories: string[];
|
|
32
|
+
}
|
|
33
|
+
/** Detect whether the request is about agents/subagents/orchestration */
|
|
34
|
+
export declare function isAgentRequest(input: string): boolean;
|
|
35
|
+
/** Map input to VoltAgent agent category directories */
|
|
36
|
+
export declare function matchAgentCategories(input: string): string[];
|
|
37
|
+
/** Classify a user request into marketplace categories and detect agent requests */
|
|
38
|
+
export declare function classifyRequest(input: string): ClassificationResult;
|
|
34
39
|
export declare function buildMarketplaceInstructions(input: string): string;
|