resolve-solo 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 (50) hide show
  1. package/README.md +199 -0
  2. package/dist/cli.d.ts +8 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +214 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/demo-generator.d.ts +12 -0
  7. package/dist/demo-generator.d.ts.map +1 -0
  8. package/dist/demo-generator.js +352 -0
  9. package/dist/demo-generator.js.map +1 -0
  10. package/dist/demo-output.d.ts +13 -0
  11. package/dist/demo-output.d.ts.map +1 -0
  12. package/dist/demo-output.js +116 -0
  13. package/dist/demo-output.js.map +1 -0
  14. package/dist/demo-schema.d.ts +66 -0
  15. package/dist/demo-schema.d.ts.map +1 -0
  16. package/dist/demo-schema.js +11 -0
  17. package/dist/demo-schema.js.map +1 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +10 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/investigation-types.d.ts +47 -0
  23. package/dist/investigation-types.d.ts.map +1 -0
  24. package/dist/investigation-types.js +5 -0
  25. package/dist/investigation-types.js.map +1 -0
  26. package/dist/investigation.d.ts +24 -0
  27. package/dist/investigation.d.ts.map +1 -0
  28. package/dist/investigation.js +135 -0
  29. package/dist/investigation.js.map +1 -0
  30. package/dist/output.d.ts +20 -0
  31. package/dist/output.d.ts.map +1 -0
  32. package/dist/output.js +151 -0
  33. package/dist/output.js.map +1 -0
  34. package/dist/parser.d.ts +16 -0
  35. package/dist/parser.d.ts.map +1 -0
  36. package/dist/parser.js +146 -0
  37. package/dist/parser.js.map +1 -0
  38. package/dist/storage.d.ts +47 -0
  39. package/dist/storage.d.ts.map +1 -0
  40. package/dist/storage.js +133 -0
  41. package/dist/storage.js.map +1 -0
  42. package/dist/timeline.d.ts +27 -0
  43. package/dist/timeline.d.ts.map +1 -0
  44. package/dist/timeline.js +145 -0
  45. package/dist/timeline.js.map +1 -0
  46. package/dist/types.d.ts +10 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +5 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +57 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Storage utilities for local data persistence
3
+ */
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ /**
7
+ * Get the .resolveai directory path (project-local)
8
+ */
9
+ export function getResolveaiDir() {
10
+ return path.join(process.cwd(), '.resolveai');
11
+ }
12
+ /**
13
+ * Get the demo data directory path
14
+ */
15
+ export function getDemoDataDir() {
16
+ return path.join(getResolveaiDir(), 'demo-data');
17
+ }
18
+ /**
19
+ * Ensure a directory exists (create if missing)
20
+ */
21
+ export function ensureDir(dirPath) {
22
+ if (!fs.existsSync(dirPath)) {
23
+ fs.mkdirSync(dirPath, { recursive: true });
24
+ }
25
+ }
26
+ /**
27
+ * Check if demo data exists
28
+ */
29
+ export function demoDataExists() {
30
+ const demoDir = getDemoDataDir();
31
+ if (!fs.existsSync(demoDir)) {
32
+ return false;
33
+ }
34
+ // Check for required files
35
+ const requiredFiles = [
36
+ 'services.json',
37
+ 'deploys.json',
38
+ 'logs.json',
39
+ 'incidents.json',
40
+ 'metadata.json',
41
+ ];
42
+ return requiredFiles.every((file) => fs.existsSync(path.join(demoDir, file)));
43
+ }
44
+ /**
45
+ * Save demo dataset to disk
46
+ */
47
+ export function saveDemoData(dataset) {
48
+ const demoDir = getDemoDataDir();
49
+ ensureDir(demoDir);
50
+ // Write each data type to separate file for easier inspection
51
+ fs.writeFileSync(path.join(demoDir, 'services.json'), JSON.stringify(dataset.services, null, 2));
52
+ fs.writeFileSync(path.join(demoDir, 'deploys.json'), JSON.stringify(dataset.deploys, null, 2));
53
+ fs.writeFileSync(path.join(demoDir, 'logs.json'), JSON.stringify(dataset.logs, null, 2));
54
+ fs.writeFileSync(path.join(demoDir, 'incidents.json'), JSON.stringify(dataset.incidents, null, 2));
55
+ fs.writeFileSync(path.join(demoDir, 'metadata.json'), JSON.stringify(dataset.metadata, null, 2));
56
+ }
57
+ /**
58
+ * Load demo dataset from disk
59
+ */
60
+ export function loadDemoData() {
61
+ if (!demoDataExists()) {
62
+ return null;
63
+ }
64
+ const demoDir = getDemoDataDir();
65
+ try {
66
+ const services = JSON.parse(fs.readFileSync(path.join(demoDir, 'services.json'), 'utf-8'));
67
+ const deploys = JSON.parse(fs.readFileSync(path.join(demoDir, 'deploys.json'), 'utf-8'));
68
+ const logs = JSON.parse(fs.readFileSync(path.join(demoDir, 'logs.json'), 'utf-8'));
69
+ const incidents = JSON.parse(fs.readFileSync(path.join(demoDir, 'incidents.json'), 'utf-8'));
70
+ const metadata = JSON.parse(fs.readFileSync(path.join(demoDir, 'metadata.json'), 'utf-8'));
71
+ return {
72
+ services,
73
+ deploys,
74
+ logs,
75
+ incidents,
76
+ metadata,
77
+ };
78
+ }
79
+ catch (error) {
80
+ console.error('Failed to load demo data:', error);
81
+ return null;
82
+ }
83
+ }
84
+ /**
85
+ * Delete all demo data
86
+ */
87
+ export function deleteDemoData() {
88
+ const demoDir = getDemoDataDir();
89
+ if (fs.existsSync(demoDir)) {
90
+ fs.rmSync(demoDir, { recursive: true, force: true });
91
+ }
92
+ }
93
+ /**
94
+ * Get storage info (sizes, counts)
95
+ */
96
+ export function getStorageInfo() {
97
+ const demoDir = getDemoDataDir();
98
+ const exists = demoDataExists();
99
+ if (!exists) {
100
+ return { exists: false, path: demoDir };
101
+ }
102
+ const dataset = loadDemoData();
103
+ if (!dataset) {
104
+ return { exists: false, path: demoDir };
105
+ }
106
+ // Calculate total size
107
+ const files = [
108
+ 'services.json',
109
+ 'deploys.json',
110
+ 'logs.json',
111
+ 'incidents.json',
112
+ 'metadata.json',
113
+ ];
114
+ let totalSize = 0;
115
+ for (const file of files) {
116
+ const filePath = path.join(demoDir, file);
117
+ if (fs.existsSync(filePath)) {
118
+ totalSize += fs.statSync(filePath).size;
119
+ }
120
+ }
121
+ return {
122
+ exists: true,
123
+ path: demoDir,
124
+ size: totalSize,
125
+ counts: {
126
+ services: dataset.services.length,
127
+ deploys: dataset.deploys.length,
128
+ logs: dataset.logs.length,
129
+ incidents: dataset.incidents.length,
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Timeline builder for investigation
3
+ *
4
+ * Merges deploys, logs, and incidents into a unified timeline.
5
+ */
6
+ import type { DemoDataset } from './demo-schema.js';
7
+ import type { TimelineItem } from './investigation-types.js';
8
+ /**
9
+ * Build a timeline from demo dataset
10
+ */
11
+ export declare function buildTimeline(dataset: DemoDataset, options?: {
12
+ hoursAgo?: number;
13
+ maxItems?: number;
14
+ relevantServices?: string[];
15
+ baseDate?: Date;
16
+ }): TimelineItem[];
17
+ /**
18
+ * Get services affected in timeline
19
+ */
20
+ export declare function getAffectedServices(timeline: TimelineItem[]): string[];
21
+ /**
22
+ * Deduplicate timeline items (e.g., multiple errors from same service)
23
+ */
24
+ export declare function deduplicateTimeline(timeline: TimelineItem[], options?: {
25
+ maxPerService?: number;
26
+ }): TimelineItem[];
27
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,0BAA0B,CAAC;AAEzE;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,IAAI,CAAC;CACZ,GACL,YAAY,EAAE,CAuHhB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAMtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,YAAY,EAAE,CAuBhB"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Timeline builder for investigation
3
+ *
4
+ * Merges deploys, logs, and incidents into a unified timeline.
5
+ */
6
+ /**
7
+ * Build a timeline from demo dataset
8
+ */
9
+ export function buildTimeline(dataset, options = {}) {
10
+ const { hoursAgo = 24, maxItems = 15, relevantServices, baseDate } = options;
11
+ const now = baseDate || new Date();
12
+ const cutoffTime = new Date(now.getTime() - hoursAgo * 60 * 60 * 1000);
13
+ const items = [];
14
+ // Add deploys
15
+ for (const deploy of dataset.deploys) {
16
+ const deployTime = new Date(deploy.timestamp);
17
+ if (deployTime < cutoffTime)
18
+ continue;
19
+ // Filter by relevant services if specified
20
+ if (relevantServices && !relevantServices.includes(deploy.service)) {
21
+ continue;
22
+ }
23
+ const service = dataset.services.find((s) => s.id === deploy.service);
24
+ const serviceName = service?.displayName || deploy.service;
25
+ items.push({
26
+ id: deploy.id,
27
+ timestamp: deploy.timestamp,
28
+ signal: 'deploy',
29
+ target: serviceName,
30
+ summary: `Deploy ${deploy.version} to ${serviceName}`,
31
+ whyItMatters: deploy.status === 'failed'
32
+ ? 'Failed deploy could cause downstream issues'
33
+ : deploy.status === 'rolled_back'
34
+ ? 'Rollback indicates problems with this version'
35
+ : 'New code deployed, potential source of change',
36
+ confidence: deploy.status === 'failed' ? 'high' : 'medium',
37
+ details: {
38
+ version: deploy.version,
39
+ deployer: deploy.deployer,
40
+ commitMessage: deploy.commitMessage,
41
+ status: deploy.status,
42
+ },
43
+ isDemo: true,
44
+ });
45
+ }
46
+ // Add error logs (high signal)
47
+ for (const log of dataset.logs) {
48
+ const logTime = new Date(log.timestamp);
49
+ if (logTime < cutoffTime)
50
+ continue;
51
+ if (log.level !== 'error')
52
+ continue; // Only errors in timeline
53
+ // Filter by relevant services if specified
54
+ if (relevantServices && !relevantServices.includes(log.service)) {
55
+ continue;
56
+ }
57
+ const service = dataset.services.find((s) => s.id === log.service);
58
+ const serviceName = service?.displayName || log.service;
59
+ items.push({
60
+ id: log.id,
61
+ timestamp: log.timestamp,
62
+ signal: 'log',
63
+ target: serviceName,
64
+ summary: `Error: ${log.message}`,
65
+ whyItMatters: 'Error log indicates potential failure point',
66
+ confidence: 'high',
67
+ details: {
68
+ level: log.level,
69
+ message: log.message,
70
+ metadata: log.metadata,
71
+ },
72
+ isDemo: true,
73
+ });
74
+ }
75
+ // Add recent incidents (for context)
76
+ for (const incident of dataset.incidents) {
77
+ const incidentTime = new Date(incident.createdAt);
78
+ // Include incidents from last 30 days for recall context
79
+ const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
80
+ if (incidentTime < thirtyDaysAgo)
81
+ continue;
82
+ // Check if any relevant services are affected
83
+ if (relevantServices) {
84
+ const hasOverlap = incident.affectedServices.some((s) => relevantServices.includes(s));
85
+ if (!hasOverlap)
86
+ continue;
87
+ }
88
+ items.push({
89
+ id: incident.id,
90
+ timestamp: incident.createdAt,
91
+ signal: 'incident',
92
+ target: incident.affectedServices
93
+ .map((sid) => dataset.services.find((s) => s.id === sid)?.displayName || sid)
94
+ .join(', '),
95
+ summary: `Past incident: ${incident.title}`,
96
+ whyItMatters: 'Similar past incident, check for patterns',
97
+ confidence: 'medium',
98
+ details: {
99
+ severity: incident.severity,
100
+ symptoms: incident.symptoms,
101
+ resolution: incident.resolution,
102
+ timeToResolve: incident.timeToResolveMinutes,
103
+ },
104
+ isDemo: true,
105
+ });
106
+ }
107
+ // Sort by timestamp (most recent first)
108
+ items.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
109
+ // Limit to maxItems
110
+ return items.slice(0, maxItems);
111
+ }
112
+ /**
113
+ * Get services affected in timeline
114
+ */
115
+ export function getAffectedServices(timeline) {
116
+ const services = new Set();
117
+ for (const item of timeline) {
118
+ services.add(item.target);
119
+ }
120
+ return Array.from(services);
121
+ }
122
+ /**
123
+ * Deduplicate timeline items (e.g., multiple errors from same service)
124
+ */
125
+ export function deduplicateTimeline(timeline, options = {}) {
126
+ const { maxPerService = 3 } = options;
127
+ const serviceCount = new Map();
128
+ const result = [];
129
+ for (const item of timeline) {
130
+ const count = serviceCount.get(item.target) || 0;
131
+ // Keep high-confidence items regardless
132
+ if (item.confidence === 'high') {
133
+ result.push(item);
134
+ serviceCount.set(item.target, count + 1);
135
+ continue;
136
+ }
137
+ // Limit medium/low confidence items per service
138
+ if (count < maxPerService) {
139
+ result.push(item);
140
+ serviceCount.set(item.target, count + 1);
141
+ }
142
+ }
143
+ return result;
144
+ }
145
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAoB,EACpB,UAKI,EAAE;IAEN,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7E,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACvE,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,cAAc;IACd,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,UAAU,GAAG,UAAU;YAAE,SAAS;QAEtC,2CAA2C;QAC3C,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnE,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,MAAM,CAAC,OAAO,CAAC;QAE3D,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,UAAU,MAAM,CAAC,OAAO,OAAO,WAAW,EAAE;YACrD,YAAY,EACV,MAAM,CAAC,MAAM,KAAK,QAAQ;gBACxB,CAAC,CAAC,6CAA6C;gBAC/C,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,aAAa;oBACjC,CAAC,CAAC,+CAA+C;oBACjD,CAAC,CAAC,+CAA+C;YACrD,UAAU,EAAE,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;YAC1D,OAAO,EAAE;gBACP,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB;YACD,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;IACL,CAAC;IAED,+BAA+B;IAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,OAAO,GAAG,UAAU;YAAE,SAAS;QACnC,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO;YAAE,SAAS,CAAC,0BAA0B;QAE/D,2CAA2C;QAC3C,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAChE,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC;QACnE,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,GAAG,CAAC,OAAO,CAAC;QAExD,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,UAAU,GAAG,CAAC,OAAO,EAAE;YAChC,YAAY,EAAE,6CAA6C;YAC3D,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE;gBACP,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;aACvB;YACD,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAClD,yDAAyD;QACzD,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACzE,IAAI,YAAY,GAAG,aAAa;YAAE,SAAS;QAE3C,8CAA8C;QAC9C,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACtD,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC7B,CAAC;YACF,IAAI,CAAC,UAAU;gBAAE,SAAS;QAC5B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,QAAQ,CAAC,gBAAgB;iBAC9B,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,WAAW,IAAI,GAAG,CACjE;iBACA,IAAI,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,kBAAkB,QAAQ,CAAC,KAAK,EAAE;YAC3C,YAAY,EAAE,2CAA2C;YACzD,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE;gBACP,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,aAAa,EAAE,QAAQ,CAAC,oBAAoB;aAC7C;YACD,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;IAEF,oBAAoB;IACpB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAwB;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAwB,EACxB,UAAsC,EAAE;IAExC,MAAM,EAAE,aAAa,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC/C,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEjD,wCAAwC;QACxC,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YACzC,SAAS;QACX,CAAC;QAED,gDAAgD;QAChD,IAAI,KAAK,GAAG,aAAa,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Core types for Resolve Solo
3
+ */
4
+ export type Intent = 'help' | 'demo' | 'demo-seed' | 'demo-reset' | 'investigate' | 'details' | 'note' | 'close' | 'report-weekly' | 'doctor' | 'uninstall' | 'unknown';
5
+ export interface ParsedCommand {
6
+ intent: Intent;
7
+ args: string[];
8
+ raw: string;
9
+ }
10
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,MAAM,GACd,MAAM,GACN,MAAM,GACN,WAAW,GACX,YAAY,GACZ,aAAa,GACb,SAAS,GACT,MAAM,GACN,OAAO,GACP,eAAe,GACf,QAAQ,GACR,WAAW,GACX,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Core types for Resolve Solo
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "resolve-solo",
3
+ "version": "0.1.0",
4
+ "description": "Local-first CLI on-call assistant for individual engineers",
5
+ "main": "./dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "resolveai": "./dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "dev": "tsx src/cli.ts",
12
+ "build": "tsc",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "test:coverage": "vitest run --coverage",
16
+ "typecheck": "tsc --noEmit",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "oncall",
21
+ "incident-response",
22
+ "investigation",
23
+ "cli",
24
+ "devtools"
25
+ ],
26
+ "author": "Resolve.ai",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.cbhq.net/srinath-sinha/resolve-solo.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.cbhq.net/srinath-sinha/resolve-solo/issues"
34
+ },
35
+ "homepage": "https://github.cbhq.net/srinath-sinha/resolve-solo#readme",
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "dependencies": {
44
+ "chalk": "^5.3.0",
45
+ "commander": "^12.1.0"
46
+ },
47
+ "optionalDependencies": {
48
+ "better-sqlite3": "^11.7.0"
49
+ },
50
+ "devDependencies": {
51
+ "@types/better-sqlite3": "^7.6.12",
52
+ "@types/node": "^20.17.10",
53
+ "tsx": "^4.19.2",
54
+ "typescript": "^5.7.3",
55
+ "vitest": "^2.1.8"
56
+ }
57
+ }