@hexclave/cli 1.0.59 → 1.0.60
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/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/commands/dev.test.ts +37 -1
- package/src/commands/dev.ts +9 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexclave/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.60",
|
|
4
4
|
"repository": "https://github.com/hexclave/hexclave",
|
|
5
5
|
"description": "The CLI for Hexclave. https://hexclave.com",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"commander": "^13.1.0",
|
|
26
26
|
"extract-zip": "^2.0.1",
|
|
27
27
|
"jiti": "^2.4.2",
|
|
28
|
-
"@hexclave/
|
|
29
|
-
"@hexclave/shared": "1.0.
|
|
30
|
-
"@hexclave/
|
|
28
|
+
"@hexclave/js": "1.0.60",
|
|
29
|
+
"@hexclave/shared": "1.0.60",
|
|
30
|
+
"@hexclave/shared-backend": "1.0.60"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "20.17.6",
|
package/src/commands/dev.test.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { tmpdir } from "os";
|
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
5
|
import { recordLocalDashboardProcess } from "../lib/dev-env-state.js";
|
|
6
|
-
import { configErrorLogPrefix, devDashboardCommandFromEnv, isHeartbeatResponse, isVersionNewer, killLocalDashboard, processExists, shouldRestartDashboard } from "./dev.js";
|
|
6
|
+
import { configErrorLogPrefix, devDashboardCommandFromEnv, isHeartbeatResponse, isVersionNewer, killLocalDashboard, logConfigSyncEvents, processExists, shouldRestartDashboard } from "./dev.js";
|
|
7
7
|
|
|
8
8
|
describe("isVersionNewer", () => {
|
|
9
9
|
it("compares core versions numerically", () => {
|
|
@@ -103,6 +103,11 @@ describe("isHeartbeatResponse", () => {
|
|
|
103
103
|
expect(isHeartbeatResponse({
|
|
104
104
|
ok: true,
|
|
105
105
|
config_sync_events: [
|
|
106
|
+
{
|
|
107
|
+
config_file_path: "/app/hexclave.config.ts",
|
|
108
|
+
status: "syncing",
|
|
109
|
+
created_at_millis: 1_717_999_999_999,
|
|
110
|
+
},
|
|
106
111
|
{
|
|
107
112
|
config_file_path: "/app/hexclave.config.ts",
|
|
108
113
|
status: "success",
|
|
@@ -142,6 +147,37 @@ describe("isHeartbeatResponse", () => {
|
|
|
142
147
|
});
|
|
143
148
|
});
|
|
144
149
|
|
|
150
|
+
describe("logConfigSyncEvents", () => {
|
|
151
|
+
afterEach(() => {
|
|
152
|
+
vi.restoreAllMocks();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("reports detection before confirming a successful sync", () => {
|
|
156
|
+
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
157
|
+
|
|
158
|
+
logConfigSyncEvents({
|
|
159
|
+
ok: true,
|
|
160
|
+
config_sync_events: [
|
|
161
|
+
{
|
|
162
|
+
config_file_path: "/app/hexclave.config.ts",
|
|
163
|
+
status: "syncing",
|
|
164
|
+
created_at_millis: 1_718_000_000_000,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
config_file_path: "/app/hexclave.config.ts",
|
|
168
|
+
status: "success",
|
|
169
|
+
created_at_millis: 1_718_000_000_001,
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(warn.mock.calls).toEqual([
|
|
175
|
+
["[Hexclave] Detected change to config file at /app/hexclave.config.ts. Syncing..."],
|
|
176
|
+
["[Hexclave] Updated config sync successful!"],
|
|
177
|
+
]);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
145
181
|
describe("killLocalDashboard", () => {
|
|
146
182
|
let tempDir: string;
|
|
147
183
|
|
package/src/commands/dev.ts
CHANGED
|
@@ -25,6 +25,8 @@ type ConfigSyncEventBase = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
type ConfigSyncEvent = ConfigSyncEventBase & ({
|
|
28
|
+
status: "syncing",
|
|
29
|
+
} | {
|
|
28
30
|
status: "success",
|
|
29
31
|
} | {
|
|
30
32
|
status: "error",
|
|
@@ -38,7 +40,7 @@ type HeartbeatResponse = {
|
|
|
38
40
|
config_sync_events?: ConfigSyncEvent[],
|
|
39
41
|
};
|
|
40
42
|
|
|
41
|
-
const HEARTBEAT_INTERVAL_MS =
|
|
43
|
+
const HEARTBEAT_INTERVAL_MS = 1_000;
|
|
42
44
|
const HEARTBEAT_STOP_POLL_MS = 100;
|
|
43
45
|
const DASHBOARD_RESTART_MIN_UPTIME_MS = 5_000;
|
|
44
46
|
const DASHBOARD_START_TIMEOUT_MS = 60_000;
|
|
@@ -568,7 +570,7 @@ function isConfigSyncEvent(value: unknown): value is ConfigSyncEvent {
|
|
|
568
570
|
) {
|
|
569
571
|
return false;
|
|
570
572
|
}
|
|
571
|
-
if (value.status === "success") {
|
|
573
|
+
if (value.status === "syncing" || value.status === "success") {
|
|
572
574
|
return true;
|
|
573
575
|
}
|
|
574
576
|
return (
|
|
@@ -611,10 +613,12 @@ function logBrowserSecretConfirmationCode(response: HeartbeatResponse): void {
|
|
|
611
613
|
: `Dashboard browser confirmation code: ${response.browser_secret_confirmation_code} (expires in ${expiresInSeconds}s)`);
|
|
612
614
|
}
|
|
613
615
|
|
|
614
|
-
function logConfigSyncEvents(response: HeartbeatResponse): void {
|
|
616
|
+
export function logConfigSyncEvents(response: HeartbeatResponse): void {
|
|
615
617
|
for (const event of response.config_sync_events ?? []) {
|
|
616
|
-
if (event.status === "
|
|
617
|
-
logDev(`
|
|
618
|
+
if (event.status === "syncing") {
|
|
619
|
+
logDev(`Detected change to config file at ${event.config_file_path}. Syncing...`);
|
|
620
|
+
} else if (event.status === "success") {
|
|
621
|
+
logDev("Updated config sync successful!");
|
|
618
622
|
} else {
|
|
619
623
|
logDevConfigError(`Config sync failed for ${event.config_file_path}: ${event.error_message}`);
|
|
620
624
|
}
|