srcpack 0.2.0 → 1.0.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.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Srcpack
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/srcpack)](https://www.npmjs.com/package/srcpack) [![npm downloads](https://img.shields.io/npm/dm/srcpack)](https://www.npmjs.com/package/srcpack) [![CI](https://img.shields.io/github/actions/workflow/status/kriasoft/srcpack/ci.yml?branch=main&label=CI)](https://github.com/kriasoft/srcpack/actions/workflows/ci.yml) [![license](https://img.shields.io/npm/l/srcpack)](./LICENSE) [![Discord](https://img.shields.io/discord/643523529131950086?label=Discord&logo=discord&logoColor=white)](https://discord.com/invite/aG83xEb6RX)
4
+
3
5
  Zero-config CLI for bundling code into LLM-optimized context files.
4
6
 
5
7
  **Requirements:** Node.js 22.18+ or Bun
@@ -8,7 +10,7 @@ Zero-config CLI for bundling code into LLM-optimized context files.
8
10
 
9
11
  ```bash
10
12
  npx srcpack init # Create config interactively
11
- npx srcpack # Bundle all
13
+ npx srcpack # Bundle all except on-demand
12
14
  ```
13
15
 
14
16
  ## Why
@@ -48,14 +50,14 @@ Or add to `package.json`:
48
50
 
49
51
  ### Options
50
52
 
51
- | Option | Default | Description |
52
- | ------------- | ---------- | -------------------------------------- |
53
- | `outDir` | `.srcpack` | Output directory for bundles |
54
- | `emptyOutDir` | `true`\* | Empty output directory before bundling |
55
- | `bundles` | — | Named bundles with glob patterns |
56
- | `upload` | — | Upload destination(s) |
53
+ | Option | Default | Description |
54
+ | ------------- | ---------- | ------------------------------------- |
55
+ | `outDir` | `.srcpack` | Output directory for bundles |
56
+ | `emptyOutDir` | `true`\* | Empty output directory before writing |
57
+ | `bundles` | — | Named bundle definitions |
58
+ | `upload` | — | Upload destination(s) |
57
59
 
58
- \*`emptyOutDir` defaults to `true` when `outDir` is inside project root. When `outDir` is outside root, a warning is emitted unless explicitly set. Emptying happens only on a full run, so `npx srcpack web` leaves other bundles in place.
60
+ \*Only the default `.srcpack` is emptied automatically it's srcpack's directory by convention. Any other `outDir` needs an explicit `emptyOutDir: true`, so `outDir: "src"` can't quietly delete your sources. Named runs (`npx srcpack web`) never empty it, so other bundles stay in place.
59
61
 
60
62
  ### Bundle Config
61
63
 
@@ -75,9 +77,12 @@ Or add to `package.json`:
75
77
  // Full options
76
78
  {
77
79
  include: "src/**/*",
80
+ linear: { team: "ENG" }, // Linear issues as virtual files
81
+ screenshot: "http://localhost:5173", // rendered page as numbered PNGs
78
82
  outfile: "~/Downloads/bundle.txt", // custom output path
79
83
  index: true, // include index header (default)
80
- prompt: "./prompts/review.md" // prepend from file (or inline text)
84
+ prompt: "./prompts/review.md", // prepend from file (or inline text)
85
+ onDemand: true // build only when named
81
86
  }
82
87
  ```
83
88
 
@@ -85,6 +90,36 @@ Patterns follow glob syntax. Prefix with `!` to exclude, `+` to force-include (b
85
90
 
86
91
  A pattern can also name a set of changed files: `git:staged`, `git:unstaged`, `git:untracked`, `git:dirty`, or `git:<rev>` (e.g. `git:main`, `git:HEAD~3`). Deleted files are skipped, and `git:<rev>` compares against the merge base so a stale branch still reports only your own changes. See [Git sources](https://kriasoft.com/srcpack/configuration#git-sources-git-prefix).
87
92
 
93
+ A full run skips bundles marked `onDemand: true`; name them explicitly to build them. Emptying `outDir` still removes their previous output there. See [On-Demand Bundles](https://kriasoft.com/srcpack/configuration#on-demand-bundles).
94
+
95
+ ### Linear Issues
96
+
97
+ A bundle can include [Linear](https://linear.app) issues next to your code. Each issue becomes a virtual file at `linear/issues/ENG-123.md`, so it gets its own index entry and line range — letting you ask whether `[4] src/board.ts` actually implements `[2] ENG-123`.
98
+
99
+ ```typescript
100
+ bundles: {
101
+ backlog: { linear: "ENG" }, // non-terminal issues, team ENG
102
+ planning: {
103
+ include: ["docs/**/*.md"],
104
+ linear: { team: "ENG", project: "Roadmap" }, // scoped to one project
105
+ },
106
+ }
107
+ ```
108
+
109
+ Authentication reads `LINEAR_API_KEY` from the environment (Linear → Settings → Security & access → Personal API keys), never from the config file. `team` is required, completed/canceled/duplicate issues are excluded by default, and issues obey `!` exclusions like any other entry. See [Linear issues](https://kriasoft.com/srcpack/configuration#linear-issues).
110
+
111
+ ### Screenshots
112
+
113
+ A bundle can capture a rendered page as PNGs, with overlapping detail slices for tall pages. Srcpack scrolls to load lazy content before capture and hides Astro and Nuxt dev toolbars.
114
+
115
+ ```typescript
116
+ bundles: {
117
+ home: { screenshot: "http://localhost:5173/", onDemand: true },
118
+ }
119
+ ```
120
+
121
+ `npx srcpack home` writes PNGs to `.srcpack`: `home-00.png` is the whole page when available; tall pages also get `home-01.png`, `home-02.png`, … detail slices. Attach them in filename order. Images stay local, even with upload configured. For a one-off, no config is needed: `npx srcpack --screenshot localhost:5173 --viewport mobile`. See [Screenshots](https://kriasoft.com/srcpack/configuration#screenshots) for Playwright and browser setup.
122
+
88
123
  ### Google Drive Upload
89
124
 
90
125
  To upload bundles to Google Drive, add OAuth credentials to your config:
@@ -115,16 +150,16 @@ export default defineConfig({
115
150
 
116
151
  ```text
117
152
  # Index (3 files)
118
- # [1] src/index.ts L1-L42 (42 lines)
119
- # [2] src/utils.ts L43-L89 (47 lines)
120
- # [3] src/api.ts L90-L150 (61 lines)
153
+ # [1] src/api.ts L7-L67 (61 lines)
154
+ # [2] src/index.ts L69-L110 (42 lines)
155
+ # [3] src/utils.ts L112-L158 (47 lines)
121
156
 
122
- #==> [1] src/index.ts <==
123
- import { utils } from "./utils";
157
+ #==> [1] src/api.ts <==
158
+ export async function fetchBoard() {
124
159
  ...
125
160
 
126
- #==> [2] src/utils.ts <==
127
- export function utils() {
161
+ #==> [2] src/index.ts <==
162
+ import { utils } from "./utils";
128
163
  ...
129
164
  ```
130
165
 
@@ -135,14 +170,15 @@ export function utils() {
135
170
  ## CLI
136
171
 
137
172
  ```bash
138
- npx srcpack # Bundle all, upload if configured
173
+ npx srcpack # Bundle all except on-demand, upload if configured
139
174
  npx srcpack web api # Bundle specific bundles only
140
175
  npx srcpack --staged # Bundle staged changes (no config needed)
141
176
  npx srcpack --dirty # Bundle staged + unstaged + untracked
142
177
  npx srcpack --since main # Bundle changes since main
178
+ npx srcpack --screenshot localhost:5173 # Capture a page as PNGs
143
179
  npx srcpack --dry-run # Preview without writing files
144
- npx srcpack --emptyOutDir # Empty output directory before bundling
145
- npx srcpack --no-emptyOutDir # Keep existing files in output directory
180
+ npx srcpack --emptyOutDir # Empty output directory before writing
181
+ npx srcpack --no-emptyOutDir # Skip clearing the output directory
146
182
  npx srcpack --no-upload # Bundle only, skip upload
147
183
  npx srcpack init # Interactive config setup
148
184
  npx srcpack login # Authenticate with Google Drive
package/dist/args.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { BundleConfig } from "./config.ts";
2
+ /** A mistake on the command line: reported without a stack trace. */
3
+ export declare class UsageError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ /**
7
+ * One-off bundle from a `git:` source or a URL; no config file required.
8
+ */
9
+ export interface AdHocBundle {
10
+ name: string;
11
+ source: BundleConfig;
12
+ }
13
+ export interface CliArgs {
14
+ /** Bundle names in input order. Empty for full and ad-hoc runs. */
15
+ bundles: string[];
16
+ adHoc: AdHocBundle | null;
17
+ dryRun: boolean;
18
+ /** Explicit CLI override; `undefined` lets the CLI apply config and run defaults. */
19
+ emptyOutDir: boolean | undefined;
20
+ upload: boolean;
21
+ }
22
+ /**
23
+ * Parse everything after `srcpack` except `--help`, `--version` and the
24
+ * `init`/`login` subcommands, which the CLI handles before this.
25
+ */
26
+ export declare function parseCliArgs(argv: string[]): CliArgs;
package/dist/bundle.d.ts CHANGED
@@ -1,5 +1,17 @@
1
1
  import { type BundleConfigInput } from "./config.ts";
2
- export interface FileEntry {
2
+ /**
3
+ * One bundle member, before its content is laid out.
4
+ *
5
+ * `content` present means the entry is virtual — produced by a non-filesystem
6
+ * source such as Linear — and its `path` is synthetic. Absent means an ordinary
7
+ * file, read from disk at bundle time.
8
+ */
9
+ export interface Entry {
10
+ path: string;
11
+ content?: string;
12
+ }
13
+ /** One line of the bundle index — a file or a virtual entry, once laid out. */
14
+ export interface IndexEntry {
3
15
  path: string;
4
16
  lines: number;
5
17
  startLine: number;
@@ -7,7 +19,7 @@ export interface FileEntry {
7
19
  }
8
20
  export interface BundleResult {
9
21
  content: string;
10
- index: FileEntry[];
22
+ index: IndexEntry[];
11
23
  }
12
24
  /**
13
25
  * Resolve bundle config to a list of file paths.
@@ -23,6 +35,15 @@ export interface BundleResult {
23
35
  * output, nesting it one level deeper every time.
24
36
  */
25
37
  export declare function resolvePatterns(config: BundleConfigInput, cwd: string, outputs?: string[]): Promise<string[]>;
38
+ /**
39
+ * Resolve every source a bundle declares into a sorted entry list.
40
+ *
41
+ * Filesystem and `git:` sources produce paths ({@link resolvePatterns}, which
42
+ * never touches the network); `linear` produces virtual entries carrying their
43
+ * own content. Both then meet the same rules — `!` exclusions apply uniformly,
44
+ * and the result is sorted by path so bundles stay deterministic.
45
+ */
46
+ export declare function resolveEntries(config: BundleConfigInput, cwd: string, outputs?: string[]): Promise<Entry[]>;
26
47
  /**
27
48
  * Format the index header block.
28
49
  * Format designed for LLM context files (ChatGPT, Grok, Gemini):
@@ -30,17 +51,17 @@ export declare function resolvePatterns(config: BundleConfigInput, cwd: string,
30
51
  * - ASCII-only characters for broad compatibility
31
52
  * - Line locations that point to actual file content
32
53
  */
33
- export declare function formatIndex(index: FileEntry[]): string;
54
+ export declare function formatIndex(index: IndexEntry[]): string;
34
55
  export interface BundleOptions {
35
56
  includeIndex?: boolean;
36
57
  prompt?: string;
37
58
  }
38
59
  /**
39
- * Create a bundle from a list of files.
60
+ * Create a bundle from a list of entries.
40
61
  * Line numbers in the index point to the first line of actual file content,
41
62
  * not to the separator line.
42
63
  */
43
- export declare function createBundle(files: string[], cwd: string, options?: BundleOptions): Promise<BundleResult>;
64
+ export declare function createBundle(entries: Entry[], cwd: string, options?: BundleOptions): Promise<BundleResult>;
44
65
  /**
45
66
  * Bundle one config entry. `outputs` lists absolute paths srcpack writes,
46
67
  * which are never bundled — see {@link resolvePatterns}.