{"_id":"shipshape-cli","_rev":"2-528d06510631ca627ae4ad21f5f3e3bd","name":"shipshape-cli","dist-tags":{"latest":"0.1.0"},"versions":{"0.0.0-stage":{"name":"shipshape-cli","version":"0.0.0-stage","_id":"shipshape-cli@0.0.0-stage","stub":true,"maintainers":[{"name":"mhk_sameera","email":"mhksameera@gmail.com"}],"dist":{"shasum":"507f5a0d3e1cfdb807f1a64f68082b893c3e8630","tarball":"https://registry.npmjs.org/shipshape-cli/-/shipshape-cli-0.0.0-stage.tgz","fileCount":2,"integrity":"sha512-3fAkcAv6I2GYxaUBb6P2X+drc5giAoJ2oU2MBS/RBt7pavdqxS2h1n2PXG0SkpFn1s4EB/ooMMRiGeVT0q/eWA==","signatures":[{"sig":"MEUCIQCXhXjbbpIANYlHWe0wWqP1BIMmoM6zbz4WUCbMwjTe7gIgVnFIZl7QhfAoF7jl14+T4xM6vljiZYdpgOxj0VJrLMg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":335},"_npmUser":{"name":"mhk_sameera","email":"mhksameera@gmail.com"},"description":"Temporary package placeholder for staged publishing","directories":{}},"0.1.0":{"_id":"shipshape-cli@0.1.0","bin":{"shipshape":"bin/shipshape.js"},"bugs":{"url":"https://github.com/Sameera-MHK/shipshape-cli/issues"},"dist":{"shasum":"ae687c4c8bfa34a6f9aa266993a79af02b8d76bf","tarball":"https://registry.npmjs.org/shipshape-cli/-/shipshape-cli-0.1.0.tgz","fileCount":16,"integrity":"sha512-z1QTYZ45YDUQGyDYDDCexz/9VXiehLvw4wcf75PHIbizBbW5J5mcwlUo6+42lXcUzj7R6cJKBVKUTl6+6PDrwA==","signatures":[{"sig":"MEQCIFo3IrOSZc71Ys5Tmic7IsEMYOZ7HHUDoevpWo6UMFdKAiAnE+6GmOWzGNY+aTJTJWnD60vi0whtXwej1271zjHRwQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID00Bp2BENiPKiO72MfK5C24pWSiDNJfVi0C4QcjnqPHAiEAgRWs2uD361q7rlQME7cBMEEGNicJ2DT7RHFRhfVBbqU="}],"unpackedSize":57532},"name":"shipshape-cli","type":"module","author":{"name":"sameera_mhk"},"engines":{"node":">=20"},"gitHead":"099d47b48175d248f7c9608de34b51cfd53df0df","license":"MIT","scripts":{"test":"node --test test/unit/*.test.js test/integration/*.test.js","start":"node bin/shipshape.js","pack:check":"npm pack --dry-run"},"version":"0.1.0","_npmUser":{"name":"mhk_sameera","email":"mhksameera@gmail.com"},"homepage":"https://github.com/Sameera-MHK/shipshape-cli#readme","keywords":["cli","preflight","lint","imports","env","react","javascript","ci"],"repository":{"url":"git+https://github.com/Sameera-MHK/shipshape-cli.git","type":"git"},"_npmVersion":"11.6.0","description":"Know what's broken before you ship. A lightweight preflight CLI for JavaScript and React projects.","directories":{},"maintainers":[{"name":"mhk_sameera","email":"mhksameera@gmail.com"}],"_nodeVersion":"22.12.0","dependencies":{"@babel/parser":"^7.29.9"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/shipshape-cli_0.1.0_1792066792441_0.2595271828588861"}}},"time":{"created":"2026-10-15T12:18:15.175Z","modified":"2026-10-15T12:19:52.855Z","0.0.0-stage":"2026-10-15T12:18:15.175Z","0.1.0":"2026-10-15T12:19:52.563Z"},"description":"Know what's broken before you ship. A lightweight preflight CLI for JavaScript and React projects.","maintainers":[{"name":"mhk_sameera","email":"mhksameera@gmail.com"}],"readme":"# shipshape-cli\n\n**Know what's broken before you ship.**\n\nshipshape-cli is a lightweight command-line preflight check for JavaScript and React projects that finds broken package configuration, unresolved relative imports, undocumented environment variables, and missing project files before handoff, CI, or deployment.\n\n> **Status:** v0.1.0 is an initial release. Rules and output may change before 1.0.\n\n## Why\n\nSmall mistakes slip through until a build fails in CI or a teammate clones the repo: an import pointing at a file that was renamed, an environment variable nobody added to `.env.example`, an empty npm script, a missing `.gitignore`. shipshape-cli catches these in one fast, read-only pass, with no account, no network access, and no telemetry.\n\n## Install and quick start\n\nRequires Node.js 20 or later.\n\n```bash\nnpx shipshape-cli check .\n```\n\nThe package is named `shipshape-cli`; the command it installs is `shipshape`. Or install it as a dev dependency and add it to your scripts:\n\n```bash\nnpm install --save-dev shipshape-cli\n```\n\n```json\n{\n  \"scripts\": {\n    \"preflight\": \"shipshape check .\"\n  }\n}\n```\n\n> Use `npx shipshape-cli`, not `npx shipshape`: the unscoped `shipshape` package on npm is an unrelated project.\n\n## Usage\n\n```text\nshipshape check [path] [options]\nshipshape --help\nshipshape --version\n```\n\n| Option | Description |\n| --- | --- |\n| `--json` | Print a machine-readable JSON report |\n| `--quiet` | Print only errors, warnings and the summary |\n| `--strict` | Exit with code 1 when warnings are found |\n| `--no-color` | Disable colored output |\n| `-h`, `--help` | Show usage |\n| `-v`, `--version` | Show the installed version |\n\n`path` defaults to the current directory. Colors are used only when output is a terminal; `NO_COLOR`, `FORCE_COLOR` and `TERM=dumb` are respected.\n\n## Sample output\n\nRunning shipshape-cli on [`examples/broken-react-app`](examples/broken-react-app):\n\n```text\nshipshape-cli v0.1.0\nScanning: examples/broken-react-app\nSource files analyzed: 3\n\nPROJECT\n  ✗ PKG008 Script \"lint\" is empty (package.json)\n      Fix: Add a command for \"lint\" or remove the script.\n  ! PKG009 No \"test\" script is defined (package.json)\n      Fix: Add a \"test\" script so \"npm test\" runs your test suite in CI.\n  i PKG010 No \"build\" script is defined, but \"vite\" is a dependency (package.json)\n      Fix: Add a \"build\" script if this project has a build step.\n  ! HYG001 README.md is missing\n      Fix: Add a README.md describing what the project does and how to run it.\n  ! HYG002 .gitignore is missing\n      Fix: Add a .gitignore that excludes node_modules, build output, and local .env files.\n\nIMPORTS\n  ✗ IMP001 Cannot resolve import \"./components/Footer\" (src/App.jsx:2:20)\n      Fix: Check the path and file name (including letter case), or create the missing file.\n  ✗ IMP001 Cannot resolve import \"./utils/date\" (src/App.jsx:3:28)\n      Fix: Check the path and file name (including letter case), or create the missing file.\n  ✗ IMP001 Cannot resolve import \"./styles.css\" (src/main.jsx:4:8)\n      Fix: Check the path and file name (including letter case), or create the missing file.\n\nENVIRONMENT\n  ! ENV001 VITE_SENTRY_DSN is referenced but missing from .env.example (src/App.jsx:6:35)\n      Fix: Add \"VITE_SENTRY_DSN=\" with a placeholder value to .env.example.\n  i ENV002 VITE_ANALYTICS_ID is listed in .env.example but not referenced in scanned source files (.env.example)\n      Fix: Remove it if it is no longer used. It may still be read by tooling outside JavaScript source (for example a framework or database config).\n\nSummary: 4 errors, 4 warnings, 2 info\n```\n\nA check that has nothing to analyze is shown as skipped (for example `- Import integrity skipped: no JavaScript or TypeScript source files found`), never as passed.\n\n## Supported checks\n\nSymbols: `✗` error, `!` warning, `i` info, `✓` passed, `-` skipped.\n\n### Package configuration\n\n| Rule | Severity | What it finds |\n| --- | --- | --- |\n| PKG001 | error | `package.json` is missing or unreadable |\n| PKG002 | error | `package.json` is not valid JSON (with line and column) |\n| PKG003 | error | `package.json` is not a JSON object |\n| PKG004 | warning | No `name` (skipped for `\"private\": true`) |\n| PKG005 | error | `name` is not a valid npm package name (skipped for `\"private\": true`) |\n| PKG006 | warning / error | `version` missing (warning, skipped for private packages) or not valid semver (error) |\n| PKG007 | error | `scripts` is not an object |\n| PKG008 | error | A script is empty or not a string |\n| PKG009 | warning | No `test` script, or the `npm init` placeholder test script |\n| PKG010 | info | No `build` script although a build tool (Vite, webpack, Next.js, etc.) is a dependency |\n| PKG011 | error | A dependency field is not an object |\n| PKG012 | error | `type` is not `\"module\"` or `\"commonjs\"` |\n\n### Import integrity\n\n| Rule | Severity | What it finds |\n| --- | --- | --- |\n| IMP001 | error | A relative import (`./` or `../`) that does not resolve to a file |\n| IMP002 | warning | A source file that could not be fully parsed |\n\nFiles are parsed with [`@babel/parser`](https://babeljs.io/docs/babel-parser), not regular expressions. Supported forms: `import`, `export ... from`, `export * from`, `import()` and `require()` with static strings, TypeScript `import type` and `import x = require()`.\n\nResolution tries the exact path, then the extensions `.js .jsx .mjs .cjs .ts .tsx .mts .cts .json .d.ts .d.mts .d.cts`, then `index.*` inside a directory (or a directory containing its own `package.json`). A `.js` import that exists as `.ts`/`.tsx` (common in TypeScript ESM projects) is accepted. Imports of other file types (`./styles.css`, `./logo.svg`) must match an existing file exactly. Query and hash suffixes such as `?raw` are ignored. Package imports (`react`, `node:fs`, `@scope/pkg`) are never reported.\n\n### Environment configuration\n\n| Rule | Severity | What it finds |\n| --- | --- | --- |\n| ENV001 | warning | A variable read in source but missing from `.env.example` |\n| ENV002 | info | A `.env.example` entry not referenced in source (only when all env access is static) |\n| ENV003 | warning | Source reads environment variables but there is no `.env.example` |\n\nDetected forms: `process.env.NAME`, `process.env['NAME']`, `process?.env?.NAME`, `const { NAME } = process.env`, and the same for `import.meta.env`. `NODE_ENV` and Vite's built-in `MODE`, `BASE_URL`, `PROD`, `DEV` and `SSR` are ignored.\n\n### Project hygiene\n\n| Rule | Severity | What it finds |\n| --- | --- | --- |\n| HYG001 | warning | No README |\n| HYG002 | warning | No `.gitignore` |\n| HYG003 | warning | A generated directory (`node_modules`, `dist`, `build`, `coverage`, `.next`, ...) exists at the project root but is not in `.gitignore` |\n\n### Scan\n\n| Rule | Severity | What it finds |\n| --- | --- | --- |\n| SCAN001 | warning | A file or directory could not be read; the rest of the scan continues |\n| SCAN002 | info | A file was skipped because it is larger than 1 MB or appears to be binary |\n| SCAN003 | warning | A check failed to run; it is reported as skipped |\n\n## Ignoring paths\n\nTo leave out paths that are broken on purpose (test fixtures, demo projects, generated code), add a `.shipshapeignore` file to the root of the scanned project:\n\n```text\n# Intentionally broken projects used by the tests\ntest/fixtures/\n\n# Generated code\n**/*.generated.js\n/legacy/*.js\n```\n\nNothing is ignored unless you list it. Matching uses a small subset of `.gitignore` syntax, applied to paths relative to the project root:\n\n| Pattern | Matches |\n| --- | --- |\n| `name` (no slash) | A file or directory called `name` at any depth |\n| `dir/sub` or `/name` | A path relative to the project root only |\n| `name/` (trailing slash) | Directories only |\n| `*` / `?` | Any characters / one character within a single path segment |\n| `**` | Any number of directories (`**/x`, `a/**`, `a/**/b`) |\n\nBlank lines and lines starting with `#` are skipped. An ignored directory is not entered at all. Negation (`!`), character classes (`[abc]`), backslash escapes, `..`, and patterns that would ignore the whole project are rejected: the scan stops with exit code 2 and names the line. The report always lists the patterns in use (`Ignoring (.shipshapeignore): ...` in text output, `ignorePatterns` in JSON) so an ignore is never silent.\n\n`.shipshapeignore` only affects which source files are analyzed for imports and environment variables. `package.json`, README, `.gitignore` and `.env.example` at the project root are always checked.\n\n## Exit codes\n\n| Code | Meaning |\n| --- | --- |\n| 0 | No errors found (warnings and info allowed) |\n| 1 | One or more errors found, or warnings found with `--strict` |\n| 2 | Invalid CLI usage, unreadable or invalid target, or a fatal execution error |\n\n## JSON output\n\n`shipshape check . --json` prints the same findings as the text report (run in `examples/broken-react-app`; the `findings` array is shortened here):\n\n```json\n{\n  \"tool\": \"shipshape\",\n  \"version\": \"0.1.0\",\n  \"target\": \".\",\n  \"ignorePatterns\": [],\n  \"filesScanned\": 3,\n  \"summary\": { \"errors\": 4, \"warnings\": 4, \"info\": 2 },\n  \"exitCode\": 1,\n  \"checks\": [\n    { \"id\": \"package-json\", \"title\": \"Package configuration\", \"status\": \"issues\" },\n    { \"id\": \"project-files\", \"title\": \"Project hygiene\", \"status\": \"issues\" },\n    { \"id\": \"imports\", \"title\": \"Import integrity\", \"status\": \"issues\" },\n    { \"id\": \"env-example\", \"title\": \"Environment configuration\", \"status\": \"issues\" }\n  ],\n  \"findings\": [\n    {\n      \"check\": \"imports\",\n      \"ruleId\": \"IMP001\",\n      \"severity\": \"error\",\n      \"message\": \"Cannot resolve import \\\"./components/Footer\\\"\",\n      \"file\": \"src/App.jsx\",\n      \"line\": 2,\n      \"column\": 20,\n      \"fix\": \"Check the path and file name (including letter case), or create the missing file.\"\n    }\n  ]\n}\n```\n\n`status` is one of `passed`, `issues`, or `skipped` (with a `reason`). `file`, `line`, `column` and `fix` are present only when available. Paths are relative to the scanned directory.\n\n## Supported Node.js versions\n\nNode.js 20, 22 and 24 are tested in CI. The `engines` field requires `>=20`.\n\n## Security and privacy\n\nThese guarantees are enforced by the code and covered by tests:\n\n- **Read-only.** shipshape-cli never writes, moves or deletes files in the scanned project.\n- **No code execution.** It never runs npm scripts, installs dependencies, or imports project code. Files are parsed, not executed.\n- **No `.env` reading.** Only `.env.example` is read, and only variable names are kept; values are never stored or printed. Actual `.env` files are never opened.\n- **No source output.** Findings contain rule IDs, messages, relative paths and positions, never source code.\n- **No network and no telemetry.** shipshape-cli makes no network requests.\n- **Bounded scope.** The target is resolved to an absolute path. Symbolic links are never followed. `node_modules`, `.git`, `dist`, `build`, `coverage`, `out`, `.next`, `.nuxt`, `.svelte-kit`, `.turbo`, `.cache` and `.output` are skipped. Paths listed in `.shipshapeignore` are skipped. Files over 1 MB and binary files are skipped. Imports that resolve outside the target directory are not checked. Scanning the filesystem root or your home directory is refused, and a scan stops with exit code 2 if it finds more than 20,000 source files.\n\n## Known limitations\n\n- **Path aliases are not resolved.** Imports such as `@/components/Button` or `~/utils` (from `tsconfig.json` `paths`, bundler aliases or `package.json` `imports`) are treated like package imports and not checked.\n- **Letter case.** On case-insensitive file systems (default macOS and Windows), an import with the wrong letter case resolves locally and is not reported, even though it will fail on Linux.\n- **Only static specifiers** are checked; `import(variable)` and `require(variable)` are ignored.\n- **Other file types** (`.vue`, `.svelte`, `.astro`, `.mdx`) are not parsed, although imports *of* such files from JS/TS are checked.\n- **Environment variables** are detected only through `process.env` and `import.meta.env`. Framework-specific loaders (for example Next.js `next.config.js` `env`, Prisma `env(\"...\")` in `schema.prisma`, Docker or CI configuration) are not understood, which is why unused `.env.example` entries are reported only as info. Only `.env.example` is used; `.env.sample` or `.env.template` are not recognised.\n- **Monorepos and nested projects:** each package is scanned as its own project; run shipshape-cli per package. When scanning a parent folder, nested example or fixture projects are included unless you list them in `.shipshapeignore`.\n- **`.gitignore` matching** is simplified to top-level names and simple wildcards; negation rules make the generated-directory check stay silent.\n- shipshape-cli does not inspect git history or the git index, so it reports generated directories that are *not ignored*, not ones that are already committed.\n\n## Dependencies\n\nshipshape-cli has one runtime dependency: [`@babel/parser`](https://www.npmjs.com/package/@babel/parser), used to parse JavaScript, JSX, TypeScript and TSX reliably. Argument parsing (`node:util` `parseArgs`), file access and tests (`node:test`) use Node.js built-ins.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, testing, and how to add a rule.\n\n```bash\nnpm install\nnpm test\nnode bin/shipshape.js check examples/broken-react-app\n```\n\n## Project status\n\nv0.1.0 is an initial release. Its npm package name is `shipshape-cli`.\n\n## License\n\n[MIT](LICENSE)\n","readmeFilename":"README.md","homepage":"https://github.com/Sameera-MHK/shipshape-cli#readme","keywords":["cli","preflight","lint","imports","env","react","javascript","ci"],"repository":{"url":"git+https://github.com/Sameera-MHK/shipshape-cli.git","type":"git"},"author":{"name":"sameera_mhk"},"bugs":{"url":"https://github.com/Sameera-MHK/shipshape-cli/issues"},"license":"MIT"}