hotsheet 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.js +131 -14
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -72,9 +72,9 @@ var init_gitignore = __esm({
|
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
// src/cli.ts
|
|
75
|
-
import { mkdirSync as
|
|
75
|
+
import { mkdirSync as mkdirSync4 } from "fs";
|
|
76
76
|
import { tmpdir } from "os";
|
|
77
|
-
import { join as
|
|
77
|
+
import { join as join7, resolve } from "path";
|
|
78
78
|
|
|
79
79
|
// src/cleanup.ts
|
|
80
80
|
import { rmSync as rmSync2 } from "fs";
|
|
@@ -1475,8 +1475,8 @@ apiRoutes.post("/tickets/:id/attachments", async (c) => {
|
|
|
1475
1475
|
mkdirSync2(attachDir, { recursive: true });
|
|
1476
1476
|
const storedPath = join4(attachDir, storedName);
|
|
1477
1477
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
1478
|
-
const { writeFileSync:
|
|
1479
|
-
|
|
1478
|
+
const { writeFileSync: writeFileSync4 } = await import("fs");
|
|
1479
|
+
writeFileSync4(storedPath, buffer);
|
|
1480
1480
|
const attachment = await addAttachment(id, originalName, storedPath);
|
|
1481
1481
|
scheduleAllSync();
|
|
1482
1482
|
notifyChange();
|
|
@@ -1501,8 +1501,8 @@ apiRoutes.get("/attachments/file/*", async (c) => {
|
|
|
1501
1501
|
if (!existsSync2(fullPath)) {
|
|
1502
1502
|
return c.json({ error: "File not found" }, 404);
|
|
1503
1503
|
}
|
|
1504
|
-
const { readFileSync:
|
|
1505
|
-
const content =
|
|
1504
|
+
const { readFileSync: readFileSync4 } = await import("fs");
|
|
1505
|
+
const content = readFileSync4(fullPath);
|
|
1506
1506
|
const ext = extname(fullPath).toLowerCase();
|
|
1507
1507
|
const mimeTypes = {
|
|
1508
1508
|
".png": "image/png",
|
|
@@ -1955,6 +1955,117 @@ async function startServer(port, dataDir2) {
|
|
|
1955
1955
|
exec(`${openCmd} ${url}`);
|
|
1956
1956
|
}
|
|
1957
1957
|
|
|
1958
|
+
// src/update-check.ts
|
|
1959
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1960
|
+
import { get } from "https";
|
|
1961
|
+
import { homedir } from "os";
|
|
1962
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
1963
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1964
|
+
var DATA_DIR = join6(homedir(), ".hotsheet");
|
|
1965
|
+
var CHECK_FILE = join6(DATA_DIR, "last-update-check");
|
|
1966
|
+
var PACKAGE_NAME = "hotsheet";
|
|
1967
|
+
function getCurrentVersion() {
|
|
1968
|
+
try {
|
|
1969
|
+
const dir = dirname2(fileURLToPath2(import.meta.url));
|
|
1970
|
+
const pkg = JSON.parse(readFileSync3(join6(dir, "..", "package.json"), "utf-8"));
|
|
1971
|
+
return pkg.version;
|
|
1972
|
+
} catch {
|
|
1973
|
+
return "0.0.0";
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
function getLastCheckDate() {
|
|
1977
|
+
try {
|
|
1978
|
+
if (existsSync4(CHECK_FILE)) {
|
|
1979
|
+
return readFileSync3(CHECK_FILE, "utf-8").trim();
|
|
1980
|
+
}
|
|
1981
|
+
} catch {
|
|
1982
|
+
}
|
|
1983
|
+
return null;
|
|
1984
|
+
}
|
|
1985
|
+
function saveCheckDate() {
|
|
1986
|
+
mkdirSync3(DATA_DIR, { recursive: true });
|
|
1987
|
+
writeFileSync3(CHECK_FILE, (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), "utf-8");
|
|
1988
|
+
}
|
|
1989
|
+
function isFirstUseToday() {
|
|
1990
|
+
const last = getLastCheckDate();
|
|
1991
|
+
if (last === null) return true;
|
|
1992
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
1993
|
+
return last !== today;
|
|
1994
|
+
}
|
|
1995
|
+
function fetchLatestVersion() {
|
|
1996
|
+
return new Promise((resolve2) => {
|
|
1997
|
+
const req = get(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, { timeout: 5e3 }, (res) => {
|
|
1998
|
+
if (res.statusCode !== 200) {
|
|
1999
|
+
resolve2(null);
|
|
2000
|
+
return;
|
|
2001
|
+
}
|
|
2002
|
+
let data = "";
|
|
2003
|
+
res.on("data", (chunk) => {
|
|
2004
|
+
data += chunk.toString();
|
|
2005
|
+
});
|
|
2006
|
+
res.on("end", () => {
|
|
2007
|
+
try {
|
|
2008
|
+
resolve2(JSON.parse(data).version);
|
|
2009
|
+
} catch {
|
|
2010
|
+
resolve2(null);
|
|
2011
|
+
}
|
|
2012
|
+
});
|
|
2013
|
+
});
|
|
2014
|
+
req.on("error", () => {
|
|
2015
|
+
resolve2(null);
|
|
2016
|
+
});
|
|
2017
|
+
req.on("timeout", () => {
|
|
2018
|
+
req.destroy();
|
|
2019
|
+
resolve2(null);
|
|
2020
|
+
});
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
function detectUpgradeCommand() {
|
|
2024
|
+
const binPath = process.argv[1] || "";
|
|
2025
|
+
if (binPath.includes("/.bun/") || binPath.includes("/bun/")) {
|
|
2026
|
+
return `bun update -g ${PACKAGE_NAME}`;
|
|
2027
|
+
}
|
|
2028
|
+
if (binPath.includes("/.pnpm/") || binPath.includes("/pnpm/")) {
|
|
2029
|
+
return `pnpm update -g ${PACKAGE_NAME}`;
|
|
2030
|
+
}
|
|
2031
|
+
if (binPath.includes("/.yarn/") || binPath.includes("/yarn/")) {
|
|
2032
|
+
return `yarn global upgrade ${PACKAGE_NAME}`;
|
|
2033
|
+
}
|
|
2034
|
+
return `npm update -g ${PACKAGE_NAME}`;
|
|
2035
|
+
}
|
|
2036
|
+
function compareVersions(current, latest) {
|
|
2037
|
+
const a = current.split(".").map(Number);
|
|
2038
|
+
const b = latest.split(".").map(Number);
|
|
2039
|
+
for (let i = 0; i < 3; i++) {
|
|
2040
|
+
if ((a[i] || 0) < (b[i] || 0)) return -1;
|
|
2041
|
+
if ((a[i] || 0) > (b[i] || 0)) return 1;
|
|
2042
|
+
}
|
|
2043
|
+
return 0;
|
|
2044
|
+
}
|
|
2045
|
+
async function checkForUpdates(force) {
|
|
2046
|
+
if (!force && !isFirstUseToday()) return;
|
|
2047
|
+
const current = getCurrentVersion();
|
|
2048
|
+
const latest = await fetchLatestVersion();
|
|
2049
|
+
saveCheckDate();
|
|
2050
|
+
if (latest === null || compareVersions(current, latest) >= 0) return;
|
|
2051
|
+
const cmd = detectUpgradeCommand();
|
|
2052
|
+
const updateLine = `Update available: ${current} \u2192 ${latest}`;
|
|
2053
|
+
const cmdLine = `Run: ${cmd}`;
|
|
2054
|
+
const width = Math.max(updateLine.length, cmdLine.length) + 4;
|
|
2055
|
+
const pad = (text, visLen) => text + " ".repeat(Math.max(0, width - visLen));
|
|
2056
|
+
const border = "\u2500".repeat(width);
|
|
2057
|
+
const empty = " ".repeat(width);
|
|
2058
|
+
console.log("");
|
|
2059
|
+
console.log(` \u250C${border}\u2510`);
|
|
2060
|
+
console.log(` \u2502${empty}\u2502`);
|
|
2061
|
+
console.log(` \u2502 ${pad(`Update available: ${current} \u2192 \x1B[32m${latest}\x1B[0m`, updateLine.length + 2)}\u2502`);
|
|
2062
|
+
console.log(` \u2502${empty}\u2502`);
|
|
2063
|
+
console.log(` \u2502 ${pad(`Run: \x1B[36m${cmd}\x1B[0m`, cmdLine.length + 2)}\u2502`);
|
|
2064
|
+
console.log(` \u2502${empty}\u2502`);
|
|
2065
|
+
console.log(` \u2514${border}\u2518`);
|
|
2066
|
+
console.log("");
|
|
2067
|
+
}
|
|
2068
|
+
|
|
1958
2069
|
// src/cli.ts
|
|
1959
2070
|
function printUsage() {
|
|
1960
2071
|
console.log(`
|
|
@@ -1964,9 +2075,10 @@ Usage:
|
|
|
1964
2075
|
hotsheet [options]
|
|
1965
2076
|
|
|
1966
2077
|
Options:
|
|
1967
|
-
--port <number>
|
|
1968
|
-
--data-dir <path>
|
|
1969
|
-
--
|
|
2078
|
+
--port <number> Port to run on (default: 4174)
|
|
2079
|
+
--data-dir <path> Store data in an alternative location (default: .hotsheet/)
|
|
2080
|
+
--check-for-updates Check for new versions now
|
|
2081
|
+
--help Show this help message
|
|
1970
2082
|
|
|
1971
2083
|
Examples:
|
|
1972
2084
|
hotsheet
|
|
@@ -1977,8 +2089,9 @@ Examples:
|
|
|
1977
2089
|
function parseArgs(argv) {
|
|
1978
2090
|
const args = argv.slice(2);
|
|
1979
2091
|
let port = 4174;
|
|
1980
|
-
let dataDir2 =
|
|
2092
|
+
let dataDir2 = join7(process.cwd(), ".hotsheet");
|
|
1981
2093
|
let demo = null;
|
|
2094
|
+
let forceUpdateCheck = false;
|
|
1982
2095
|
for (let i = 0; i < args.length; i++) {
|
|
1983
2096
|
const arg = args[i];
|
|
1984
2097
|
if (arg.startsWith("--demo:")) {
|
|
@@ -2005,13 +2118,16 @@ function parseArgs(argv) {
|
|
|
2005
2118
|
case "--data-dir":
|
|
2006
2119
|
dataDir2 = resolve(args[++i]);
|
|
2007
2120
|
break;
|
|
2121
|
+
case "--check-for-updates":
|
|
2122
|
+
forceUpdateCheck = true;
|
|
2123
|
+
break;
|
|
2008
2124
|
default:
|
|
2009
2125
|
console.error(`Unknown option: ${arg}`);
|
|
2010
2126
|
printUsage();
|
|
2011
2127
|
process.exit(1);
|
|
2012
2128
|
}
|
|
2013
2129
|
}
|
|
2014
|
-
return { port, dataDir: dataDir2, demo };
|
|
2130
|
+
return { port, dataDir: dataDir2, demo, forceUpdateCheck };
|
|
2015
2131
|
}
|
|
2016
2132
|
async function main() {
|
|
2017
2133
|
const parsed = parseArgs(process.argv);
|
|
@@ -2019,8 +2135,9 @@ async function main() {
|
|
|
2019
2135
|
printUsage();
|
|
2020
2136
|
process.exit(1);
|
|
2021
2137
|
}
|
|
2022
|
-
const { port, demo } = parsed;
|
|
2138
|
+
const { port, demo, forceUpdateCheck } = parsed;
|
|
2023
2139
|
let { dataDir: dataDir2 } = parsed;
|
|
2140
|
+
await checkForUpdates(forceUpdateCheck);
|
|
2024
2141
|
if (demo !== null) {
|
|
2025
2142
|
const scenario = DEMO_SCENARIOS.find((s) => s.id === demo);
|
|
2026
2143
|
if (!scenario) {
|
|
@@ -2031,12 +2148,12 @@ async function main() {
|
|
|
2031
2148
|
}
|
|
2032
2149
|
process.exit(1);
|
|
2033
2150
|
}
|
|
2034
|
-
dataDir2 =
|
|
2151
|
+
dataDir2 = join7(tmpdir(), `hotsheet-demo-${demo}-${Date.now()}`);
|
|
2035
2152
|
console.log(`
|
|
2036
2153
|
DEMO MODE: ${scenario.label}
|
|
2037
2154
|
`);
|
|
2038
2155
|
}
|
|
2039
|
-
|
|
2156
|
+
mkdirSync4(dataDir2, { recursive: true });
|
|
2040
2157
|
if (demo === null) {
|
|
2041
2158
|
ensureGitignore(process.cwd());
|
|
2042
2159
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hotsheet",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
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",
|