coolhand-cli 0.10.0 → 0.11.0

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 (69) hide show
  1. package/README.md +7 -0
  2. package/dist/api/llm-reference-client.d.ts +25 -0
  3. package/dist/api/llm-reference-client.d.ts.map +1 -0
  4. package/dist/api/llm-reference-client.js +49 -0
  5. package/dist/api/llm-reference-client.js.map +1 -0
  6. package/dist/api/template-client.d.ts +19 -0
  7. package/dist/api/template-client.d.ts.map +1 -0
  8. package/dist/api/template-client.js +47 -0
  9. package/dist/api/template-client.js.map +1 -0
  10. package/dist/auth/open-browser.d.ts.map +1 -1
  11. package/dist/auth/open-browser.js +3 -1
  12. package/dist/auth/open-browser.js.map +1 -1
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +240 -2
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/get-template.d.ts +3 -0
  17. package/dist/commands/get-template.d.ts.map +1 -0
  18. package/dist/commands/get-template.js +66 -0
  19. package/dist/commands/get-template.js.map +1 -0
  20. package/dist/commands/list-referenced-file-sessions.d.ts +3 -0
  21. package/dist/commands/list-referenced-file-sessions.d.ts.map +1 -0
  22. package/dist/commands/list-referenced-file-sessions.js +44 -0
  23. package/dist/commands/list-referenced-file-sessions.js.map +1 -0
  24. package/dist/commands/map-claude-projects.d.ts.map +1 -1
  25. package/dist/commands/map-claude-projects.js +20 -0
  26. package/dist/commands/map-claude-projects.js.map +1 -1
  27. package/dist/commands/search-referenced-files.d.ts +3 -0
  28. package/dist/commands/search-referenced-files.d.ts.map +1 -0
  29. package/dist/commands/search-referenced-files.js +53 -0
  30. package/dist/commands/search-referenced-files.js.map +1 -0
  31. package/dist/commands/search-templates.d.ts +3 -0
  32. package/dist/commands/search-templates.d.ts.map +1 -0
  33. package/dist/commands/search-templates.js +63 -0
  34. package/dist/commands/search-templates.js.map +1 -0
  35. package/dist/commands/sync-skills.d.ts +18 -0
  36. package/dist/commands/sync-skills.d.ts.map +1 -0
  37. package/dist/commands/sync-skills.js +222 -0
  38. package/dist/commands/sync-skills.js.map +1 -0
  39. package/dist/errors.d.ts +1 -1
  40. package/dist/errors.d.ts.map +1 -1
  41. package/dist/errors.js.map +1 -1
  42. package/dist/proxy/proxy.d.ts.map +1 -1
  43. package/dist/proxy/proxy.js +71 -3
  44. package/dist/proxy/proxy.js.map +1 -1
  45. package/dist/proxy/wrap-runner.d.ts +2 -5
  46. package/dist/proxy/wrap-runner.d.ts.map +1 -1
  47. package/dist/proxy/wrap-runner.js +2 -31
  48. package/dist/proxy/wrap-runner.js.map +1 -1
  49. package/dist/sessions/redact-secrets.d.ts.map +1 -1
  50. package/dist/sessions/redact-secrets.js +3 -0
  51. package/dist/sessions/redact-secrets.js.map +1 -1
  52. package/dist/skills/skill-scanner.d.ts +55 -0
  53. package/dist/skills/skill-scanner.d.ts.map +1 -0
  54. package/dist/skills/skill-scanner.js +132 -0
  55. package/dist/skills/skill-scanner.js.map +1 -0
  56. package/dist/skills/skill-state.d.ts +29 -0
  57. package/dist/skills/skill-state.d.ts.map +1 -0
  58. package/dist/skills/skill-state.js +111 -0
  59. package/dist/skills/skill-state.js.map +1 -0
  60. package/dist/types.d.ts +55 -0
  61. package/dist/types.d.ts.map +1 -1
  62. package/dist/types.js.map +1 -1
  63. package/dist/version.d.ts +2 -2
  64. package/dist/version.js +1 -1
  65. package/dist/win-spawn.d.ts +6 -0
  66. package/dist/win-spawn.d.ts.map +1 -0
  67. package/dist/win-spawn.js +32 -0
  68. package/dist/win-spawn.js.map +1 -0
  69. package/package.json +3 -3
@@ -0,0 +1,18 @@
1
+ import { type SkillRoot } from '../skills/skill-scanner.js';
2
+ import type { SyncSkillsOptions } from '../types.js';
3
+ export interface SyncSkillsDeps {
4
+ /** Overrides `os.homedir()` for the `authored` and `claude-code` default roots only. The
5
+ * `installed` root always comes from the canonical `defaultCoworkSessionsDir()` (reused as-is
6
+ * from cowork-scanner.ts, deliberately not re-derived here to avoid drift) — that function has
7
+ * no override parameter of its own and always reads the real `os.homedir()`, so it does NOT
8
+ * move with this override. Note that mutating `process.env.HOME` in a test is not a substitute
9
+ * for this: Node's `os.homedir()` native binding does not reliably observe a `HOME` mutated
10
+ * after process start under Jest, which is why this injection point exists at all. */
11
+ homedir?: () => string;
12
+ /** Override the roots to scan, bypassing the default 3-root/--root/--source resolution
13
+ * entirely (including the `installed` root) — used by tests that need every root, including
14
+ * `installed`, pointed at a temp directory. */
15
+ roots?: SkillRoot[];
16
+ }
17
+ export declare function run(opts: SyncSkillsOptions, deps?: SyncSkillsDeps): Promise<number>;
18
+ //# sourceMappingURL=sync-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-skills.d.ts","sourceRoot":"","sources":["../../src/commands/sync-skills.ts"],"names":[],"mappings":"AAQA,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B;;;;;;2FAMuF;IACvF,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IACvB;;oDAEgD;IAChD,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAqED,wBAAsB,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4J7F"}
@@ -0,0 +1,222 @@
1
+ import * as os from 'os';
2
+ import * as path from 'path';
3
+ import { CliError, ExitCode } from '../errors.js';
4
+ import { logger, redact } from '../logger.js';
5
+ import { loadConfig, resolveClientForDryRun } from '../config.js';
6
+ import { uploadClientFile } from '../upload-client-file.js';
7
+ import { defaultCoworkSessionsDir } from '../sessions/cowork-scanner.js';
8
+ import { sanitizeProjectKey } from '../sessions/session-filter.js';
9
+ import { findSkillFiles, dedupeSkillFiles, } from '../skills/skill-scanner.js';
10
+ import { loadSkillState, getUploadRecord, recordUpload, saveSkillState } from '../skills/skill-state.js';
11
+ /** Errors that apply to every candidate (auth/config), so the run should abort rather than fail
12
+ * identically for each remaining upload. Deliberately narrower than analyze-claude-sessions'
13
+ * FATAL_CODES: INVALID_ARGS from uploadClientFile here is a per-FILE condition (unreadable file,
14
+ * over the size cap) that can easily succeed for the next candidate, so it must NOT be fatal —
15
+ * unlike analyze-claude-sessions, where INVALID_ARGS comes from a malformed envelope shape that
16
+ * would fail identically for every session. NO_PRIVATE_KEY, absent from analyze-claude-sessions'
17
+ * set (logRequest uses the public-key tier), is fatal here because uploadClientFile always
18
+ * requires a private key — identical for every candidate, so retrying per-item is pointless. */
19
+ const FATAL_CODES = new Set(['NOT_CONFIGURED', 'CLIENT_NOT_FOUND', 'INVALID_BASE_URL', 'NO_PRIVATE_KEY']);
20
+ const VALID_SOURCE_KINDS = ['authored', 'installed', 'claude-code'];
21
+ function defaultRoots(homedir) {
22
+ return [
23
+ { root: path.join(homedir(), 'Documents', 'Claude'), sourceKind: 'authored' },
24
+ { root: defaultCoworkSessionsDir(), sourceKind: 'installed' },
25
+ { root: path.join(homedir(), '.claude', 'skills'), sourceKind: 'claude-code' },
26
+ ];
27
+ }
28
+ function resolveRoots(opts, homedir) {
29
+ if (opts.root) {
30
+ return [{ root: opts.root, sourceKind: 'custom' }];
31
+ }
32
+ const roots = defaultRoots(homedir);
33
+ if (!opts.sources || opts.sources.length === 0) {
34
+ return roots;
35
+ }
36
+ const wanted = new Set(opts.sources.map((s) => s.toLowerCase()));
37
+ for (const s of wanted) {
38
+ if (!VALID_SOURCE_KINDS.includes(s)) {
39
+ throw new CliError('INVALID_ARGS', `--source must be one of: ${VALID_SOURCE_KINDS.join(', ')} (got "${s}")`);
40
+ }
41
+ }
42
+ return roots.filter((r) => wanted.has(r.sourceKind));
43
+ }
44
+ /** Substring/case-insensitive match on skill name, using the same normalization
45
+ * (`sanitizeProjectKey`) as --project/--exclude-project so filter semantics stay consistent
46
+ * across commands. */
47
+ function matchesFilter(skillName, needles) {
48
+ const key = sanitizeProjectKey(skillName);
49
+ return needles.some((needle) => key.includes(sanitizeProjectKey(needle)));
50
+ }
51
+ function applyNameFilters(candidates, opts) {
52
+ let result = candidates;
53
+ const includeNeedles = opts.skills;
54
+ if (includeNeedles && includeNeedles.length > 0) {
55
+ result = result.filter((c) => matchesFilter(c.skillName, includeNeedles));
56
+ }
57
+ const excludeNeedles = opts.excludeSkills;
58
+ if (excludeNeedles && excludeNeedles.length > 0) {
59
+ result = result.filter((c) => !matchesFilter(c.skillName, excludeNeedles));
60
+ }
61
+ return result;
62
+ }
63
+ function describeCandidate(candidate) {
64
+ if (candidate.description) {
65
+ return candidate.description;
66
+ }
67
+ const extraCopies = candidate.duplicateCount - 1;
68
+ const copiesNote = extraCopies > 0 ? `, ${extraCopies} duplicate cop${extraCopies === 1 ? 'y' : 'ies'} found on this machine` : '';
69
+ return `Claude skill "${candidate.skillName}" (source: ${candidate.sourceKind}${copiesNote})`;
70
+ }
71
+ export async function run(opts, deps = {}) {
72
+ try {
73
+ const cfg = await loadConfig();
74
+ const client = await resolveClientForDryRun(cfg, opts.clientId);
75
+ const stateClientId = client?.client_id ?? '_default';
76
+ // Pass the already-resolved client_id downstream (not opts.clientId) so each per-skill
77
+ // uploadClientFile() call takes the fast "explicit clientId" branch of its own internal
78
+ // resolveClientForDryRun/resolveClient call instead of re-running the full priority chain —
79
+ // in particular, never re-prompting interactively over a TTY once per skill upload. That
80
+ // inner call still re-reads config.json and re-prints "Client: <name> (<id>)" to stderr once
81
+ // per upload (resolveClient always does, with no silent/quiet option) — a known, accepted
82
+ // cost of reusing uploadClientFile()'s shared core as-is rather than duplicating its
83
+ // auth/dry-run/size-cap logic in a separate lower-level upload path.
84
+ const resolvedClientId = client?.client_id;
85
+ // Fail fast on a fully logged-out, non-dry-run invocation — mirrors the same guard inside
86
+ // uploadClientFile() itself, but checked here too so a real run doesn't waste time scanning
87
+ // and SHA-256-hashing every SKILL.md across all default roots only to fail on the very first
88
+ // upload attempt.
89
+ if (!client && !opts.dryRun) {
90
+ throw new CliError('NOT_CONFIGURED', 'Not logged in. Run `coolhand login` to authenticate.');
91
+ }
92
+ const roots = deps.roots ?? resolveRoots(opts, deps.homedir ?? os.homedir);
93
+ // Captured once, before the scan, so every candidate uploaded from this run reports the same
94
+ // discoveredAt — stamping it per-candidate inside the upload loop instead would both misname
95
+ // the field (it'd reflect upload time, not discovery time) and drift across a large batch.
96
+ const discoveredAt = new Date().toISOString();
97
+ const warnings = [];
98
+ const discovered = await findSkillFiles(roots, (message) => warnings.push(message));
99
+ for (const message of warnings) {
100
+ logger.warn(message);
101
+ }
102
+ const allCandidates = dedupeSkillFiles(discovered);
103
+ const candidates = applyNameFilters(allCandidates, opts);
104
+ const duplicatesSkipped = discovered.length - allCandidates.length;
105
+ const filteredOut = allCandidates.length - candidates.length;
106
+ const state = await loadSkillState();
107
+ const toUpload = [];
108
+ let unchangedCount = 0;
109
+ for (const candidate of candidates) {
110
+ // The state key already embeds contentHash (see skill-state.ts's stateKey), so a hit here
111
+ // means this exact content was already uploaded under this name — no separate hash
112
+ // comparison needed.
113
+ const record = getUploadRecord(state, stateClientId, candidate.skillName, candidate.contentHash);
114
+ if (record && !opts.force) {
115
+ unchangedCount += 1;
116
+ }
117
+ else {
118
+ toUpload.push(candidate);
119
+ }
120
+ }
121
+ if (opts.dryRun) {
122
+ if (opts.json) {
123
+ logger.json({
124
+ ok: true,
125
+ dryRun: true,
126
+ found: discovered.length,
127
+ duplicatesSkipped,
128
+ filteredOut,
129
+ new: toUpload.length,
130
+ unchanged: unchangedCount,
131
+ });
132
+ }
133
+ else {
134
+ logger.info(`Dry run: found ${discovered.length} skill file(s), ${duplicatesSkipped} duplicate(s) skipped` +
135
+ (filteredOut > 0 ? `, ${filteredOut} filtered out` : '') +
136
+ ` — would upload ${toUpload.length}, ${unchangedCount} unchanged. Nothing sent.`);
137
+ }
138
+ return ExitCode.OK;
139
+ }
140
+ let uploaded = 0;
141
+ let failed = 0;
142
+ try {
143
+ for (const candidate of toUpload) {
144
+ try {
145
+ const result = await uploadClientFile({
146
+ filePath: candidate.filePath,
147
+ name: candidate.skillName,
148
+ fileType: 'document',
149
+ description: describeCandidate(candidate),
150
+ metadata: {
151
+ source: 'sync-skills',
152
+ skillName: candidate.skillName,
153
+ sourceKind: candidate.sourceKind,
154
+ sourcePath: candidate.filePath,
155
+ contentHash: candidate.contentHash,
156
+ discoveredAt,
157
+ duplicateCount: candidate.duplicateCount,
158
+ root: candidate.root,
159
+ },
160
+ },
161
+ // dryRun is deliberately omitted here (unlike map-claude-projects' single call) —
162
+ // this loop is only ever reached after the opts.dryRun early-return above, so it
163
+ // would always be false; sync-skills has its own independent dry-run short-circuit.
164
+ { clientId: resolvedClientId });
165
+ recordUpload(state, stateClientId, candidate.skillName, candidate.contentHash, {
166
+ contentHash: candidate.contentHash,
167
+ uploadedAt: new Date().toISOString(),
168
+ ...(result.response?.id && { clientFileId: result.response.id }),
169
+ });
170
+ uploaded += 1;
171
+ }
172
+ catch (err) {
173
+ if (err instanceof CliError && FATAL_CODES.has(err.code)) {
174
+ throw err;
175
+ }
176
+ failed += 1;
177
+ logger.warn(`Failed to upload skill "${candidate.skillName}": ${redact(err.message)}`);
178
+ }
179
+ }
180
+ }
181
+ finally {
182
+ try {
183
+ await saveSkillState(state);
184
+ }
185
+ catch (err) {
186
+ logger.warn(`Failed to save skill state: ${redact(err.message)}`);
187
+ }
188
+ }
189
+ if (opts.json) {
190
+ logger.json({
191
+ ok: failed === 0,
192
+ found: discovered.length,
193
+ duplicatesSkipped,
194
+ filteredOut,
195
+ uploaded,
196
+ unchanged: unchangedCount,
197
+ failed,
198
+ });
199
+ }
200
+ else {
201
+ const failureNote = failed > 0 ? `, ${failed} failed` : '';
202
+ logger.info(`Uploaded ${uploaded} skill(s), ${unchangedCount} unchanged` +
203
+ (duplicatesSkipped > 0 ? `, ${duplicatesSkipped} duplicate(s) skipped` : '') +
204
+ (filteredOut > 0 ? `, ${filteredOut} filtered out` : '') +
205
+ `${failureNote}.`);
206
+ }
207
+ return failed === 0 ? ExitCode.OK : ExitCode.USER_ERROR;
208
+ }
209
+ catch (err) {
210
+ if (err instanceof CliError) {
211
+ if (opts.json) {
212
+ logger.json({ ok: false, error: err.code, message: redact(err.message) });
213
+ }
214
+ else {
215
+ logger.info(`Error: ${redact(err.message)} [${err.code}]`);
216
+ }
217
+ return err.exitCode;
218
+ }
219
+ throw err;
220
+ }
221
+ }
222
+ //# sourceMappingURL=sync-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-skills.js","sourceRoot":"","sources":["../../src/commands/sync-skills.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -4,7 +4,7 @@ export declare enum ExitCode {
4
4
  INTERNAL = 2,
5
5
  ABORTED = 130
6
6
  }
7
- export type ErrorCode = 'TIMEOUT' | 'STATE_MISMATCH' | 'INVALID_CALLBACK' | 'BROWSER_FAILED' | 'CONFIG_WRITE_FAILED' | 'CONFIG_READ_FAILED' | 'NOT_CONFIGURED' | 'INVALID_REDIRECT_URI' | 'INVALID_BASE_URL' | 'INVALID_ARGS' | 'WRITE_ENV_FAILED' | 'CLIENT_NOT_FOUND' | 'NO_PRIVATE_KEY' | 'MCP_ERROR' | 'INGEST_ERROR' | 'FEEDBACK_ERROR' | 'LOG_ERROR' | 'CERT_FILE_INSECURE' | 'UPLOAD_ERROR';
7
+ export type ErrorCode = 'TIMEOUT' | 'STATE_MISMATCH' | 'INVALID_CALLBACK' | 'BROWSER_FAILED' | 'CONFIG_WRITE_FAILED' | 'CONFIG_READ_FAILED' | 'NOT_CONFIGURED' | 'INVALID_REDIRECT_URI' | 'INVALID_BASE_URL' | 'INVALID_ARGS' | 'WRITE_ENV_FAILED' | 'CLIENT_NOT_FOUND' | 'NO_PRIVATE_KEY' | 'MCP_ERROR' | 'INGEST_ERROR' | 'FEEDBACK_ERROR' | 'LOG_ERROR' | 'TEMPLATE_ERROR' | 'LLM_REFERENCE_ERROR' | 'CERT_FILE_INSECURE' | 'UPLOAD_ERROR' | 'OUTPUT_EXISTS';
8
8
  export declare class CliError extends Error {
9
9
  readonly code: ErrorCode;
10
10
  readonly exitCode: number;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,EAAE,IAAI;IACN,UAAU,IAAI;IACd,QAAQ,IAAI;IACZ,OAAO,MAAM;CACd;AAED,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,GACrB,oBAAoB,GACpB,gBAAgB,GAChB,sBAAsB,GACtB,kBAAkB,GAClB,cAAc,GACd,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,WAAW,GACX,oBAAoB,GACpB,cAAc,CAAC;AAEnB,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,IAAI,EAAE,SAAS,CAAC;IAChC,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA4B;CAMrF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oBAAY,QAAQ;IAClB,EAAE,IAAI;IACN,UAAU,IAAI;IACd,QAAQ,IAAI;IACZ,OAAO,MAAM;CACd;AAED,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,GACrB,oBAAoB,GACpB,gBAAgB,GAChB,sBAAsB,GACtB,kBAAkB,GAClB,cAAc,GACd,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,WAAW,GACX,gBAAgB,GAChB,qBAAqB,GACrB,oBAAoB,GACpB,cAAc,GACd,eAAe,CAAC;AAEpB,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,IAAI,EAAE,SAAS,CAAC;IAChC,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA4B;CAMrF"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,mCAAM,CAAA;IACN,mDAAc,CAAA;IACd,+CAAY,CAAA;IACZ,+CAAa,CAAA;AACf,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AAuBD,MAAM,OAAO,QAAS,SAAQ,KAAK;IAIjC,YAAY,IAAe,EAAE,OAAe,EAAE,WAAmB,QAAQ,CAAC,UAAU;QAClF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,mCAAM,CAAA;IACN,mDAAc,CAAA;IACd,+CAAY,CAAA;IACZ,+CAAa,CAAA;AACf,CAAC,EALW,QAAQ,KAAR,QAAQ,QAKnB;AA0BD,MAAM,OAAO,QAAS,SAAQ,KAAK;IAIjC,YAAY,IAAe,EAAE,OAAe,EAAE,WAAmB,QAAQ,CAAC,UAAU;QAClF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/proxy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAWD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,aAAa,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA+GxB"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/proxy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAwEhD,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAeD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,aAAa,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,CA+GxB"}
@@ -1,6 +1,74 @@
1
+ import * as net from "node:net";
1
2
  import * as mockttp from "mockttp";
2
3
  import { shouldCapture, sanitizeHeaders, sanitizeURL, flattenHeaders } from "./interceptor.js";
3
4
  import { sendToCoolhand } from "./sender.js";
5
+ import { redactSecrets } from "../sessions/redact-secrets.js";
6
+ const LOOPBACK = "127.0.0.1";
7
+ /**
8
+ * mockttp has no host/bind-address option anywhere in its public API (checked
9
+ * every published 4.x release, including latest) — Mockttp#start(port) always
10
+ * calls its internal combo server's .listen(port) with no host, which binds
11
+ * the wildcard address and turns this MITM proxy into an unauthenticated open
12
+ * forward proxy reachable from the local network (coolhand-cli#119).
13
+ *
14
+ * mockttp's combo server is built via httpolyglot, whose `Server` class
15
+ * `extends net.Server` without overriding `listen()`, so it inherits
16
+ * `net.Server.prototype.listen` directly — same as http.Server/https.Server.
17
+ * We exploit that to force a real loopback bind, identical in effect to
18
+ * callback-server.ts's own `server.listen(0, LOOPBACK, ...)`, by scope-patching
19
+ * the prototype for the exact duration of the start() call. Do not remove this
20
+ * without confirming upstream mockttp has added a real host option.
21
+ */
22
+ // Guards against two overlapping startMockttpOnLoopback() calls stepping on
23
+ // each other's prototype patch — startProxy() only ever runs once per CLI
24
+ // process, so this should never trip in practice; it exists so a future
25
+ // concurrent caller fails loudly instead of silently reverting to a wildcard
26
+ // bind for whichever call restores the prototype first.
27
+ let patchInFlight = false;
28
+ async function startMockttpOnLoopback(server, port) {
29
+ if (patchInFlight) {
30
+ throw new Error("[coolhand-proxy] a proxy is already starting — concurrent startProxy() calls are not supported");
31
+ }
32
+ patchInFlight = true;
33
+ const originalListen = net.Server.prototype.listen;
34
+ net.Server.prototype.listen = function (...args) {
35
+ // Only the (port[, callback]) shape needs a host injected — leave any
36
+ // other call shape (e.g. one that already specifies a host) untouched.
37
+ if (typeof args[0] === "number" && (args.length === 1 || typeof args[1] === "function")) {
38
+ args.splice(1, 0, LOOPBACK);
39
+ }
40
+ return originalListen.apply(this, args);
41
+ };
42
+ try {
43
+ await server.start(port ?? 0);
44
+ }
45
+ finally {
46
+ net.Server.prototype.listen = originalListen;
47
+ patchInFlight = false;
48
+ }
49
+ // Defense in depth: if a future mockttp release changes its internals such
50
+ // that the patch above silently no-ops, fail loudly here rather than run an
51
+ // open proxy unnoticed. Verification itself is best-effort — if it can't
52
+ // determine the bound host (e.g. the private field was renamed), skip the
53
+ // check rather than fail the whole command over an inability to double-check.
54
+ let boundHost;
55
+ try {
56
+ const internal = server.server;
57
+ const address = internal?.address();
58
+ boundHost = address && typeof address === "object" ? address.address : undefined;
59
+ }
60
+ catch {
61
+ return;
62
+ }
63
+ if (boundHost !== undefined && boundHost !== LOOPBACK) {
64
+ await server.stop().catch(() => undefined);
65
+ throw new Error(`[coolhand-proxy] refused to start: proxy bound to ${boundHost}, expected ${LOOPBACK}. ` +
66
+ `This likely means mockttp's internals changed in a way that broke the loopback-only fix — see coolhand-cli#119.`);
67
+ }
68
+ }
69
+ function redactBodyText(text) {
70
+ return text === undefined ? undefined : redactSecrets(text);
71
+ }
4
72
  /**
5
73
  * Start an HTTPS MITM proxy that intercepts LLM API calls
6
74
  * and forwards them to the Coolhand platform.
@@ -58,12 +126,12 @@ export async function startProxy(ca, options) {
58
126
  method: req.method,
59
127
  url: sanitizedUrl,
60
128
  headers: sanitizeHeaders(req.headers),
61
- body: requestBodyText,
129
+ body: redactBodyText(requestBodyText),
62
130
  },
63
131
  response: {
64
132
  statusCode: res.statusCode,
65
133
  headers: sanitizeHeaders(flattenHeaders(res.headers)),
66
- body: responseBodyText,
134
+ body: redactBodyText(responseBodyText),
67
135
  },
68
136
  timestamp: req.timestamp,
69
137
  };
@@ -86,7 +154,7 @@ export async function startProxy(ca, options) {
86
154
  });
87
155
  // Pass all requests through to their real destinations
88
156
  await server.forAnyRequest().thenPassThrough();
89
- await server.start(options.port ?? 0);
157
+ await startMockttpOnLoopback(server, options.port);
90
158
  const port = server.port;
91
159
  if (!options.silent) {
92
160
  console.error(`[coolhand-proxy] Proxy started on port ${port}`);
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/proxy/proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/proxy/proxy.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,12 @@
1
1
  import { spawn } from 'child_process';
2
2
  import { startProxy, type ProxyInstance } from './proxy.js';
3
3
  import { getOrCreateCA } from './certs.js';
4
+ import { resolveWrapSpawn } from '../win-spawn.js';
5
+ export { resolveWrapSpawn };
4
6
  export interface WrapDeps {
5
7
  spawnFn?: typeof spawn;
6
8
  startProxyFn?: (ca: Awaited<ReturnType<typeof getOrCreateCA>>, opts: Parameters<typeof startProxy>[1]) => Promise<ProxyInstance>;
7
9
  }
8
- export declare function resolveWrapSpawn(cmd: string, args: string[], platform?: NodeJS.Platform): {
9
- cmd: string;
10
- spawnArgs: string[];
11
- windowsVerbatimArguments?: true;
12
- };
13
10
  /**
14
11
  * Build the full ingest endpoint for a given client's base_url.
15
12
  * The CLI stores only the site base_url, so append the ingest path here.
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-runner.d.ts","sourceRoot":"","sources":["../../src/proxy/wrap-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAGxD,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAClI;AAsBD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,kBAAmB,GAC1B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,wBAAwB,CAAC,EAAE,IAAI,CAAA;CAAE,CAWvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiBtE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CA4FjB"}
1
+ {"version":3,"file":"wrap-runner.d.ts","sourceRoot":"","sources":["../../src/proxy/wrap-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAMtC,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAClI;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAiBtE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,MAAM,CAAC,CA4FjB"}
@@ -7,37 +7,8 @@ import { DEFAULT_BASE_URL } from '../types.js';
7
7
  import { startProxy } from './proxy.js';
8
8
  import { getOrCreateCA, getCertPath } from './certs.js';
9
9
  import { PACKAGE_IDENTIFIER } from '../version.js';
10
- /**
11
- * On Windows, .cmd shims cannot be spawned without a shell. Rather than using
12
- * shell:true (which forwards args as an unquoted string to cmd.exe, enabling
13
- * metacharacter injection), we invoke cmd.exe /d /s /c directly with the command
14
- * and each arg double-quoted and windowsVerbatimArguments:true so Node does not
15
- * re-quote them.
16
- *
17
- * Quoting rules applied to the command and every arg:
18
- * 1. Double trailing backslashes (a trailing \ would escape the closing ")
19
- * 2. Escape embedded " as ""
20
- * 3. Escape % as %% to prevent cmd.exe environment-variable expansion
21
- * 4. Wrap in double quotes unconditionally
22
- */
23
- function escapeForCmdExe(s) {
24
- return s
25
- .replace(/(\\+)$/, '$1$1') // double trailing backslashes
26
- .replace(/"/g, '""') // escape embedded quotes
27
- .replace(/%/g, '%%'); // prevent env-var expansion
28
- }
29
- export function resolveWrapSpawn(cmd, args, platform = process.platform) {
30
- if (platform !== 'win32') {
31
- return { cmd, spawnArgs: args };
32
- }
33
- const escapedCmd = `"${escapeForCmdExe(cmd)}"`;
34
- const escapedArgs = args.map((a) => `"${escapeForCmdExe(a)}"`);
35
- return {
36
- cmd: process.env['ComSpec'] ?? 'cmd.exe',
37
- spawnArgs: ['/d', '/s', '/c', [escapedCmd, ...escapedArgs].join(' ')],
38
- windowsVerbatimArguments: true,
39
- };
40
- }
10
+ import { resolveWrapSpawn } from '../win-spawn.js';
11
+ export { resolveWrapSpawn };
41
12
  /**
42
13
  * Build the full ingest endpoint for a given client's base_url.
43
14
  * The CLI stores only the site base_url, so append the ingest path here.
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-runner.js","sourceRoot":"","sources":["../../src/proxy/wrap-runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrap-runner.js","sourceRoot":"","sources":["../../src/proxy/wrap-runner.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"redact-secrets.d.ts","sourceRoot":"","sources":["../../src/sessions/redact-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqCH,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWlD"}
1
+ {"version":3,"file":"redact-secrets.d.ts","sourceRoot":"","sources":["../../src/sessions/redact-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAwCH,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWlD"}
@@ -24,6 +24,9 @@ const TOKEN_PATTERNS = [
24
24
  /sk_test_[0-9A-Za-z]{16,}/g, // Stripe test secret key
25
25
  /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, // JWT (three base64url segments)
26
26
  /\bBearer\s+[A-Za-z0-9._~+/-]{12,}=*/gi, // Authorization: Bearer <token>
27
+ /\bBasic\s+[A-Za-z0-9+/=]{8,}/gi, // Authorization: Basic <base64 user:pass>
28
+ /https:\/\/hooks\.slack\.com\/services\/\S+/g, // Slack incoming webhook URL
29
+ /https:\/\/discord(?:app)?\.com\/api\/webhooks\/\S+/g, // Discord webhook URL
27
30
  /\b[A-Fa-f0-9]{40,}\b/g, // long hex blobs (generic tokens / hashes)
28
31
  // PEM-formatted private key blocks (SSH/RSA/EC/OpenSSH/PGP/encrypted) — no assignment keyword
29
32
  // sits next to the base64 body, so ASSIGNMENT_QUOTED/BARE never catch these; a `cat ~/.ssh/id_rsa`
@@ -1 +1 @@
1
- {"version":3,"file":"redact-secrets.js","sourceRoot":"","sources":["../../src/sessions/redact-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uEAAuE;AACvE,MAAM,cAAc,GAAsB;IACxC,2BAA2B,EAAE,wBAAwB;IACrD,4BAA4B,EAAE,yBAAyB;IACvD,wBAAwB,EAAE,sCAAsC;IAChE,uBAAuB,EAAE,+BAA+B;IACxD,uBAAuB,EAAE,qBAAqB;IAC9C,+BAA+B,EAAE,0BAA0B;IAC3D,mBAAmB,EAAE,oBAAoB;IACzC,+BAA+B,EAAE,4CAA4C;IAC7E,wBAAwB,EAAE,iBAAiB;IAC3C,2BAA2B,EAAE,yBAAyB;IACtD,2BAA2B,EAAE,yBAAyB;IACtD,sDAAsD,EAAE,iCAAiC;IACzF,uCAAuC,EAAE,gCAAgC;IACzE,uBAAuB,EAAE,2CAA2C;IACpE,8FAA8F;IAC9F,mGAAmG;IACnG,iGAAiG;IACjG,uGAAuG;CACxG,CAAC;AAEF,6FAA6F;AAC7F,mGAAmG;AACnG,+FAA+F;AAC/F,oGAAoG;AACpG,qFAAqF;AACrF,yEAAyE;AACzE,MAAM,iBAAiB,GACrB,gHAAgH,CAAC;AACnH,MAAM,eAAe,GACnB,0GAA0G,CAAC;AAE7G,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,GAAG,IAAI;SACX,OAAO,CAAC,iBAAiB,EAAE,OAAO,QAAQ,IAAI,CAAC;SAC/C,OAAO,CAAC,eAAe,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"redact-secrets.js","sourceRoot":"","sources":["../../src/sessions/redact-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uEAAuE;AACvE,MAAM,cAAc,GAAsB;IACxC,2BAA2B,EAAE,wBAAwB;IACrD,4BAA4B,EAAE,yBAAyB;IACvD,wBAAwB,EAAE,sCAAsC;IAChE,uBAAuB,EAAE,+BAA+B;IACxD,uBAAuB,EAAE,qBAAqB;IAC9C,+BAA+B,EAAE,0BAA0B;IAC3D,mBAAmB,EAAE,oBAAoB;IACzC,+BAA+B,EAAE,4CAA4C;IAC7E,wBAAwB,EAAE,iBAAiB;IAC3C,2BAA2B,EAAE,yBAAyB;IACtD,2BAA2B,EAAE,yBAAyB;IACtD,sDAAsD,EAAE,iCAAiC;IACzF,uCAAuC,EAAE,gCAAgC;IACzE,gCAAgC,EAAE,0CAA0C;IAC5E,6CAA6C,EAAE,6BAA6B;IAC5E,qDAAqD,EAAE,sBAAsB;IAC7E,uBAAuB,EAAE,2CAA2C;IACpE,8FAA8F;IAC9F,mGAAmG;IACnG,iGAAiG;IACjG,uGAAuG;CACxG,CAAC;AAEF,6FAA6F;AAC7F,mGAAmG;AACnG,+FAA+F;AAC/F,oGAAoG;AACpG,qFAAqF;AACrF,yEAAyE;AACzE,MAAM,iBAAiB,GACrB,gHAAgH,CAAC;AACnH,MAAM,eAAe,GACnB,0GAA0G,CAAC;AAE7G,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,GAAG,IAAI;SACX,OAAO,CAAC,iBAAiB,EAAE,OAAO,QAAQ,IAAI,CAAC;SAC/C,OAAO,CAAC,eAAe,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,55 @@
1
+ /** Where a discovered SKILL.md was found, used both for display and for dedup priority
2
+ * (see `dedupeSkillFiles`) — an authored copy is preferred over an installed runtime copy of
3
+ * the same content. */
4
+ export type SkillSourceKind = 'authored' | 'installed' | 'claude-code' | 'custom';
5
+ export interface SkillRoot {
6
+ root: string;
7
+ sourceKind: SkillSourceKind;
8
+ }
9
+ export interface DiscoveredSkillFile {
10
+ filePath: string;
11
+ sourceKind: SkillSourceKind;
12
+ root: string;
13
+ mtimeMs: number;
14
+ contentHash: string;
15
+ skillName: string;
16
+ description?: string;
17
+ }
18
+ export interface SkillCandidate {
19
+ skillName: string;
20
+ contentHash: string;
21
+ /** The chosen canonical file to upload for this (skillName, contentHash) group. */
22
+ filePath: string;
23
+ sourceKind: SkillSourceKind;
24
+ root: string;
25
+ description?: string;
26
+ /** How many other on-disk copies (this file included) share this exact (skillName, contentHash). */
27
+ duplicateCount: number;
28
+ }
29
+ /**
30
+ * Extract `name:`/`description:` from a SKILL.md's YAML frontmatter block (`---\n...\n---` at
31
+ * the top of the file) with a small regex extractor rather than a YAML dependency — `js-yaml`
32
+ * is only an `overrides` pin in package.json (a transitive-dependency version pin), not a direct
33
+ * dependency, so parsing full YAML here would require adding one for a single flat key lookup.
34
+ * Values may be quoted or bare; quotes are stripped. Returns {} when there's no frontmatter block
35
+ * or it has no `name:`/`description:` field.
36
+ */
37
+ export declare function parseSkillFrontmatter(content: string): {
38
+ name?: string;
39
+ description?: string;
40
+ };
41
+ /**
42
+ * Discover SKILL.md files across every root, reading and hashing each one. A file that can't be
43
+ * read (permissions, a race with deletion, etc.) is skipped with a warning via `onWarn` rather
44
+ * than aborting the whole scan — same convention as `map-claude-projects`' directory walk.
45
+ */
46
+ export declare function findSkillFiles(roots: SkillRoot[], onWarn?: (message: string) => void): Promise<DiscoveredSkillFile[]>;
47
+ /**
48
+ * Group discovered files by `(skillName, contentHash)` — not skill name alone, so a genuinely
49
+ * edited authored copy is never silently squashed by a stale installed duplicate of the same
50
+ * name — and pick one canonical file per group to actually upload. Within a group, prefer
51
+ * (in order): `sourceKind` priority (authored > claude-code > installed > custom), then newest
52
+ * `mtimeMs`, then path ascending for a deterministic tie-break.
53
+ */
54
+ export declare function dedupeSkillFiles(files: DiscoveredSkillFile[]): SkillCandidate[];
55
+ //# sourceMappingURL=skill-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-scanner.d.ts","sourceRoot":"","sources":["../../src/skills/skill-scanner.ts"],"names":[],"mappings":"AAIA;;wBAEwB;AACxB,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;AAElF,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oGAAoG;IACpG,cAAc,EAAE,MAAM,CAAC;CACxB;AAuBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAgB9F;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,SAAS,EAAE,EAClB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAoChC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,cAAc,EAAE,CAqC/E"}