@staff0rd/assist 0.55.0 → 0.56.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.
Files changed (2) hide show
  1. package/dist/index.js +85 -58
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { Command } from "commander";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@staff0rd/assist",
10
- version: "0.55.0",
10
+ version: "0.56.0",
11
11
  type: "module",
12
12
  main: "dist/index.js",
13
13
  bin: {
@@ -1874,6 +1874,10 @@ function getNextId(items) {
1874
1874
  }
1875
1875
 
1876
1876
  // src/commands/backlog/add/shared.ts
1877
+ import { spawnSync } from "child_process";
1878
+ import { mkdtempSync, readFileSync as readFileSync10, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
1879
+ import { tmpdir } from "os";
1880
+ import { join as join9 } from "path";
1877
1881
  import enquirer4 from "enquirer";
1878
1882
  async function promptName() {
1879
1883
  const { name } = await enquirer4.prompt({
@@ -1885,12 +1889,35 @@ async function promptName() {
1885
1889
  return name.trim();
1886
1890
  }
1887
1891
  async function promptDescription() {
1888
- const { description } = await enquirer4.prompt({
1889
- type: "input",
1890
- name: "description",
1891
- message: "Description (optional):"
1892
+ const { useEditor } = await enquirer4.prompt({
1893
+ type: "confirm",
1894
+ name: "useEditor",
1895
+ message: "Open editor for description?",
1896
+ initial: false
1892
1897
  });
1893
- return description.trim() || void 0;
1898
+ if (!useEditor) {
1899
+ const { description } = await enquirer4.prompt({
1900
+ type: "input",
1901
+ name: "description",
1902
+ message: "Description (optional):"
1903
+ });
1904
+ return description.trim() || void 0;
1905
+ }
1906
+ return openEditor();
1907
+ }
1908
+ function openEditor() {
1909
+ const editor = process.env.EDITOR || process.env.VISUAL || "vi";
1910
+ const dir = mkdtempSync(join9(tmpdir(), "assist-"));
1911
+ const filePath = join9(dir, "description.md");
1912
+ writeFileSync11(filePath, "");
1913
+ const result = spawnSync(editor, [filePath], { stdio: "inherit" });
1914
+ if (result.status !== 0) {
1915
+ unlinkSync2(filePath);
1916
+ return void 0;
1917
+ }
1918
+ const content = readFileSync10(filePath, "utf-8").trim();
1919
+ unlinkSync2(filePath);
1920
+ return content || void 0;
1894
1921
  }
1895
1922
  async function promptAcceptanceCriteria() {
1896
1923
  const criteria = [];
@@ -2510,7 +2537,7 @@ function registerComplexity(program2) {
2510
2537
  }
2511
2538
 
2512
2539
  // src/commands/deploy/redirect.ts
2513
- import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync11 } from "fs";
2540
+ import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync12 } from "fs";
2514
2541
  import chalk34 from "chalk";
2515
2542
  var TRAILING_SLASH_SCRIPT = ` <script>
2516
2543
  if (!window.location.pathname.endsWith('/')) {
@@ -2523,7 +2550,7 @@ function redirect() {
2523
2550
  console.log(chalk34.yellow("No index.html found"));
2524
2551
  return;
2525
2552
  }
2526
- const content = readFileSync10(indexPath, "utf-8");
2553
+ const content = readFileSync11(indexPath, "utf-8");
2527
2554
  if (content.includes("window.location.pathname.endsWith('/')")) {
2528
2555
  console.log(chalk34.dim("Trailing slash script already present"));
2529
2556
  return;
@@ -2534,7 +2561,7 @@ function redirect() {
2534
2561
  return;
2535
2562
  }
2536
2563
  const newContent = content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT + "\n " + content.slice(headCloseIndex);
2537
- writeFileSync11(indexPath, newContent);
2564
+ writeFileSync12(indexPath, newContent);
2538
2565
  console.log(chalk34.green("Added trailing slash redirect to index.html"));
2539
2566
  }
2540
2567
 
@@ -2554,16 +2581,16 @@ import { execSync as execSync11 } from "child_process";
2554
2581
  import chalk35 from "chalk";
2555
2582
 
2556
2583
  // src/commands/devlog/loadDevlogEntries.ts
2557
- import { readdirSync, readFileSync as readFileSync11 } from "fs";
2584
+ import { readdirSync, readFileSync as readFileSync12 } from "fs";
2558
2585
  import { homedir } from "os";
2559
- import { join as join9 } from "path";
2560
- var DEVLOG_DIR = join9(homedir(), "git/blog/src/content/devlog");
2586
+ import { join as join10 } from "path";
2587
+ var DEVLOG_DIR = join10(homedir(), "git/blog/src/content/devlog");
2561
2588
  function loadDevlogEntries(repoName) {
2562
2589
  const entries = /* @__PURE__ */ new Map();
2563
2590
  try {
2564
2591
  const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
2565
2592
  for (const file of files) {
2566
- const content = readFileSync11(join9(DEVLOG_DIR, file), "utf-8");
2593
+ const content = readFileSync12(join10(DEVLOG_DIR, file), "utf-8");
2567
2594
  const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
2568
2595
  if (frontmatterMatch) {
2569
2596
  const frontmatter = frontmatterMatch[1];
@@ -2918,29 +2945,29 @@ import { execSync as execSync17 } from "child_process";
2918
2945
 
2919
2946
  // src/commands/prs/resolveCommentWithReply.ts
2920
2947
  import { execSync as execSync16 } from "child_process";
2921
- import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync12 } from "fs";
2922
- import { tmpdir } from "os";
2923
- import { join as join11 } from "path";
2948
+ import { unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "fs";
2949
+ import { tmpdir as tmpdir2 } from "os";
2950
+ import { join as join12 } from "path";
2924
2951
 
2925
2952
  // src/commands/prs/loadCommentsCache.ts
2926
- import { existsSync as existsSync16, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "fs";
2927
- import { join as join10 } from "path";
2953
+ import { existsSync as existsSync16, readFileSync as readFileSync13, unlinkSync as unlinkSync3 } from "fs";
2954
+ import { join as join11 } from "path";
2928
2955
  import { parse } from "yaml";
2929
2956
  function getCachePath(prNumber) {
2930
- return join10(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
2957
+ return join11(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
2931
2958
  }
2932
2959
  function loadCommentsCache(prNumber) {
2933
2960
  const cachePath = getCachePath(prNumber);
2934
2961
  if (!existsSync16(cachePath)) {
2935
2962
  return null;
2936
2963
  }
2937
- const content = readFileSync12(cachePath, "utf-8");
2964
+ const content = readFileSync13(cachePath, "utf-8");
2938
2965
  return parse(content);
2939
2966
  }
2940
2967
  function deleteCommentsCache(prNumber) {
2941
2968
  const cachePath = getCachePath(prNumber);
2942
2969
  if (existsSync16(cachePath)) {
2943
- unlinkSync2(cachePath);
2970
+ unlinkSync3(cachePath);
2944
2971
  console.log("No more unresolved line comments. Cache dropped.");
2945
2972
  }
2946
2973
  }
@@ -2990,15 +3017,15 @@ function replyToComment(org, repo, prNumber, commentId, message) {
2990
3017
  }
2991
3018
  function resolveThread(threadId) {
2992
3019
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
2993
- const queryFile = join11(tmpdir(), `gh-mutation-${Date.now()}.graphql`);
2994
- writeFileSync12(queryFile, mutation);
3020
+ const queryFile = join12(tmpdir2(), `gh-mutation-${Date.now()}.graphql`);
3021
+ writeFileSync13(queryFile, mutation);
2995
3022
  try {
2996
3023
  execSync16(
2997
3024
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
2998
3025
  { stdio: "inherit" }
2999
3026
  );
3000
3027
  } finally {
3001
- unlinkSync3(queryFile);
3028
+ unlinkSync4(queryFile);
3002
3029
  }
3003
3030
  }
3004
3031
  function requireCache(prNumber) {
@@ -3071,8 +3098,8 @@ function fixed(commentId, sha) {
3071
3098
  }
3072
3099
 
3073
3100
  // src/commands/prs/listComments/index.ts
3074
- import { existsSync as existsSync17, mkdirSync as mkdirSync4, writeFileSync as writeFileSync14 } from "fs";
3075
- import { join as join13 } from "path";
3101
+ import { existsSync as existsSync17, mkdirSync as mkdirSync4, writeFileSync as writeFileSync15 } from "fs";
3102
+ import { join as join14 } from "path";
3076
3103
  import { stringify } from "yaml";
3077
3104
 
3078
3105
  // src/lib/isClaudeCode.ts
@@ -3082,13 +3109,13 @@ function isClaudeCode() {
3082
3109
 
3083
3110
  // src/commands/prs/fetchThreadIds.ts
3084
3111
  import { execSync as execSync18 } from "child_process";
3085
- import { unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "fs";
3086
- import { tmpdir as tmpdir2 } from "os";
3087
- import { join as join12 } from "path";
3112
+ import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync14 } from "fs";
3113
+ import { tmpdir as tmpdir3 } from "os";
3114
+ import { join as join13 } from "path";
3088
3115
  var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
3089
3116
  function fetchThreadIds(org, repo, prNumber) {
3090
- const queryFile = join12(tmpdir2(), `gh-query-${Date.now()}.graphql`);
3091
- writeFileSync13(queryFile, THREAD_QUERY);
3117
+ const queryFile = join13(tmpdir3(), `gh-query-${Date.now()}.graphql`);
3118
+ writeFileSync14(queryFile, THREAD_QUERY);
3092
3119
  try {
3093
3120
  const result = execSync18(
3094
3121
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
@@ -3107,7 +3134,7 @@ function fetchThreadIds(org, repo, prNumber) {
3107
3134
  }
3108
3135
  return { threadMap, resolvedThreadIds };
3109
3136
  } finally {
3110
- unlinkSync4(queryFile);
3137
+ unlinkSync5(queryFile);
3111
3138
  }
3112
3139
  }
3113
3140
 
@@ -3190,7 +3217,7 @@ function printComments(comments) {
3190
3217
  }
3191
3218
  }
3192
3219
  function writeCommentsCache(prNumber, comments) {
3193
- const assistDir = join13(process.cwd(), ".assist");
3220
+ const assistDir = join14(process.cwd(), ".assist");
3194
3221
  if (!existsSync17(assistDir)) {
3195
3222
  mkdirSync4(assistDir, { recursive: true });
3196
3223
  }
@@ -3199,8 +3226,8 @@ function writeCommentsCache(prNumber, comments) {
3199
3226
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
3200
3227
  comments
3201
3228
  };
3202
- const cachePath = join13(assistDir, `pr-${prNumber}-comments.yaml`);
3203
- writeFileSync14(cachePath, stringify(cacheData));
3229
+ const cachePath = join14(assistDir, `pr-${prNumber}-comments.yaml`);
3230
+ writeFileSync15(cachePath, stringify(cacheData));
3204
3231
  }
3205
3232
  function handleKnownErrors(error) {
3206
3233
  if (isGhNotInstalled(error)) {
@@ -4162,7 +4189,7 @@ function registerRefactor(program2) {
4162
4189
 
4163
4190
  // src/commands/transcript/shared.ts
4164
4191
  import { existsSync as existsSync18, readdirSync as readdirSync2, statSync } from "fs";
4165
- import { basename as basename4, join as join14, relative } from "path";
4192
+ import { basename as basename4, join as join15, relative } from "path";
4166
4193
  import * as readline2 from "readline";
4167
4194
  var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
4168
4195
  function getDatePrefix(daysOffset = 0) {
@@ -4180,7 +4207,7 @@ function collectFiles(dir, extension) {
4180
4207
  if (!existsSync18(dir)) return [];
4181
4208
  const results = [];
4182
4209
  for (const entry of readdirSync2(dir)) {
4183
- const fullPath = join14(dir, entry);
4210
+ const fullPath = join15(dir, entry);
4184
4211
  if (statSync(fullPath).isDirectory()) {
4185
4212
  results.push(...collectFiles(fullPath, extension));
4186
4213
  } else if (entry.endsWith(extension)) {
@@ -4277,11 +4304,11 @@ async function configure() {
4277
4304
  import { existsSync as existsSync20 } from "fs";
4278
4305
 
4279
4306
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
4280
- import { dirname as dirname12, join as join16 } from "path";
4307
+ import { dirname as dirname12, join as join17 } from "path";
4281
4308
 
4282
4309
  // src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
4283
4310
  import { renameSync } from "fs";
4284
- import { join as join15 } from "path";
4311
+ import { join as join16 } from "path";
4285
4312
  async function resolveDate(rl, choice) {
4286
4313
  if (choice === "1") return getDatePrefix(0);
4287
4314
  if (choice === "2") return getDatePrefix(-1);
@@ -4296,7 +4323,7 @@ async function resolveDate(rl, choice) {
4296
4323
  }
4297
4324
  function renameWithPrefix(vttDir, vttFile, prefix) {
4298
4325
  const newFilename = `${prefix}.${vttFile}`;
4299
- renameSync(join15(vttDir, vttFile), join15(vttDir, newFilename));
4326
+ renameSync(join16(vttDir, vttFile), join16(vttDir, newFilename));
4300
4327
  console.log(`Renamed to: ${newFilename}`);
4301
4328
  return newFilename;
4302
4329
  }
@@ -4330,12 +4357,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
4330
4357
  const vttFileDir = dirname12(vttFile.absolutePath);
4331
4358
  const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
4332
4359
  if (newFilename) {
4333
- const newRelativePath = join16(
4360
+ const newRelativePath = join17(
4334
4361
  dirname12(vttFile.relativePath),
4335
4362
  newFilename
4336
4363
  );
4337
4364
  vttFiles[i] = {
4338
- absolutePath: join16(vttFileDir, newFilename),
4365
+ absolutePath: join17(vttFileDir, newFilename),
4339
4366
  relativePath: newRelativePath,
4340
4367
  filename: newFilename
4341
4368
  };
@@ -4348,8 +4375,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
4348
4375
  }
4349
4376
 
4350
4377
  // src/commands/transcript/format/processVttFile/index.ts
4351
- import { existsSync as existsSync19, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync15 } from "fs";
4352
- import { basename as basename5, dirname as dirname13, join as join17 } from "path";
4378
+ import { existsSync as existsSync19, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync16 } from "fs";
4379
+ import { basename as basename5, dirname as dirname13, join as join18 } from "path";
4353
4380
 
4354
4381
  // src/commands/transcript/cleanText.ts
4355
4382
  function cleanText(text) {
@@ -4559,17 +4586,17 @@ function toMdFilename(vttFilename) {
4559
4586
  return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
4560
4587
  }
4561
4588
  function resolveOutputDir(relativeDir, transcriptsDir) {
4562
- return relativeDir === "." ? transcriptsDir : join17(transcriptsDir, relativeDir);
4589
+ return relativeDir === "." ? transcriptsDir : join18(transcriptsDir, relativeDir);
4563
4590
  }
4564
4591
  function buildOutputPaths(vttFile, transcriptsDir) {
4565
4592
  const mdFile = toMdFilename(vttFile.filename);
4566
4593
  const relativeDir = dirname13(vttFile.relativePath);
4567
4594
  const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
4568
- const outputPath = join17(outputDir, mdFile);
4595
+ const outputPath = join18(outputDir, mdFile);
4569
4596
  return { outputDir, outputPath, mdFile, relativeDir };
4570
4597
  }
4571
4598
  function logSkipped(relativeDir, mdFile) {
4572
- console.log(`Skipping (already exists): ${join17(relativeDir, mdFile)}`);
4599
+ console.log(`Skipping (already exists): ${join18(relativeDir, mdFile)}`);
4573
4600
  return "skipped";
4574
4601
  }
4575
4602
  function ensureDirectory(dir, label) {
@@ -4596,10 +4623,10 @@ function logReduction(cueCount, messageCount) {
4596
4623
  }
4597
4624
  function readAndParseCues(inputPath) {
4598
4625
  console.log(`Reading: ${inputPath}`);
4599
- return processCues(readFileSync13(inputPath, "utf-8"));
4626
+ return processCues(readFileSync14(inputPath, "utf-8"));
4600
4627
  }
4601
4628
  function writeFormatted(outputPath, content) {
4602
- writeFileSync15(outputPath, content, "utf-8");
4629
+ writeFileSync16(outputPath, content, "utf-8");
4603
4630
  console.log(`Written: ${outputPath}`);
4604
4631
  }
4605
4632
  function convertVttToMarkdown(inputPath, outputPath) {
@@ -4668,17 +4695,17 @@ async function format() {
4668
4695
 
4669
4696
  // src/commands/transcript/summarise/index.ts
4670
4697
  import { existsSync as existsSync22 } from "fs";
4671
- import { basename as basename6, dirname as dirname15, join as join19, relative as relative2 } from "path";
4698
+ import { basename as basename6, dirname as dirname15, join as join20, relative as relative2 } from "path";
4672
4699
 
4673
4700
  // src/commands/transcript/summarise/processStagedFile/index.ts
4674
4701
  import {
4675
4702
  existsSync as existsSync21,
4676
4703
  mkdirSync as mkdirSync6,
4677
- readFileSync as readFileSync14,
4704
+ readFileSync as readFileSync15,
4678
4705
  renameSync as renameSync2,
4679
4706
  rmSync
4680
4707
  } from "fs";
4681
- import { dirname as dirname14, join as join18 } from "path";
4708
+ import { dirname as dirname14, join as join19 } from "path";
4682
4709
 
4683
4710
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
4684
4711
  import chalk48 from "chalk";
@@ -4707,7 +4734,7 @@ function validateStagedContent(filename, content) {
4707
4734
  }
4708
4735
 
4709
4736
  // src/commands/transcript/summarise/processStagedFile/index.ts
4710
- var STAGING_DIR = join18(process.cwd(), ".assist", "transcript");
4737
+ var STAGING_DIR = join19(process.cwd(), ".assist", "transcript");
4711
4738
  function processStagedFile() {
4712
4739
  if (!existsSync21(STAGING_DIR)) {
4713
4740
  return false;
@@ -4718,7 +4745,7 @@ function processStagedFile() {
4718
4745
  }
4719
4746
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
4720
4747
  const stagedFile = stagedFiles[0];
4721
- const content = readFileSync14(stagedFile.absolutePath, "utf-8");
4748
+ const content = readFileSync15(stagedFile.absolutePath, "utf-8");
4722
4749
  validateStagedContent(stagedFile.filename, content);
4723
4750
  const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
4724
4751
  const transcriptFiles = findMdFilesRecursive(transcriptsDir);
@@ -4731,7 +4758,7 @@ function processStagedFile() {
4731
4758
  );
4732
4759
  process.exit(1);
4733
4760
  }
4734
- const destPath = join18(summaryDir, matchingTranscript.relativePath);
4761
+ const destPath = join19(summaryDir, matchingTranscript.relativePath);
4735
4762
  const destDir = dirname14(destPath);
4736
4763
  if (!existsSync21(destDir)) {
4737
4764
  mkdirSync6(destDir, { recursive: true });
@@ -4747,7 +4774,7 @@ function processStagedFile() {
4747
4774
  // src/commands/transcript/summarise/index.ts
4748
4775
  function buildRelativeKey(relativePath, baseName) {
4749
4776
  const relDir = dirname15(relativePath);
4750
- return relDir === "." ? baseName : join19(relDir, baseName);
4777
+ return relDir === "." ? baseName : join20(relDir, baseName);
4751
4778
  }
4752
4779
  function buildSummaryIndex(summaryDir) {
4753
4780
  const summaryFiles = findMdFilesRecursive(summaryDir);
@@ -4781,8 +4808,8 @@ function summarise() {
4781
4808
  }
4782
4809
  const next2 = missing[0];
4783
4810
  const outputFilename = `${getTranscriptBaseName(next2.filename)}.md`;
4784
- const outputPath = join19(STAGING_DIR, outputFilename);
4785
- const summaryFileDir = join19(summaryDir, dirname15(next2.relativePath));
4811
+ const outputPath = join20(STAGING_DIR, outputFilename);
4812
+ const summaryFileDir = join20(summaryDir, dirname15(next2.relativePath));
4786
4813
  const relativeTranscriptPath = encodeURI(
4787
4814
  relative2(summaryFileDir, next2.absolutePath).replace(/\\/g, "/")
4788
4815
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {