@hoox-sh/hoox-shared 1.2.1 → 1.3.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.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +223 -59
- package/dist/path-utils.d.ts +35 -4
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/path-utils.js +72 -5
- package/dist/session.js +69 -5
- package/dist/stores/config-store.d.ts +2 -0
- package/dist/stores/config-store.d.ts.map +1 -1
- package/dist/stores/config-store.js +267 -16
- package/dist/stores/service-store.d.ts +12 -0
- package/dist/stores/service-store.d.ts.map +1 -1
- package/dist/stores/service-store.js +100 -39
- package/dist/stores/ui-store.d.ts +14 -0
- package/dist/stores/ui-store.d.ts.map +1 -1
- package/dist/stores/ui-store.js +8 -1
- package/package.json +1 -1
package/dist/path-utils.js
CHANGED
|
@@ -16,7 +16,13 @@ var __export = (target, all) => {
|
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
17
|
|
|
18
18
|
// src/path-utils.ts
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
existsSync,
|
|
21
|
+
mkdirSync,
|
|
22
|
+
readFileSync,
|
|
23
|
+
writeFileSync,
|
|
24
|
+
chmodSync
|
|
25
|
+
} from "fs";
|
|
20
26
|
import { homedir } from "os";
|
|
21
27
|
import { dirname, join, resolve } from "path";
|
|
22
28
|
function createHooxPath(path) {
|
|
@@ -42,7 +48,55 @@ function isHooxSetupRoot(dir) {
|
|
|
42
48
|
return false;
|
|
43
49
|
try {
|
|
44
50
|
const root = resolve(dir);
|
|
45
|
-
|
|
51
|
+
if (!existsSync(join(root, "packages", "cli", "package.json"))) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return existsSync(join(root, "wrangler.jsonc")) || existsSync(join(root, "wrangler.jsonc.example")) || existsSync(join(root, "workers")) || existsSync(join(root, ".gitmodules"));
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function getRememberedMonorepoPath() {
|
|
60
|
+
return resolveHooxPath("config/monorepo.json");
|
|
61
|
+
}
|
|
62
|
+
function getRememberedMonorepoRoot() {
|
|
63
|
+
try {
|
|
64
|
+
const path = getRememberedMonorepoPath();
|
|
65
|
+
if (!existsSync(path))
|
|
66
|
+
return null;
|
|
67
|
+
const raw = readFileSync(path, "utf-8");
|
|
68
|
+
const data = JSON.parse(raw);
|
|
69
|
+
if (!data.root || typeof data.root !== "string")
|
|
70
|
+
return null;
|
|
71
|
+
const resolved = resolve(data.root);
|
|
72
|
+
return isHooxSetupRoot(resolved) ? resolved : null;
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function rememberMonorepoRoot(root) {
|
|
78
|
+
try {
|
|
79
|
+
const resolved = resolve(root);
|
|
80
|
+
if (!isHooxSetupRoot(resolved))
|
|
81
|
+
return false;
|
|
82
|
+
const configDir = getHooxConfigDir();
|
|
83
|
+
mkdirSync(configDir, { recursive: true, mode: 448 });
|
|
84
|
+
try {
|
|
85
|
+
chmodSync(configDir, 448);
|
|
86
|
+
} catch {}
|
|
87
|
+
const payload = {
|
|
88
|
+
root: resolved,
|
|
89
|
+
updatedAt: new Date().toISOString()
|
|
90
|
+
};
|
|
91
|
+
const path = getRememberedMonorepoPath();
|
|
92
|
+
writeFileSync(path, JSON.stringify(payload, null, 2) + `
|
|
93
|
+
`, {
|
|
94
|
+
mode: 384
|
|
95
|
+
});
|
|
96
|
+
try {
|
|
97
|
+
chmodSync(path, 384);
|
|
98
|
+
} catch {}
|
|
99
|
+
return true;
|
|
46
100
|
} catch {
|
|
47
101
|
return false;
|
|
48
102
|
}
|
|
@@ -62,6 +116,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
62
116
|
const env = options?.env ?? process.env;
|
|
63
117
|
const cwd = resolve(options?.cwd ?? process.cwd());
|
|
64
118
|
const globalRepo = getHooxRepoPath();
|
|
119
|
+
const remembered = options?.skipRemembered ? null : getRememberedMonorepoRoot();
|
|
65
120
|
const envRepo = env.HOOX_REPO?.trim();
|
|
66
121
|
if (envRepo) {
|
|
67
122
|
const resolved = resolve(envRepo);
|
|
@@ -72,6 +127,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
72
127
|
checked: {
|
|
73
128
|
env: resolved,
|
|
74
129
|
cwd: findHooxSetupRoot(cwd),
|
|
130
|
+
remembered,
|
|
75
131
|
global: globalRepo
|
|
76
132
|
}
|
|
77
133
|
};
|
|
@@ -82,6 +138,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
82
138
|
checked: {
|
|
83
139
|
env: resolved,
|
|
84
140
|
cwd: findHooxSetupRoot(cwd),
|
|
141
|
+
remembered,
|
|
85
142
|
global: globalRepo
|
|
86
143
|
}
|
|
87
144
|
};
|
|
@@ -91,20 +148,27 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
91
148
|
return {
|
|
92
149
|
root: local,
|
|
93
150
|
source: "cwd",
|
|
94
|
-
checked: { cwd: local, global: globalRepo }
|
|
151
|
+
checked: { cwd: local, remembered, global: globalRepo }
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (remembered) {
|
|
155
|
+
return {
|
|
156
|
+
root: remembered,
|
|
157
|
+
source: "remembered",
|
|
158
|
+
checked: { cwd: null, remembered, global: globalRepo }
|
|
95
159
|
};
|
|
96
160
|
}
|
|
97
161
|
if (isHooxSetupRoot(globalRepo)) {
|
|
98
162
|
return {
|
|
99
163
|
root: globalRepo,
|
|
100
164
|
source: "global",
|
|
101
|
-
checked: { cwd: null, global: globalRepo }
|
|
165
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
102
166
|
};
|
|
103
167
|
}
|
|
104
168
|
return {
|
|
105
169
|
root: null,
|
|
106
170
|
source: "none",
|
|
107
|
-
checked: { cwd: null, global: globalRepo }
|
|
171
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
108
172
|
};
|
|
109
173
|
}
|
|
110
174
|
function getTuiEntryCandidates(runtimeRoot) {
|
|
@@ -174,9 +238,12 @@ function getHooxStatePath() {
|
|
|
174
238
|
export {
|
|
175
239
|
resolveHooxRuntimeRoot,
|
|
176
240
|
resolveHooxPath,
|
|
241
|
+
rememberMonorepoRoot,
|
|
177
242
|
isWithinHooxHome,
|
|
178
243
|
isHooxSetupRoot,
|
|
179
244
|
getTuiEntryCandidates,
|
|
245
|
+
getRememberedMonorepoRoot,
|
|
246
|
+
getRememberedMonorepoPath,
|
|
180
247
|
getRelativeHooxPath,
|
|
181
248
|
getHooxWranglerPath,
|
|
182
249
|
getHooxStatePath,
|
package/dist/session.js
CHANGED
|
@@ -16,7 +16,13 @@ var __export = (target, all) => {
|
|
|
16
16
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
17
|
|
|
18
18
|
// src/path-utils.ts
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
existsSync,
|
|
21
|
+
mkdirSync,
|
|
22
|
+
readFileSync,
|
|
23
|
+
writeFileSync,
|
|
24
|
+
chmodSync
|
|
25
|
+
} from "fs";
|
|
20
26
|
import { homedir } from "os";
|
|
21
27
|
import { dirname, join, resolve } from "path";
|
|
22
28
|
function createHooxPath(path) {
|
|
@@ -42,7 +48,55 @@ function isHooxSetupRoot(dir) {
|
|
|
42
48
|
return false;
|
|
43
49
|
try {
|
|
44
50
|
const root = resolve(dir);
|
|
45
|
-
|
|
51
|
+
if (!existsSync(join(root, "packages", "cli", "package.json"))) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return existsSync(join(root, "wrangler.jsonc")) || existsSync(join(root, "wrangler.jsonc.example")) || existsSync(join(root, "workers")) || existsSync(join(root, ".gitmodules"));
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function getRememberedMonorepoPath() {
|
|
60
|
+
return resolveHooxPath("config/monorepo.json");
|
|
61
|
+
}
|
|
62
|
+
function getRememberedMonorepoRoot() {
|
|
63
|
+
try {
|
|
64
|
+
const path = getRememberedMonorepoPath();
|
|
65
|
+
if (!existsSync(path))
|
|
66
|
+
return null;
|
|
67
|
+
const raw = readFileSync(path, "utf-8");
|
|
68
|
+
const data = JSON.parse(raw);
|
|
69
|
+
if (!data.root || typeof data.root !== "string")
|
|
70
|
+
return null;
|
|
71
|
+
const resolved = resolve(data.root);
|
|
72
|
+
return isHooxSetupRoot(resolved) ? resolved : null;
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function rememberMonorepoRoot(root) {
|
|
78
|
+
try {
|
|
79
|
+
const resolved = resolve(root);
|
|
80
|
+
if (!isHooxSetupRoot(resolved))
|
|
81
|
+
return false;
|
|
82
|
+
const configDir = getHooxConfigDir();
|
|
83
|
+
mkdirSync(configDir, { recursive: true, mode: 448 });
|
|
84
|
+
try {
|
|
85
|
+
chmodSync(configDir, 448);
|
|
86
|
+
} catch {}
|
|
87
|
+
const payload = {
|
|
88
|
+
root: resolved,
|
|
89
|
+
updatedAt: new Date().toISOString()
|
|
90
|
+
};
|
|
91
|
+
const path = getRememberedMonorepoPath();
|
|
92
|
+
writeFileSync(path, JSON.stringify(payload, null, 2) + `
|
|
93
|
+
`, {
|
|
94
|
+
mode: 384
|
|
95
|
+
});
|
|
96
|
+
try {
|
|
97
|
+
chmodSync(path, 384);
|
|
98
|
+
} catch {}
|
|
99
|
+
return true;
|
|
46
100
|
} catch {
|
|
47
101
|
return false;
|
|
48
102
|
}
|
|
@@ -62,6 +116,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
62
116
|
const env = options?.env ?? process.env;
|
|
63
117
|
const cwd = resolve(options?.cwd ?? process.cwd());
|
|
64
118
|
const globalRepo = getHooxRepoPath();
|
|
119
|
+
const remembered = options?.skipRemembered ? null : getRememberedMonorepoRoot();
|
|
65
120
|
const envRepo = env.HOOX_REPO?.trim();
|
|
66
121
|
if (envRepo) {
|
|
67
122
|
const resolved = resolve(envRepo);
|
|
@@ -72,6 +127,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
72
127
|
checked: {
|
|
73
128
|
env: resolved,
|
|
74
129
|
cwd: findHooxSetupRoot(cwd),
|
|
130
|
+
remembered,
|
|
75
131
|
global: globalRepo
|
|
76
132
|
}
|
|
77
133
|
};
|
|
@@ -82,6 +138,7 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
82
138
|
checked: {
|
|
83
139
|
env: resolved,
|
|
84
140
|
cwd: findHooxSetupRoot(cwd),
|
|
141
|
+
remembered,
|
|
85
142
|
global: globalRepo
|
|
86
143
|
}
|
|
87
144
|
};
|
|
@@ -91,20 +148,27 @@ function resolveHooxRuntimeRoot(options) {
|
|
|
91
148
|
return {
|
|
92
149
|
root: local,
|
|
93
150
|
source: "cwd",
|
|
94
|
-
checked: { cwd: local, global: globalRepo }
|
|
151
|
+
checked: { cwd: local, remembered, global: globalRepo }
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (remembered) {
|
|
155
|
+
return {
|
|
156
|
+
root: remembered,
|
|
157
|
+
source: "remembered",
|
|
158
|
+
checked: { cwd: null, remembered, global: globalRepo }
|
|
95
159
|
};
|
|
96
160
|
}
|
|
97
161
|
if (isHooxSetupRoot(globalRepo)) {
|
|
98
162
|
return {
|
|
99
163
|
root: globalRepo,
|
|
100
164
|
source: "global",
|
|
101
|
-
checked: { cwd: null, global: globalRepo }
|
|
165
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
102
166
|
};
|
|
103
167
|
}
|
|
104
168
|
return {
|
|
105
169
|
root: null,
|
|
106
170
|
source: "none",
|
|
107
|
-
checked: { cwd: null, global: globalRepo }
|
|
171
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
108
172
|
};
|
|
109
173
|
}
|
|
110
174
|
function getTuiEntryCandidates(runtimeRoot) {
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import type { ViewId, LogFilter, NotificationPreferences } from "../types";
|
|
6
|
+
/** TUI prefs file — isolated from operator config.json (which may hold apiToken). */
|
|
7
|
+
export declare function getTuiPreferencesPath(): string;
|
|
6
8
|
export interface ConfigState {
|
|
7
9
|
theme: "dark" | "light";
|
|
8
10
|
refreshIntervalMs: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAM3E,qFAAqF;AACrF,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AA0ID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,EAAE,SAAS,CAAC;IACtB,aAAa,EAAE,uBAAuB,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB;AAID,UAAU,aAAa;IACrB,+DAA+D;IAC/D,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACtD,8CAA8C;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,yCAAyC;IACzC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,8CAA8C;IAC9C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI,CAAC;CACtE;AAiBD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;eAtClB,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;;eApB7D,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;EA+ErE,CAAC"}
|
|
@@ -131,37 +131,287 @@ function validateConfig(config) {
|
|
|
131
131
|
return errors;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// src/path-utils.ts
|
|
135
|
+
import {
|
|
136
|
+
existsSync as existsSync2,
|
|
137
|
+
mkdirSync as mkdirSync2,
|
|
138
|
+
readFileSync as readFileSync2,
|
|
139
|
+
writeFileSync as writeFileSync2,
|
|
140
|
+
chmodSync as chmodSync2
|
|
141
|
+
} from "fs";
|
|
142
|
+
import { homedir as homedir2 } from "os";
|
|
143
|
+
import { dirname, join as join2, resolve } from "path";
|
|
144
|
+
function createHooxPath(path) {
|
|
145
|
+
return path;
|
|
146
|
+
}
|
|
147
|
+
function getHooxHome() {
|
|
148
|
+
try {
|
|
149
|
+
const override = process.env.HOOX_HOME?.trim();
|
|
150
|
+
if (override) {
|
|
151
|
+
return createHooxPath(resolve(override));
|
|
152
|
+
}
|
|
153
|
+
const home = homedir2();
|
|
154
|
+
if (!home || home.length === 0) {
|
|
155
|
+
return createHooxPath(resolve(process.cwd(), ".hoox"));
|
|
156
|
+
}
|
|
157
|
+
return createHooxPath(join2(home, ".hoox"));
|
|
158
|
+
} catch {
|
|
159
|
+
return createHooxPath(resolve(process.cwd(), ".hoox"));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function isHooxSetupRoot(dir) {
|
|
163
|
+
if (!dir)
|
|
164
|
+
return false;
|
|
165
|
+
try {
|
|
166
|
+
const root = resolve(dir);
|
|
167
|
+
if (!existsSync2(join2(root, "packages", "cli", "package.json"))) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return existsSync2(join2(root, "wrangler.jsonc")) || existsSync2(join2(root, "wrangler.jsonc.example")) || existsSync2(join2(root, "workers")) || existsSync2(join2(root, ".gitmodules"));
|
|
171
|
+
} catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function getRememberedMonorepoPath() {
|
|
176
|
+
return resolveHooxPath("config/monorepo.json");
|
|
177
|
+
}
|
|
178
|
+
function getRememberedMonorepoRoot() {
|
|
179
|
+
try {
|
|
180
|
+
const path = getRememberedMonorepoPath();
|
|
181
|
+
if (!existsSync2(path))
|
|
182
|
+
return null;
|
|
183
|
+
const raw = readFileSync2(path, "utf-8");
|
|
184
|
+
const data = JSON.parse(raw);
|
|
185
|
+
if (!data.root || typeof data.root !== "string")
|
|
186
|
+
return null;
|
|
187
|
+
const resolved = resolve(data.root);
|
|
188
|
+
return isHooxSetupRoot(resolved) ? resolved : null;
|
|
189
|
+
} catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function rememberMonorepoRoot(root) {
|
|
194
|
+
try {
|
|
195
|
+
const resolved = resolve(root);
|
|
196
|
+
if (!isHooxSetupRoot(resolved))
|
|
197
|
+
return false;
|
|
198
|
+
const configDir = getHooxConfigDir();
|
|
199
|
+
mkdirSync2(configDir, { recursive: true, mode: 448 });
|
|
200
|
+
try {
|
|
201
|
+
chmodSync2(configDir, 448);
|
|
202
|
+
} catch {}
|
|
203
|
+
const payload = {
|
|
204
|
+
root: resolved,
|
|
205
|
+
updatedAt: new Date().toISOString()
|
|
206
|
+
};
|
|
207
|
+
const path = getRememberedMonorepoPath();
|
|
208
|
+
writeFileSync2(path, JSON.stringify(payload, null, 2) + `
|
|
209
|
+
`, {
|
|
210
|
+
mode: 384
|
|
211
|
+
});
|
|
212
|
+
try {
|
|
213
|
+
chmodSync2(path, 384);
|
|
214
|
+
} catch {}
|
|
215
|
+
return true;
|
|
216
|
+
} catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function findHooxSetupRoot(startDir = process.cwd()) {
|
|
221
|
+
let dir = resolve(startDir);
|
|
222
|
+
for (;; ) {
|
|
223
|
+
if (isHooxSetupRoot(dir))
|
|
224
|
+
return dir;
|
|
225
|
+
const parent = dirname(dir);
|
|
226
|
+
if (parent === dir)
|
|
227
|
+
return null;
|
|
228
|
+
dir = parent;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function resolveHooxRuntimeRoot(options) {
|
|
232
|
+
const env = options?.env ?? process.env;
|
|
233
|
+
const cwd = resolve(options?.cwd ?? process.cwd());
|
|
234
|
+
const globalRepo = getHooxRepoPath();
|
|
235
|
+
const remembered = options?.skipRemembered ? null : getRememberedMonorepoRoot();
|
|
236
|
+
const envRepo = env.HOOX_REPO?.trim();
|
|
237
|
+
if (envRepo) {
|
|
238
|
+
const resolved = resolve(envRepo);
|
|
239
|
+
if (isHooxSetupRoot(resolved)) {
|
|
240
|
+
return {
|
|
241
|
+
root: resolved,
|
|
242
|
+
source: "env",
|
|
243
|
+
checked: {
|
|
244
|
+
env: resolved,
|
|
245
|
+
cwd: findHooxSetupRoot(cwd),
|
|
246
|
+
remembered,
|
|
247
|
+
global: globalRepo
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
root: null,
|
|
253
|
+
source: "env",
|
|
254
|
+
checked: {
|
|
255
|
+
env: resolved,
|
|
256
|
+
cwd: findHooxSetupRoot(cwd),
|
|
257
|
+
remembered,
|
|
258
|
+
global: globalRepo
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
const local = findHooxSetupRoot(cwd);
|
|
263
|
+
if (local) {
|
|
264
|
+
return {
|
|
265
|
+
root: local,
|
|
266
|
+
source: "cwd",
|
|
267
|
+
checked: { cwd: local, remembered, global: globalRepo }
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (remembered) {
|
|
271
|
+
return {
|
|
272
|
+
root: remembered,
|
|
273
|
+
source: "remembered",
|
|
274
|
+
checked: { cwd: null, remembered, global: globalRepo }
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
if (isHooxSetupRoot(globalRepo)) {
|
|
278
|
+
return {
|
|
279
|
+
root: globalRepo,
|
|
280
|
+
source: "global",
|
|
281
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
root: null,
|
|
286
|
+
source: "none",
|
|
287
|
+
checked: { cwd: null, remembered: null, global: globalRepo }
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function getTuiEntryCandidates(runtimeRoot) {
|
|
291
|
+
const root = resolve(runtimeRoot);
|
|
292
|
+
return [
|
|
293
|
+
join2(root, "packages", "tui", "src", "main.tsx"),
|
|
294
|
+
join2(root, "packages", "tui", "dist", "main.js"),
|
|
295
|
+
join2(root, "packages", "tui", "src", "main.ts")
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
function resolveHooxPath(relativePath) {
|
|
299
|
+
if (!relativePath || typeof relativePath !== "string") {
|
|
300
|
+
throw new Error("relativePath must be a non-empty string");
|
|
301
|
+
}
|
|
302
|
+
if (relativePath.includes("..")) {
|
|
303
|
+
throw new Error(`Path traversal detected in relativePath: "${relativePath}"`);
|
|
304
|
+
}
|
|
305
|
+
const normalizedPath = relativePath.replace(/\\/g, "/");
|
|
306
|
+
const hooxHome = getHooxHome();
|
|
307
|
+
const fullPath = join2(hooxHome, normalizedPath);
|
|
308
|
+
const resolvedPath = resolve(fullPath);
|
|
309
|
+
const resolvedHome = resolve(hooxHome);
|
|
310
|
+
if (!resolvedPath.startsWith(resolvedHome)) {
|
|
311
|
+
throw new Error(`Resolved path "${resolvedPath}" is outside Hoox home directory`);
|
|
312
|
+
}
|
|
313
|
+
return createHooxPath(resolvedPath);
|
|
314
|
+
}
|
|
315
|
+
function isWithinHooxHome(path) {
|
|
316
|
+
try {
|
|
317
|
+
const hooxHome = getHooxHome();
|
|
318
|
+
const resolvedPath = resolve(path);
|
|
319
|
+
const resolvedHome = resolve(hooxHome);
|
|
320
|
+
return resolvedPath.startsWith(resolvedHome);
|
|
321
|
+
} catch {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function getRelativeHooxPath(absolutePath) {
|
|
326
|
+
try {
|
|
327
|
+
if (!isWithinHooxHome(absolutePath)) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
const hooxHome = getHooxHome();
|
|
331
|
+
const resolvedPath = resolve(absolutePath);
|
|
332
|
+
const resolvedHome = resolve(hooxHome);
|
|
333
|
+
const relativePath = resolvedPath.slice(resolvedHome.length);
|
|
334
|
+
return relativePath.startsWith("/") || relativePath.startsWith("\\") ? relativePath.slice(1) : relativePath;
|
|
335
|
+
} catch {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function getHooxRepoPath() {
|
|
340
|
+
return resolveHooxPath("repo");
|
|
341
|
+
}
|
|
342
|
+
function getHooxConfigDir() {
|
|
343
|
+
return resolveHooxPath("config");
|
|
344
|
+
}
|
|
345
|
+
function getHooxDataDir() {
|
|
346
|
+
return resolveHooxPath("data");
|
|
347
|
+
}
|
|
348
|
+
function getHooxWranglerPath() {
|
|
349
|
+
return resolveHooxPath("config/wrangler.jsonc");
|
|
350
|
+
}
|
|
351
|
+
function getHooxStatePath() {
|
|
352
|
+
return resolveHooxPath("data/state.json");
|
|
353
|
+
}
|
|
354
|
+
|
|
134
355
|
// src/stores/config-store.ts
|
|
135
356
|
import { create } from "zustand";
|
|
136
357
|
import { immer } from "zustand/middleware/immer";
|
|
137
358
|
import { persist, createJSONStorage } from "zustand/middleware";
|
|
138
|
-
import { chmodSync as
|
|
139
|
-
import {
|
|
140
|
-
|
|
359
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
360
|
+
import { join as join3 } from "path";
|
|
361
|
+
function getTuiPreferencesPath() {
|
|
362
|
+
return join3(getHooxHome(), ".tui-state", "preferences.json");
|
|
363
|
+
}
|
|
364
|
+
function getLegacyConfigJsonPath() {
|
|
365
|
+
return join3(getHooxHome(), "config.json");
|
|
366
|
+
}
|
|
367
|
+
function extractZustandPrefsPayload(raw) {
|
|
368
|
+
try {
|
|
369
|
+
const parsed = JSON.parse(raw);
|
|
370
|
+
if (parsed && typeof parsed === "object" && parsed.state && typeof parsed.state === "object" && !Array.isArray(parsed.state) && (("theme" in parsed.state) || ("refreshIntervalMs" in parsed.state)) && !("apiToken" in parsed)) {
|
|
371
|
+
return raw;
|
|
372
|
+
}
|
|
373
|
+
} catch {}
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
141
376
|
var bunConfigStorage = {
|
|
142
377
|
getItem: async (_name) => {
|
|
143
378
|
try {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
return
|
|
148
|
-
|
|
379
|
+
const prefsPath = getTuiPreferencesPath();
|
|
380
|
+
const prefsFile = Bun.file(prefsPath);
|
|
381
|
+
if (await prefsFile.exists()) {
|
|
382
|
+
return await prefsFile.text();
|
|
383
|
+
}
|
|
384
|
+
const legacyPath = getLegacyConfigJsonPath();
|
|
385
|
+
if (existsSync3(legacyPath)) {
|
|
386
|
+
const legacyRaw = readFileSync3(legacyPath, "utf-8");
|
|
387
|
+
const envelope = extractZustandPrefsPayload(legacyRaw);
|
|
388
|
+
if (envelope) {
|
|
389
|
+
await bunConfigStorage.setItem(_name, envelope);
|
|
390
|
+
return envelope;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return null;
|
|
149
394
|
} catch {
|
|
150
395
|
return null;
|
|
151
396
|
}
|
|
152
397
|
},
|
|
153
398
|
setItem: async (_name, value) => {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
399
|
+
const home = getHooxHome();
|
|
400
|
+
const stateDir = join3(home, ".tui-state");
|
|
401
|
+
if (!existsSync3(home)) {
|
|
402
|
+
mkdirSync3(home, { recursive: true, mode: HOOX_DIR_MODE });
|
|
403
|
+
}
|
|
404
|
+
if (!existsSync3(stateDir)) {
|
|
405
|
+
mkdirSync3(stateDir, { recursive: true, mode: HOOX_DIR_MODE });
|
|
157
406
|
}
|
|
158
407
|
try {
|
|
159
|
-
|
|
408
|
+
chmodSync3(home, HOOX_DIR_MODE);
|
|
409
|
+
chmodSync3(stateDir, HOOX_DIR_MODE);
|
|
160
410
|
} catch {}
|
|
161
|
-
const filePath =
|
|
411
|
+
const filePath = getTuiPreferencesPath();
|
|
162
412
|
await Bun.write(filePath, value);
|
|
163
413
|
try {
|
|
164
|
-
|
|
414
|
+
chmodSync3(filePath, HOOX_CONFIG_FILE_MODE);
|
|
165
415
|
} catch {}
|
|
166
416
|
},
|
|
167
417
|
removeItem: async (_name) => {}
|
|
@@ -233,7 +483,7 @@ var useConfigStore = create()(persist(immer((set) => ({
|
|
|
233
483
|
state.notifications[channel] = !state.notifications[channel];
|
|
234
484
|
})
|
|
235
485
|
})), {
|
|
236
|
-
name: "hoox-
|
|
486
|
+
name: "hoox-tui-prefs",
|
|
237
487
|
storage: createJSONStorage(() => bunConfigStorage),
|
|
238
488
|
partialize: (state) => ({
|
|
239
489
|
theme: state.theme,
|
|
@@ -251,5 +501,6 @@ var useConfigStore = create()(persist(immer((set) => ({
|
|
|
251
501
|
})
|
|
252
502
|
}));
|
|
253
503
|
export {
|
|
254
|
-
useConfigStore
|
|
504
|
+
useConfigStore,
|
|
505
|
+
getTuiPreferencesPath
|
|
255
506
|
};
|
|
@@ -41,6 +41,12 @@ interface ServiceActions {
|
|
|
41
41
|
stopStreams: () => void;
|
|
42
42
|
addAlert: (alert: Alert) => void;
|
|
43
43
|
addAlerts: (alerts: Alert[]) => void;
|
|
44
|
+
/** Mark a single alert as acknowledged (UI triage). */
|
|
45
|
+
acknowledgeAlert: (id: string) => void;
|
|
46
|
+
/** Remove a single alert from the ring buffer. */
|
|
47
|
+
dismissAlert: (id: string) => void;
|
|
48
|
+
/** Clear the local log ring buffer (TUI display only). */
|
|
49
|
+
clearLogs: () => void;
|
|
44
50
|
setConnectionStatus: (status: ConnectionStatus) => void;
|
|
45
51
|
selectWorker: (id: string | null) => void;
|
|
46
52
|
setWorkers: (workers: WorkerInfo[]) => void;
|
|
@@ -154,6 +160,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
|
|
|
154
160
|
stopStreams: () => void;
|
|
155
161
|
addAlert: (alert: Alert) => void;
|
|
156
162
|
addAlerts: (alerts: Alert[]) => void;
|
|
163
|
+
acknowledgeAlert: (id: string) => void;
|
|
164
|
+
dismissAlert: (id: string) => void;
|
|
165
|
+
clearLogs: () => void;
|
|
157
166
|
setConnectionStatus: (status: ConnectionStatus) => void;
|
|
158
167
|
selectWorker: (id: string | null) => void;
|
|
159
168
|
setWorkers: (workers: WorkerInfo[]) => void;
|
|
@@ -247,6 +256,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
|
|
|
247
256
|
stopStreams: () => void;
|
|
248
257
|
addAlert: (alert: Alert) => void;
|
|
249
258
|
addAlerts: (alerts: Alert[]) => void;
|
|
259
|
+
acknowledgeAlert: (id: string) => void;
|
|
260
|
+
dismissAlert: (id: string) => void;
|
|
261
|
+
clearLogs: () => void;
|
|
250
262
|
setConnectionStatus: (status: ConnectionStatus) => void;
|
|
251
263
|
selectWorker: (id: string | null) => void;
|
|
252
264
|
setWorkers: (workers: WorkerInfo[]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+BH,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,KAAK,EACL,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,UAAU,CAAC;AAwClB,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,WAAW,EAAE,KAAK,EAAE,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhC,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,sDAAsD;IACtD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAID,UAAU,cAAc;IACtB,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC;;;OAGG;IACH,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACrC,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;IAG7C,6DAA6D;IAC7D,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,gEAAgE;IAChE,uBAAuB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,0DAA0D;IAC1D,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,kDAAkD;IAClD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D;;;;OAIG;IACH,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CACtD;
|
|
1
|
+
{"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"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"}
|