skill-distill 1.0.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.
@@ -0,0 +1,631 @@
1
+ import { z } from 'zod';
2
+
3
+ interface Message {
4
+ role: 'user' | 'assistant';
5
+ content: string;
6
+ timestamp: string;
7
+ toolCalls?: ToolCall[];
8
+ toolResults?: ToolResult[];
9
+ }
10
+ interface ToolCall {
11
+ name: string;
12
+ input: Record<string, unknown>;
13
+ }
14
+ interface ToolResult {
15
+ name: string;
16
+ output: string;
17
+ success: boolean;
18
+ }
19
+ interface Session {
20
+ id: string;
21
+ projectPath: string;
22
+ messages: Message[];
23
+ startTime: string;
24
+ endTime?: string;
25
+ metadata?: Record<string, unknown>;
26
+ }
27
+
28
+ interface SkillMetadata {
29
+ name: string;
30
+ description: string;
31
+ version: string;
32
+ license?: string;
33
+ }
34
+ interface SkillStep {
35
+ title: string;
36
+ description: string;
37
+ substeps?: string[];
38
+ }
39
+ interface SkillParameter {
40
+ name: string;
41
+ type: 'string' | 'boolean' | 'number';
42
+ default?: unknown;
43
+ description: string;
44
+ required: boolean;
45
+ }
46
+ interface Skill {
47
+ metadata: SkillMetadata;
48
+ overview: string;
49
+ triggers: string[];
50
+ prerequisites: string[];
51
+ steps: SkillStep[];
52
+ parameters: SkillParameter[];
53
+ errorHandling: Record<string, string>;
54
+ examples: string[];
55
+ notes?: string[];
56
+ references?: string[];
57
+ }
58
+
59
+ interface Config {
60
+ defaultPlatform: 'claude' | 'codex' | 'cursor';
61
+ apiKey?: string;
62
+ outputDir: string;
63
+ autoInstall: boolean;
64
+ sessionSources: {
65
+ claude?: string;
66
+ codex?: string;
67
+ cursor?: string;
68
+ };
69
+ }
70
+ interface DistillOptions {
71
+ sessionId?: string;
72
+ last?: boolean;
73
+ prompts?: string[];
74
+ format?: 'claude' | 'codex' | 'cursor' | 'all';
75
+ outputDir?: string;
76
+ install?: boolean;
77
+ interactive?: boolean;
78
+ }
79
+
80
+ declare const logger: {
81
+ info: (msg: string) => void;
82
+ success: (msg: string) => void;
83
+ warn: (msg: string) => void;
84
+ error: (msg: string) => void;
85
+ step: (msg: string) => void;
86
+ };
87
+
88
+ declare function expandHome(path: string): string;
89
+ declare function ensureDir(path: string): Promise<void>;
90
+ declare function fileExists(path: string): Promise<boolean>;
91
+ declare function readJson<T>(path: string): Promise<T>;
92
+ declare function writeJson(path: string, data: unknown): Promise<void>;
93
+
94
+ declare const SessionIdSchema: z.ZodString;
95
+ declare const PlatformSchema: z.ZodEnum<["claude", "codex", "cursor"]>;
96
+ declare const DistillOptionsSchema: z.ZodObject<{
97
+ sessionId: z.ZodOptional<z.ZodString>;
98
+ last: z.ZodOptional<z.ZodBoolean>;
99
+ prompts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
100
+ format: z.ZodOptional<z.ZodEnum<["claude", "codex", "cursor", "all"]>>;
101
+ outputDir: z.ZodOptional<z.ZodString>;
102
+ install: z.ZodOptional<z.ZodBoolean>;
103
+ interactive: z.ZodOptional<z.ZodBoolean>;
104
+ }, "strip", z.ZodTypeAny, {
105
+ sessionId?: string | undefined;
106
+ last?: boolean | undefined;
107
+ prompts?: string[] | undefined;
108
+ format?: "claude" | "codex" | "cursor" | "all" | undefined;
109
+ outputDir?: string | undefined;
110
+ install?: boolean | undefined;
111
+ interactive?: boolean | undefined;
112
+ }, {
113
+ sessionId?: string | undefined;
114
+ last?: boolean | undefined;
115
+ prompts?: string[] | undefined;
116
+ format?: "claude" | "codex" | "cursor" | "all" | undefined;
117
+ outputDir?: string | undefined;
118
+ install?: boolean | undefined;
119
+ interactive?: boolean | undefined;
120
+ }>;
121
+ declare function validateSessionId(id: unknown): string;
122
+ declare function validatePlatform(platform: unknown): 'claude' | 'codex' | 'cursor';
123
+
124
+ interface SessionInfo {
125
+ id: string;
126
+ projectPath: string;
127
+ startTime: string;
128
+ endTime?: string;
129
+ messageCount: number;
130
+ summary?: string;
131
+ }
132
+ interface SessionLoaderOptions {
133
+ basePath?: string;
134
+ projectPath?: string;
135
+ }
136
+ declare abstract class SessionLoader {
137
+ protected basePath: string;
138
+ protected projectPath?: string;
139
+ constructor(options?: SessionLoaderOptions);
140
+ abstract getDefaultBasePath(): string;
141
+ abstract listSessions(): Promise<SessionInfo[]>;
142
+ abstract getSession(id: string): Promise<Session>;
143
+ getLatestSession(): Promise<Session>;
144
+ searchSessions(query: string): Promise<SessionInfo[]>;
145
+ }
146
+
147
+ declare class ClaudeSessionLoader extends SessionLoader {
148
+ constructor(options?: SessionLoaderOptions);
149
+ getDefaultBasePath(): string;
150
+ listSessions(): Promise<SessionInfo[]>;
151
+ getSession(id: string): Promise<Session>;
152
+ private readSessionFile;
153
+ private transformSession;
154
+ private transformMessage;
155
+ private extractSummary;
156
+ }
157
+
158
+ declare class CodexSessionLoader extends SessionLoader {
159
+ getDefaultBasePath(): string;
160
+ listSessions(): Promise<SessionInfo[]>;
161
+ getSession(_id: string): Promise<Session>;
162
+ }
163
+
164
+ declare class CursorSessionLoader extends SessionLoader {
165
+ getDefaultBasePath(): string;
166
+ listSessions(): Promise<SessionInfo[]>;
167
+ getSession(_id: string): Promise<Session>;
168
+ }
169
+
170
+ type Platform = 'claude' | 'codex' | 'cursor';
171
+ declare function createSessionLoader(platform: Platform, options?: SessionLoaderOptions): SessionLoader;
172
+
173
+ declare const IntentSchema: z.ZodObject<{
174
+ goal: z.ZodString;
175
+ problem: z.ZodString;
176
+ outcome: z.ZodString;
177
+ triggers: z.ZodArray<z.ZodString, "many">;
178
+ category: z.ZodString;
179
+ }, "strip", z.ZodTypeAny, {
180
+ goal: string;
181
+ problem: string;
182
+ outcome: string;
183
+ triggers: string[];
184
+ category: string;
185
+ }, {
186
+ goal: string;
187
+ problem: string;
188
+ outcome: string;
189
+ triggers: string[];
190
+ category: string;
191
+ }>;
192
+ declare const StepSchema: z.ZodObject<{
193
+ title: z.ZodString;
194
+ description: z.ZodString;
195
+ substeps: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
196
+ isKeyStep: z.ZodBoolean;
197
+ toolsUsed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
198
+ }, "strip", z.ZodTypeAny, {
199
+ title: string;
200
+ description: string;
201
+ isKeyStep: boolean;
202
+ substeps?: string[] | undefined;
203
+ toolsUsed?: string[] | undefined;
204
+ }, {
205
+ title: string;
206
+ description: string;
207
+ isKeyStep: boolean;
208
+ substeps?: string[] | undefined;
209
+ toolsUsed?: string[] | undefined;
210
+ }>;
211
+ declare const StepsResultSchema: z.ZodObject<{
212
+ steps: z.ZodArray<z.ZodObject<{
213
+ title: z.ZodString;
214
+ description: z.ZodString;
215
+ substeps: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
216
+ isKeyStep: z.ZodBoolean;
217
+ toolsUsed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
218
+ }, "strip", z.ZodTypeAny, {
219
+ title: string;
220
+ description: string;
221
+ isKeyStep: boolean;
222
+ substeps?: string[] | undefined;
223
+ toolsUsed?: string[] | undefined;
224
+ }, {
225
+ title: string;
226
+ description: string;
227
+ isKeyStep: boolean;
228
+ substeps?: string[] | undefined;
229
+ toolsUsed?: string[] | undefined;
230
+ }>, "many">;
231
+ parameters: z.ZodArray<z.ZodObject<{
232
+ name: z.ZodString;
233
+ type: z.ZodEnum<["string", "boolean", "number"]>;
234
+ description: z.ZodString;
235
+ defaultValue: z.ZodOptional<z.ZodUnknown>;
236
+ }, "strip", z.ZodTypeAny, {
237
+ type: "string" | "number" | "boolean";
238
+ description: string;
239
+ name: string;
240
+ defaultValue?: unknown;
241
+ }, {
242
+ type: "string" | "number" | "boolean";
243
+ description: string;
244
+ name: string;
245
+ defaultValue?: unknown;
246
+ }>, "many">;
247
+ prerequisites: z.ZodArray<z.ZodString, "many">;
248
+ errorHandling: z.ZodRecord<z.ZodString, z.ZodString>;
249
+ }, "strip", z.ZodTypeAny, {
250
+ steps: {
251
+ title: string;
252
+ description: string;
253
+ isKeyStep: boolean;
254
+ substeps?: string[] | undefined;
255
+ toolsUsed?: string[] | undefined;
256
+ }[];
257
+ parameters: {
258
+ type: "string" | "number" | "boolean";
259
+ description: string;
260
+ name: string;
261
+ defaultValue?: unknown;
262
+ }[];
263
+ prerequisites: string[];
264
+ errorHandling: Record<string, string>;
265
+ }, {
266
+ steps: {
267
+ title: string;
268
+ description: string;
269
+ isKeyStep: boolean;
270
+ substeps?: string[] | undefined;
271
+ toolsUsed?: string[] | undefined;
272
+ }[];
273
+ parameters: {
274
+ type: "string" | "number" | "boolean";
275
+ description: string;
276
+ name: string;
277
+ defaultValue?: unknown;
278
+ }[];
279
+ prerequisites: string[];
280
+ errorHandling: Record<string, string>;
281
+ }>;
282
+ type Intent = z.infer<typeof IntentSchema>;
283
+ type DistilledStep = z.infer<typeof StepSchema>;
284
+ type StepsResult = z.infer<typeof StepsResultSchema>;
285
+ interface LLMEngineOptions {
286
+ apiKey?: string;
287
+ model?: string;
288
+ maxTokens?: number;
289
+ }
290
+ interface TokenUsage {
291
+ inputTokens: number;
292
+ outputTokens: number;
293
+ }
294
+ declare class LLMEngine {
295
+ private client;
296
+ private model;
297
+ private maxTokens;
298
+ private totalUsage;
299
+ constructor(options?: LLMEngineOptions);
300
+ extractIntent(session: Session): Promise<Intent>;
301
+ distillSteps(session: Session, intent: Intent, userPrompts?: string[]): Promise<StepsResult>;
302
+ enhanceQuality(skill: Partial<Skill>): Promise<Skill>;
303
+ generateDescription(intent: Intent): Promise<string>;
304
+ chat(prompt: string, system?: string): Promise<string>;
305
+ getTokenUsage(): TokenUsage;
306
+ private formatConversation;
307
+ private parseJson;
308
+ private withRetry;
309
+ private sleep;
310
+ }
311
+
312
+ interface DistillerOptions {
313
+ userPrompts?: string[];
314
+ skipFailedFilter?: boolean;
315
+ verbose?: boolean;
316
+ }
317
+ interface DistillResult {
318
+ skill: Skill;
319
+ metadata: {
320
+ sessionId: string;
321
+ distilledAt: string;
322
+ tokenUsage: {
323
+ input: number;
324
+ output: number;
325
+ };
326
+ stepsFiltered: number;
327
+ };
328
+ }
329
+ declare class Distiller {
330
+ private llmEngine;
331
+ private preprocessor;
332
+ private failedFilter;
333
+ private parameterExtractor;
334
+ constructor(llmEngine?: LLMEngine);
335
+ distill(session: Session, options?: DistillerOptions): Promise<DistillResult>;
336
+ private convertParameters;
337
+ private assembleSkill;
338
+ private generateName;
339
+ private generateExamples;
340
+ }
341
+
342
+ interface ProcessedMessage extends Message {
343
+ turnIndex: number;
344
+ hasToolCalls: boolean;
345
+ hasCodeBlocks: boolean;
346
+ codeBlocks: string[];
347
+ sentiment: 'positive' | 'negative' | 'neutral';
348
+ }
349
+ interface PreprocessResult {
350
+ messages: ProcessedMessage[];
351
+ totalTurns: number;
352
+ toolCallCount: number;
353
+ }
354
+ declare class ConversationPreprocessor {
355
+ private positiveSignals;
356
+ private negativeSignals;
357
+ process(messages: Message[]): PreprocessResult;
358
+ private extractCodeBlocks;
359
+ private analyzeSentiment;
360
+ }
361
+
362
+ interface FilterResult {
363
+ messages: ProcessedMessage[];
364
+ removedCount: number;
365
+ removedTurns: number[];
366
+ }
367
+ declare class FailedAttemptFilter {
368
+ private failureIndicators;
369
+ filter(messages: ProcessedMessage[]): FilterResult;
370
+ private identifyFailedTurns;
371
+ private hasFailureSignal;
372
+ }
373
+
374
+ interface ExtractResult {
375
+ steps: SkillStep[];
376
+ parameters: SkillParameter[];
377
+ }
378
+ declare class ParameterExtractor {
379
+ private patterns;
380
+ extract(steps: DistilledStep[], existingParams: SkillParameter[]): ExtractResult;
381
+ private generateParamName;
382
+ }
383
+
384
+ type PromptType = 'focus' | 'constraint' | 'supplement' | 'style' | 'exclude';
385
+ interface ClassifiedPrompt {
386
+ original: string;
387
+ type: PromptType;
388
+ keywords: string[];
389
+ target?: string;
390
+ action?: string;
391
+ }
392
+ interface PromptEffect {
393
+ stepWeights?: Map<string, number>;
394
+ additionalPrerequisites?: string[];
395
+ stepEnrichments?: Map<string, string[]>;
396
+ verbosityLevel?: 'minimal' | 'standard' | 'detailed';
397
+ excludePatterns?: string[];
398
+ }
399
+
400
+ interface PromptHandlerOptions {
401
+ language?: 'en' | 'zh';
402
+ }
403
+ declare class PromptHandler {
404
+ private classifier;
405
+ private fuser;
406
+ constructor(options?: PromptHandlerOptions);
407
+ process(prompts: string[]): PromptEffect;
408
+ classify(prompt: string): ClassifiedPrompt;
409
+ toPromptText(prompts: string[]): string;
410
+ }
411
+
412
+ declare class PromptClassifier {
413
+ private language;
414
+ private patterns;
415
+ constructor(language?: 'en' | 'zh');
416
+ classify(prompt: string): ClassifiedPrompt;
417
+ private extractTarget;
418
+ }
419
+
420
+ declare class PromptFuser {
421
+ fuse(prompts: ClassifiedPrompt[]): PromptEffect;
422
+ private applyFocus;
423
+ private applyConstraint;
424
+ private applySupplement;
425
+ private applyStyle;
426
+ private applyExclude;
427
+ }
428
+
429
+ interface CollectedPrompts {
430
+ prompts: string[];
431
+ confirmed: boolean;
432
+ }
433
+ declare function collectPromptsInteractively(): Promise<CollectedPrompts>;
434
+ declare function selectPromptsFromSuggestions(suggestions: string[]): Promise<string[]>;
435
+
436
+ interface ValidationError {
437
+ field: string;
438
+ message: string;
439
+ severity: 'error' | 'warning';
440
+ }
441
+ interface ValidationResult {
442
+ valid: boolean;
443
+ errors: ValidationError[];
444
+ warnings: ValidationError[];
445
+ }
446
+ declare class TemplateValidator {
447
+ validate(content: string, skill: Skill): ValidationResult;
448
+ private validateFrontmatter;
449
+ private validateRequiredSections;
450
+ private validateWritingStyle;
451
+ private validateLength;
452
+ }
453
+
454
+ interface GenerateOptions {
455
+ outputDir: string;
456
+ overwrite?: boolean;
457
+ includeReferences?: boolean;
458
+ includeExamples?: boolean;
459
+ }
460
+ interface GenerateResult {
461
+ skillPath: string;
462
+ files: string[];
463
+ validation: ValidationResult;
464
+ }
465
+ declare class SkillGenerator {
466
+ private frontmatterBuilder;
467
+ private markdownRenderer;
468
+ private directoryBuilder;
469
+ private validator;
470
+ constructor();
471
+ generate(skill: Skill, options: GenerateOptions): Promise<GenerateResult>;
472
+ renderSkill(skill: Skill): string;
473
+ private generateReferences;
474
+ private toKebabCase;
475
+ private exists;
476
+ }
477
+
478
+ declare class FrontmatterBuilder {
479
+ build(metadata: SkillMetadata): string;
480
+ validateDescription(description: string): boolean;
481
+ }
482
+
483
+ declare class MarkdownRenderer {
484
+ renderTitle(name: string): string;
485
+ renderOverview(overview: string): string;
486
+ renderTriggers(triggers: string[]): string;
487
+ renderPrerequisites(prerequisites: string[]): string;
488
+ renderSteps(steps: SkillStep[]): string;
489
+ renderParameters(parameters: SkillParameter[]): string;
490
+ renderErrorHandling(errorHandling: Record<string, string>): string;
491
+ renderExamples(examples: string[]): string;
492
+ renderReferences(references: string[]): string;
493
+ renderNotes(notes: string[]): string;
494
+ }
495
+
496
+ interface DirectoryOptions {
497
+ includeReferences: boolean;
498
+ includeExamples: boolean;
499
+ includeScripts: boolean;
500
+ }
501
+ declare class DirectoryBuilder {
502
+ create(basePath: string, options?: Partial<DirectoryOptions>): Promise<void>;
503
+ listStructure(basePath: string): Promise<string[]>;
504
+ }
505
+
506
+ interface ConvertOptions {
507
+ includeMetadata?: boolean;
508
+ includeExamples?: boolean;
509
+ verbose?: boolean;
510
+ }
511
+ declare class ClaudeFormatter {
512
+ format(skill: Skill, options?: ConvertOptions): string;
513
+ private formatFrontmatter;
514
+ private formatTriggers;
515
+ private formatPrerequisites;
516
+ private formatSteps;
517
+ private formatParameters;
518
+ private formatErrorHandling;
519
+ private formatExamples;
520
+ private formatNotes;
521
+ }
522
+
523
+ type OutputFormat = 'claude' | 'codex' | 'cursor';
524
+
525
+ declare class FormatConverter {
526
+ private claudeFormatter;
527
+ private codexFormatter;
528
+ private cursorFormatter;
529
+ constructor();
530
+ convert(skill: Skill, format: OutputFormat, options?: ConvertOptions): string;
531
+ convertAll(skill: Skill, options?: ConvertOptions): Map<OutputFormat, string>;
532
+ toClaudeFormat(skill: Skill, options?: ConvertOptions): string;
533
+ toCodexFormat(skill: Skill, options?: ConvertOptions): string;
534
+ toCursorFormat(skill: Skill, options?: ConvertOptions): string;
535
+ }
536
+
537
+ declare class CodexFormatter {
538
+ format(skill: Skill, _options?: ConvertOptions): string;
539
+ private formatFrontmatter;
540
+ private toKebabCase;
541
+ }
542
+
543
+ declare class CursorFormatter {
544
+ format(skill: Skill, _options?: ConvertOptions): string;
545
+ }
546
+
547
+ interface FormatValidation {
548
+ valid: boolean;
549
+ format: string;
550
+ errors: string[];
551
+ warnings: string[];
552
+ }
553
+ declare class FormatValidator {
554
+ validateClaude(content: string): FormatValidation;
555
+ validateCodex(content: string): FormatValidation;
556
+ validateCursor(content: string): FormatValidation;
557
+ }
558
+
559
+ interface InstallOptions {
560
+ overwrite?: boolean;
561
+ backup?: boolean;
562
+ verify?: boolean;
563
+ }
564
+ interface InstallResult {
565
+ success: boolean;
566
+ path: string;
567
+ message: string;
568
+ backupPath?: string;
569
+ }
570
+ interface InstalledSkill {
571
+ name: string;
572
+ path: string;
573
+ version: string;
574
+ installedAt: string;
575
+ }
576
+ declare abstract class AgentInstaller {
577
+ protected basePath: string;
578
+ constructor(basePath?: string);
579
+ abstract getDefaultBasePath(): string;
580
+ abstract getPlatformName(): string;
581
+ abstract install(skill: Skill, options?: InstallOptions): Promise<InstallResult>;
582
+ abstract uninstall(skillName: string): Promise<void>;
583
+ abstract list(): Promise<InstalledSkill[]>;
584
+ verify(skillName: string): Promise<boolean>;
585
+ }
586
+
587
+ declare class ClaudeCodeInstaller extends AgentInstaller {
588
+ private generator;
589
+ constructor(basePath?: string);
590
+ getDefaultBasePath(): string;
591
+ getPlatformName(): string;
592
+ install(skill: Skill, options?: InstallOptions): Promise<InstallResult>;
593
+ uninstall(skillName: string): Promise<void>;
594
+ list(): Promise<InstalledSkill[]>;
595
+ private verifyInstallation;
596
+ private parseMetadata;
597
+ private toKebabCase;
598
+ }
599
+
600
+ declare class CodexInstaller extends AgentInstaller {
601
+ private converter;
602
+ constructor(basePath?: string);
603
+ getDefaultBasePath(): string;
604
+ getPlatformName(): string;
605
+ install(skill: Skill, options?: InstallOptions): Promise<InstallResult>;
606
+ uninstall(skillName: string): Promise<void>;
607
+ list(): Promise<InstalledSkill[]>;
608
+ private toKebabCase;
609
+ }
610
+
611
+ declare class CursorInstaller extends AgentInstaller {
612
+ private converter;
613
+ private projectPath;
614
+ constructor(projectPath: string);
615
+ getDefaultBasePath(): string;
616
+ getPlatformName(): string;
617
+ install(skill: Skill, options?: InstallOptions): Promise<InstallResult>;
618
+ uninstall(_skillName: string): Promise<void>;
619
+ list(): Promise<InstalledSkill[]>;
620
+ }
621
+
622
+ type InstallerPlatform = 'claude' | 'codex' | 'cursor';
623
+ interface InstallerOptions {
624
+ basePath?: string;
625
+ projectPath?: string;
626
+ }
627
+ declare function createInstaller(platform: InstallerPlatform, options?: InstallerOptions): AgentInstaller;
628
+
629
+ declare const VERSION = "0.1.0";
630
+
631
+ export { AgentInstaller, type ClassifiedPrompt, ClaudeCodeInstaller, ClaudeFormatter, ClaudeSessionLoader, CodexFormatter, CodexInstaller, CodexSessionLoader, type CollectedPrompts, type Config, ConversationPreprocessor, type ConvertOptions, CursorFormatter, CursorInstaller, CursorSessionLoader, DirectoryBuilder, type DirectoryOptions, type DistillOptions, DistillOptionsSchema, type DistillResult, type DistilledStep, Distiller, type DistillerOptions, FailedAttemptFilter, type FilterResult, FormatConverter, type FormatValidation, FormatValidator, FrontmatterBuilder, type GenerateOptions, type GenerateResult, type InstallOptions, type InstallResult, type InstalledSkill, type InstallerOptions, type InstallerPlatform, type Intent, LLMEngine, MarkdownRenderer, type Message, type OutputFormat, ParameterExtractor, type Platform, PlatformSchema, type PreprocessResult, type ProcessedMessage, PromptClassifier, type PromptEffect, PromptFuser, PromptHandler, type PromptHandlerOptions, type PromptType, type Session, SessionIdSchema, type SessionInfo, SessionLoader, type SessionLoaderOptions, type Skill, SkillGenerator, type SkillMetadata, type SkillParameter, type SkillStep, type StepsResult, TemplateValidator, type ToolCall, type ToolResult, VERSION, type ValidationError, type ValidationResult, collectPromptsInteractively, createInstaller, createSessionLoader, ensureDir, expandHome, fileExists, logger, readJson, selectPromptsFromSuggestions, validatePlatform, validateSessionId, writeJson };