@sudocode-ai/cli 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/feedback-commands.d.ts.map +1 -0
- package/dist/cli/feedback-commands.js +274 -0
- package/dist/cli/feedback-commands.js.map +1 -0
- package/dist/cli/init-commands.d.ts.map +1 -0
- package/dist/cli/init-commands.js +148 -0
- package/dist/cli/init-commands.js.map +1 -0
- package/dist/cli/issue-commands.d.ts.map +1 -0
- package/dist/cli/issue-commands.js +310 -0
- package/dist/cli/issue-commands.js.map +1 -0
- package/dist/cli/query-commands.d.ts.map +1 -0
- package/dist/cli/query-commands.js +61 -0
- package/dist/cli/query-commands.js.map +1 -0
- package/dist/cli/reference-commands.d.ts.map +1 -0
- package/dist/cli/reference-commands.js +136 -0
- package/dist/cli/reference-commands.js.map +1 -0
- package/dist/cli/relationship-commands.d.ts.map +1 -0
- package/dist/cli/relationship-commands.js +76 -0
- package/dist/cli/relationship-commands.js.map +1 -0
- package/dist/cli/server-commands.d.ts.map +1 -0
- package/dist/cli/server-commands.js +99 -0
- package/dist/cli/server-commands.js.map +1 -0
- package/dist/cli/spec-commands.d.ts.map +1 -0
- package/dist/cli/spec-commands.js +321 -0
- package/dist/cli/spec-commands.js.map +1 -0
- package/dist/cli/status-commands.d.ts.map +1 -0
- package/dist/cli/status-commands.js +131 -0
- package/dist/cli/status-commands.js.map +1 -0
- package/dist/cli/sync-commands.d.ts.map +1 -0
- package/dist/cli/sync-commands.js +416 -0
- package/dist/cli/sync-commands.js.map +1 -0
- package/dist/cli/update-commands.d.ts.map +1 -0
- package/dist/cli/update-commands.js +78 -0
- package/dist/cli/update-commands.js.map +1 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +425 -195
- package/dist/cli.js.map +1 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +54 -0
- package/dist/db.js.map +1 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +195 -0
- package/dist/export.js.map +1 -0
- package/dist/filename-generator.d.ts.map +1 -0
- package/dist/filename-generator.js +93 -0
- package/dist/filename-generator.js.map +1 -0
- package/dist/id-generator.d.ts.map +1 -0
- package/dist/id-generator.js +123 -0
- package/dist/id-generator.js.map +1 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +608 -0
- package/dist/import.js.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -189
- package/dist/index.js.map +1 -0
- package/dist/jsonl.d.ts.map +1 -0
- package/dist/jsonl.js +333 -0
- package/dist/jsonl.js.map +1 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +357 -0
- package/dist/markdown.js.map +1 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +57 -0
- package/dist/migrations.js.map +1 -0
- package/dist/operations/events.d.ts.map +1 -0
- package/dist/operations/events.js +108 -0
- package/dist/operations/events.js.map +1 -0
- package/dist/operations/feedback-anchors.d.ts.map +1 -0
- package/dist/operations/feedback-anchors.js +444 -0
- package/dist/operations/feedback-anchors.js.map +1 -0
- package/dist/operations/feedback.d.ts.map +1 -0
- package/dist/operations/feedback.js +234 -0
- package/dist/operations/feedback.js.map +1 -0
- package/dist/operations/index.d.ts.map +1 -0
- package/dist/operations/index.js +10 -0
- package/dist/operations/index.js.map +1 -0
- package/dist/operations/issues.d.ts.map +1 -0
- package/dist/operations/issues.js +411 -0
- package/dist/operations/issues.js.map +1 -0
- package/dist/operations/references.d.ts.map +1 -0
- package/dist/operations/references.js +117 -0
- package/dist/operations/references.js.map +1 -0
- package/dist/operations/relationships.d.ts.map +1 -0
- package/dist/operations/relationships.js +236 -0
- package/dist/operations/relationships.js.map +1 -0
- package/dist/operations/specs.d.ts.map +1 -0
- package/dist/operations/specs.js +290 -0
- package/dist/operations/specs.js.map +1 -0
- package/dist/operations/tags.d.ts.map +1 -0
- package/dist/operations/tags.js +127 -0
- package/dist/operations/tags.js.map +1 -0
- package/dist/operations/transactions.d.ts.map +1 -0
- package/dist/operations/transactions.js +111 -0
- package/dist/operations/transactions.js.map +1 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +442 -0
- package/dist/sync.js.map +1 -0
- package/dist/test-schema.d.ts.map +1 -0
- package/dist/test-schema.js +46 -0
- package/dist/test-schema.js.map +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/update-checker.d.ts.map +1 -0
- package/dist/update-checker.js +151 -0
- package/dist/update-checker.js.map +1 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +438 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +4 -7
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update checker with caching
|
|
3
|
+
* Checks npm registry for new versions and caches results
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import * as os from "os";
|
|
8
|
+
import { VERSION } from "./version.js";
|
|
9
|
+
const PACKAGE_NAME = "@sudocode-ai/cli";
|
|
10
|
+
const CACHE_DIR = path.join(os.tmpdir(), "sudocode-cli");
|
|
11
|
+
const CACHE_FILE = path.join(CACHE_DIR, "update-cache.json");
|
|
12
|
+
const CACHE_DURATION = 1000 * 60 * 60 * 24; // 24 hours
|
|
13
|
+
/**
|
|
14
|
+
* Fetch latest version from npm registry
|
|
15
|
+
*/
|
|
16
|
+
async function fetchLatestVersion() {
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
19
|
+
headers: {
|
|
20
|
+
Accept: "application/json",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const data = (await response.json());
|
|
27
|
+
return data.version || null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Read cached version info
|
|
35
|
+
*/
|
|
36
|
+
function readCache() {
|
|
37
|
+
try {
|
|
38
|
+
if (!fs.existsSync(CACHE_FILE)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const content = fs.readFileSync(CACHE_FILE, "utf-8");
|
|
42
|
+
const cache = JSON.parse(content);
|
|
43
|
+
// Check if cache is still valid
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
if (now - cache.timestamp > CACHE_DURATION) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return cache;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Write version info to cache
|
|
56
|
+
*/
|
|
57
|
+
function writeCache(latest) {
|
|
58
|
+
try {
|
|
59
|
+
// Ensure cache directory exists
|
|
60
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
61
|
+
const cache = {
|
|
62
|
+
timestamp: Date.now(),
|
|
63
|
+
latest,
|
|
64
|
+
};
|
|
65
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Silently fail if we can't write cache
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check for updates
|
|
73
|
+
* Returns null if check fails or update info if successful
|
|
74
|
+
*/
|
|
75
|
+
export async function checkForUpdates() {
|
|
76
|
+
// Try to use cached version first
|
|
77
|
+
const cached = readCache();
|
|
78
|
+
if (cached) {
|
|
79
|
+
return {
|
|
80
|
+
current: VERSION,
|
|
81
|
+
latest: cached.latest,
|
|
82
|
+
updateAvailable: VERSION !== cached.latest,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Fetch latest version from npm
|
|
86
|
+
const latest = await fetchLatestVersion();
|
|
87
|
+
if (!latest) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
// Cache the result
|
|
91
|
+
writeCache(latest);
|
|
92
|
+
return {
|
|
93
|
+
current: VERSION,
|
|
94
|
+
latest,
|
|
95
|
+
updateAvailable: VERSION !== latest,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Compare semver versions
|
|
100
|
+
* Returns true if v1 < v2
|
|
101
|
+
*/
|
|
102
|
+
function isOlderVersion(v1, v2) {
|
|
103
|
+
const parts1 = v1.split(".").map(Number);
|
|
104
|
+
const parts2 = v2.split(".").map(Number);
|
|
105
|
+
for (let i = 0; i < 3; i++) {
|
|
106
|
+
const p1 = parts1[i] || 0;
|
|
107
|
+
const p2 = parts2[i] || 0;
|
|
108
|
+
if (p1 < p2)
|
|
109
|
+
return true;
|
|
110
|
+
if (p1 > p2)
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check for updates and return formatted notification message
|
|
117
|
+
*/
|
|
118
|
+
export async function getUpdateNotification() {
|
|
119
|
+
const info = await checkForUpdates();
|
|
120
|
+
if (!info || !info.updateAvailable) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
// Only notify if latest is actually newer (not just different)
|
|
124
|
+
if (!isOlderVersion(info.current, info.latest)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
return `
|
|
128
|
+
╭─────────────────────────────────────────────────╮
|
|
129
|
+
│ │
|
|
130
|
+
│ Update available: ${info.current} → ${info.latest} │
|
|
131
|
+
│ │
|
|
132
|
+
│ Run: npm install -g ${PACKAGE_NAME} │
|
|
133
|
+
│ Or: sudocode update │
|
|
134
|
+
│ │
|
|
135
|
+
╰─────────────────────────────────────────────────╯
|
|
136
|
+
`.trim();
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Clear update cache (useful for testing)
|
|
140
|
+
*/
|
|
141
|
+
export function clearUpdateCache() {
|
|
142
|
+
try {
|
|
143
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
144
|
+
fs.unlinkSync(CACHE_FILE);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Silently fail
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=update-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-checker.js","sourceRoot":"","sources":["../src/update-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC;AACzD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;AAC7D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW;AAiBvD;;GAEG;AACH,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,8BAA8B,YAAY,SAAS,EACnD;YACE,OAAO,EAAE;gBACP,MAAM,EAAE,kBAAkB;aAC3B;SACF,CACF,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;QAC5D,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,KAAK,GAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE/C,gCAAgC;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,cAAc,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,CAAC;QACH,gCAAgC;QAChC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,MAAM,KAAK,GAAgB;YACzB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,MAAM;SACP,CAAC;QAEF,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,kCAAkC;IAClC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,eAAe,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM;SAC3C,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mBAAmB;IACnB,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnB,OAAO;QACL,OAAO,EAAE,OAAO;QAChB,MAAM;QACN,eAAe,EAAE,OAAO,KAAK,MAAM;KACpC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,EAAU,EAAE,EAAU;IAC5C,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE1B,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;IAC5B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IAErC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;;;uBAGc,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,MAAM;;yBAE3B,YAAY;;;;GAIlC,CAAC,IAAI,EAAE,CAAC;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAMnC;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,QAAe,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version utilities
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
/**
|
|
10
|
+
* Get the CLI version from package.json
|
|
11
|
+
*/
|
|
12
|
+
export function getVersion() {
|
|
13
|
+
// In development (running from src/), go up one level
|
|
14
|
+
// In production (running from dist/), go up one level
|
|
15
|
+
const packageJsonPath = path.join(__dirname, "..", "package.json");
|
|
16
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
17
|
+
return packageJson.version;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The current CLI version
|
|
21
|
+
*/
|
|
22
|
+
export const VERSION = getVersion();
|
|
23
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,sDAAsD;IACtD,sDAAsD;IACtD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,OAAO,WAAW,CAAC,OAAO,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAe3C,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACtB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;OAEG;IACH,QAAQ,EAAE,MAAM,YAAY,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CA+dpE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CA+BnE"}
|
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File watcher for automatic synchronization
|
|
3
|
+
* Watches .sudocode directory for changes and triggers sync operations
|
|
4
|
+
*/
|
|
5
|
+
import chokidar from "chokidar";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import { syncMarkdownToJSONL, syncJSONLToMarkdown } from "./sync.js";
|
|
9
|
+
import { importFromJSONL } from "./import.js";
|
|
10
|
+
import { exportToJSONL } from "./export.js";
|
|
11
|
+
import { getSpecByFilePath, deleteSpec, listSpecs, getSpec, } from "./operations/specs.js";
|
|
12
|
+
import { listIssues, getIssue } from "./operations/issues.js";
|
|
13
|
+
import { parseMarkdownFile } from "./markdown.js";
|
|
14
|
+
import { listFeedback } from "./operations/feedback.js";
|
|
15
|
+
import { getTags } from "./operations/tags.js";
|
|
16
|
+
/**
|
|
17
|
+
* Start watching files for changes
|
|
18
|
+
* Returns a control object to stop the watcher
|
|
19
|
+
*/
|
|
20
|
+
export function startWatcher(options) {
|
|
21
|
+
const { db, baseDir, debounceDelay = 2000, onLog = console.log, onError = console.error, ignoreInitial = true, syncJSONLToMarkdown: enableReverseSync = false, } = options;
|
|
22
|
+
const stats = {
|
|
23
|
+
filesWatched: 0,
|
|
24
|
+
changesPending: 0,
|
|
25
|
+
changesProcessed: 0,
|
|
26
|
+
errors: 0,
|
|
27
|
+
};
|
|
28
|
+
// Map of file paths to pending timeout IDs
|
|
29
|
+
const pendingChanges = new Map();
|
|
30
|
+
/**
|
|
31
|
+
* Check if markdown file content matches database content
|
|
32
|
+
* Returns true if they match (no sync needed)
|
|
33
|
+
*/
|
|
34
|
+
function contentMatches(mdPath, entityId, entityType) {
|
|
35
|
+
try {
|
|
36
|
+
// Check if file exists
|
|
37
|
+
if (!fs.existsSync(mdPath)) {
|
|
38
|
+
return false; // File doesn't exist, needs to be created
|
|
39
|
+
}
|
|
40
|
+
// Parse markdown file
|
|
41
|
+
const parsed = parseMarkdownFile(mdPath, db, baseDir);
|
|
42
|
+
const { data: frontmatter, content: mdContent } = parsed;
|
|
43
|
+
// Get entity from database
|
|
44
|
+
const dbEntity = entityType === "spec" ? getSpec(db, entityId) : getIssue(db, entityId);
|
|
45
|
+
if (!dbEntity) {
|
|
46
|
+
return false; // Entity not in DB, shouldn't happen
|
|
47
|
+
}
|
|
48
|
+
// Compare title
|
|
49
|
+
if (frontmatter.title !== dbEntity.title) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
// Compare content (trim to ignore whitespace differences)
|
|
53
|
+
if (mdContent.trim() !== (dbEntity.content || "").trim()) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
// Compare other key fields
|
|
57
|
+
if (entityType === "spec") {
|
|
58
|
+
if (frontmatter.priority !== dbEntity.priority)
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const issue = dbEntity;
|
|
63
|
+
if (frontmatter.status !== issue.status)
|
|
64
|
+
return false;
|
|
65
|
+
if (frontmatter.priority !== issue.priority)
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true; // Content matches
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// If there's an error parsing, assume they don't match
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if JSONL file needs to be imported to database
|
|
77
|
+
* Returns true if import is needed (JSONL has changes not in DB)
|
|
78
|
+
*/
|
|
79
|
+
function jsonlNeedsImport(jsonlPath) {
|
|
80
|
+
try {
|
|
81
|
+
if (!fs.existsSync(jsonlPath)) {
|
|
82
|
+
return false; // File doesn't exist
|
|
83
|
+
}
|
|
84
|
+
// Read JSONL file
|
|
85
|
+
const content = fs.readFileSync(jsonlPath, "utf8");
|
|
86
|
+
const lines = content
|
|
87
|
+
.trim()
|
|
88
|
+
.split("\n")
|
|
89
|
+
.filter((line) => line.trim());
|
|
90
|
+
// Parse each line and check if it differs from database
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
const jsonlEntity = JSON.parse(line);
|
|
93
|
+
const entityId = jsonlEntity.id;
|
|
94
|
+
const entityType = jsonlPath.includes("specs.jsonl") ? "spec" : "issue";
|
|
95
|
+
// Get entity from database
|
|
96
|
+
const dbEntity = entityType === "spec"
|
|
97
|
+
? getSpec(db, entityId)
|
|
98
|
+
: getIssue(db, entityId);
|
|
99
|
+
// If entity doesn't exist in DB, import is needed
|
|
100
|
+
if (!dbEntity) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
// Compare all substantial fields
|
|
104
|
+
if (jsonlEntity.title !== dbEntity.title)
|
|
105
|
+
return true;
|
|
106
|
+
if ((jsonlEntity.content || "").trim() !== (dbEntity.content || "").trim())
|
|
107
|
+
return true;
|
|
108
|
+
if (jsonlEntity.priority !== dbEntity.priority)
|
|
109
|
+
return true;
|
|
110
|
+
if (jsonlEntity.parent_id !== dbEntity.parent_id)
|
|
111
|
+
return true;
|
|
112
|
+
if (jsonlEntity.archived !== dbEntity.archived)
|
|
113
|
+
return true;
|
|
114
|
+
if (jsonlEntity.archived_at !== dbEntity.archived_at)
|
|
115
|
+
return true;
|
|
116
|
+
if (entityType === "spec") {
|
|
117
|
+
const dbSpec = dbEntity;
|
|
118
|
+
// Compare spec-specific fields
|
|
119
|
+
if (jsonlEntity.file_path !== dbSpec.file_path)
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
else if (entityType === "issue") {
|
|
123
|
+
const dbIssue = dbEntity;
|
|
124
|
+
if (jsonlEntity.status !== dbIssue.status)
|
|
125
|
+
return true;
|
|
126
|
+
if (jsonlEntity.assignee !== dbIssue.assignee)
|
|
127
|
+
return true;
|
|
128
|
+
if (jsonlEntity.closed_at !== dbIssue.closed_at)
|
|
129
|
+
return true;
|
|
130
|
+
// Compare feedback
|
|
131
|
+
const dbFeedback = listFeedback(db, { issue_id: entityId });
|
|
132
|
+
const jsonlFeedback = jsonlEntity.feedback || [];
|
|
133
|
+
if (jsonlFeedback.length !== dbFeedback.length)
|
|
134
|
+
return true;
|
|
135
|
+
// Compare feedback content
|
|
136
|
+
for (const jf of jsonlFeedback) {
|
|
137
|
+
const dbf = dbFeedback.find((f) => f.id === jf.id);
|
|
138
|
+
if (!dbf)
|
|
139
|
+
return true;
|
|
140
|
+
if (jf.content !== dbf.content)
|
|
141
|
+
return true;
|
|
142
|
+
if (jf.feedback_type !== dbf.feedback_type)
|
|
143
|
+
return true;
|
|
144
|
+
if (jf.spec_id !== dbf.spec_id)
|
|
145
|
+
return true;
|
|
146
|
+
if (jf.dismissed !== dbf.dismissed)
|
|
147
|
+
return true;
|
|
148
|
+
// Compare anchor (stringified for comparison)
|
|
149
|
+
const jfAnchor = JSON.stringify(jf.anchor || null);
|
|
150
|
+
const dbfAnchor = JSON.stringify(dbf.anchor && typeof dbf.anchor === "string"
|
|
151
|
+
? JSON.parse(dbf.anchor)
|
|
152
|
+
: dbf.anchor || null);
|
|
153
|
+
if (jfAnchor !== dbfAnchor)
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Compare tags
|
|
158
|
+
const dbTags = getTags(db, entityId, entityType);
|
|
159
|
+
const jsonlTags = jsonlEntity.tags || [];
|
|
160
|
+
if (jsonlTags.length !== dbTags.length)
|
|
161
|
+
return true;
|
|
162
|
+
const dbTagsSet = new Set(dbTags);
|
|
163
|
+
if (jsonlTags.some((tag) => !dbTagsSet.has(tag)))
|
|
164
|
+
return true;
|
|
165
|
+
// Compare relationships
|
|
166
|
+
const { getOutgoingRelationships } = require("./operations/relationships.js");
|
|
167
|
+
const dbRels = getOutgoingRelationships(db, entityId, entityType);
|
|
168
|
+
const jsonlRels = jsonlEntity.relationships || [];
|
|
169
|
+
if (jsonlRels.length !== dbRels.length)
|
|
170
|
+
return true;
|
|
171
|
+
// Compare relationship content
|
|
172
|
+
for (const jr of jsonlRels) {
|
|
173
|
+
const dr = dbRels.find((r) => r.to_id === jr.to &&
|
|
174
|
+
r.to_type === jr.to_type &&
|
|
175
|
+
r.relationship_type === jr.type);
|
|
176
|
+
if (!dr)
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
// Compare updated_at timestamp - if JSONL is newer, import is needed
|
|
180
|
+
if (jsonlEntity.updated_at &&
|
|
181
|
+
new Date(jsonlEntity.updated_at).getTime() >
|
|
182
|
+
new Date(dbEntity.updated_at).getTime()) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return false; // All entities match
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
// If there's an error, assume import is needed
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Paths to watch
|
|
194
|
+
const specsDir = path.join(baseDir, "specs");
|
|
195
|
+
const issuesDir = path.join(baseDir, "issues");
|
|
196
|
+
const specsJSONL = path.join(baseDir, "specs.jsonl");
|
|
197
|
+
const issuesJSONL = path.join(baseDir, "issues.jsonl");
|
|
198
|
+
// Watch directories and JSONL files - chokidar will recursively watch all files inside
|
|
199
|
+
const watcher = chokidar.watch([specsDir, issuesDir, specsJSONL, issuesJSONL], {
|
|
200
|
+
persistent: true,
|
|
201
|
+
ignoreInitial,
|
|
202
|
+
awaitWriteFinish: {
|
|
203
|
+
stabilityThreshold: 100, // Reduced for faster detection in tests
|
|
204
|
+
pollInterval: 50,
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
// Log watch patterns for debugging
|
|
208
|
+
onLog(`[watch] Watching directories: ${specsDir}, ${issuesDir} and JSONL files`);
|
|
209
|
+
/**
|
|
210
|
+
* Process a file change
|
|
211
|
+
*/
|
|
212
|
+
async function processChange(filePath, event) {
|
|
213
|
+
try {
|
|
214
|
+
const ext = path.extname(filePath);
|
|
215
|
+
const basename = path.basename(filePath);
|
|
216
|
+
if (ext === ".md") {
|
|
217
|
+
// Markdown file changed - sync to database and JSONL
|
|
218
|
+
onLog(`[watch] ${event} ${path.relative(baseDir, filePath)}`);
|
|
219
|
+
if (event === "unlink") {
|
|
220
|
+
// File was deleted - remove from database and JSONL
|
|
221
|
+
// Calculate relative file path
|
|
222
|
+
const relPath = path.relative(baseDir, filePath);
|
|
223
|
+
// Look up spec by file path
|
|
224
|
+
const spec = getSpecByFilePath(db, relPath);
|
|
225
|
+
if (spec) {
|
|
226
|
+
// Delete from database
|
|
227
|
+
const deleted = deleteSpec(db, spec.id);
|
|
228
|
+
if (deleted) {
|
|
229
|
+
onLog(`[watch] Deleted spec ${spec.id} (file removed)`);
|
|
230
|
+
// Export to JSONL to reflect deletion
|
|
231
|
+
await exportToJSONL(db, { outputDir: baseDir });
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
onLog(`[watch] File deleted but no spec found: ${relPath}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
// Parse markdown to get entity info
|
|
240
|
+
try {
|
|
241
|
+
const parsed = parseMarkdownFile(filePath, db, baseDir);
|
|
242
|
+
const { data: frontmatter } = parsed;
|
|
243
|
+
const entityId = frontmatter.id;
|
|
244
|
+
// Determine entity type based on file location
|
|
245
|
+
const relPath = path.relative(baseDir, filePath);
|
|
246
|
+
const entityType = relPath.startsWith("specs/") || relPath.startsWith("specs\\")
|
|
247
|
+
? "spec"
|
|
248
|
+
: "issue";
|
|
249
|
+
// Skip if content already matches (prevents oscillation)
|
|
250
|
+
if (entityId && contentMatches(filePath, entityId, entityType)) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// Check timestamps to determine sync direction
|
|
254
|
+
if (entityId) {
|
|
255
|
+
const dbEntity = entityType === "spec"
|
|
256
|
+
? getSpec(db, entityId)
|
|
257
|
+
: getIssue(db, entityId);
|
|
258
|
+
if (dbEntity) {
|
|
259
|
+
// Get file modification time
|
|
260
|
+
const fileStat = fs.statSync(filePath);
|
|
261
|
+
const fileTime = fileStat.mtimeMs;
|
|
262
|
+
// Get database updated_at time
|
|
263
|
+
const dbTime = new Date(dbEntity.updated_at).getTime();
|
|
264
|
+
// If database is newer than file, skip markdown → database sync
|
|
265
|
+
if (dbTime > fileTime) {
|
|
266
|
+
onLog(`[watch] Skipping sync for ${entityType} ${entityId} (database is newer)`);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
// If parsing fails, continue with sync (might be a new file)
|
|
274
|
+
}
|
|
275
|
+
// Sync markdown to database
|
|
276
|
+
const result = await syncMarkdownToJSONL(db, filePath, {
|
|
277
|
+
outputDir: baseDir,
|
|
278
|
+
autoExport: true,
|
|
279
|
+
autoInitialize: true,
|
|
280
|
+
writeBackFrontmatter: true,
|
|
281
|
+
});
|
|
282
|
+
if (result.success) {
|
|
283
|
+
onLog(`[watch] Synced ${result.entityType} ${result.entityId} (${result.action})`);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
onError(new Error(`Failed to sync ${filePath}: ${result.error}`));
|
|
287
|
+
stats.errors++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else if (basename === "specs.jsonl" || basename === "issues.jsonl") {
|
|
292
|
+
// JSONL file changed (e.g., from git pull) - check if import is needed
|
|
293
|
+
onLog(`[watch] ${event} ${path.relative(baseDir, filePath)}`);
|
|
294
|
+
if (event !== "unlink") {
|
|
295
|
+
// Check if JSONL actually differs from database before importing
|
|
296
|
+
if (jsonlNeedsImport(filePath)) {
|
|
297
|
+
await importFromJSONL(db, {
|
|
298
|
+
inputDir: baseDir,
|
|
299
|
+
});
|
|
300
|
+
onLog(`[watch] Imported JSONL changes to database`);
|
|
301
|
+
}
|
|
302
|
+
// Optionally sync database changes back to markdown files
|
|
303
|
+
// Only sync entities where content actually differs (contentMatches check)
|
|
304
|
+
if (enableReverseSync) {
|
|
305
|
+
onLog(`[watch] Checking for entities that need markdown updates...`);
|
|
306
|
+
let syncedCount = 0;
|
|
307
|
+
// Get all specs and sync to markdown
|
|
308
|
+
const specs = listSpecs(db);
|
|
309
|
+
for (const spec of specs) {
|
|
310
|
+
if (spec.file_path) {
|
|
311
|
+
const mdPath = path.join(baseDir, spec.file_path);
|
|
312
|
+
// Skip if content already matches (prevents oscillation)
|
|
313
|
+
if (contentMatches(mdPath, spec.id, "spec")) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const result = await syncJSONLToMarkdown(db, spec.id, "spec", mdPath);
|
|
317
|
+
if (result.success) {
|
|
318
|
+
syncedCount++;
|
|
319
|
+
onLog(`[watch] Synced spec ${spec.id} to ${spec.file_path} (${result.action})`);
|
|
320
|
+
}
|
|
321
|
+
else if (result.error) {
|
|
322
|
+
onError(new Error(`Failed to sync spec ${spec.id}: ${result.error}`));
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Get all issues and check if any need syncing
|
|
327
|
+
const issues = listIssues(db);
|
|
328
|
+
const issuesDir = path.join(baseDir, "issues");
|
|
329
|
+
for (const issue of issues) {
|
|
330
|
+
const fileName = `${issue.id}.md`;
|
|
331
|
+
const mdPath = path.join(issuesDir, fileName);
|
|
332
|
+
// Skip if content already matches (prevents unnecessary writes and oscillation)
|
|
333
|
+
if (contentMatches(mdPath, issue.id, "issue")) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const result = await syncJSONLToMarkdown(db, issue.id, "issue", mdPath);
|
|
337
|
+
if (result.success) {
|
|
338
|
+
syncedCount++;
|
|
339
|
+
onLog(`[watch] Synced issue ${issue.id} to markdown (${result.action})`);
|
|
340
|
+
}
|
|
341
|
+
else if (result.error) {
|
|
342
|
+
onError(new Error(`Failed to sync issue ${issue.id}: ${result.error}`));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (syncedCount > 0) {
|
|
346
|
+
onLog(`[watch] Synced ${syncedCount} entities to markdown`);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
onLog(`[watch] All markdown files are up to date`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
stats.changesProcessed++;
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
358
|
+
onError(new Error(`Error processing ${filePath}: ${message}`));
|
|
359
|
+
stats.errors++;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Debounced file change handler
|
|
364
|
+
*/
|
|
365
|
+
function handleFileChange(filePath, event) {
|
|
366
|
+
// Cancel pending change for this file
|
|
367
|
+
const existingTimeout = pendingChanges.get(filePath);
|
|
368
|
+
if (existingTimeout) {
|
|
369
|
+
clearTimeout(existingTimeout);
|
|
370
|
+
stats.changesPending--;
|
|
371
|
+
}
|
|
372
|
+
// Schedule new change
|
|
373
|
+
stats.changesPending++;
|
|
374
|
+
const timeout = setTimeout(() => {
|
|
375
|
+
pendingChanges.delete(filePath);
|
|
376
|
+
stats.changesPending--;
|
|
377
|
+
processChange(filePath, event);
|
|
378
|
+
}, debounceDelay);
|
|
379
|
+
pendingChanges.set(filePath, timeout);
|
|
380
|
+
}
|
|
381
|
+
// Set up event handlers
|
|
382
|
+
watcher.on("add", (filePath) => handleFileChange(filePath, "add"));
|
|
383
|
+
watcher.on("change", (filePath) => handleFileChange(filePath, "change"));
|
|
384
|
+
watcher.on("unlink", (filePath) => handleFileChange(filePath, "unlink"));
|
|
385
|
+
watcher.on("ready", () => {
|
|
386
|
+
const watched = watcher.getWatched();
|
|
387
|
+
stats.filesWatched = Object.keys(watched).reduce((total, dir) => total + watched[dir].length, 0);
|
|
388
|
+
onLog(`[watch] Watching ${stats.filesWatched} files in ${baseDir}`);
|
|
389
|
+
});
|
|
390
|
+
watcher.on("error", (error) => {
|
|
391
|
+
onError(error);
|
|
392
|
+
stats.errors++;
|
|
393
|
+
});
|
|
394
|
+
// Return control object
|
|
395
|
+
return {
|
|
396
|
+
stop: async () => {
|
|
397
|
+
onLog("[watch] Stopping watcher...");
|
|
398
|
+
// Cancel all pending changes
|
|
399
|
+
for (const timeout of pendingChanges.values()) {
|
|
400
|
+
clearTimeout(timeout);
|
|
401
|
+
}
|
|
402
|
+
pendingChanges.clear();
|
|
403
|
+
stats.changesPending = 0;
|
|
404
|
+
// Close watcher
|
|
405
|
+
await watcher.close();
|
|
406
|
+
onLog("[watch] Watcher stopped");
|
|
407
|
+
},
|
|
408
|
+
getStats: () => ({ ...stats }),
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Wait for termination signal and stop watcher gracefully
|
|
413
|
+
*/
|
|
414
|
+
export function setupGracefulShutdown(control) {
|
|
415
|
+
let isShuttingDown = false;
|
|
416
|
+
const shutdown = async (signal) => {
|
|
417
|
+
if (isShuttingDown)
|
|
418
|
+
return;
|
|
419
|
+
isShuttingDown = true;
|
|
420
|
+
console.log(`\n[watch] Received ${signal}, shutting down gracefully...`);
|
|
421
|
+
try {
|
|
422
|
+
await control.stop();
|
|
423
|
+
process.exit(0);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
console.error("[watch] Error during shutdown:", error);
|
|
427
|
+
process.exit(1);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
// Handle termination signals
|
|
431
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
432
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
433
|
+
// Handle unhandled promise rejections
|
|
434
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
435
|
+
console.error("[watch] Unhandled Rejection at:", promise, "reason:", reason);
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|