@drewpayment/mink 0.1.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 (72) hide show
  1. package/README.md +347 -0
  2. package/package.json +32 -0
  3. package/src/cli.ts +176 -0
  4. package/src/commands/bug-search.ts +32 -0
  5. package/src/commands/config.ts +109 -0
  6. package/src/commands/cron.ts +295 -0
  7. package/src/commands/daemon.ts +46 -0
  8. package/src/commands/dashboard.ts +21 -0
  9. package/src/commands/designqc.ts +160 -0
  10. package/src/commands/detect-waste.ts +81 -0
  11. package/src/commands/framework-advisor.ts +52 -0
  12. package/src/commands/init.ts +159 -0
  13. package/src/commands/post-read.ts +123 -0
  14. package/src/commands/post-write.ts +157 -0
  15. package/src/commands/pre-read.ts +109 -0
  16. package/src/commands/pre-write.ts +136 -0
  17. package/src/commands/reflect.ts +39 -0
  18. package/src/commands/restore.ts +31 -0
  19. package/src/commands/scan.ts +101 -0
  20. package/src/commands/session-start.ts +21 -0
  21. package/src/commands/session-stop.ts +115 -0
  22. package/src/commands/status.ts +152 -0
  23. package/src/commands/update.ts +121 -0
  24. package/src/core/action-log.ts +341 -0
  25. package/src/core/backup.ts +122 -0
  26. package/src/core/bug-memory.ts +223 -0
  27. package/src/core/cron-parser.ts +94 -0
  28. package/src/core/daemon.ts +152 -0
  29. package/src/core/dashboard-api.ts +280 -0
  30. package/src/core/dashboard-server.ts +580 -0
  31. package/src/core/description.ts +232 -0
  32. package/src/core/design-eval/capture.ts +269 -0
  33. package/src/core/design-eval/route-detect.ts +165 -0
  34. package/src/core/design-eval/server-detect.ts +91 -0
  35. package/src/core/framework-advisor/catalog.ts +360 -0
  36. package/src/core/framework-advisor/decision-tree.ts +287 -0
  37. package/src/core/framework-advisor/generate.ts +132 -0
  38. package/src/core/framework-advisor/migration-prompts.ts +502 -0
  39. package/src/core/framework-advisor/validate.ts +137 -0
  40. package/src/core/fs-utils.ts +30 -0
  41. package/src/core/global-config.ts +74 -0
  42. package/src/core/index-store.ts +72 -0
  43. package/src/core/learning-memory.ts +120 -0
  44. package/src/core/paths.ts +86 -0
  45. package/src/core/pattern-engine.ts +108 -0
  46. package/src/core/project-id.ts +19 -0
  47. package/src/core/project-registry.ts +64 -0
  48. package/src/core/reflection.ts +256 -0
  49. package/src/core/scanner.ts +99 -0
  50. package/src/core/scheduler.ts +352 -0
  51. package/src/core/seed.ts +239 -0
  52. package/src/core/session.ts +128 -0
  53. package/src/core/stdin.ts +13 -0
  54. package/src/core/task-registry.ts +202 -0
  55. package/src/core/token-estimate.ts +36 -0
  56. package/src/core/token-ledger.ts +185 -0
  57. package/src/core/waste-detection.ts +214 -0
  58. package/src/core/write-exclusions.ts +24 -0
  59. package/src/types/action-log.ts +20 -0
  60. package/src/types/backup.ts +6 -0
  61. package/src/types/bug-memory.ts +24 -0
  62. package/src/types/config.ts +59 -0
  63. package/src/types/dashboard.ts +104 -0
  64. package/src/types/design-eval.ts +64 -0
  65. package/src/types/file-index.ts +38 -0
  66. package/src/types/framework-advisor.ts +97 -0
  67. package/src/types/hook-input.ts +27 -0
  68. package/src/types/learning-memory.ts +36 -0
  69. package/src/types/scheduler.ts +82 -0
  70. package/src/types/session.ts +50 -0
  71. package/src/types/token-ledger.ts +43 -0
  72. package/src/types/waste-detection.ts +21 -0
@@ -0,0 +1,64 @@
1
+ // ── Design Evaluation Types (Spec 13) ─────────────────────────────────────
2
+
3
+ export interface Viewport {
4
+ name: "desktop" | "mobile";
5
+ width: number;
6
+ height: number;
7
+ }
8
+
9
+ export interface DesignQcOptions {
10
+ url?: string;
11
+ routes?: string[];
12
+ quality: number;
13
+ desktopOnly: boolean;
14
+ maxSections: number;
15
+ }
16
+
17
+ export interface CaptureResult {
18
+ route: string;
19
+ viewport: string;
20
+ section: number;
21
+ totalSections: number;
22
+ filePath: string;
23
+ fileName: string;
24
+ fileSize: number;
25
+ pageHeight: number;
26
+ statusCode: number;
27
+ timestamp: string;
28
+ }
29
+
30
+ export interface DesignEvalReport {
31
+ capturedAt: string;
32
+ serverUrl: string;
33
+ routes: string[];
34
+ viewports: Viewport[];
35
+ quality: number;
36
+ captures: CaptureResult[];
37
+ errors: Array<{ route: string; viewport: string; error: string }>;
38
+ }
39
+
40
+ // ── Defaults ──────────────────────────────────────────────────────────────
41
+
42
+ export const DEFAULT_VIEWPORTS: Viewport[] = [
43
+ { name: "desktop", width: 1440, height: 900 },
44
+ { name: "mobile", width: 375, height: 812 },
45
+ ];
46
+
47
+ export const DEFAULT_QUALITY = 70;
48
+ export const DEFAULT_MAX_SECTIONS = 8;
49
+
50
+ export const DEFAULT_PROBE_PORTS = [
51
+ 3000, 3001, 4000, 5000, 5173, 8000, 8080,
52
+ ];
53
+
54
+ // ── Type Guard ────────────────────────────────────────────────────────────
55
+
56
+ export function isDesignEvalReport(v: unknown): v is DesignEvalReport {
57
+ return (
58
+ typeof v === "object" &&
59
+ v !== null &&
60
+ "capturedAt" in v &&
61
+ "captures" in v &&
62
+ Array.isArray((v as DesignEvalReport).captures)
63
+ );
64
+ }
@@ -0,0 +1,38 @@
1
+ export interface FileIndexHeader {
2
+ lastScanTimestamp: string;
3
+ totalFiles: number;
4
+ lifetimeHits: number;
5
+ lifetimeMisses: number;
6
+ }
7
+
8
+ export interface FileIndexEntry {
9
+ filePath: string;
10
+ description: string;
11
+ estimatedTokens: number;
12
+ lastModified: string;
13
+ lastIndexed: string;
14
+ }
15
+
16
+ export interface FileIndex {
17
+ header: FileIndexHeader;
18
+ entries: Record<string, FileIndexEntry>;
19
+ }
20
+
21
+ export interface ProjectConfig {
22
+ excludePatterns?: string[];
23
+ maxFiles?: number;
24
+ learningMemoryTokenBudget?: number;
25
+ actionLogMaxEntries?: number;
26
+ actionLogRetentionDays?: number;
27
+ }
28
+
29
+ export interface StalenessReport {
30
+ missingFromIndex: string[];
31
+ orphanedEntries: string[];
32
+ isStale: boolean;
33
+ }
34
+
35
+ export interface ScannedFile {
36
+ relativePath: string;
37
+ mtimeMs: number;
38
+ }
@@ -0,0 +1,97 @@
1
+ // ── Framework Advisor Types (Spec 14) ─────────────────────────────────────
2
+
3
+ export type CssApproach =
4
+ | "utility-first"
5
+ | "css-in-js"
6
+ | "css-modules"
7
+ | "scoped"
8
+ | "traditional"
9
+ | "hybrid";
10
+
11
+ export type BundleSize = "tiny" | "small" | "medium" | "large";
12
+
13
+ export type LearningCurve = "low" | "moderate" | "steep";
14
+
15
+ export type AccessibilityRating = "basic" | "good" | "excellent";
16
+
17
+ export type TypescriptSupport = "native" | "supported" | "limited";
18
+
19
+ export interface FrameworkEntry {
20
+ id: string;
21
+ name: string;
22
+ description: string;
23
+ cssApproach: CssApproach;
24
+ darkModeSupport: boolean;
25
+ accessibilityRating: AccessibilityRating;
26
+ bundleSize: BundleSize;
27
+ learningCurve: LearningCurve;
28
+ typescriptSupport: TypescriptSupport;
29
+ designTokens: boolean;
30
+ ecosystem: string;
31
+ bestFor: string[];
32
+ limitations: string[];
33
+ officialUrl: string;
34
+ }
35
+
36
+ export interface DecisionTreeOption {
37
+ label: string;
38
+ value: string;
39
+ nextNodeId: string | null;
40
+ recommends?: string[];
41
+ }
42
+
43
+ export interface DecisionTreeNode {
44
+ id: string;
45
+ question: string;
46
+ options: DecisionTreeOption[];
47
+ }
48
+
49
+ export const MIGRATION_SECTION_KEYS = [
50
+ "install",
51
+ "configure",
52
+ "migrate-components",
53
+ "migrate-styles",
54
+ "gotchas",
55
+ "verification",
56
+ ] as const;
57
+
58
+ export type MigrationSectionKey = (typeof MIGRATION_SECTION_KEYS)[number];
59
+
60
+ export interface MigrationPromptSection {
61
+ key: MigrationSectionKey;
62
+ content: string;
63
+ }
64
+
65
+ export interface MigrationPrompt {
66
+ frameworkId: string;
67
+ sections: MigrationPromptSection[];
68
+ }
69
+
70
+ export interface FrameworkAdvisorKnowledge {
71
+ version: string;
72
+ generatedAt: string;
73
+ frameworks: FrameworkEntry[];
74
+ decisionTree: DecisionTreeNode[];
75
+ migrationPrompts: MigrationPrompt[];
76
+ }
77
+
78
+ export interface ValidationResult {
79
+ valid: boolean;
80
+ errors: string[];
81
+ }
82
+
83
+ // ── Type Guard ────────────────────────────────────────────────────────────
84
+
85
+ export function isFrameworkAdvisorKnowledge(
86
+ v: unknown
87
+ ): v is FrameworkAdvisorKnowledge {
88
+ return (
89
+ typeof v === "object" &&
90
+ v !== null &&
91
+ "version" in v &&
92
+ "frameworks" in v &&
93
+ "decisionTree" in v &&
94
+ "migrationPrompts" in v &&
95
+ Array.isArray((v as FrameworkAdvisorKnowledge).frameworks)
96
+ );
97
+ }
@@ -0,0 +1,27 @@
1
+ export interface PreToolUseInput {
2
+ tool_name: string;
3
+ tool_input: {
4
+ file_path?: string;
5
+ // Write tool
6
+ content?: string;
7
+ // Edit tool
8
+ old_string?: string;
9
+ new_string?: string;
10
+ };
11
+ }
12
+
13
+ export interface PostToolUseInput {
14
+ tool_name: string;
15
+ tool_input: {
16
+ file_path?: string;
17
+ // Write tool
18
+ content?: string;
19
+ // Edit tool
20
+ old_string?: string;
21
+ new_string?: string;
22
+ };
23
+ tool_output?: {
24
+ content?: string;
25
+ [key: string]: unknown;
26
+ };
27
+ }
@@ -0,0 +1,36 @@
1
+ export type SectionName =
2
+ | "User Preferences"
3
+ | "Key Learnings"
4
+ | "Do-Not-Repeat"
5
+ | "Decision Log";
6
+
7
+ export interface LearningMemory {
8
+ projectName: string;
9
+ sections: Record<SectionName, string[]>;
10
+ }
11
+
12
+ export interface ExtractedPattern {
13
+ type: "literal" | "word-boundary";
14
+ pattern: string;
15
+ sourceEntry: string;
16
+ }
17
+
18
+ export interface PatternMatch {
19
+ pattern: ExtractedPattern;
20
+ matchedText: string;
21
+ index: number;
22
+ }
23
+
24
+ export interface ReflectionResult {
25
+ beforeTokens: number;
26
+ afterTokens: number;
27
+ mergedCount: number;
28
+ trimmedCount: number;
29
+ withinBudget: boolean;
30
+ }
31
+
32
+ export interface SeedInfo {
33
+ projectName: string;
34
+ description: string;
35
+ frameworks: string[];
36
+ }
@@ -0,0 +1,82 @@
1
+ // ── Cron ────────────────────────────────────────────────────────────────────
2
+
3
+ export interface CronSchedule {
4
+ minute: number[]; // 0-59
5
+ hour: number[]; // 0-23
6
+ dayOfMonth: number[]; // 1-31
7
+ month: number[]; // 1-12
8
+ dayOfWeek: number[]; // 0-6 (0=Sunday)
9
+ }
10
+
11
+ // ── Task Definition ─────────────────────────────────────────────────────────
12
+
13
+ export type ActionType = "function" | "ai-cli";
14
+
15
+ export type TaskStatus = "idle" | "running" | "retrying" | "dead-lettered";
16
+
17
+ export interface RetryPolicy {
18
+ maxAttempts: number;
19
+ baseDelayMs: number;
20
+ }
21
+
22
+ export interface TaskDefinition {
23
+ id: string;
24
+ name: string;
25
+ description: string;
26
+ schedule: string;
27
+ actionType: ActionType;
28
+ enabled: boolean;
29
+ retryPolicy: RetryPolicy;
30
+ timeoutMs: number;
31
+ }
32
+
33
+ // ── Task Execution State ────────────────────────────────────────────────────
34
+
35
+ export interface TaskRunRecord {
36
+ taskId: string;
37
+ lastRunAt: string | null;
38
+ lastSuccessAt: string | null;
39
+ lastFailureAt: string | null;
40
+ nextRunAt: string;
41
+ status: TaskStatus;
42
+ consecutiveFailures: number;
43
+ currentAttempt: number;
44
+ }
45
+
46
+ // ── Dead Letter ─────────────────────────────────────────────────────────────
47
+
48
+ export interface DeadLetterEntry {
49
+ taskId: string;
50
+ deadLetteredAt: string;
51
+ failureTimestamps: string[];
52
+ errorMessages: string[];
53
+ attemptCount: number;
54
+ }
55
+
56
+ // ── Health ───────────────────────────────────────────────────────────────────
57
+
58
+ export interface HealthStatus {
59
+ pid: number;
60
+ startedAt: string;
61
+ lastHeartbeatAt: string;
62
+ uptimeMs: number;
63
+ activeTasks: string[];
64
+ deadLetterCount: number;
65
+ taskCount: number;
66
+ }
67
+
68
+ // ── Scheduler Manifest (persisted state) ────────────────────────────────────
69
+
70
+ export interface SchedulerManifest {
71
+ tasks: TaskRunRecord[];
72
+ deadLetterQueue: DeadLetterEntry[];
73
+ lastHeartbeat: string;
74
+ }
75
+
76
+ // ── PID File ────────────────────────────────────────────────────────────────
77
+
78
+ export interface PidFileData {
79
+ pid: number;
80
+ startedAt: string;
81
+ projectCwd: string;
82
+ }
@@ -0,0 +1,50 @@
1
+ export interface FileRead {
2
+ readCount: number;
3
+ estimatedTokens: number;
4
+ firstReadAt: string; // ISO 8601 UTC
5
+ }
6
+
7
+ export interface WriteEntry {
8
+ filePath: string;
9
+ action: "create" | "edit";
10
+ estimatedTokens: number;
11
+ timestamp: string; // ISO 8601 UTC
12
+ }
13
+
14
+ export interface SessionCounters {
15
+ fileIndexHits: number;
16
+ fileIndexMisses: number;
17
+ repeatedReadWarnings: number;
18
+ learnedRuleWarnings: number;
19
+ }
20
+
21
+ export interface SessionState {
22
+ sessionId: string;
23
+ startTimestamp: string; // ISO 8601 UTC
24
+ stopCount: number;
25
+ reads: Record<string, FileRead>;
26
+ writes: WriteEntry[];
27
+ counters: SessionCounters;
28
+ }
29
+
30
+ export interface SessionSummary {
31
+ sessionId: string;
32
+ startTimestamp: string;
33
+ endTimestamp: string;
34
+ reads: Array<{ filePath: string } & FileRead>;
35
+ writes: WriteEntry[];
36
+ totals: {
37
+ readCount: number;
38
+ writeCount: number;
39
+ estimatedTokens: number;
40
+ repeatedReads: number;
41
+ fileIndexHits: number;
42
+ fileIndexMisses: number;
43
+ };
44
+ estimatedSavings: number;
45
+ }
46
+
47
+ export interface SessionFinalizer {
48
+ appendSession(summary: SessionSummary): void;
49
+ updateSession(summary: SessionSummary): void;
50
+ }
@@ -0,0 +1,43 @@
1
+ export interface LifetimeCounters {
2
+ totalTokens: number;
3
+ totalReads: number;
4
+ totalWrites: number;
5
+ totalSessions: number;
6
+ totalFileIndexHits: number;
7
+ totalFileIndexMisses: number;
8
+ totalRepeatedReads: number;
9
+ totalEstimatedSavings: number;
10
+ }
11
+
12
+ export interface LedgerSession {
13
+ sessionId: string;
14
+ startTimestamp: string;
15
+ endTimestamp: string;
16
+ reads: Array<{
17
+ filePath: string;
18
+ estimatedTokens: number;
19
+ readCount: number;
20
+ }>;
21
+ writes: Array<{
22
+ filePath: string;
23
+ estimatedTokens: number;
24
+ action: "create" | "edit";
25
+ }>;
26
+ totals: {
27
+ readCount: number;
28
+ writeCount: number;
29
+ estimatedTokens: number;
30
+ repeatedReads: number;
31
+ fileIndexHits: number;
32
+ fileIndexMisses: number;
33
+ };
34
+ estimatedSavings: number;
35
+ }
36
+
37
+ import type { WasteFlag } from "./waste-detection";
38
+
39
+ export interface TokenLedger {
40
+ lifetime: LifetimeCounters;
41
+ sessions: LedgerSession[];
42
+ wasteFlags?: WasteFlag[];
43
+ }
@@ -0,0 +1,21 @@
1
+ export type WastePattern =
2
+ | "repeated-reads"
3
+ | "missed-index-opportunity"
4
+ | "action-log-bloat"
5
+ | "learning-memory-staleness"
6
+ | "index-miss-rate";
7
+
8
+ export interface WasteFlag {
9
+ pattern: WastePattern;
10
+ description: string;
11
+ estimatedTokensWasted: number;
12
+ suggestion: string;
13
+ detectedAt: string;
14
+ }
15
+
16
+ export interface DetectionConfig {
17
+ actionLogBloatThreshold: number;
18
+ learningMemoryStaleDays: number;
19
+ indexMissRateThreshold: number;
20
+ missedIndexMinTokens: number;
21
+ }