helpshelf 0.4.1 → 0.4.2

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 +36 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import { Command } from "commander";
8
8
 
9
9
  // src/commands/scan.ts
10
10
  import { resolve, join as join8, relative as relative4 } from "path";
11
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync8, mkdirSync, readdirSync as readdirSync4 } from "fs";
11
+ import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync8, mkdirSync, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
12
12
  import { createInterface } from "readline";
13
13
  import { basename as basename2 } from "path";
14
14
  import chalk from "chalk";
@@ -915,6 +915,36 @@ function generateDepFaqs(deps) {
915
915
  }
916
916
 
917
917
  // src/commands/scan.ts
918
+ function isICloudEvicted(filePath) {
919
+ try {
920
+ const stat = statSync3(filePath);
921
+ return stat.isFile() && stat.size > 0 && stat.blocks === 0;
922
+ } catch {
923
+ return false;
924
+ }
925
+ }
926
+ function checkICloudStatus(dir, log) {
927
+ const criticalFiles = ["package.json", "README.md", ".env", ".env.example", "tsconfig.json", "pyproject.toml"];
928
+ const evictedFiles = [];
929
+ for (const file of criticalFiles) {
930
+ const filePath = join8(dir, file);
931
+ if (existsSync8(filePath) && isICloudEvicted(filePath)) {
932
+ evictedFiles.push(file);
933
+ }
934
+ }
935
+ if (evictedFiles.length > 0) {
936
+ log(chalk.yellow.bold("\u26A0 iCloud Drive detected \u2014 key files are not downloaded locally:"));
937
+ for (const file of evictedFiles) {
938
+ log(chalk.yellow(` \u2022 ${file}`));
939
+ }
940
+ log();
941
+ log(chalk.dim(' To fix, open Finder \u2192 right-click the project folder \u2192 "Download Now"'));
942
+ log(chalk.dim(" Or move the project out of Desktop/Documents to a non-iCloud folder."));
943
+ log();
944
+ return true;
945
+ }
946
+ return false;
947
+ }
918
948
  async function scanCommand(options) {
919
949
  const startTime = Date.now();
920
950
  const projectDir = resolve(options.dir);
@@ -928,6 +958,10 @@ async function scanCommand(options) {
928
958
  console.error(chalk.red(`Directory not found: ${projectDir}`));
929
959
  process.exit(1);
930
960
  }
961
+ const hasEvictedFiles = checkICloudStatus(projectDir, log);
962
+ if (hasEvictedFiles) {
963
+ log(chalk.yellow(" Scanning anyway, but results will be incomplete.\n"));
964
+ }
931
965
  const spinner = ora("Reading project metadata...").start();
932
966
  const project = scanProjectMeta(projectDir);
933
967
  spinner.succeed(`Project: ${chalk.cyan(project.name)}${project.version ? ` v${project.version}` : ""}`);
@@ -1777,7 +1811,7 @@ async function screenshotCommand(options) {
1777
1811
 
1778
1812
  // src/index.ts
1779
1813
  var program = new Command();
1780
- program.name("helpshelf").description("AI-agent toolkit for auto-generating support docs").version("0.4.1");
1814
+ program.name("helpshelf").description("AI-agent toolkit for auto-generating support docs").version("0.4.2");
1781
1815
  program.command("scan").description("Scan your codebase \u2192 snapshot.json + docs-template.json").option("-d, --dir <path>", "Project directory to scan", ".").option("-o, --output <path>", "Output file path", ".helpshelf/snapshot.json").option("--no-readme", "Skip README parsing").option("--no-deps", "Skip dependency analysis").option("--no-api", "Skip API route detection").option("--no-env", "Skip environment variable detection").option("--verbose", "Show detailed scan output").option("--quiet", "Suppress output (for programmatic use)").option("-u, --url <url>", "Also capture screenshots from a running app (e.g., http://localhost:3000)").option("-e, --email <email>", "Login email for screenshot auth").option("-p, --password <password>", "Login password for screenshot auth").option("-m, --max-pages <n>", "Max pages to screenshot", "20").action(scanCommand);
1782
1816
  program.command("screenshot").description("Capture screenshots of your running app's pages").requiredOption("-u, --url <url>", "URL of your running app (e.g., http://localhost:3000)").option("-e, --email <email>", "Login email for authenticated pages").option("-p, --password <password>", "Login password").option("-s, --snapshot <path>", "Path to scan snapshot (for route intelligence)", ".helpshelf/snapshot.json").option("-o, --output <path>", "Output directory for screenshots", ".helpshelf/screenshots").option("-m, --max-pages <n>", "Maximum pages to capture", "20").action(screenshotCommand);
1783
1817
  program.command("push").description("Push docs to HelpShelf (creates account if needed)").option("--email <email>", "HelpShelf account email").option("--domain <domain>", "Your app domain (for help center URL)").option("--docs-dir <path>", "Directory containing markdown docs", ".helpshelf/docs").option("--site <hash>", "Existing HelpShelf site hash").option("--api-key <key>", "Existing HelpShelf API key").option("--api-url <url>", "HelpShelf API URL", "https://app.helpshelf.com").option("--dry-run", "Preview what would be pushed without sending").action(pushCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helpshelf",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Scan your codebase and auto-generate support docs for HelpShelf",
5
5
  "type": "module",
6
6
  "bin": {