hotsheet 0.8.0 → 0.9.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/cli.js +27 -21
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -552,7 +552,7 @@ var init_channel_config = __esm({
|
|
|
552
552
|
// src/cli.ts
|
|
553
553
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
554
554
|
import { tmpdir } from "os";
|
|
555
|
-
import { join as join12, resolve as
|
|
555
|
+
import { join as join12, resolve as resolve4 } from "path";
|
|
556
556
|
|
|
557
557
|
// src/backup.ts
|
|
558
558
|
init_connection();
|
|
@@ -2394,7 +2394,7 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
2394
2394
|
// src/routes/api.ts
|
|
2395
2395
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, rmSync as rmSync5 } from "fs";
|
|
2396
2396
|
import { Hono } from "hono";
|
|
2397
|
-
import { basename, extname, join as join9, relative as relative2 } from "path";
|
|
2397
|
+
import { basename, extname, join as join9, relative as relative2, resolve as resolve3 } from "path";
|
|
2398
2398
|
|
|
2399
2399
|
// src/skills.ts
|
|
2400
2400
|
init_file_settings();
|
|
@@ -2886,8 +2886,8 @@ function notifyChange() {
|
|
|
2886
2886
|
changeVersion++;
|
|
2887
2887
|
const waiters = pollWaiters;
|
|
2888
2888
|
pollWaiters = [];
|
|
2889
|
-
for (const
|
|
2890
|
-
|
|
2889
|
+
for (const resolve5 of waiters) {
|
|
2890
|
+
resolve5(changeVersion);
|
|
2891
2891
|
}
|
|
2892
2892
|
}
|
|
2893
2893
|
apiRoutes.get("/poll", async (c) => {
|
|
@@ -2896,11 +2896,11 @@ apiRoutes.get("/poll", async (c) => {
|
|
|
2896
2896
|
return c.json({ version: changeVersion });
|
|
2897
2897
|
}
|
|
2898
2898
|
const version = await Promise.race([
|
|
2899
|
-
new Promise((
|
|
2900
|
-
pollWaiters.push(
|
|
2899
|
+
new Promise((resolve5) => {
|
|
2900
|
+
pollWaiters.push(resolve5);
|
|
2901
2901
|
}),
|
|
2902
|
-
new Promise((
|
|
2903
|
-
setTimeout(() =>
|
|
2902
|
+
new Promise((resolve5) => {
|
|
2903
|
+
setTimeout(() => resolve5(changeVersion), 3e4);
|
|
2904
2904
|
})
|
|
2905
2905
|
]);
|
|
2906
2906
|
return c.json({ version });
|
|
@@ -3140,7 +3140,11 @@ apiRoutes.post("/attachments/:id/reveal", async (c) => {
|
|
|
3140
3140
|
apiRoutes.get("/attachments/file/*", async (c) => {
|
|
3141
3141
|
const filePath = c.req.path.replace("/api/attachments/file/", "");
|
|
3142
3142
|
const dataDir2 = c.get("dataDir");
|
|
3143
|
-
const
|
|
3143
|
+
const attachDir = resolve3(join9(dataDir2, "attachments"));
|
|
3144
|
+
const fullPath = resolve3(join9(attachDir, filePath));
|
|
3145
|
+
if (!fullPath.startsWith(attachDir + "/") && fullPath !== attachDir) {
|
|
3146
|
+
return c.json({ error: "Invalid path" }, 403);
|
|
3147
|
+
}
|
|
3144
3148
|
if (!existsSync7(fullPath)) {
|
|
3145
3149
|
return c.json({ error: "File not found" }, 404);
|
|
3146
3150
|
}
|
|
@@ -3213,7 +3217,8 @@ apiRoutes.patch("/settings", async (c) => {
|
|
|
3213
3217
|
apiRoutes.get("/file-settings", async (c) => {
|
|
3214
3218
|
const { readFileSettings: readFileSettings2 } = await Promise.resolve().then(() => (init_file_settings(), file_settings_exports));
|
|
3215
3219
|
const dataDir2 = c.get("dataDir");
|
|
3216
|
-
|
|
3220
|
+
const { secret, secretPathHash, port: port2, ...safe } = readFileSettings2(dataDir2);
|
|
3221
|
+
return c.json(safe);
|
|
3217
3222
|
});
|
|
3218
3223
|
apiRoutes.patch("/file-settings", async (c) => {
|
|
3219
3224
|
const { writeFileSettings: writeFileSettings2 } = await Promise.resolve().then(() => (init_file_settings(), file_settings_exports));
|
|
@@ -4072,10 +4077,10 @@ pageRoutes.get("/", (c) => {
|
|
|
4072
4077
|
|
|
4073
4078
|
// src/server.ts
|
|
4074
4079
|
function tryServe(fetch2, port2) {
|
|
4075
|
-
return new Promise((
|
|
4080
|
+
return new Promise((resolve5, reject) => {
|
|
4076
4081
|
const server = serve({ fetch: fetch2, port: port2 });
|
|
4077
4082
|
server.on("listening", () => {
|
|
4078
|
-
|
|
4083
|
+
resolve5(port2);
|
|
4079
4084
|
});
|
|
4080
4085
|
server.on("error", (err) => {
|
|
4081
4086
|
reject(err);
|
|
@@ -4127,8 +4132,9 @@ async function startServer(port2, dataDir2, options) {
|
|
|
4127
4132
|
} else if (isMutation) {
|
|
4128
4133
|
const origin = c.req.header("Origin");
|
|
4129
4134
|
const referer = c.req.header("Referer");
|
|
4130
|
-
const
|
|
4131
|
-
|
|
4135
|
+
const localhostPattern = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/;
|
|
4136
|
+
const isSameOrigin = origin && localhostPattern.test(origin) || referer && localhostPattern.test(referer);
|
|
4137
|
+
if (!isSameOrigin) {
|
|
4132
4138
|
return c.json({
|
|
4133
4139
|
error: "Missing X-Hotsheet-Secret header. Read .hotsheet/settings.json for the correct port and secret.",
|
|
4134
4140
|
recovery: "Re-read .hotsheet/settings.json to get the correct port and secret, and re-read your skill files for updated instructions."
|
|
@@ -4213,10 +4219,10 @@ function isFirstUseToday() {
|
|
|
4213
4219
|
return last !== today;
|
|
4214
4220
|
}
|
|
4215
4221
|
function fetchLatestVersion() {
|
|
4216
|
-
return new Promise((
|
|
4222
|
+
return new Promise((resolve5) => {
|
|
4217
4223
|
const req = get(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, { timeout: 5e3 }, (res) => {
|
|
4218
4224
|
if (res.statusCode !== 200) {
|
|
4219
|
-
|
|
4225
|
+
resolve5(null);
|
|
4220
4226
|
return;
|
|
4221
4227
|
}
|
|
4222
4228
|
let data = "";
|
|
@@ -4225,18 +4231,18 @@ function fetchLatestVersion() {
|
|
|
4225
4231
|
});
|
|
4226
4232
|
res.on("end", () => {
|
|
4227
4233
|
try {
|
|
4228
|
-
|
|
4234
|
+
resolve5(JSON.parse(data).version);
|
|
4229
4235
|
} catch {
|
|
4230
|
-
|
|
4236
|
+
resolve5(null);
|
|
4231
4237
|
}
|
|
4232
4238
|
});
|
|
4233
4239
|
});
|
|
4234
4240
|
req.on("error", () => {
|
|
4235
|
-
|
|
4241
|
+
resolve5(null);
|
|
4236
4242
|
});
|
|
4237
4243
|
req.on("timeout", () => {
|
|
4238
4244
|
req.destroy();
|
|
4239
|
-
|
|
4245
|
+
resolve5(null);
|
|
4240
4246
|
});
|
|
4241
4247
|
});
|
|
4242
4248
|
}
|
|
@@ -4338,7 +4344,7 @@ function parseArgs(argv) {
|
|
|
4338
4344
|
}
|
|
4339
4345
|
break;
|
|
4340
4346
|
case "--data-dir":
|
|
4341
|
-
dataDir2 =
|
|
4347
|
+
dataDir2 = resolve4(args[++i]);
|
|
4342
4348
|
break;
|
|
4343
4349
|
case "--check-for-updates":
|
|
4344
4350
|
forceUpdateCheck = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hotsheet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "A lightweight local project management tool. Create, categorize, and prioritize tickets with a fast bullet-list interface, then export an Up Next worklist for AI tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|