@storybloq/storybloq 1.4.2 → 1.4.3
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 +443 -106
- package/dist/index.d.ts +50 -50
- package/dist/index.js +1 -1
- package/dist/mcp.js +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1809,7 +1809,7 @@ var init_init = __esm({
|
|
|
1809
1809
|
init_esm_shims();
|
|
1810
1810
|
init_project_loader();
|
|
1811
1811
|
init_errors();
|
|
1812
|
-
STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/"];
|
|
1812
|
+
STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/", "federation-cache.json"];
|
|
1813
1813
|
}
|
|
1814
1814
|
});
|
|
1815
1815
|
|
|
@@ -9424,7 +9424,7 @@ async function scanNodeSummary(storyDir, signal) {
|
|
|
9424
9424
|
};
|
|
9425
9425
|
}
|
|
9426
9426
|
function withTimeout(promise, ms, controller) {
|
|
9427
|
-
return new Promise((
|
|
9427
|
+
return new Promise((resolve16, reject) => {
|
|
9428
9428
|
const timer = setTimeout(() => {
|
|
9429
9429
|
controller.abort();
|
|
9430
9430
|
reject(new Error("timeout"));
|
|
@@ -9432,7 +9432,7 @@ function withTimeout(promise, ms, controller) {
|
|
|
9432
9432
|
promise.then(
|
|
9433
9433
|
(val) => {
|
|
9434
9434
|
clearTimeout(timer);
|
|
9435
|
-
|
|
9435
|
+
resolve16(val);
|
|
9436
9436
|
},
|
|
9437
9437
|
(err) => {
|
|
9438
9438
|
clearTimeout(timer);
|
|
@@ -11240,17 +11240,17 @@ __export(git_inspector_exports, {
|
|
|
11240
11240
|
});
|
|
11241
11241
|
import { execFile } from "child_process";
|
|
11242
11242
|
async function git(cwd, args, parse) {
|
|
11243
|
-
return new Promise((
|
|
11243
|
+
return new Promise((resolve16) => {
|
|
11244
11244
|
execFile("git", args, { cwd, timeout: GIT_TIMEOUT, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
11245
11245
|
if (err) {
|
|
11246
11246
|
const message = stderr?.trim() || err.message || "unknown git error";
|
|
11247
|
-
|
|
11247
|
+
resolve16({ ok: false, reason: "git_error", message });
|
|
11248
11248
|
return;
|
|
11249
11249
|
}
|
|
11250
11250
|
try {
|
|
11251
|
-
|
|
11251
|
+
resolve16({ ok: true, data: parse(stdout) });
|
|
11252
11252
|
} catch (parseErr) {
|
|
11253
|
-
|
|
11253
|
+
resolve16({ ok: false, reason: "parse_error", message: parseErr.message });
|
|
11254
11254
|
}
|
|
11255
11255
|
});
|
|
11256
11256
|
});
|
|
@@ -11357,22 +11357,22 @@ async function gitIsAncestor(cwd, ancestor, descendant) {
|
|
|
11357
11357
|
if (!SAFE_REF.test(ancestor) || !SAFE_REF.test(descendant)) {
|
|
11358
11358
|
return { ok: false, reason: "git_error", message: "invalid ref format" };
|
|
11359
11359
|
}
|
|
11360
|
-
return new Promise((
|
|
11360
|
+
return new Promise((resolve16) => {
|
|
11361
11361
|
execFile(
|
|
11362
11362
|
"git",
|
|
11363
11363
|
["merge-base", "--is-ancestor", ancestor, descendant],
|
|
11364
11364
|
{ cwd, timeout: GIT_TIMEOUT },
|
|
11365
11365
|
(err) => {
|
|
11366
11366
|
if (!err) {
|
|
11367
|
-
|
|
11367
|
+
resolve16({ ok: true, data: true });
|
|
11368
11368
|
return;
|
|
11369
11369
|
}
|
|
11370
11370
|
const code = err.code;
|
|
11371
11371
|
if (code === 1) {
|
|
11372
|
-
|
|
11372
|
+
resolve16({ ok: true, data: false });
|
|
11373
11373
|
return;
|
|
11374
11374
|
}
|
|
11375
|
-
|
|
11375
|
+
resolve16({ ok: false, reason: "git_error", message: err.message });
|
|
11376
11376
|
}
|
|
11377
11377
|
);
|
|
11378
11378
|
});
|
|
@@ -11394,14 +11394,14 @@ async function gitLogRange(cwd, from, to, limit = 20) {
|
|
|
11394
11394
|
);
|
|
11395
11395
|
}
|
|
11396
11396
|
async function gitHeadHash(cwd) {
|
|
11397
|
-
return new Promise((
|
|
11397
|
+
return new Promise((resolve16) => {
|
|
11398
11398
|
execFile("git", ["rev-parse", "HEAD"], { cwd, timeout: 3e3 }, (err, stdout) => {
|
|
11399
11399
|
if (err) {
|
|
11400
11400
|
const message = err.stderr?.trim() || err.message || "unknown git error";
|
|
11401
|
-
|
|
11401
|
+
resolve16({ ok: false, reason: "git_error", message });
|
|
11402
11402
|
return;
|
|
11403
11403
|
}
|
|
11404
|
-
|
|
11404
|
+
resolve16({ ok: true, data: stdout.trim() });
|
|
11405
11405
|
});
|
|
11406
11406
|
});
|
|
11407
11407
|
}
|
|
@@ -11419,7 +11419,7 @@ async function gitResolveCommit(cwd, hash) {
|
|
|
11419
11419
|
if (!SAFE_REF.test(hash)) {
|
|
11420
11420
|
return { ok: false, reason: "git_error", message: "invalid ref format" };
|
|
11421
11421
|
}
|
|
11422
|
-
return new Promise((
|
|
11422
|
+
return new Promise((resolve16) => {
|
|
11423
11423
|
execFile(
|
|
11424
11424
|
"git",
|
|
11425
11425
|
["rev-parse", "--verify", `${hash}^{commit}`],
|
|
@@ -11427,10 +11427,10 @@ async function gitResolveCommit(cwd, hash) {
|
|
|
11427
11427
|
(err, stdout, stderr) => {
|
|
11428
11428
|
if (err) {
|
|
11429
11429
|
const message = stderr?.trim() || err.message || "unknown git error";
|
|
11430
|
-
|
|
11430
|
+
resolve16({ ok: false, reason: "git_error", message });
|
|
11431
11431
|
return;
|
|
11432
11432
|
}
|
|
11433
|
-
|
|
11433
|
+
resolve16({ ok: true, data: stdout.trim() });
|
|
11434
11434
|
}
|
|
11435
11435
|
);
|
|
11436
11436
|
});
|
|
@@ -11452,18 +11452,18 @@ async function gitCheckoutNewBranch(cwd, branchName, base) {
|
|
|
11452
11452
|
return git(cwd, ["checkout", "-b", branchName, base], () => void 0);
|
|
11453
11453
|
}
|
|
11454
11454
|
async function gitBranchExists(cwd, branchName) {
|
|
11455
|
-
return new Promise((
|
|
11455
|
+
return new Promise((resolve16) => {
|
|
11456
11456
|
execFile("git", ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], { cwd, timeout: GIT_TIMEOUT }, (err) => {
|
|
11457
11457
|
if (err) {
|
|
11458
11458
|
const exitCode = err.code;
|
|
11459
11459
|
if (exitCode === 1) {
|
|
11460
|
-
|
|
11460
|
+
resolve16({ ok: true, data: false });
|
|
11461
11461
|
} else {
|
|
11462
|
-
|
|
11462
|
+
resolve16({ ok: false, reason: "git_error", message: err.message });
|
|
11463
11463
|
}
|
|
11464
11464
|
return;
|
|
11465
11465
|
}
|
|
11466
|
-
|
|
11466
|
+
resolve16({ ok: true, data: true });
|
|
11467
11467
|
});
|
|
11468
11468
|
});
|
|
11469
11469
|
}
|
|
@@ -11471,13 +11471,13 @@ async function gitCheckoutBranch(cwd, branchName) {
|
|
|
11471
11471
|
return git(cwd, ["checkout", branchName], () => void 0);
|
|
11472
11472
|
}
|
|
11473
11473
|
async function gitCheckRefFormat(cwd, refName) {
|
|
11474
|
-
return new Promise((
|
|
11474
|
+
return new Promise((resolve16) => {
|
|
11475
11475
|
execFile("git", ["check-ref-format", "--branch", refName], { cwd, timeout: GIT_TIMEOUT }, (err) => {
|
|
11476
11476
|
if (err) {
|
|
11477
|
-
|
|
11477
|
+
resolve16({ ok: true, data: false });
|
|
11478
11478
|
return;
|
|
11479
11479
|
}
|
|
11480
|
-
|
|
11480
|
+
resolve16({ ok: true, data: true });
|
|
11481
11481
|
});
|
|
11482
11482
|
});
|
|
11483
11483
|
}
|
|
@@ -17571,7 +17571,7 @@ function getInstalledVersion() {
|
|
|
17571
17571
|
}
|
|
17572
17572
|
}
|
|
17573
17573
|
function getRunningVersion() {
|
|
17574
|
-
return "1.4.
|
|
17574
|
+
return "1.4.3";
|
|
17575
17575
|
}
|
|
17576
17576
|
var init_version_check = __esm({
|
|
17577
17577
|
"src/autonomous/version-check.ts"() {
|
|
@@ -19863,7 +19863,7 @@ function registerAllTools(server, pinnedRoot) {
|
|
|
19863
19863
|
const result = await runMcpReadTool(pinnedRoot, handleStatus);
|
|
19864
19864
|
try {
|
|
19865
19865
|
const { readUpdateCacheSync: readUpdateCacheSync2, refreshUpdateCacheInBackground: refreshUpdateCacheInBackground2 } = await Promise.resolve().then(() => (init_update_check(), update_check_exports));
|
|
19866
|
-
const running = "1.4.
|
|
19866
|
+
const running = "1.4.3";
|
|
19867
19867
|
const info = readUpdateCacheSync2(running);
|
|
19868
19868
|
refreshUpdateCacheInBackground2();
|
|
19869
19869
|
if (info?.updateAvailable && result.content[0]?.type === "text") {
|
|
@@ -21506,7 +21506,7 @@ var init_mcp = __esm({
|
|
|
21506
21506
|
ENV_VAR2 = "STORYBLOQ_PROJECT_ROOT";
|
|
21507
21507
|
LEGACY_ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
21508
21508
|
CONFIG_PATH2 = ".story/config.json";
|
|
21509
|
-
version = "1.4.
|
|
21509
|
+
version = "1.4.3";
|
|
21510
21510
|
main().catch((err) => {
|
|
21511
21511
|
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}
|
|
21512
21512
|
`);
|
|
@@ -22973,7 +22973,7 @@ function codePrompt(sessionId) {
|
|
|
22973
22973
|
].join(" ");
|
|
22974
22974
|
}
|
|
22975
22975
|
async function runCodexExec(root, prompt, schemaPath, outputPath, timeoutMs) {
|
|
22976
|
-
await new Promise((
|
|
22976
|
+
await new Promise((resolve16, reject) => {
|
|
22977
22977
|
const child = spawn3("codex", [
|
|
22978
22978
|
"exec",
|
|
22979
22979
|
"--ephemeral",
|
|
@@ -23016,7 +23016,7 @@ async function runCodexExec(root, prompt, schemaPath, outputPath, timeoutMs) {
|
|
|
23016
23016
|
if (timedOut) {
|
|
23017
23017
|
finish(() => reject(new Error(`codex exec timed out after ${Math.round(timeoutMs / 1e3)} seconds`)));
|
|
23018
23018
|
} else if (code === 0) {
|
|
23019
|
-
finish(() =>
|
|
23019
|
+
finish(() => resolve16());
|
|
23020
23020
|
} else {
|
|
23021
23021
|
finish(() => reject(new Error(`codex exec exited with status ${code}: ${stderr.trim()}`)));
|
|
23022
23022
|
}
|
|
@@ -23110,6 +23110,64 @@ var init_codex_review = __esm({
|
|
|
23110
23110
|
}
|
|
23111
23111
|
});
|
|
23112
23112
|
|
|
23113
|
+
// src/core/symlink-write.ts
|
|
23114
|
+
import { lstat as lstat3, mkdir as mkdir7, readlink, realpath as realpath2, rename as rename3, unlink as unlink4, writeFile as writeFile4 } from "fs/promises";
|
|
23115
|
+
import { dirname as dirname8, isAbsolute as isAbsolute3, resolve as resolve15 } from "path";
|
|
23116
|
+
async function resolveSymlinkTarget(path2) {
|
|
23117
|
+
try {
|
|
23118
|
+
return await realpath2(path2);
|
|
23119
|
+
} catch (e) {
|
|
23120
|
+
if (e.code !== "ENOENT") throw e;
|
|
23121
|
+
let cur = path2;
|
|
23122
|
+
for (let depth = 0; depth < MAX_SYMLINK_DEPTH; depth++) {
|
|
23123
|
+
const link = await readlink(cur);
|
|
23124
|
+
const next = isAbsolute3(link) ? link : resolve15(dirname8(cur), link);
|
|
23125
|
+
let st;
|
|
23126
|
+
try {
|
|
23127
|
+
st = await lstat3(next);
|
|
23128
|
+
} catch (le) {
|
|
23129
|
+
if (le.code === "ENOENT") return next;
|
|
23130
|
+
throw le;
|
|
23131
|
+
}
|
|
23132
|
+
if (st.isSymbolicLink()) {
|
|
23133
|
+
cur = next;
|
|
23134
|
+
continue;
|
|
23135
|
+
}
|
|
23136
|
+
return next;
|
|
23137
|
+
}
|
|
23138
|
+
throw new Error(`symlink chain too deep at ${path2}`);
|
|
23139
|
+
}
|
|
23140
|
+
}
|
|
23141
|
+
async function atomicWriteFollowingSymlink(targetPath, contents) {
|
|
23142
|
+
let st = null;
|
|
23143
|
+
try {
|
|
23144
|
+
st = await lstat3(targetPath);
|
|
23145
|
+
} catch (e) {
|
|
23146
|
+
if (e.code !== "ENOENT") throw e;
|
|
23147
|
+
}
|
|
23148
|
+
const realTarget = st?.isSymbolicLink() ? await resolveSymlinkTarget(targetPath) : targetPath;
|
|
23149
|
+
const tmpPath = `${realTarget}.${process.pid}.tmp`;
|
|
23150
|
+
try {
|
|
23151
|
+
await mkdir7(dirname8(realTarget), { recursive: true });
|
|
23152
|
+
await writeFile4(tmpPath, contents, "utf-8");
|
|
23153
|
+
await rename3(tmpPath, realTarget);
|
|
23154
|
+
} catch (err) {
|
|
23155
|
+
try {
|
|
23156
|
+
await unlink4(tmpPath);
|
|
23157
|
+
} catch {
|
|
23158
|
+
}
|
|
23159
|
+
throw err;
|
|
23160
|
+
}
|
|
23161
|
+
}
|
|
23162
|
+
var MAX_SYMLINK_DEPTH;
|
|
23163
|
+
var init_symlink_write = __esm({
|
|
23164
|
+
"src/core/symlink-write.ts"() {
|
|
23165
|
+
"use strict";
|
|
23166
|
+
init_esm_shims();
|
|
23167
|
+
MAX_SYMLINK_DEPTH = 40;
|
|
23168
|
+
}
|
|
23169
|
+
});
|
|
23170
|
+
|
|
23113
23171
|
// src/core/hook-migration.ts
|
|
23114
23172
|
var hook_migration_exports = {};
|
|
23115
23173
|
__export(hook_migration_exports, {
|
|
@@ -23123,10 +23181,10 @@ __export(hook_migration_exports, {
|
|
|
23123
23181
|
parseHookCommand: () => parseHookCommand,
|
|
23124
23182
|
sweepLegacyHooks: () => sweepLegacyHooks
|
|
23125
23183
|
});
|
|
23126
|
-
import {
|
|
23184
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
23127
23185
|
import { existsSync as existsSync22 } from "fs";
|
|
23128
23186
|
import { homedir as homedir4 } from "os";
|
|
23129
|
-
import { basename as basename5,
|
|
23187
|
+
import { basename as basename5, join as join51 } from "path";
|
|
23130
23188
|
function defaultSettingsPath() {
|
|
23131
23189
|
return join51(homedir4(), ".claude", "settings.json");
|
|
23132
23190
|
}
|
|
@@ -23253,17 +23311,9 @@ async function migrateLegacyHookVariants(hookType, subcommand, newCommand, setti
|
|
|
23253
23311
|
removedCount += before - g.hooks.length;
|
|
23254
23312
|
}
|
|
23255
23313
|
if (removedCount === 0) return 0;
|
|
23256
|
-
const tmpPath = `${path2}.${process.pid}.tmp`;
|
|
23257
23314
|
try {
|
|
23258
|
-
|
|
23259
|
-
await mkdir7(dir, { recursive: true });
|
|
23260
|
-
await writeFile4(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
23261
|
-
await rename3(tmpPath, path2);
|
|
23315
|
+
await atomicWriteFollowingSymlink(path2, JSON.stringify(settings, null, 2) + "\n");
|
|
23262
23316
|
} catch {
|
|
23263
|
-
try {
|
|
23264
|
-
await unlink4(tmpPath);
|
|
23265
|
-
} catch {
|
|
23266
|
-
}
|
|
23267
23317
|
return 0;
|
|
23268
23318
|
}
|
|
23269
23319
|
return removedCount;
|
|
@@ -23341,6 +23391,7 @@ var init_hook_migration = __esm({
|
|
|
23341
23391
|
"src/core/hook-migration.ts"() {
|
|
23342
23392
|
"use strict";
|
|
23343
23393
|
init_esm_shims();
|
|
23394
|
+
init_symlink_write();
|
|
23344
23395
|
PRECOMPACT_SUBCOMMAND = "session compact-prepare";
|
|
23345
23396
|
SESSIONSTART_SUBCOMMAND = "session resume-prompt";
|
|
23346
23397
|
STOP_SUBCOMMAND = "hook-status";
|
|
@@ -23458,6 +23509,7 @@ __export(setup_skill_exports, {
|
|
|
23458
23509
|
SESSIONSTART_SUBCOMMAND: () => SESSIONSTART_SUBCOMMAND,
|
|
23459
23510
|
STOP_SUBCOMMAND: () => STOP_SUBCOMMAND,
|
|
23460
23511
|
STORYBLOQ_LEGACY_BASENAMES: () => STORYBLOQ_LEGACY_BASENAMES,
|
|
23512
|
+
__copyDirRecursiveForTest: () => __copyDirRecursiveForTest,
|
|
23461
23513
|
copyDirRecursive: () => copyDirRecursive,
|
|
23462
23514
|
ensureCodexClientEnv: () => ensureCodexClientEnv,
|
|
23463
23515
|
ensureCodexToolApprovals: () => ensureCodexToolApprovals,
|
|
@@ -23478,7 +23530,7 @@ __export(setup_skill_exports, {
|
|
|
23478
23530
|
resolveStorybloqBin: () => resolveStorybloqBin,
|
|
23479
23531
|
sweepLegacyHooks: () => sweepLegacyHooks
|
|
23480
23532
|
});
|
|
23481
|
-
import { mkdir as mkdir8, writeFile as writeFile5, readFile as readFile11, readdir as readdir7, copyFile, rm, rename as rename4,
|
|
23533
|
+
import { mkdir as mkdir8, writeFile as writeFile5, readFile as readFile11, readdir as readdir7, copyFile, rm, rename as rename4, lstat as lstat4 } from "fs/promises";
|
|
23482
23534
|
import { existsSync as existsSync24, accessSync as accessSync4, readdirSync as readdirSync9, constants as fsConstants } from "fs";
|
|
23483
23535
|
import { join as join53, dirname as dirname9, delimiter as pathDelimiter } from "path";
|
|
23484
23536
|
import { homedir as homedir6 } from "os";
|
|
@@ -23500,10 +23552,38 @@ function resolveSkillSourceDir() {
|
|
|
23500
23552
|
);
|
|
23501
23553
|
}
|
|
23502
23554
|
async function copyDirRecursive(srcDir, destDir) {
|
|
23503
|
-
|
|
23504
|
-
|
|
23505
|
-
|
|
23506
|
-
|
|
23555
|
+
return runCopyDir(srcDir, destDir);
|
|
23556
|
+
}
|
|
23557
|
+
async function __copyDirRecursiveForTest(srcDir, destDir, testHooks) {
|
|
23558
|
+
return runCopyDir(srcDir, destDir, testHooks);
|
|
23559
|
+
}
|
|
23560
|
+
async function runCopyDir(srcDir, destDir, testHooks) {
|
|
23561
|
+
let st = null;
|
|
23562
|
+
try {
|
|
23563
|
+
st = await lstat4(destDir);
|
|
23564
|
+
} catch (e) {
|
|
23565
|
+
if (e.code !== "ENOENT") throw e;
|
|
23566
|
+
}
|
|
23567
|
+
let targetDir = destDir;
|
|
23568
|
+
if (st?.isSymbolicLink()) {
|
|
23569
|
+
targetDir = await resolveSymlinkTarget(destDir);
|
|
23570
|
+
let resolvedStat = null;
|
|
23571
|
+
try {
|
|
23572
|
+
resolvedStat = await lstat4(targetDir);
|
|
23573
|
+
} catch (e) {
|
|
23574
|
+
if (e.code !== "ENOENT") throw e;
|
|
23575
|
+
}
|
|
23576
|
+
if (resolvedStat && !resolvedStat.isDirectory()) {
|
|
23577
|
+
throw new Error(`refusing to replace non-directory symlink target: ${targetDir}`);
|
|
23578
|
+
}
|
|
23579
|
+
}
|
|
23580
|
+
return copyDirSwap(srcDir, targetDir, testHooks);
|
|
23581
|
+
}
|
|
23582
|
+
async function copyDirSwap(srcDir, targetDir, testHooks) {
|
|
23583
|
+
const tmpDir = targetDir + ".tmp";
|
|
23584
|
+
const bakDir = targetDir + ".bak";
|
|
23585
|
+
if (!existsSync24(targetDir) && existsSync24(bakDir)) {
|
|
23586
|
+
await rename4(bakDir, targetDir);
|
|
23507
23587
|
}
|
|
23508
23588
|
if (existsSync24(tmpDir)) await rm(tmpDir, { recursive: true, force: true });
|
|
23509
23589
|
if (existsSync24(bakDir)) await rm(bakDir, { recursive: true, force: true });
|
|
@@ -23520,13 +23600,14 @@ async function copyDirRecursive(srcDir, destDir) {
|
|
|
23520
23600
|
await copyFile(srcPath, destPath);
|
|
23521
23601
|
written.push(relativePath);
|
|
23522
23602
|
}
|
|
23523
|
-
if (existsSync24(
|
|
23524
|
-
await rename4(
|
|
23603
|
+
if (existsSync24(targetDir)) {
|
|
23604
|
+
await rename4(targetDir, bakDir);
|
|
23525
23605
|
}
|
|
23526
23606
|
try {
|
|
23527
|
-
await
|
|
23607
|
+
if (testHooks?.beforeSwapRename) await testHooks.beforeSwapRename();
|
|
23608
|
+
await rename4(tmpDir, targetDir);
|
|
23528
23609
|
} catch (err) {
|
|
23529
|
-
if (existsSync24(bakDir)) await rename4(bakDir,
|
|
23610
|
+
if (existsSync24(bakDir)) await rename4(bakDir, targetDir).catch(() => {
|
|
23530
23611
|
});
|
|
23531
23612
|
await rm(tmpDir, { recursive: true, force: true }).catch(() => {
|
|
23532
23613
|
});
|
|
@@ -23687,17 +23768,9 @@ async function registerHook(hookType, hookEntry, settingsPath, matcher) {
|
|
|
23687
23768
|
if (!appended) {
|
|
23688
23769
|
hookArray.push({ matcher: targetMatcher, hooks: [hookEntry] });
|
|
23689
23770
|
}
|
|
23690
|
-
const tmpPath = `${path2}.${process.pid}.tmp`;
|
|
23691
23771
|
try {
|
|
23692
|
-
|
|
23693
|
-
await mkdir8(dir, { recursive: true });
|
|
23694
|
-
await writeFile5(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
23695
|
-
await rename4(tmpPath, path2);
|
|
23772
|
+
await atomicWriteFollowingSymlink(path2, JSON.stringify(settings, null, 2) + "\n");
|
|
23696
23773
|
} catch (err) {
|
|
23697
|
-
try {
|
|
23698
|
-
await unlink5(tmpPath);
|
|
23699
|
-
} catch {
|
|
23700
|
-
}
|
|
23701
23774
|
const message = err instanceof Error ? err.message : String(err);
|
|
23702
23775
|
process.stderr.write(`Failed to write settings.json: ${message}
|
|
23703
23776
|
`);
|
|
@@ -23751,17 +23824,9 @@ async function removeHook(hookType, command, settingsPath) {
|
|
|
23751
23824
|
if (g.hooks.length < before) removed = true;
|
|
23752
23825
|
}
|
|
23753
23826
|
if (!removed) return "not_found";
|
|
23754
|
-
const tmpPath = `${path2}.${process.pid}.tmp`;
|
|
23755
23827
|
try {
|
|
23756
|
-
|
|
23757
|
-
await mkdir8(dir, { recursive: true });
|
|
23758
|
-
await writeFile5(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
23759
|
-
await rename4(tmpPath, path2);
|
|
23828
|
+
await atomicWriteFollowingSymlink(path2, JSON.stringify(settings, null, 2) + "\n");
|
|
23760
23829
|
} catch {
|
|
23761
|
-
try {
|
|
23762
|
-
await unlink5(tmpPath);
|
|
23763
|
-
} catch {
|
|
23764
|
-
}
|
|
23765
23830
|
return "skipped";
|
|
23766
23831
|
}
|
|
23767
23832
|
return "removed";
|
|
@@ -24009,16 +24074,9 @@ approval_mode = "approve"
|
|
|
24009
24074
|
if (next.length > 0 && !next.endsWith("\n\n")) next += "\n";
|
|
24010
24075
|
next += additions.join("\n");
|
|
24011
24076
|
}
|
|
24012
|
-
const tmpPath = `${configPath}.${process.pid}.tmp`;
|
|
24013
24077
|
try {
|
|
24014
|
-
await
|
|
24015
|
-
await writeFile5(tmpPath, next, "utf-8");
|
|
24016
|
-
await rename4(tmpPath, configPath);
|
|
24078
|
+
await atomicWriteFollowingSymlink(configPath, next);
|
|
24017
24079
|
} catch (err) {
|
|
24018
|
-
try {
|
|
24019
|
-
await unlink5(tmpPath);
|
|
24020
|
-
} catch {
|
|
24021
|
-
}
|
|
24022
24080
|
const message = err instanceof Error ? err.message : String(err);
|
|
24023
24081
|
process.stderr.write(`Failed to write Codex config.toml: ${message}
|
|
24024
24082
|
`);
|
|
@@ -24098,16 +24156,9 @@ async function ensureCodexClientEnv(configPath = codexConfigPath()) {
|
|
|
24098
24156
|
STORYBLOQ_CLIENT = "codex"
|
|
24099
24157
|
`;
|
|
24100
24158
|
}
|
|
24101
|
-
const tmpPath = `${configPath}.${process.pid}.tmp`;
|
|
24102
24159
|
try {
|
|
24103
|
-
await
|
|
24104
|
-
await writeFile5(tmpPath, next, "utf-8");
|
|
24105
|
-
await rename4(tmpPath, configPath);
|
|
24160
|
+
await atomicWriteFollowingSymlink(configPath, next);
|
|
24106
24161
|
} catch (err) {
|
|
24107
|
-
try {
|
|
24108
|
-
await unlink5(tmpPath);
|
|
24109
|
-
} catch {
|
|
24110
|
-
}
|
|
24111
24162
|
const message = err instanceof Error ? err.message : String(err);
|
|
24112
24163
|
process.stderr.write(`Failed to write Codex config.toml: ${message}
|
|
24113
24164
|
`);
|
|
@@ -24154,16 +24205,9 @@ async function migrateCodexHookVariants(hookType, acceptedRests, newCommand, hoo
|
|
|
24154
24205
|
removedCount += before - g.hooks.length;
|
|
24155
24206
|
}
|
|
24156
24207
|
if (removedCount === 0) return 0;
|
|
24157
|
-
const tmpPath = `${hooksPath}.${process.pid}.tmp`;
|
|
24158
24208
|
try {
|
|
24159
|
-
await
|
|
24160
|
-
await writeFile5(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
24161
|
-
await rename4(tmpPath, hooksPath);
|
|
24209
|
+
await atomicWriteFollowingSymlink(hooksPath, JSON.stringify(settings, null, 2) + "\n");
|
|
24162
24210
|
} catch {
|
|
24163
|
-
try {
|
|
24164
|
-
await unlink5(tmpPath);
|
|
24165
|
-
} catch {
|
|
24166
|
-
}
|
|
24167
24211
|
return 0;
|
|
24168
24212
|
}
|
|
24169
24213
|
return removedCount;
|
|
@@ -24239,16 +24283,9 @@ async function registerCodexHook(hookType, hookEntry, hooksPath = codexHooksPath
|
|
|
24239
24283
|
if (targetMatcher) group.matcher = targetMatcher;
|
|
24240
24284
|
hookArray.push(group);
|
|
24241
24285
|
}
|
|
24242
|
-
const tmpPath = `${hooksPath}.${process.pid}.tmp`;
|
|
24243
24286
|
try {
|
|
24244
|
-
await
|
|
24245
|
-
await writeFile5(tmpPath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
24246
|
-
await rename4(tmpPath, hooksPath);
|
|
24287
|
+
await atomicWriteFollowingSymlink(hooksPath, JSON.stringify(settings, null, 2) + "\n");
|
|
24247
24288
|
} catch (err) {
|
|
24248
|
-
try {
|
|
24249
|
-
await unlink5(tmpPath);
|
|
24250
|
-
} catch {
|
|
24251
|
-
}
|
|
24252
24289
|
const message = err instanceof Error ? err.message : String(err);
|
|
24253
24290
|
process.stderr.write(`Failed to write Codex hooks.json: ${message}
|
|
24254
24291
|
`);
|
|
@@ -24276,8 +24313,14 @@ async function handleSetupCodex(options = {}) {
|
|
|
24276
24313
|
log(` ${writtenFiles.join(" + ")} written`);
|
|
24277
24314
|
const compatSkillDir = join53(codexHome(), "skills", "story");
|
|
24278
24315
|
if (existsSync24(join53(compatSkillDir, "SKILL.md"))) {
|
|
24279
|
-
|
|
24280
|
-
|
|
24316
|
+
try {
|
|
24317
|
+
const compatFiles = await copyDirRecursive(srcSkillDir, compatSkillDir);
|
|
24318
|
+
log(` Refreshed existing Codex skill copy at ${compatSkillDir}/ (${compatFiles.length} files)`);
|
|
24319
|
+
} catch (err) {
|
|
24320
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
24321
|
+
process.stderr.write(`Warning: Codex skill copy refresh failed: ${msg}
|
|
24322
|
+
`);
|
|
24323
|
+
}
|
|
24281
24324
|
}
|
|
24282
24325
|
let cliInPath = false;
|
|
24283
24326
|
try {
|
|
@@ -24400,6 +24443,7 @@ var init_setup_skill = __esm({
|
|
|
24400
24443
|
"src/cli/commands/setup-skill.ts"() {
|
|
24401
24444
|
"use strict";
|
|
24402
24445
|
init_esm_shims();
|
|
24446
|
+
init_symlink_write();
|
|
24403
24447
|
init_hook_migration();
|
|
24404
24448
|
LEGACY_PRECOMPACT_HOOK_COMMAND = "storybloq snapshot --quiet";
|
|
24405
24449
|
CODEX_READ_ONLY_APPROVAL_TOOLS = [
|
|
@@ -25347,7 +25391,7 @@ function renderRepairSummary(toSupersede, skippedPreLock, mutationSkipped, resul
|
|
|
25347
25391
|
return lines.join("\n");
|
|
25348
25392
|
}
|
|
25349
25393
|
async function readOneLine(stream) {
|
|
25350
|
-
return new Promise((
|
|
25394
|
+
return new Promise((resolve16) => {
|
|
25351
25395
|
let buf = "";
|
|
25352
25396
|
let done = false;
|
|
25353
25397
|
const onData = (chunk) => {
|
|
@@ -25358,7 +25402,7 @@ async function readOneLine(stream) {
|
|
|
25358
25402
|
done = true;
|
|
25359
25403
|
stream.removeListener("data", onData);
|
|
25360
25404
|
stream.removeListener("end", onEnd);
|
|
25361
|
-
|
|
25405
|
+
resolve16(buf.slice(0, nl));
|
|
25362
25406
|
}
|
|
25363
25407
|
};
|
|
25364
25408
|
const onEnd = () => {
|
|
@@ -25366,7 +25410,7 @@ async function readOneLine(stream) {
|
|
|
25366
25410
|
done = true;
|
|
25367
25411
|
stream.removeListener("data", onData);
|
|
25368
25412
|
stream.removeListener("end", onEnd);
|
|
25369
|
-
|
|
25413
|
+
resolve16(buf);
|
|
25370
25414
|
};
|
|
25371
25415
|
stream.on("data", onData);
|
|
25372
25416
|
stream.on("end", onEnd);
|
|
@@ -25572,6 +25616,220 @@ var init_session_watch = __esm({
|
|
|
25572
25616
|
}
|
|
25573
25617
|
});
|
|
25574
25618
|
|
|
25619
|
+
// src/feedback/github-client.ts
|
|
25620
|
+
async function fetchIssues(options) {
|
|
25621
|
+
const params = new URLSearchParams({
|
|
25622
|
+
state: "open",
|
|
25623
|
+
per_page: String(options.limit ?? 100)
|
|
25624
|
+
});
|
|
25625
|
+
if (options.category) {
|
|
25626
|
+
const label = CATEGORY_TO_LABEL[options.category] ?? options.category;
|
|
25627
|
+
params.set("labels", label);
|
|
25628
|
+
}
|
|
25629
|
+
const url = `${API_BASE}/issues?${params.toString()}`;
|
|
25630
|
+
let response;
|
|
25631
|
+
try {
|
|
25632
|
+
response = await fetch(url, {
|
|
25633
|
+
headers: {
|
|
25634
|
+
Accept: "application/vnd.github+json",
|
|
25635
|
+
"User-Agent": "storybloq-cli"
|
|
25636
|
+
}
|
|
25637
|
+
});
|
|
25638
|
+
} catch (err) {
|
|
25639
|
+
throw new FeedbackClientError(
|
|
25640
|
+
"network_error",
|
|
25641
|
+
`Failed to reach GitHub API: ${err instanceof Error ? err.message : String(err)}`
|
|
25642
|
+
);
|
|
25643
|
+
}
|
|
25644
|
+
if (!response.ok) {
|
|
25645
|
+
throw new FeedbackClientError(
|
|
25646
|
+
"api_error",
|
|
25647
|
+
`GitHub API returned ${response.status}`
|
|
25648
|
+
);
|
|
25649
|
+
}
|
|
25650
|
+
let data;
|
|
25651
|
+
try {
|
|
25652
|
+
data = await response.json();
|
|
25653
|
+
} catch {
|
|
25654
|
+
throw new FeedbackClientError("parse_error", "Failed to parse GitHub API response");
|
|
25655
|
+
}
|
|
25656
|
+
data = data.filter((issue) => !issue.pull_request);
|
|
25657
|
+
let rateLimitWarning = null;
|
|
25658
|
+
const remaining = response.headers.get("X-RateLimit-Remaining");
|
|
25659
|
+
if (remaining !== null) {
|
|
25660
|
+
const n = parseInt(remaining, 10);
|
|
25661
|
+
if (!isNaN(n) && n < 10) {
|
|
25662
|
+
rateLimitWarning = `GitHub API rate limit low: ${n} requests remaining`;
|
|
25663
|
+
}
|
|
25664
|
+
}
|
|
25665
|
+
return { issues: data, rateLimitWarning };
|
|
25666
|
+
}
|
|
25667
|
+
var REPO, API_BASE, CATEGORY_TO_LABEL, FeedbackClientError;
|
|
25668
|
+
var init_github_client = __esm({
|
|
25669
|
+
"src/feedback/github-client.ts"() {
|
|
25670
|
+
"use strict";
|
|
25671
|
+
init_esm_shims();
|
|
25672
|
+
REPO = "Storybloq/storybloq";
|
|
25673
|
+
API_BASE = `https://api.github.com/repos/${REPO}`;
|
|
25674
|
+
CATEGORY_TO_LABEL = {
|
|
25675
|
+
bug: "bug",
|
|
25676
|
+
feature: "enhancement",
|
|
25677
|
+
idea: "idea"
|
|
25678
|
+
};
|
|
25679
|
+
FeedbackClientError = class extends Error {
|
|
25680
|
+
code;
|
|
25681
|
+
constructor(code, message) {
|
|
25682
|
+
super(message);
|
|
25683
|
+
this.name = "FeedbackClientError";
|
|
25684
|
+
this.code = code;
|
|
25685
|
+
}
|
|
25686
|
+
};
|
|
25687
|
+
}
|
|
25688
|
+
});
|
|
25689
|
+
|
|
25690
|
+
// src/cli/commands/feedback.ts
|
|
25691
|
+
var feedback_exports = {};
|
|
25692
|
+
__export(feedback_exports, {
|
|
25693
|
+
buildCreateURL: () => buildCreateURL,
|
|
25694
|
+
handleFeedbackCreate: () => handleFeedbackCreate,
|
|
25695
|
+
handleFeedbackList: () => handleFeedbackList,
|
|
25696
|
+
handleFeedbackOpen: () => handleFeedbackOpen,
|
|
25697
|
+
handleFeedbackVote: () => handleFeedbackVote,
|
|
25698
|
+
openBrowser: () => openBrowser
|
|
25699
|
+
});
|
|
25700
|
+
import { spawn as spawn4 } from "child_process";
|
|
25701
|
+
function labelToCategory(labels) {
|
|
25702
|
+
for (const l of labels) {
|
|
25703
|
+
if (l.name === "bug") return "bug";
|
|
25704
|
+
if (l.name === "enhancement") return "feature";
|
|
25705
|
+
if (l.name === "idea") return "idea";
|
|
25706
|
+
}
|
|
25707
|
+
return "-";
|
|
25708
|
+
}
|
|
25709
|
+
function relativeDate(iso) {
|
|
25710
|
+
const ms = Date.now() - new Date(iso).getTime();
|
|
25711
|
+
const mins = Math.floor(ms / 6e4);
|
|
25712
|
+
if (mins < 60) return `${mins}m ago`;
|
|
25713
|
+
const hours = Math.floor(mins / 60);
|
|
25714
|
+
if (hours < 24) return `${hours}h ago`;
|
|
25715
|
+
const days = Math.floor(hours / 24);
|
|
25716
|
+
return `${days}d ago`;
|
|
25717
|
+
}
|
|
25718
|
+
function openBrowser(url) {
|
|
25719
|
+
const platform = process.platform;
|
|
25720
|
+
let cmd;
|
|
25721
|
+
let args;
|
|
25722
|
+
if (platform === "darwin") {
|
|
25723
|
+
cmd = "open";
|
|
25724
|
+
args = [url];
|
|
25725
|
+
} else if (platform === "win32") {
|
|
25726
|
+
cmd = "powershell.exe";
|
|
25727
|
+
args = ["-NoProfile", "-Command", "Start-Process $args[0]", "-args", url];
|
|
25728
|
+
} else {
|
|
25729
|
+
cmd = "xdg-open";
|
|
25730
|
+
args = [url];
|
|
25731
|
+
}
|
|
25732
|
+
const child = spawn4(cmd, args, { detached: true, stdio: "ignore" });
|
|
25733
|
+
child.unref();
|
|
25734
|
+
}
|
|
25735
|
+
async function handleFeedbackOpen() {
|
|
25736
|
+
openBrowser(`${REPO_URL}/issues`);
|
|
25737
|
+
return { output: `Opened ${REPO_URL}/issues`, exitCode: ExitCode.OK };
|
|
25738
|
+
}
|
|
25739
|
+
async function handleFeedbackList(options, format) {
|
|
25740
|
+
try {
|
|
25741
|
+
const result = await fetchIssues(options);
|
|
25742
|
+
if (format === "json") {
|
|
25743
|
+
return {
|
|
25744
|
+
output: JSON.stringify(successEnvelope({
|
|
25745
|
+
issues: result.issues.map((i) => ({
|
|
25746
|
+
number: i.number,
|
|
25747
|
+
title: i.title,
|
|
25748
|
+
category: labelToCategory(i.labels),
|
|
25749
|
+
votes: i.reactions["+1"],
|
|
25750
|
+
date: i.created_at,
|
|
25751
|
+
url: i.html_url
|
|
25752
|
+
})),
|
|
25753
|
+
rateLimitWarning: result.rateLimitWarning
|
|
25754
|
+
}), null, 2),
|
|
25755
|
+
exitCode: ExitCode.OK
|
|
25756
|
+
};
|
|
25757
|
+
}
|
|
25758
|
+
if (result.issues.length === 0) {
|
|
25759
|
+
let msg = "No feedback found.";
|
|
25760
|
+
if (result.rateLimitWarning) msg += `
|
|
25761
|
+
|
|
25762
|
+
${result.rateLimitWarning}`;
|
|
25763
|
+
return { output: msg, exitCode: ExitCode.OK };
|
|
25764
|
+
}
|
|
25765
|
+
const rows = result.issues.map(
|
|
25766
|
+
(i) => `| ${i.number} | ${i.title} | ${labelToCategory(i.labels)} | ${i.reactions["+1"]} | ${relativeDate(i.created_at)} |`
|
|
25767
|
+
);
|
|
25768
|
+
let output = "# Community Feedback\n\n";
|
|
25769
|
+
output += "| # | Title | Category | Votes | Date |\n";
|
|
25770
|
+
output += "|---|-------|----------|-------|------|\n";
|
|
25771
|
+
output += rows.join("\n");
|
|
25772
|
+
if (result.rateLimitWarning) {
|
|
25773
|
+
output += `
|
|
25774
|
+
|
|
25775
|
+
> ${result.rateLimitWarning}`;
|
|
25776
|
+
}
|
|
25777
|
+
return { output, exitCode: ExitCode.OK };
|
|
25778
|
+
} catch (err) {
|
|
25779
|
+
if (err instanceof FeedbackClientError) {
|
|
25780
|
+
return { output: `Error: ${err.message}`, exitCode: ExitCode.USER_ERROR };
|
|
25781
|
+
}
|
|
25782
|
+
throw err;
|
|
25783
|
+
}
|
|
25784
|
+
}
|
|
25785
|
+
function buildCreateURL(title, category, body) {
|
|
25786
|
+
const params = new URLSearchParams();
|
|
25787
|
+
params.set("title", title);
|
|
25788
|
+
const version2 = process.env.npm_package_version ?? "unknown";
|
|
25789
|
+
const footer = `
|
|
25790
|
+
|
|
25791
|
+
---
|
|
25792
|
+
*Submitted via \`storybloq feedback create\`*
|
|
25793
|
+
CLI version: ${version2}
|
|
25794
|
+
Platform: ${process.platform}
|
|
25795
|
+
Node: ${process.version}`;
|
|
25796
|
+
params.set("body", (body ?? "") + footer);
|
|
25797
|
+
if (category) {
|
|
25798
|
+
const label = CATEGORY_TO_LABEL[category] ?? category;
|
|
25799
|
+
params.set("labels", label);
|
|
25800
|
+
}
|
|
25801
|
+
return `${REPO_URL}/issues/new?${params.toString()}`;
|
|
25802
|
+
}
|
|
25803
|
+
async function handleFeedbackCreate(title, category, body) {
|
|
25804
|
+
const trimmed = title.trim();
|
|
25805
|
+
if (!trimmed) {
|
|
25806
|
+
return { output: "Error: Title is required", exitCode: ExitCode.USER_ERROR };
|
|
25807
|
+
}
|
|
25808
|
+
const url = buildCreateURL(trimmed, category, body);
|
|
25809
|
+
openBrowser(url);
|
|
25810
|
+
return { output: `Opening browser to create feedback...
|
|
25811
|
+
${url}`, exitCode: ExitCode.OK };
|
|
25812
|
+
}
|
|
25813
|
+
async function handleFeedbackVote(issueNumber) {
|
|
25814
|
+
if (!issueNumber || issueNumber <= 0) {
|
|
25815
|
+
return { output: "Error: Issue number must be a positive integer", exitCode: ExitCode.USER_ERROR };
|
|
25816
|
+
}
|
|
25817
|
+
const url = `${REPO_URL}/issues/${issueNumber}`;
|
|
25818
|
+
openBrowser(url);
|
|
25819
|
+
return { output: `Opening issue #${issueNumber} to vote...
|
|
25820
|
+
${url}`, exitCode: ExitCode.OK };
|
|
25821
|
+
}
|
|
25822
|
+
var REPO_URL;
|
|
25823
|
+
var init_feedback = __esm({
|
|
25824
|
+
"src/cli/commands/feedback.ts"() {
|
|
25825
|
+
"use strict";
|
|
25826
|
+
init_esm_shims();
|
|
25827
|
+
init_github_client();
|
|
25828
|
+
init_output_formatter();
|
|
25829
|
+
REPO_URL = "https://github.com/Storybloq/storybloq";
|
|
25830
|
+
}
|
|
25831
|
+
});
|
|
25832
|
+
|
|
25575
25833
|
// src/cli/register.ts
|
|
25576
25834
|
var register_exports = {};
|
|
25577
25835
|
__export(register_exports, {
|
|
@@ -25580,6 +25838,7 @@ __export(register_exports, {
|
|
|
25580
25838
|
registerConfigCommand: () => registerConfigCommand,
|
|
25581
25839
|
registerDispatchCommand: () => registerDispatchCommand,
|
|
25582
25840
|
registerExportCommand: () => registerExportCommand,
|
|
25841
|
+
registerFeedbackCommand: () => registerFeedbackCommand,
|
|
25583
25842
|
registerHandoverCommand: () => registerHandoverCommand,
|
|
25584
25843
|
registerHookStatusCommand: () => registerHookStatusCommand,
|
|
25585
25844
|
registerInitCommand: () => registerInitCommand,
|
|
@@ -28503,6 +28762,82 @@ function registerSessionCommand(yargs) {
|
|
|
28503
28762
|
}
|
|
28504
28763
|
);
|
|
28505
28764
|
}
|
|
28765
|
+
function registerFeedbackCommand(yargs) {
|
|
28766
|
+
return yargs.command(
|
|
28767
|
+
"feedback [subcommand]",
|
|
28768
|
+
"Community feedback via GitHub Issues",
|
|
28769
|
+
(y) => y.command(
|
|
28770
|
+
"list",
|
|
28771
|
+
"List community feedback",
|
|
28772
|
+
(sub) => sub.option("category", {
|
|
28773
|
+
type: "string",
|
|
28774
|
+
choices: ["bug", "feature", "idea"],
|
|
28775
|
+
describe: "Filter by category"
|
|
28776
|
+
}).option("format", {
|
|
28777
|
+
type: "string",
|
|
28778
|
+
default: "md",
|
|
28779
|
+
choices: ["md", "json"],
|
|
28780
|
+
describe: "Output format"
|
|
28781
|
+
}),
|
|
28782
|
+
async (argv) => {
|
|
28783
|
+
const { handleFeedbackList: handleFeedbackList2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
28784
|
+
const result = await handleFeedbackList2(
|
|
28785
|
+
{ category: argv.category },
|
|
28786
|
+
argv.format
|
|
28787
|
+
);
|
|
28788
|
+
process.stdout.write(result.output + "\n");
|
|
28789
|
+
if (result.exitCode) process.exitCode = result.exitCode;
|
|
28790
|
+
}
|
|
28791
|
+
).command(
|
|
28792
|
+
"create",
|
|
28793
|
+
"Create new feedback (opens browser)",
|
|
28794
|
+
(sub) => sub.option("title", {
|
|
28795
|
+
type: "string",
|
|
28796
|
+
demandOption: true,
|
|
28797
|
+
describe: "Feedback title"
|
|
28798
|
+
}).option("category", {
|
|
28799
|
+
type: "string",
|
|
28800
|
+
choices: ["bug", "feature", "idea"],
|
|
28801
|
+
describe: "Feedback category"
|
|
28802
|
+
}).option("body", {
|
|
28803
|
+
type: "string",
|
|
28804
|
+
describe: "Feedback body"
|
|
28805
|
+
}),
|
|
28806
|
+
async (argv) => {
|
|
28807
|
+
const { handleFeedbackCreate: handleFeedbackCreate2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
28808
|
+
const result = await handleFeedbackCreate2(
|
|
28809
|
+
argv.title,
|
|
28810
|
+
argv.category,
|
|
28811
|
+
argv.body
|
|
28812
|
+
);
|
|
28813
|
+
process.stdout.write(result.output + "\n");
|
|
28814
|
+
if (result.exitCode) process.exitCode = result.exitCode;
|
|
28815
|
+
}
|
|
28816
|
+
).command(
|
|
28817
|
+
"vote <number>",
|
|
28818
|
+
"Vote on feedback (opens browser)",
|
|
28819
|
+
(sub) => sub.positional("number", {
|
|
28820
|
+
type: "number",
|
|
28821
|
+
demandOption: true,
|
|
28822
|
+
describe: "Issue number"
|
|
28823
|
+
}),
|
|
28824
|
+
async (argv) => {
|
|
28825
|
+
const { handleFeedbackVote: handleFeedbackVote2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
28826
|
+
const result = await handleFeedbackVote2(argv.number);
|
|
28827
|
+
process.stdout.write(result.output + "\n");
|
|
28828
|
+
if (result.exitCode) process.exitCode = result.exitCode;
|
|
28829
|
+
}
|
|
28830
|
+
),
|
|
28831
|
+
async (argv) => {
|
|
28832
|
+
if (!argv.subcommand || argv.subcommand === "feedback") {
|
|
28833
|
+
const { handleFeedbackOpen: handleFeedbackOpen2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
28834
|
+
const result = await handleFeedbackOpen2();
|
|
28835
|
+
process.stdout.write(result.output + "\n");
|
|
28836
|
+
if (result.exitCode) process.exitCode = result.exitCode;
|
|
28837
|
+
}
|
|
28838
|
+
}
|
|
28839
|
+
);
|
|
28840
|
+
}
|
|
28506
28841
|
var init_register = __esm({
|
|
28507
28842
|
"src/cli/register.ts"() {
|
|
28508
28843
|
"use strict";
|
|
@@ -28605,9 +28940,10 @@ async function runCli() {
|
|
|
28605
28940
|
registerSessionCommand: registerSessionCommand2,
|
|
28606
28941
|
registerRepairCommand: registerRepairCommand2,
|
|
28607
28942
|
registerMigrateCommand: registerMigrateCommand2,
|
|
28608
|
-
registerNodeCommand: registerNodeCommand2
|
|
28943
|
+
registerNodeCommand: registerNodeCommand2,
|
|
28944
|
+
registerFeedbackCommand: registerFeedbackCommand2
|
|
28609
28945
|
} = await Promise.resolve().then(() => (init_register(), register_exports));
|
|
28610
|
-
const version2 = "1.4.
|
|
28946
|
+
const version2 = "1.4.3";
|
|
28611
28947
|
const { preCommandHousekeeping: preCommandHousekeeping2 } = await Promise.resolve().then(() => (init_housekeeping(), housekeeping_exports));
|
|
28612
28948
|
await preCommandHousekeeping2(version2);
|
|
28613
28949
|
class HandledError extends Error {
|
|
@@ -28657,6 +28993,7 @@ async function runCli() {
|
|
|
28657
28993
|
cli = registerConfigCommand2(cli);
|
|
28658
28994
|
cli = registerNodeCommand2(cli);
|
|
28659
28995
|
cli = registerSessionCommand2(cli);
|
|
28996
|
+
cli = registerFeedbackCommand2(cli);
|
|
28660
28997
|
function handleUnexpectedError(err) {
|
|
28661
28998
|
if (err instanceof HandledError) return;
|
|
28662
28999
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/index.d.ts
CHANGED
|
@@ -1503,16 +1503,49 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1503
1503
|
file: z.ZodString;
|
|
1504
1504
|
message: z.ZodString;
|
|
1505
1505
|
}, "strip", z.ZodTypeAny, {
|
|
1506
|
-
message: string;
|
|
1507
1506
|
type: string;
|
|
1507
|
+
message: string;
|
|
1508
1508
|
file: string;
|
|
1509
1509
|
}, {
|
|
1510
|
-
message: string;
|
|
1511
1510
|
type: string;
|
|
1511
|
+
message: string;
|
|
1512
1512
|
file: string;
|
|
1513
1513
|
}>, "many">>;
|
|
1514
1514
|
gitHead: z.ZodOptional<z.ZodString>;
|
|
1515
1515
|
}, "strip", z.ZodTypeAny, {
|
|
1516
|
+
version: 1;
|
|
1517
|
+
config: {
|
|
1518
|
+
version: number;
|
|
1519
|
+
type: string;
|
|
1520
|
+
language: string;
|
|
1521
|
+
project: string;
|
|
1522
|
+
features: {
|
|
1523
|
+
issues: boolean;
|
|
1524
|
+
tickets: boolean;
|
|
1525
|
+
handovers: boolean;
|
|
1526
|
+
roadmap: boolean;
|
|
1527
|
+
reviews: boolean;
|
|
1528
|
+
} & {
|
|
1529
|
+
[k: string]: unknown;
|
|
1530
|
+
};
|
|
1531
|
+
orchestrator?: string | undefined;
|
|
1532
|
+
nodes?: Record<string, unknown> | undefined;
|
|
1533
|
+
federation?: Record<string, unknown> | undefined;
|
|
1534
|
+
schemaVersion?: number | undefined;
|
|
1535
|
+
recipe?: string | undefined;
|
|
1536
|
+
recipeOverrides?: {
|
|
1537
|
+
maxTicketsPerSession?: number | undefined;
|
|
1538
|
+
compactThreshold?: string | undefined;
|
|
1539
|
+
reviewBackends?: string[] | undefined;
|
|
1540
|
+
codexReviewBackends?: string[] | undefined;
|
|
1541
|
+
handoverInterval?: number | undefined;
|
|
1542
|
+
stages?: Record<string, Record<string, unknown>> | undefined;
|
|
1543
|
+
branchStrategy?: "none" | "per-ticket" | undefined;
|
|
1544
|
+
maxParallelAgents?: number | undefined;
|
|
1545
|
+
} | undefined;
|
|
1546
|
+
} & {
|
|
1547
|
+
[k: string]: unknown;
|
|
1548
|
+
};
|
|
1516
1549
|
issues: z.objectOutputType<{
|
|
1517
1550
|
id: z.ZodString;
|
|
1518
1551
|
title: z.ZodString;
|
|
@@ -1550,8 +1583,8 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1550
1583
|
crossNodeBlockedBy: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1551
1584
|
}, z.ZodTypeAny, "passthrough">[];
|
|
1552
1585
|
roadmap: {
|
|
1553
|
-
title: string;
|
|
1554
1586
|
date: string;
|
|
1587
|
+
title: string;
|
|
1555
1588
|
phases: z.objectOutputType<{
|
|
1556
1589
|
id: z.ZodString;
|
|
1557
1590
|
label: z.ZodString;
|
|
@@ -1569,7 +1602,6 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1569
1602
|
} & {
|
|
1570
1603
|
[k: string]: unknown;
|
|
1571
1604
|
};
|
|
1572
|
-
version: 1;
|
|
1573
1605
|
project: string;
|
|
1574
1606
|
notes: z.objectOutputType<{
|
|
1575
1607
|
id: z.ZodString;
|
|
@@ -1594,11 +1626,21 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1594
1626
|
supersedes: z.ZodNullable<z.ZodString>;
|
|
1595
1627
|
status: z.ZodEnum<["active", "deprecated", "superseded"]>;
|
|
1596
1628
|
}, z.ZodTypeAny, "passthrough">[];
|
|
1597
|
-
|
|
1629
|
+
createdAt: string;
|
|
1630
|
+
handoverFilenames: string[];
|
|
1631
|
+
warnings?: {
|
|
1598
1632
|
type: string;
|
|
1633
|
+
message: string;
|
|
1634
|
+
file: string;
|
|
1635
|
+
}[] | undefined;
|
|
1636
|
+
gitHead?: string | undefined;
|
|
1637
|
+
}, {
|
|
1638
|
+
version: 1;
|
|
1639
|
+
config: {
|
|
1599
1640
|
version: number;
|
|
1600
|
-
|
|
1641
|
+
type: string;
|
|
1601
1642
|
language: string;
|
|
1643
|
+
project: string;
|
|
1602
1644
|
features: {
|
|
1603
1645
|
issues: boolean;
|
|
1604
1646
|
tickets: boolean;
|
|
@@ -1626,15 +1668,6 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1626
1668
|
} & {
|
|
1627
1669
|
[k: string]: unknown;
|
|
1628
1670
|
};
|
|
1629
|
-
createdAt: string;
|
|
1630
|
-
handoverFilenames: string[];
|
|
1631
|
-
warnings?: {
|
|
1632
|
-
message: string;
|
|
1633
|
-
type: string;
|
|
1634
|
-
file: string;
|
|
1635
|
-
}[] | undefined;
|
|
1636
|
-
gitHead?: string | undefined;
|
|
1637
|
-
}, {
|
|
1638
1671
|
issues: z.objectInputType<{
|
|
1639
1672
|
id: z.ZodString;
|
|
1640
1673
|
title: z.ZodString;
|
|
@@ -1672,8 +1705,8 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1672
1705
|
crossNodeBlockedBy: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
1673
1706
|
}, z.ZodTypeAny, "passthrough">[];
|
|
1674
1707
|
roadmap: {
|
|
1675
|
-
title: string;
|
|
1676
1708
|
date: string;
|
|
1709
|
+
title: string;
|
|
1677
1710
|
phases: z.objectInputType<{
|
|
1678
1711
|
id: z.ZodString;
|
|
1679
1712
|
label: z.ZodString;
|
|
@@ -1691,40 +1724,7 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1691
1724
|
} & {
|
|
1692
1725
|
[k: string]: unknown;
|
|
1693
1726
|
};
|
|
1694
|
-
version: 1;
|
|
1695
1727
|
project: string;
|
|
1696
|
-
config: {
|
|
1697
|
-
type: string;
|
|
1698
|
-
version: number;
|
|
1699
|
-
project: string;
|
|
1700
|
-
language: string;
|
|
1701
|
-
features: {
|
|
1702
|
-
issues: boolean;
|
|
1703
|
-
tickets: boolean;
|
|
1704
|
-
handovers: boolean;
|
|
1705
|
-
roadmap: boolean;
|
|
1706
|
-
reviews: boolean;
|
|
1707
|
-
} & {
|
|
1708
|
-
[k: string]: unknown;
|
|
1709
|
-
};
|
|
1710
|
-
orchestrator?: string | undefined;
|
|
1711
|
-
nodes?: Record<string, unknown> | undefined;
|
|
1712
|
-
federation?: Record<string, unknown> | undefined;
|
|
1713
|
-
schemaVersion?: number | undefined;
|
|
1714
|
-
recipe?: string | undefined;
|
|
1715
|
-
recipeOverrides?: {
|
|
1716
|
-
maxTicketsPerSession?: number | undefined;
|
|
1717
|
-
compactThreshold?: string | undefined;
|
|
1718
|
-
reviewBackends?: string[] | undefined;
|
|
1719
|
-
codexReviewBackends?: string[] | undefined;
|
|
1720
|
-
handoverInterval?: number | undefined;
|
|
1721
|
-
stages?: Record<string, Record<string, unknown>> | undefined;
|
|
1722
|
-
branchStrategy?: "none" | "per-ticket" | undefined;
|
|
1723
|
-
maxParallelAgents?: number | undefined;
|
|
1724
|
-
} | undefined;
|
|
1725
|
-
} & {
|
|
1726
|
-
[k: string]: unknown;
|
|
1727
|
-
};
|
|
1728
1728
|
createdAt: string;
|
|
1729
1729
|
notes?: z.objectInputType<{
|
|
1730
1730
|
id: z.ZodString;
|
|
@@ -1750,8 +1750,8 @@ declare const SnapshotV1Schema: z.ZodObject<{
|
|
|
1750
1750
|
status: z.ZodEnum<["active", "deprecated", "superseded"]>;
|
|
1751
1751
|
}, z.ZodTypeAny, "passthrough">[] | undefined;
|
|
1752
1752
|
warnings?: {
|
|
1753
|
-
message: string;
|
|
1754
1753
|
type: string;
|
|
1754
|
+
message: string;
|
|
1755
1755
|
file: string;
|
|
1756
1756
|
}[] | undefined;
|
|
1757
1757
|
handoverFilenames?: string[] | undefined;
|
package/dist/index.js
CHANGED
|
@@ -2453,7 +2453,7 @@ async function initProject(root, options) {
|
|
|
2453
2453
|
warnings
|
|
2454
2454
|
};
|
|
2455
2455
|
}
|
|
2456
|
-
var STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/"];
|
|
2456
|
+
var STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/", "federation-cache.json"];
|
|
2457
2457
|
async function ensureGitignoreEntries(gitignorePath, entries) {
|
|
2458
2458
|
let existing = "";
|
|
2459
2459
|
try {
|
package/dist/mcp.js
CHANGED
|
@@ -6064,7 +6064,7 @@ async function initProject(root, options) {
|
|
|
6064
6064
|
warnings
|
|
6065
6065
|
};
|
|
6066
6066
|
}
|
|
6067
|
-
var STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/"];
|
|
6067
|
+
var STORY_GITIGNORE_ENTRIES = ["snapshots/", "status.json", "sessions/", "federation-cache.json"];
|
|
6068
6068
|
async function ensureGitignoreEntries(gitignorePath, entries) {
|
|
6069
6069
|
let existing = "";
|
|
6070
6070
|
try {
|
|
@@ -16743,7 +16743,7 @@ function getInstalledVersion() {
|
|
|
16743
16743
|
}
|
|
16744
16744
|
}
|
|
16745
16745
|
function getRunningVersion() {
|
|
16746
|
-
return "1.4.
|
|
16746
|
+
return "1.4.3";
|
|
16747
16747
|
}
|
|
16748
16748
|
|
|
16749
16749
|
// src/autonomous/guide.ts
|
|
@@ -18753,7 +18753,7 @@ function registerAllTools(server, pinnedRoot) {
|
|
|
18753
18753
|
const result = await runMcpReadTool(pinnedRoot, handleStatus);
|
|
18754
18754
|
try {
|
|
18755
18755
|
const { readUpdateCacheSync: readUpdateCacheSync2, refreshUpdateCacheInBackground: refreshUpdateCacheInBackground2 } = await Promise.resolve().then(() => (init_update_check(), update_check_exports));
|
|
18756
|
-
const running = "1.4.
|
|
18756
|
+
const running = "1.4.3";
|
|
18757
18757
|
const info = readUpdateCacheSync2(running);
|
|
18758
18758
|
refreshUpdateCacheInBackground2();
|
|
18759
18759
|
if (info?.updateAvailable && result.content[0]?.type === "text") {
|
|
@@ -20112,7 +20112,7 @@ async function trimFailedDirectory(inboxPath) {
|
|
|
20112
20112
|
var ENV_VAR2 = "STORYBLOQ_PROJECT_ROOT";
|
|
20113
20113
|
var LEGACY_ENV_VAR2 = "CLAUDESTORY_PROJECT_ROOT";
|
|
20114
20114
|
var CONFIG_PATH2 = ".story/config.json";
|
|
20115
|
-
var version = "1.4.
|
|
20115
|
+
var version = "1.4.3";
|
|
20116
20116
|
function tryDiscoverRoot() {
|
|
20117
20117
|
const envRoot = process.env[ENV_VAR2] ?? process.env[LEGACY_ENV_VAR2];
|
|
20118
20118
|
const envName = process.env[ENV_VAR2] ? ENV_VAR2 : LEGACY_ENV_VAR2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybloq/storybloq",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
5
5
|
"description": "Project memory for Claude Code. Storybloq stores tickets, issues, handovers, and lessons in a .story/ folder inside your repo so every session starts where the last one left off. Pairs with the Storybloq Mac app on the App Store.",
|
|
6
6
|
"homepage": "https://storybloq.com",
|