raindrop-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -339,14 +339,40 @@ src/
339
339
 
340
340
  ## Releasing
341
341
 
342
- For maintainers publishing a new version to npm.
342
+ For maintainers publishing a new version to npm. We use [release-it](https://github.com/release-it/release-it) to automate the release process.
343
343
 
344
344
  ### Prerequisites
345
345
 
346
346
  - Push access to the repository
347
- - npm account with publish rights to `raindrop-cli`
348
- - Logged in to npm (`npm whoami` to verify)
347
+ - npm account with publish rights to `raindrop-cli` (`npm whoami` to verify)
349
348
  - ggshield installed and authenticated (`ggshield auth status`)
349
+ - `GITHUB_TOKEN` environment variable set (for creating GitHub releases)
350
+
351
+ #### Getting a GitHub Token
352
+
353
+ 1. Go to [GitHub Settings → Tokens](https://github.com/settings/tokens?type=beta) (fine-grained)
354
+ 2. Click **Generate new token**
355
+ 3. Set expiration and select **Only select repositories** → `raindrop-cli`
356
+ 4. Under **Repository permissions**, set **Contents** to **Read and write**
357
+ 5. Generate and export: `export GITHUB_TOKEN=github_pat_xxxx`
358
+
359
+ Or use a [classic token](https://github.com/settings/tokens/new) with the `repo` scope (broader access).
360
+
361
+ ### Before You Release
362
+
363
+ Update `CHANGELOG.md` with your changes under the `[Unreleased]` section:
364
+
365
+ ```markdown
366
+ ## [Unreleased]
367
+
368
+ ### Added
369
+ - New feature X
370
+
371
+ ### Fixed
372
+ - Bug Y
373
+ ```
374
+
375
+ The release process will automatically move these entries to the new version section.
350
376
 
351
377
  ### Release Process
352
378
 
@@ -355,47 +381,56 @@ For maintainers publishing a new version to npm.
355
381
  git checkout main
356
382
  git pull
357
383
 
358
- # 2. Update CHANGELOG.md
359
- # - Move items from "Unreleased" to new version section
360
- # - Set the release date (e.g., ## [0.2.0] - 2026-01-15)
384
+ # 2. Preview what will happen (recommended first time)
385
+ bun run release:dry
361
386
 
362
- # 3. Commit the changelog
363
- git add CHANGELOG.md
364
- git commit -m "chore: update changelog for vX.Y.Z"
387
+ # 3. Run the release
388
+ bun run release
389
+ ```
365
390
 
366
- # 4. Bump version (creates commit + git tag automatically)
367
- npm version patch # or: minor, major
368
- # This updates package.json and creates a vX.Y.Z tag
391
+ The interactive prompt will ask you to select the version bump (patch/minor/major). Then release-it will:
369
392
 
370
- # 5. Dry run to verify package contents
371
- npm publish --dry-run --access public
393
+ 1. **Verify** runs tests, lint, typecheck, format
394
+ 2. **Bump version** updates `package.json`
395
+ 3. **Update changelog** — moves "Unreleased" items to new version section with date
396
+ 4. **Build** — compiles to `dist/`
397
+ 5. **Commit** — creates "chore: release vX.Y.Z" commit
398
+ 6. **Tag** — creates `vX.Y.Z` git tag
399
+ 7. **Secret scan** — ggshield scans for leaked secrets
400
+ 8. **Publish to npm** — uploads package
401
+ 9. **Push** — pushes commit and tag to GitHub
402
+ 10. **GitHub Release** — creates release with changelog notes
372
403
 
373
- # 6. Publish to npm
374
- npm publish --access public
404
+ ### Manual Steps (if needed)
375
405
 
376
- # 7. Push commits and tags to GitHub
377
- git push && git push --tags
406
+ If you need to skip certain steps or recover from a partial release:
378
407
 
379
- # 8. Verify installation works
380
- npm info raindrop-cli
381
- npx raindrop-cli@latest --version
382
- ```
408
+ ```bash
409
+ # Skip npm publish (e.g., if it succeeded but git push failed)
410
+ bun run release -- --no-npm
383
411
 
384
- ### What Happens During Publish
412
+ # Skip GitHub release
413
+ bun run release -- --no-github
385
414
 
386
- The `prepublishOnly` script runs automatically before upload:
415
+ # Specific version (skip prompt)
416
+ bun run release -- 1.2.3
387
417
 
388
- 1. **Verify** — runs tests, lint, typecheck, format
389
- 2. **Build** compiles to `dist/`
390
- 3. **Secret scan** — ggshield scans source and `dist/` for leaked secrets
391
- 4. **Package** — creates tarball with only: `dist/*`, `README.md`, `LICENSE`, `package.json`
418
+ # Pre-release
419
+ bun run release -- --preRelease=beta
420
+ ```
392
421
 
393
- No need to run `bun run build` manually — it's all handled automatically.
422
+ ### Verify After Release
423
+
424
+ ```bash
425
+ npm info raindrop-cli
426
+ npx raindrop-cli@latest --version
427
+ ```
394
428
 
395
429
  ### Notes
396
430
 
397
- - **Immutable** — published versions cannot be changed, only deprecated
398
- - **Tags** `npm version` creates the git tag; just remember to `git push --tags`
431
+ - **Immutable** — published npm versions cannot be changed, only deprecated
432
+ - **Clean working directory required** commit or stash changes before releasing
433
+ - **Main branch only** — releases must be from the `main` branch
399
434
  - **Secrets** — publish will fail if ggshield detects secrets in the bundle
400
435
 
401
436
  ## Contributing
@@ -0,0 +1,52 @@
1
+ /**
2
+ * CLI context module - consolidated global state for CLI operations.
3
+ *
4
+ * Creates a CliContext object from argv and environment, providing:
5
+ * - Output configuration (format, color, verbosity)
6
+ * - TTY detection
7
+ * - Color functions that respect color settings
8
+ * - Prefixes for different message types
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { createContext } from './cli/context.js';
13
+ *
14
+ * const ctx = createContext(process.argv.slice(2), process.env);
15
+ * console.log(ctx.colors.green('Success!'));
16
+ * ```
17
+ */
18
+ import type { OutputFormat } from "../types/index.js";
19
+ export type OutputConfig = {
20
+ format: OutputFormat | undefined;
21
+ color: boolean;
22
+ verbose: boolean;
23
+ debug: boolean;
24
+ quiet: boolean;
25
+ };
26
+ export type CliContext = {
27
+ isTty: boolean;
28
+ output: OutputConfig;
29
+ colors: {
30
+ bold: (t: string) => string;
31
+ dim: (t: string) => string;
32
+ cyan: (t: string) => string;
33
+ yellow: (t: string) => string;
34
+ green: (t: string) => string;
35
+ red: (t: string) => string;
36
+ };
37
+ prefix: {
38
+ ok: string;
39
+ warn: string;
40
+ err: string;
41
+ info: string;
42
+ };
43
+ };
44
+ /**
45
+ * Create CLI context from argv and environment.
46
+ *
47
+ * @param argv - Command line arguments (without node/script path)
48
+ * @param env - Environment variables
49
+ * @param isTty - Whether stdout is a TTY (passed explicitly for testability)
50
+ */
51
+ export declare function createContext(argv: string[], env: Record<string, string | undefined>, isTty?: boolean): CliContext;
52
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE;QACN,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC5B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9B,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC7B,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;KAC5B,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,KAAK,GAAE,OAAuC,GAC7C,UAAU,CAuCZ"}
@@ -0,0 +1,3 @@
1
+ export { createContext, type CliContext, type OutputConfig } from "./context.js";
2
+ export { createProgram } from "./program.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Commander program setup - creates and configures the CLI program.
3
+ *
4
+ * This module:
5
+ * - Creates the root Command program
6
+ * - Registers all global options
7
+ * - Sets up the preAction hook for global option handling
8
+ * - Registers all commands and shortcuts
9
+ * - Configures styled help output
10
+ */
11
+ import { Command } from "commander";
12
+ import type { CliContext } from "./context.js";
13
+ /**
14
+ * Create and configure the Commander program.
15
+ *
16
+ * @param ctx - CLI context with output configuration
17
+ * @returns Configured Commander program ready for parsing
18
+ */
19
+ export declare function createProgram(ctx: CliContext): Command;
20
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAA0B,MAAM,WAAW,CAAC;AAI5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA+K/C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CA8ItD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CLI main orchestration - error handling and stream setup.
3
+ *
4
+ * This layer:
5
+ * - Sets up output streams (for testability)
6
+ * - Handles EPIPE errors gracefully (pipe closed by consumer)
7
+ * - Handles top-level errors with proper formatting
8
+ * - Coordinates between the thin shell (cli.ts) and core logic (run.ts)
9
+ */
10
+ /**
11
+ * Handle EPIPE errors gracefully (pipe closed by consumer like head/grep).
12
+ * This is normal when piping to commands that don't consume all output.
13
+ */
14
+ export declare function handlePipeErrors(stream: NodeJS.WritableStream, exit: (code: number) => void): void;
15
+ export type CliMainArgs = {
16
+ argv: string[];
17
+ env: Record<string, string | undefined>;
18
+ stdout: NodeJS.WritableStream;
19
+ stderr: NodeJS.WritableStream;
20
+ exit: (code: number) => void;
21
+ setExitCode: (code: number) => void;
22
+ };
23
+ export declare function runCliMain(args: CliMainArgs): Promise<void>;
24
+ //# sourceMappingURL=cli-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-main.d.ts","sourceRoot":"","sources":["../src/cli-main.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,EAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC3B,IAAI,CAQN;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCjE"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point - thin shell that injects process.* dependencies.
4
+ *
5
+ * This is the executable entry point (package.json bin).
6
+ * All it does is inject process.* dependencies and call runCliMain().
7
+ *
8
+ * Why this thin layer?
9
+ * - Makes the CLI testable without spawning subprocesses
10
+ * - Keeps process.* access in one place
11
+ * - Enables dependency injection for streams, exit, etc.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG"}