@haystackeditor/cli 0.24.1 → 0.25.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/dist/assets/capture/capture.cb4204fcc997d8e8.js +2 -0
- package/dist/assets/capture/release.json +4 -0
- package/dist/assets/telemetry/runtime.cjs +829 -1254
- package/dist/capture/adapters/client-routes.js +383 -0
- package/dist/capture/adapters/django.js +127 -0
- package/dist/capture/adapters/files.js +77 -0
- package/dist/capture/adapters/index.js +64 -0
- package/dist/capture/adapters/jsx-edit.js +81 -0
- package/dist/capture/adapters/next.js +327 -0
- package/dist/capture/adapters/nuxt.js +192 -0
- package/dist/capture/adapters/rails.js +171 -0
- package/dist/capture/adapters/react-router.js +432 -0
- package/dist/capture/adapters/sveltekit.js +102 -0
- package/dist/capture/adapters/types.js +4 -0
- package/dist/capture/adapters/vite.js +121 -0
- package/dist/capture/app-config.js +106 -0
- package/dist/capture/consent.js +127 -0
- package/dist/capture/csp.js +331 -0
- package/dist/capture/html.js +74 -0
- package/dist/capture/js-ast.js +400 -0
- package/dist/capture/manifest.js +95 -0
- package/dist/capture/project.js +177 -0
- package/dist/capture/route-pattern.js +119 -0
- package/dist/capture/script-release.js +47 -0
- package/dist/capture/tag.js +74 -0
- package/dist/capture-step.js +53 -0
- package/dist/commands/capture-brief.js +92 -0
- package/dist/commands/capture-contract.js +46 -0
- package/dist/commands/capture-manifest.js +78 -0
- package/dist/commands/init-capture.js +409 -0
- package/dist/commands/init-telemetry.js +1011 -0
- package/dist/commands/init.js +68 -5
- package/dist/commands/server-telemetry-contract.d.ts +66 -0
- package/dist/commands/server-telemetry-contract.js +127 -0
- package/dist/commands/telemetry-token.js +238 -0
- package/dist/commands/telemetry.d.ts +161 -8
- package/dist/commands/telemetry.js +940 -158
- package/dist/commands/verify-onboarding.js +5 -1
- package/dist/commands/verify.js +54 -7
- package/dist/index.js +83 -6
- package/dist/schema.js +2 -2
- package/dist/telemetry/next-loader.cjs +66 -9
- package/dist/telemetry/next.d.ts +11 -3
- package/dist/telemetry/next.js +95 -15
- package/dist/telemetry/typed-source.d.ts +47 -0
- package/dist/telemetry/typed-source.js +379 -0
- package/package.json +4 -2
- package/schemas/init.v1.json +63 -4
- package/schemas/pre-verify.v1.json +60 -3
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { type SettingLiteral, type TelemetrySettingsEntryV1, type TelemetrySettingsProposal } from './server-telemetry-contract.js';
|
|
2
|
+
import { type TypeImportResolver } from '../telemetry/typed-source.js';
|
|
1
3
|
export declare function preloadBabel(): Promise<void>;
|
|
2
|
-
declare const MANIFEST_SCHEMA_VERSION = "haystack-node-telemetry-instrumentation-
|
|
4
|
+
declare const MANIFEST_SCHEMA_VERSION = "haystack-node-telemetry-instrumentation-v4";
|
|
3
5
|
export interface TelemetryInstrumentOptions {
|
|
4
6
|
entry: string;
|
|
5
7
|
sourceRoot?: string;
|
|
@@ -24,6 +26,31 @@ export interface InstrumentedFileSummary {
|
|
|
24
26
|
returns: number;
|
|
25
27
|
throws: number;
|
|
26
28
|
};
|
|
29
|
+
/** Rule 9(b)/(c): the file's typed source was read (declared fields, literal domains); false: shape-only. */
|
|
30
|
+
typed: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Rule 9(c): what the build did with `.haystack/telemetry-settings.json`. */
|
|
33
|
+
export interface TelemetrySettingsReport {
|
|
34
|
+
/** The settings file read, repository-relative, or null when the repository has none. */
|
|
35
|
+
file: string | null;
|
|
36
|
+
/** Why the file (or an entry) was not used; the build still ships. */
|
|
37
|
+
problems: string[];
|
|
38
|
+
/** Sites that record literals: the approved literals their typed source still declares. */
|
|
39
|
+
applied: Array<{
|
|
40
|
+
source_path: string;
|
|
41
|
+
qualified_name: string;
|
|
42
|
+
label: string;
|
|
43
|
+
literals: SettingLiteral[];
|
|
44
|
+
}>;
|
|
45
|
+
/** Approved entries the instrumenter refused (identity- or secret-looking, or no longer a literal domain). */
|
|
46
|
+
refused: Array<{
|
|
47
|
+
source_path: string;
|
|
48
|
+
qualified_name: string;
|
|
49
|
+
label: string;
|
|
50
|
+
why: string;
|
|
51
|
+
}>;
|
|
52
|
+
/** Approved entries no instrumented site of this build matches. */
|
|
53
|
+
unmatched: TelemetrySettingsEntryV1[];
|
|
27
54
|
}
|
|
28
55
|
export interface TelemetryInstrumentationResult {
|
|
29
56
|
schema_version: typeof MANIFEST_SCHEMA_VERSION;
|
|
@@ -34,6 +61,12 @@ export interface TelemetryInstrumentationResult {
|
|
|
34
61
|
instrumented_files: InstrumentedFileSummary[];
|
|
35
62
|
sites: InstrumentedSite[];
|
|
36
63
|
skipped_unmapped_files: string[];
|
|
64
|
+
/** Rule 13(b): compiled files the instrumenter could not transform, shipped exactly as built. */
|
|
65
|
+
skipped_untransformed_files: Array<{
|
|
66
|
+
output_path: string;
|
|
67
|
+
reason: string;
|
|
68
|
+
}>;
|
|
69
|
+
settings: TelemetrySettingsReport;
|
|
37
70
|
already_instrumented: boolean;
|
|
38
71
|
}
|
|
39
72
|
export interface InstrumentedSite {
|
|
@@ -45,7 +78,10 @@ export interface InstrumentedSite {
|
|
|
45
78
|
owner_key: string;
|
|
46
79
|
structural_key: string;
|
|
47
80
|
label?: string;
|
|
81
|
+
/** Rule 9(b): source-declared field names (read on the value, or declared by its type), at most SERVER_FIELDS_PER_SITE. */
|
|
48
82
|
allowed_fields: string[];
|
|
83
|
+
/** Rule 9(c): an approved settings site's literals (approved and still declared by the typed source). */
|
|
84
|
+
settings?: SettingLiteral[];
|
|
49
85
|
/**
|
|
50
86
|
* 1-based line and 0-based column of the probed node in `source_path`.
|
|
51
87
|
* Present only when the instrumented text IS the source (the bundler
|
|
@@ -63,6 +99,22 @@ export interface FileProbeCounts {
|
|
|
63
99
|
returns: number;
|
|
64
100
|
throws: number;
|
|
65
101
|
}
|
|
102
|
+
/** What the typed source declares at one site; `fields` in declaration order. */
|
|
103
|
+
interface SiteTypeFacts {
|
|
104
|
+
fields: string[];
|
|
105
|
+
domain: SettingLiteral[] | null;
|
|
106
|
+
typeNames: string[];
|
|
107
|
+
}
|
|
108
|
+
type TypedSiteFacts = Map<string, SiteTypeFacts | {
|
|
109
|
+
ambiguous: true;
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* Rule 9(b)/(c): per site of a TYPED source file (keyed by the site's function and label exactly as instrumentSource
|
|
113
|
+
* names them), the fields its type declares and its literal domain. Compiled output loses the types, so the compiled-
|
|
114
|
+
* output path reads the original TypeScript beside it and joins by this key; the bundler path reads the module it
|
|
115
|
+
* instruments. A key the file declares twice with different facts is ambiguous and keeps neither.
|
|
116
|
+
*/
|
|
117
|
+
export declare function collectTypedSiteFacts(code: string, parserPlugins: string[], resolve: TypeImportResolver | null): TypedSiteFacts;
|
|
66
118
|
/**
|
|
67
119
|
* The runtime source bound to one control channel, plus the integrity token
|
|
68
120
|
* generated probes present to it and the hash a bootstrap verifies before
|
|
@@ -75,19 +127,45 @@ export declare function authenticateTelemetryRuntime(controlChannel: string): {
|
|
|
75
127
|
integrity: string;
|
|
76
128
|
hash: string;
|
|
77
129
|
};
|
|
130
|
+
/** The repository root settings and repository-relative paths are read against: git's top level, else `start`. */
|
|
131
|
+
export declare function repositoryRoot(start: string): string;
|
|
132
|
+
/** Rule 9(c): the repository's reviewed settings allowlist, the only file instrumentation treats as approval (a
|
|
133
|
+
* proposal never is). A missing file is no settings; an unreadable file or entry is a problem the build reports,
|
|
134
|
+
* never a reason to fail it. */
|
|
135
|
+
export declare function readTelemetrySettings(repoRoot: string): {
|
|
136
|
+
file: string | null;
|
|
137
|
+
entries: TelemetrySettingsEntryV1[];
|
|
138
|
+
problems: string[];
|
|
139
|
+
};
|
|
140
|
+
/** Relative imports one hop away, parsed once per build: `./types`, `./types.js` (NodeNext) and `./types/index`. */
|
|
141
|
+
export declare function typeImportResolver(repoRoot: string): (fromFile: string) => TypeImportResolver;
|
|
78
142
|
export declare function instrumentNodeTelemetryBuild(distDirectory: string, options: TelemetryInstrumentOptions): TelemetryInstrumentationResult;
|
|
143
|
+
/** The build output could not be put back exactly as it was; the files named are left instrumented, without a
|
|
144
|
+
* manifest, so the runtime installs nothing and every probe passes values through. */
|
|
145
|
+
export declare class PartialRestoreError extends Error {
|
|
146
|
+
}
|
|
79
147
|
export declare const BUNDLED_SOURCE_EXTENSIONS: string[];
|
|
148
|
+
/** What one bundled module did with the settings allowlist (merged by the post-compile step). */
|
|
149
|
+
export interface BundledSettingsRecord {
|
|
150
|
+
applied: TelemetrySettingsReport['applied'];
|
|
151
|
+
refused: TelemetrySettingsReport['refused'];
|
|
152
|
+
/** Approved entries this module's sites matched, as `sourcePath\0qualifiedName\0label`. */
|
|
153
|
+
matched: string[];
|
|
154
|
+
}
|
|
80
155
|
export type BundledModuleResult = {
|
|
81
156
|
kind: 'instrumented';
|
|
82
157
|
code: string;
|
|
158
|
+
map: Record<string, unknown> | null;
|
|
83
159
|
probes: FileProbeCounts;
|
|
84
160
|
sites: InstrumentedSite[];
|
|
161
|
+
typed: boolean;
|
|
162
|
+
settings: BundledSettingsRecord;
|
|
85
163
|
}
|
|
86
|
-
/** Already instrumented,
|
|
164
|
+
/** Already instrumented, a "use client" module, or an edge-runtime module. */
|
|
87
165
|
| {
|
|
88
166
|
kind: 'unchanged';
|
|
89
167
|
}
|
|
90
|
-
/** Babel cannot parse it (syntax the bundler's own compiler accepts but Babel does not). */
|
|
168
|
+
/** Babel cannot parse it (syntax the bundler's own compiler accepts but Babel does not), or the transform failed. */
|
|
91
169
|
| {
|
|
92
170
|
kind: 'unparsed';
|
|
93
171
|
reason: string;
|
|
@@ -95,15 +173,19 @@ export type BundledModuleResult = {
|
|
|
95
173
|
/**
|
|
96
174
|
* Instrument one source module inside a bundler. `sourcePath` is the
|
|
97
175
|
* repository-relative path every site records, so production counts join the
|
|
98
|
-
* change's files and line ranges exactly.
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* is ours and stays loud.
|
|
176
|
+
* change's files and line ranges exactly. Rule 13(b): nothing here fails a
|
|
177
|
+
* build: a module Babel cannot parse or this pass cannot transform is reported
|
|
178
|
+
* and ships as written, with its input map.
|
|
102
179
|
*/
|
|
103
180
|
export declare function instrumentBundledModule(code: string, options: {
|
|
104
181
|
sourcePath: string;
|
|
182
|
+
/** The module's absolute path (its source map's file, and where relative type imports resolve from). */
|
|
183
|
+
absolutePath: string;
|
|
184
|
+
/** The repository root: where `.haystack/telemetry-settings.json` is read. */
|
|
185
|
+
sourceRoot: string;
|
|
105
186
|
controlChannel: string;
|
|
106
187
|
runtimeIntegrity: string;
|
|
188
|
+
inputSourceMap: object | null;
|
|
107
189
|
}): BundledModuleResult;
|
|
108
190
|
export interface BundledTelemetryManifest {
|
|
109
191
|
schema_version: typeof MANIFEST_SCHEMA_VERSION;
|
|
@@ -116,14 +198,48 @@ export interface BundledTelemetryManifest {
|
|
|
116
198
|
instrumented_files: Array<{
|
|
117
199
|
source_path: string;
|
|
118
200
|
probes: FileProbeCounts;
|
|
201
|
+
typed: boolean;
|
|
119
202
|
}>;
|
|
120
|
-
/** Server modules shipped uninstrumented because Babel could not parse
|
|
203
|
+
/** Server modules shipped uninstrumented because Babel could not parse or this pass could not transform them. */
|
|
121
204
|
skipped_unparsed_files: Array<{
|
|
122
205
|
source_path: string;
|
|
123
206
|
reason: string;
|
|
124
207
|
}>;
|
|
208
|
+
/** How site paths were named: from the git checkout (repository-relative, tracked files only), or, in a build without
|
|
209
|
+
* git, relative to the project with what that loses said. */
|
|
210
|
+
source_identity: BundledSourceIdentity;
|
|
211
|
+
settings: TelemetrySettingsReport;
|
|
125
212
|
sites: InstrumentedSite[];
|
|
126
213
|
}
|
|
214
|
+
export interface BundledSourceIdentity {
|
|
215
|
+
git: boolean;
|
|
216
|
+
lost: string | null;
|
|
217
|
+
}
|
|
218
|
+
/** Rule 13(b): what a build that could not be instrumented leaves behind: the reason, and a preload that does nothing,
|
|
219
|
+
* so a server started with NODE_OPTIONS=--require=<it> starts exactly as it would without telemetry. */
|
|
220
|
+
export interface BundledTelemetryNotInstalled {
|
|
221
|
+
schema_version: typeof MANIFEST_SCHEMA_VERSION;
|
|
222
|
+
bundler: string;
|
|
223
|
+
installed: false;
|
|
224
|
+
reason: string;
|
|
225
|
+
skipped_unparsed_files: Array<{
|
|
226
|
+
source_path: string;
|
|
227
|
+
reason: string;
|
|
228
|
+
}>;
|
|
229
|
+
sites: [];
|
|
230
|
+
}
|
|
231
|
+
export declare function writeInertTelemetryRuntime(options: {
|
|
232
|
+
outputDirectory: string;
|
|
233
|
+
bundler: string;
|
|
234
|
+
reason: string;
|
|
235
|
+
unparsed?: Array<{
|
|
236
|
+
sourcePath: string;
|
|
237
|
+
reason: string;
|
|
238
|
+
}>;
|
|
239
|
+
}): {
|
|
240
|
+
registerPath: string;
|
|
241
|
+
report: BundledTelemetryNotInstalled;
|
|
242
|
+
};
|
|
127
243
|
/**
|
|
128
244
|
* Write the runtime, its manifest and the preload that installs it into
|
|
129
245
|
* `<outputDirectory>/.haystack-telemetry/`. The runtime reads the manifest
|
|
@@ -135,10 +251,13 @@ export declare function writeBundledTelemetryRuntime(options: {
|
|
|
135
251
|
controlChannel: string;
|
|
136
252
|
bundler: string;
|
|
137
253
|
sourceRoot: string;
|
|
254
|
+
sourceIdentity: BundledSourceIdentity;
|
|
138
255
|
modules: Array<{
|
|
139
256
|
sourcePath: string;
|
|
140
257
|
probes: FileProbeCounts;
|
|
141
258
|
sites: InstrumentedSite[];
|
|
259
|
+
typed: boolean;
|
|
260
|
+
settings: BundledSettingsRecord;
|
|
142
261
|
}>;
|
|
143
262
|
unparsed: Array<{
|
|
144
263
|
sourcePath: string;
|
|
@@ -148,7 +267,41 @@ export declare function writeBundledTelemetryRuntime(options: {
|
|
|
148
267
|
registerPath: string;
|
|
149
268
|
manifest: BundledTelemetryManifest;
|
|
150
269
|
};
|
|
270
|
+
/** The settings and typed-source lines a build prints (rule 8e: init's status repeats them). */
|
|
271
|
+
export declare function settingsSummary(report: TelemetrySettingsReport, typedFiles: number, totalFiles: number): string[];
|
|
151
272
|
export declare function telemetryInstrumentCommand(distDirectory: string, options: TelemetryInstrumentOptions & {
|
|
152
273
|
includeSymbolsFile?: string;
|
|
153
274
|
}): Promise<void>;
|
|
275
|
+
/**
|
|
276
|
+
* Rule 9(c): propose settings. Every parameter and binding of the repository's typed source whose type is a closed set
|
|
277
|
+
* of literals (a union, a boolean, an enum, an `as const` array or object) is a candidate, refused when its name or a
|
|
278
|
+
* literal looks like identity or a secret. The proposal (SETTINGS_PROPOSAL_PATH) is the approved entries, unchanged,
|
|
279
|
+
* plus the new candidates; it approves nothing: only `haystack telemetry settings --approve`, run by a person, makes it
|
|
280
|
+
* the allowlist instrumentation reads.
|
|
281
|
+
*/
|
|
282
|
+
export declare function proposeTelemetrySettings(repoRoot: string): TelemetrySettingsProposal;
|
|
283
|
+
/** What promoting the proposal would change in the approved allowlist, entry by entry. */
|
|
284
|
+
export declare function settingsApprovalDiff(repoRoot: string): {
|
|
285
|
+
proposal: {
|
|
286
|
+
file: string | null;
|
|
287
|
+
entries: TelemetrySettingsEntryV1[];
|
|
288
|
+
problems: string[];
|
|
289
|
+
};
|
|
290
|
+
added: TelemetrySettingsEntryV1[];
|
|
291
|
+
removed: TelemetrySettingsEntryV1[];
|
|
292
|
+
changed: Array<{
|
|
293
|
+
from: TelemetrySettingsEntryV1;
|
|
294
|
+
to: TelemetrySettingsEntryV1;
|
|
295
|
+
}>;
|
|
296
|
+
refused: Array<{
|
|
297
|
+
entry: TelemetrySettingsEntryV1;
|
|
298
|
+
why: string;
|
|
299
|
+
}>;
|
|
300
|
+
};
|
|
301
|
+
export declare function telemetrySettingsCommand(options: {
|
|
302
|
+
propose?: boolean;
|
|
303
|
+
approve?: boolean;
|
|
304
|
+
json?: boolean;
|
|
305
|
+
dryRun?: boolean;
|
|
306
|
+
}): Promise<void>;
|
|
154
307
|
export {};
|