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 +55 -19
- package/dist/args.d.ts +26 -0
- package/dist/bundle.d.ts +26 -5
- package/dist/cli.js +5454 -15133
- package/dist/config.d.ts +92 -11
- package/dist/fs.d.ts +41 -0
- package/dist/index.js +448 -10447
- package/dist/linear.d.ts +17 -0
- package/dist/plan.d.ts +64 -0
- package/dist/screenshot.d.ts +113 -0
- package/package.json +13 -1
- package/src/args.ts +221 -0
- package/src/bundle.ts +219 -51
- package/src/cli.ts +304 -236
- package/src/config.ts +250 -37
- package/src/fs.ts +80 -0
- package/src/linear.ts +368 -0
- package/src/plan.ts +238 -0
- package/src/screenshot.ts +545 -0
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare function expandPath(p: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Linear issues as a bundle source. Each issue becomes a virtual file at
|
|
5
|
+
* `linear/issues/<identifier>.md`, so it gets its own index entry and line
|
|
6
|
+
* range and can be filtered with ordinary `!` exclusions.
|
|
7
|
+
*
|
|
8
|
+
* Authentication reads `LINEAR_API_KEY` from the environment. It is
|
|
9
|
+
* deliberately not a config field: config files are committed, and the
|
|
10
|
+
* `package.json` config form cannot express `process.env`.
|
|
11
|
+
*
|
|
12
|
+
* `team` is required. A workspace-wide fetch is a footgun — it looks innocuous
|
|
13
|
+
* and can pull thousands of issues into a context window.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* bundles: {
|
|
18
|
+
* backlog: { linear: "ENG" },
|
|
19
|
+
* roadmap: { linear: { team: "ENG", project: "Roadmap" } },
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare const LinearSourceSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
24
|
+
team: z.ZodString;
|
|
25
|
+
project: z.ZodOptional<z.ZodString>;
|
|
26
|
+
includeClosed: z.ZodDefault<z.ZodBoolean>;
|
|
27
|
+
}, z.core.$strict>]>;
|
|
28
|
+
/**
|
|
29
|
+
* A rendered page as numbered PNGs in `outDir`, independent of the text
|
|
30
|
+
* output path. See ADR 006 for why it is a separate source key.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* bundles: {
|
|
35
|
+
* home: { screenshot: "http://localhost:5173/", onDemand: true },
|
|
36
|
+
* phone: { screenshot: { url: "http://localhost:5173/", viewport: "mobile" } },
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare const ScreenshotSourceSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
41
|
+
url: z.ZodString;
|
|
42
|
+
viewport: z.ZodOptional<z.ZodEnum<{
|
|
43
|
+
desktop: "desktop";
|
|
44
|
+
mobile: "mobile";
|
|
45
|
+
}>>;
|
|
46
|
+
hide: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
47
|
+
}, z.core.$strict>]>;
|
|
3
48
|
/**
|
|
4
49
|
* Bundle configuration. Accepts a string pattern, array of patterns, or object.
|
|
5
50
|
* Patterns prefixed with `!` are exclusions. Patterns prefixed with `+` force
|
|
@@ -9,17 +54,37 @@ export declare function expandPath(p: string): string;
|
|
|
9
54
|
* `git:unstaged`, `git:untracked`, `git:dirty`, or `git:<rev>` (e.g.
|
|
10
55
|
* `git:main`, `git:HEAD~3`).
|
|
11
56
|
*
|
|
57
|
+
* The object form takes files (`include`), Linear issues (`linear`), page
|
|
58
|
+
* screenshots (`screenshot`), or any combination.
|
|
59
|
+
*
|
|
12
60
|
* @example
|
|
13
61
|
* ```ts
|
|
14
|
-
* bundles: {
|
|
62
|
+
* bundles: {
|
|
63
|
+
* review: ["git:staged", "!bun.lock"],
|
|
64
|
+
* planning: { include: ["docs/**"], linear: { team: "ENG" } },
|
|
65
|
+
* }
|
|
15
66
|
* ```
|
|
16
67
|
*/
|
|
17
68
|
declare const BundleConfigSchema: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
|
|
18
|
-
include: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]
|
|
69
|
+
include: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
70
|
+
linear: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
71
|
+
team: z.ZodString;
|
|
72
|
+
project: z.ZodOptional<z.ZodString>;
|
|
73
|
+
includeClosed: z.ZodDefault<z.ZodBoolean>;
|
|
74
|
+
}, z.core.$strict>]>>;
|
|
75
|
+
screenshot: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
76
|
+
url: z.ZodString;
|
|
77
|
+
viewport: z.ZodOptional<z.ZodEnum<{
|
|
78
|
+
desktop: "desktop";
|
|
79
|
+
mobile: "mobile";
|
|
80
|
+
}>>;
|
|
81
|
+
hide: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
82
|
+
}, z.core.$strict>]>>;
|
|
19
83
|
outfile: z.ZodOptional<z.ZodString>;
|
|
20
|
-
index: z.
|
|
84
|
+
index: z.ZodOptional<z.ZodBoolean>;
|
|
21
85
|
prompt: z.ZodOptional<z.ZodString>;
|
|
22
|
-
|
|
86
|
+
onDemand: z.ZodOptional<z.ZodBoolean>;
|
|
87
|
+
}, z.core.$strict>]>;
|
|
23
88
|
/**
|
|
24
89
|
* Upload destination configuration.
|
|
25
90
|
*
|
|
@@ -40,7 +105,7 @@ declare const UploadConfigSchema: z.ZodObject<{
|
|
|
40
105
|
clientId: z.ZodString;
|
|
41
106
|
clientSecret: z.ZodString;
|
|
42
107
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
43
|
-
}, z.core.$
|
|
108
|
+
}, z.core.$strict>;
|
|
44
109
|
/** Root configuration for srcpack. */
|
|
45
110
|
declare const ConfigSchema: z.ZodObject<{
|
|
46
111
|
root: z.ZodDefault<z.ZodString>;
|
|
@@ -52,21 +117,37 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
52
117
|
clientId: z.ZodString;
|
|
53
118
|
clientSecret: z.ZodString;
|
|
54
119
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
55
|
-
}, z.core.$
|
|
120
|
+
}, z.core.$strict>, z.ZodArray<z.ZodObject<{
|
|
56
121
|
provider: z.ZodLiteral<"gdrive">;
|
|
57
122
|
folderId: z.ZodOptional<z.ZodString>;
|
|
58
123
|
clientId: z.ZodString;
|
|
59
124
|
clientSecret: z.ZodString;
|
|
60
125
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
61
|
-
}, z.core.$
|
|
126
|
+
}, z.core.$strict>>]>>;
|
|
62
127
|
bundles: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>, z.ZodObject<{
|
|
63
|
-
include: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]
|
|
128
|
+
include: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
129
|
+
linear: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
130
|
+
team: z.ZodString;
|
|
131
|
+
project: z.ZodOptional<z.ZodString>;
|
|
132
|
+
includeClosed: z.ZodDefault<z.ZodBoolean>;
|
|
133
|
+
}, z.core.$strict>]>>;
|
|
134
|
+
screenshot: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
135
|
+
url: z.ZodString;
|
|
136
|
+
viewport: z.ZodOptional<z.ZodEnum<{
|
|
137
|
+
desktop: "desktop";
|
|
138
|
+
mobile: "mobile";
|
|
139
|
+
}>>;
|
|
140
|
+
hide: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
|
+
}, z.core.$strict>]>>;
|
|
64
142
|
outfile: z.ZodOptional<z.ZodString>;
|
|
65
|
-
index: z.
|
|
143
|
+
index: z.ZodOptional<z.ZodBoolean>;
|
|
66
144
|
prompt: z.ZodOptional<z.ZodString>;
|
|
67
|
-
|
|
68
|
-
}, z.core.$
|
|
145
|
+
onDemand: z.ZodOptional<z.ZodBoolean>;
|
|
146
|
+
}, z.core.$strict>]>>;
|
|
147
|
+
}, z.core.$strict>;
|
|
69
148
|
export type UploadConfig = z.infer<typeof UploadConfigSchema>;
|
|
149
|
+
export type LinearSourceInput = z.input<typeof LinearSourceSchema>;
|
|
150
|
+
export type ScreenshotSource = z.infer<typeof ScreenshotSourceSchema>;
|
|
70
151
|
export type BundleConfig = z.infer<typeof BundleConfigSchema>;
|
|
71
152
|
export type BundleConfigInput = z.input<typeof BundleConfigSchema>;
|
|
72
153
|
export type Config = z.infer<typeof ConfigSchema>;
|
package/dist/fs.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare paths using Unicode NFC followed by lowercase, on every platform.
|
|
3
|
+
* Normalizing first gives equivalent spellings the same input to lowercasing.
|
|
4
|
+
* This catches case and normalization collisions even for unwritten outputs
|
|
5
|
+
* and unresolved final entries, where realpath cannot canonicalize spelling.
|
|
6
|
+
* Applying one rule everywhere prevents a config from passing on Linux and
|
|
7
|
+
* overwriting a bundle on a case-insensitive filesystem (ADR 004).
|
|
8
|
+
*
|
|
9
|
+
* Comparison only: I/O retains the original spelling. Ownership and deletion
|
|
10
|
+
* use exact matches so folding cannot widen what srcpack removes.
|
|
11
|
+
*/
|
|
12
|
+
export declare function pathKey(path: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Where a path physically is, with symlinks resolved. Destructive decisions are
|
|
15
|
+
* made on this rather than the lexical path: `.srcpack -> ../shared` is inside
|
|
16
|
+
* the project by name and somewhere else in fact, and it is the somewhere else
|
|
17
|
+
* whose contents `rm` would take.
|
|
18
|
+
*
|
|
19
|
+
* Resolves as much of the path as exists, however deep that is. Stopping at the
|
|
20
|
+
* immediate parent would call `.srcpack/nested/x.txt` and `alias/nested/x.txt`
|
|
21
|
+
* different files until `mkdir -p` runs, which is one step too late to still be
|
|
22
|
+
* a check: aliasing is a property of the ancestors, not of when they were made.
|
|
23
|
+
*/
|
|
24
|
+
export declare function physicalPath(path: string): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Where `rename` puts a directory entry: ancestors resolved, the entry itself
|
|
27
|
+
* left alone. Writing replaces the entry instead of following it, so a bundle
|
|
28
|
+
* whose output is a symlink is identified as the link rather than its target —
|
|
29
|
+
* writing to the link path and to its target produces two separate files.
|
|
30
|
+
*/
|
|
31
|
+
export declare function entryPath(path: string): Promise<string>;
|
|
32
|
+
export declare function isInside(path: string, dir: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Write a file by replacing the directory entry rather than the file behind
|
|
35
|
+
* it. Writing in place follows a symlink sitting at the output path, so
|
|
36
|
+
* `.srcpack/web.txt -> ~/.ssh/config` would be written through; rename replaces
|
|
37
|
+
* the link itself. It also makes each file appear whole or not at all.
|
|
38
|
+
*
|
|
39
|
+
* The temp name carries the pid so two runs can't rename each other's file.
|
|
40
|
+
*/
|
|
41
|
+
export declare function writeFileAtomic(path: string, data: string | Uint8Array): Promise<void>;
|