srcpack 0.2.0 → 0.3.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
@@ -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. Emptying also happens only on a full run, so `npx srcpack web` leaves other bundles in place.
59
61
 
60
62
  ### Bundle Config
61
63
 
@@ -75,6 +77,7 @@ Or add to `package.json`:
75
77
  // Full options
76
78
  {
77
79
  include: "src/**/*",
80
+ linear: { team: "ENG" }, // Linear issues as virtual files
78
81
  outfile: "~/Downloads/bundle.txt", // custom output path
79
82
  index: true, // include index header (default)
80
83
  prompt: "./prompts/review.md" // prepend from file (or inline text)
@@ -85,6 +88,22 @@ Patterns follow glob syntax. Prefix with `!` to exclude, `+` to force-include (b
85
88
 
86
89
  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
90
 
91
+ ### Linear Issues
92
+
93
+ 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`.
94
+
95
+ ```typescript
96
+ bundles: {
97
+ backlog: { linear: "ENG" }, // non-terminal issues, team ENG
98
+ planning: {
99
+ include: ["docs/**/*.md"],
100
+ linear: { team: "ENG", project: "Roadmap" }, // scoped to one project
101
+ },
102
+ }
103
+ ```
104
+
105
+ 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).
106
+
88
107
  ### Google Drive Upload
89
108
 
90
109
  To upload bundles to Google Drive, add OAuth credentials to your config:
@@ -115,16 +134,16 @@ export default defineConfig({
115
134
 
116
135
  ```text
117
136
  # 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)
137
+ # [1] src/api.ts L7-L67 (61 lines)
138
+ # [2] src/index.ts L69-L110 (42 lines)
139
+ # [3] src/utils.ts L112-L158 (47 lines)
121
140
 
122
- #==> [1] src/index.ts <==
123
- import { utils } from "./utils";
141
+ #==> [1] src/api.ts <==
142
+ export async function fetchBoard() {
124
143
  ...
125
144
 
126
- #==> [2] src/utils.ts <==
127
- export function utils() {
145
+ #==> [2] src/index.ts <==
146
+ import { utils } from "./utils";
128
147
  ...
129
148
  ```
130
149
 
@@ -141,7 +160,7 @@ npx srcpack --staged # Bundle staged changes (no config needed)
141
160
  npx srcpack --dirty # Bundle staged + unstaged + untracked
142
161
  npx srcpack --since main # Bundle changes since main
143
162
  npx srcpack --dry-run # Preview without writing files
144
- npx srcpack --emptyOutDir # Empty output directory before bundling
163
+ npx srcpack --emptyOutDir # Empty output directory before writing
145
164
  npx srcpack --no-emptyOutDir # Keep existing files in output directory
146
165
  npx srcpack --no-upload # Bundle only, skip upload
147
166
  npx srcpack init # Interactive config setup
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,8 +19,29 @@ export interface FileEntry {
7
19
  }
8
20
  export interface BundleResult {
9
21
  content: string;
10
- index: FileEntry[];
22
+ index: IndexEntry[];
11
23
  }
24
+ /**
25
+ * The key two paths are compared by: canonical spelling, then case folded, on
26
+ * every platform. A case-insensitive filesystem — the default on macOS and
27
+ * Windows — treats `Context.txt` and `context.txt` as one directory entry, and
28
+ * APFS additionally folds Unicode normalisation, so `Café.txt` written as
29
+ * precomposed U+00E9 and as `e` plus U+0301 is also one entry. Normalising
30
+ * before folding is what makes the comparison sound: equal inputs stay equal
31
+ * afterwards whether or not case folding preserves normalisation. `realpath`
32
+ * resolves
33
+ * an existing component to its on-disk spelling, but that doesn't cover these:
34
+ * an output not yet written has no on-disk spelling, and the destination entry
35
+ * is deliberately left unresolved so `rename` replaces a symlink rather than
36
+ * following it. A config that works in Linux CI and loses a bundle on the
37
+ * author's laptop is worse than one rejected everywhere, so the rule is the
38
+ * same on every platform rather than keyed to the filesystem under it.
39
+ *
40
+ * Comparison only. Paths used for I/O keep their original spelling, and
41
+ * ownership stays an exact match: folding there could only widen what srcpack
42
+ * deletes, which is the one direction that must never be widened by a guess.
43
+ */
44
+ export declare function pathKey(path: string): string;
12
45
  /**
13
46
  * Resolve bundle config to a list of file paths.
14
47
  * - Regular patterns respect .gitignore
@@ -23,6 +56,15 @@ export interface BundleResult {
23
56
  * output, nesting it one level deeper every time.
24
57
  */
25
58
  export declare function resolvePatterns(config: BundleConfigInput, cwd: string, outputs?: string[]): Promise<string[]>;
59
+ /**
60
+ * Resolve every source a bundle declares into a sorted entry list.
61
+ *
62
+ * Filesystem and `git:` sources produce paths ({@link resolvePatterns}, which
63
+ * never touches the network); `linear` produces virtual entries carrying their
64
+ * own content. Both then meet the same rules — `!` exclusions apply uniformly,
65
+ * and the result is sorted by path so bundles stay deterministic.
66
+ */
67
+ export declare function resolveEntries(config: BundleConfigInput, cwd: string, outputs?: string[]): Promise<Entry[]>;
26
68
  /**
27
69
  * Format the index header block.
28
70
  * Format designed for LLM context files (ChatGPT, Grok, Gemini):
@@ -30,17 +72,17 @@ export declare function resolvePatterns(config: BundleConfigInput, cwd: string,
30
72
  * - ASCII-only characters for broad compatibility
31
73
  * - Line locations that point to actual file content
32
74
  */
33
- export declare function formatIndex(index: FileEntry[]): string;
75
+ export declare function formatIndex(index: IndexEntry[]): string;
34
76
  export interface BundleOptions {
35
77
  includeIndex?: boolean;
36
78
  prompt?: string;
37
79
  }
38
80
  /**
39
- * Create a bundle from a list of files.
81
+ * Create a bundle from a list of entries.
40
82
  * Line numbers in the index point to the first line of actual file content,
41
83
  * not to the separator line.
42
84
  */
43
- export declare function createBundle(files: string[], cwd: string, options?: BundleOptions): Promise<BundleResult>;
85
+ export declare function createBundle(entries: Entry[], cwd: string, options?: BundleOptions): Promise<BundleResult>;
44
86
  /**
45
87
  * Bundle one config entry. `outputs` lists absolute paths srcpack writes,
46
88
  * which are never bundled — see {@link resolvePatterns}.