@bastani/atomic 0.6.5 → 0.6.6-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/.agents/skills/ado-commit/SKILL.md +2 -0
- package/.agents/skills/ado-create-pr/SKILL.md +2 -0
- package/.agents/skills/advanced-evaluation/SKILL.md +2 -0
- package/.agents/skills/ast-grep/SKILL.md +2 -0
- package/.agents/skills/bdi-mental-states/SKILL.md +2 -0
- package/.agents/skills/bun/SKILL.md +156 -122
- package/.agents/skills/context-compression/SKILL.md +2 -0
- package/.agents/skills/context-degradation/SKILL.md +2 -0
- package/.agents/skills/context-fundamentals/SKILL.md +2 -0
- package/.agents/skills/context-optimization/SKILL.md +2 -0
- package/.agents/skills/create-spec/SKILL.md +2 -0
- package/.agents/skills/docx/SKILL.md +2 -0
- package/.agents/skills/evaluation/SKILL.md +2 -0
- package/.agents/skills/explain-code/SKILL.md +2 -0
- package/.agents/skills/filesystem-context/SKILL.md +2 -0
- package/.agents/skills/find-skills/SKILL.md +2 -0
- package/.agents/skills/gh-commit/SKILL.md +2 -0
- package/.agents/skills/gh-create-pr/SKILL.md +2 -0
- package/.agents/skills/hosted-agents/SKILL.md +2 -0
- package/.agents/skills/impeccable/SKILL.md +117 -304
- package/.agents/skills/impeccable/agents/openai.yaml +4 -0
- package/.agents/skills/{adapt/SKILL.md → impeccable/reference/adapt.md} +2 -11
- package/.agents/skills/{animate/SKILL.md → impeccable/reference/animate.md} +15 -15
- package/.agents/skills/{audit/SKILL.md → impeccable/reference/audit.md} +8 -22
- package/.agents/skills/{bolder/SKILL.md → impeccable/reference/bolder.md} +9 -13
- package/.agents/skills/impeccable/reference/brand.md +114 -0
- package/.agents/skills/{clarify/SKILL.md → impeccable/reference/clarify.md} +2 -11
- package/.agents/skills/{colorize/SKILL.md → impeccable/reference/colorize.md} +23 -12
- package/.agents/skills/impeccable/reference/craft.md +152 -29
- package/.agents/skills/{critique/SKILL.md → impeccable/reference/critique.md} +25 -37
- package/.agents/skills/{delight/SKILL.md → impeccable/reference/delight.md} +9 -11
- package/.agents/skills/{distill/SKILL.md → impeccable/reference/distill.md} +2 -13
- package/.agents/skills/impeccable/reference/document.md +427 -0
- package/.agents/skills/impeccable/reference/extract.md +1 -1
- package/.agents/skills/{harden/SKILL.md → impeccable/reference/harden.md} +1 -43
- package/.agents/skills/{layout/SKILL.md → impeccable/reference/layout.md} +27 -11
- package/.agents/skills/impeccable/reference/live.md +594 -0
- package/.agents/skills/impeccable/reference/motion-design.md +12 -2
- package/.agents/skills/impeccable/reference/onboard.md +234 -0
- package/.agents/skills/{optimize/SKILL.md → impeccable/reference/optimize.md} +4 -12
- package/.agents/skills/{overdrive/SKILL.md → impeccable/reference/overdrive.md} +9 -21
- package/.agents/skills/{critique → impeccable}/reference/personas.md +1 -1
- package/.agents/skills/{polish/SKILL.md → impeccable/reference/polish.md} +31 -23
- package/.agents/skills/impeccable/reference/product.md +62 -0
- package/.agents/skills/{quieter/SKILL.md → impeccable/reference/quieter.md} +7 -11
- package/.agents/skills/impeccable/reference/shape.md +151 -0
- package/.agents/skills/impeccable/reference/teach.md +156 -0
- package/.agents/skills/{typeset/SKILL.md → impeccable/reference/typeset.md} +19 -11
- package/.agents/skills/impeccable/reference/typography.md +31 -14
- package/.agents/skills/impeccable/scripts/cleanup-deprecated.mjs +87 -17
- package/.agents/skills/impeccable/scripts/command-metadata.json +94 -0
- package/.agents/skills/impeccable/scripts/design-parser.mjs +820 -0
- package/.agents/skills/impeccable/scripts/detect-csp.mjs +198 -0
- package/.agents/skills/impeccable/scripts/is-generated.mjs +69 -0
- package/.agents/skills/impeccable/scripts/live-accept.mjs +595 -0
- package/.agents/skills/impeccable/scripts/live-browser.js +4781 -0
- package/.agents/skills/impeccable/scripts/live-inject.mjs +445 -0
- package/.agents/skills/impeccable/scripts/live-poll.mjs +186 -0
- package/.agents/skills/impeccable/scripts/live-server.mjs +694 -0
- package/.agents/skills/impeccable/scripts/live-wrap.mjs +571 -0
- package/.agents/skills/impeccable/scripts/live.mjs +247 -0
- package/.agents/skills/impeccable/scripts/load-context.mjs +141 -0
- package/.agents/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
- package/.agents/skills/impeccable/scripts/pin.mjs +214 -0
- package/.agents/skills/init/SKILL.md +2 -0
- package/.agents/skills/liteparse/SKILL.md +1 -0
- package/.agents/skills/memory-systems/SKILL.md +2 -0
- package/.agents/skills/multi-agent-patterns/SKILL.md +2 -0
- package/.agents/skills/opentui/SKILL.md +1 -0
- package/.agents/skills/pdf/SKILL.md +2 -0
- package/.agents/skills/playwright-cli/SKILL.md +51 -5
- package/.agents/skills/playwright-cli/references/playwright-tests.md +1 -1
- package/.agents/skills/playwright-cli/references/running-code.md +10 -0
- package/.agents/skills/playwright-cli/references/session-management.md +56 -0
- package/.agents/skills/playwright-cli/references/spec-driven-testing.md +305 -0
- package/.agents/skills/playwright-cli/references/test-generation.md +49 -3
- package/.agents/skills/pptx/SKILL.md +2 -0
- package/.agents/skills/project-development/SKILL.md +2 -0
- package/.agents/skills/prompt-engineer/SKILL.md +2 -0
- package/.agents/skills/research-codebase/SKILL.md +2 -0
- package/.agents/skills/ripgrep/SKILL.md +2 -0
- package/.agents/skills/skill-creator/LICENSE.txt +1 -1
- package/.agents/skills/skill-creator/SKILL.md +2 -0
- package/.agents/skills/sl-commit/SKILL.md +2 -0
- package/.agents/skills/sl-submit-diff/SKILL.md +2 -0
- package/.agents/skills/tdd/SKILL.md +4 -0
- package/.agents/skills/tool-design/SKILL.md +2 -0
- package/.agents/skills/typescript-advanced-types/SKILL.md +2 -1
- package/.agents/skills/typescript-expert/SKILL.md +7 -1
- package/.agents/skills/typescript-react-reviewer/SKILL.md +2 -1
- package/.agents/skills/workflow-creator/SKILL.md +75 -72
- package/.agents/skills/workflow-creator/references/session-config.md +48 -1
- package/.agents/skills/xlsx/SKILL.md +2 -0
- package/.opencode/opencode.json +4 -2
- package/dist/sdk/runtime/executor.d.ts +8 -0
- package/dist/sdk/runtime/executor.d.ts.map +1 -1
- package/dist/sdk/runtime/port-discovery.d.ts +71 -0
- package/dist/sdk/runtime/port-discovery.d.ts.map +1 -0
- package/dist/sdk/runtime/tmux.d.ts +10 -0
- package/dist/sdk/runtime/tmux.d.ts.map +1 -1
- package/dist/sdk/types.d.ts +1 -0
- package/dist/sdk/types.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/open-claude-design/opencode/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts +15 -0
- package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts.map +1 -1
- package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/sdk/runtime/executor.test.ts +254 -1
- package/src/sdk/runtime/executor.ts +135 -89
- package/src/sdk/runtime/port-discovery.test.ts +573 -0
- package/src/sdk/runtime/port-discovery.ts +496 -0
- package/src/sdk/runtime/tmux.ts +16 -0
- package/src/sdk/types.ts +1 -0
- package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +24 -6
- package/src/sdk/workflows/builtin/open-claude-design/opencode/index.ts +52 -13
- package/src/sdk/workflows/builtin/ralph/claude/index.ts +31 -3
- package/src/sdk/workflows/builtin/ralph/copilot/index.ts +16 -0
- package/src/sdk/workflows/builtin/ralph/helpers/prompts.ts +70 -3
- package/src/sdk/workflows/builtin/ralph/opencode/index.ts +50 -6
- package/.agents/skills/shape/SKILL.md +0 -96
- /package/.agents/skills/{critique → impeccable}/reference/cognitive-load.md +0 -0
- /package/.agents/skills/{critique → impeccable}/reference/heuristics-scoring.md +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan a project tree for Content-Security-Policy signals and classify the
|
|
3
|
+
* shape so the agent knows which patch template to propose.
|
|
4
|
+
*
|
|
5
|
+
* Used at first-time `live.mjs` setup. Mechanical (grep-based) — no network,
|
|
6
|
+
* no dev server, no JS evaluation. The classification drives a user-facing
|
|
7
|
+
* consent prompt; the agent does the actual patch writing.
|
|
8
|
+
*
|
|
9
|
+
* Shapes are named by patch mechanism, not framework origin:
|
|
10
|
+
* - "append-arrays": CSP defined as structured directive arrays. Patch
|
|
11
|
+
* appends a dev-only localhost entry. Covers:
|
|
12
|
+
* - Monorepo helpers with additional*Src options
|
|
13
|
+
* (e.g. createBaseNextConfig for Next)
|
|
14
|
+
* - SvelteKit kit.csp.directives
|
|
15
|
+
* - nuxt-security module's contentSecurityPolicy
|
|
16
|
+
* - "append-string": CSP built as a literal value string. Patch splices
|
|
17
|
+
* a dev-only token into script-src and connect-src.
|
|
18
|
+
* Covers:
|
|
19
|
+
* - Inline Next.js headers() with CSP string
|
|
20
|
+
* - Nuxt routeRules / nitro.routeRules CSP headers
|
|
21
|
+
* - "middleware": CSP set dynamically in middleware.{ts,js}.
|
|
22
|
+
* Detected but not auto-patched in v1.
|
|
23
|
+
* - "meta-tag": <meta http-equiv="Content-Security-Policy"> in
|
|
24
|
+
* layout files. Detected but not auto-patched in v1.
|
|
25
|
+
* - null: no CSP signals found; no patch needed.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import fs from 'node:fs';
|
|
29
|
+
import path from 'node:path';
|
|
30
|
+
|
|
31
|
+
const SKIP_DIRS = new Set([
|
|
32
|
+
'node_modules',
|
|
33
|
+
'.git',
|
|
34
|
+
'.next',
|
|
35
|
+
'.turbo',
|
|
36
|
+
'.svelte-kit',
|
|
37
|
+
'.nuxt',
|
|
38
|
+
'.astro',
|
|
39
|
+
'dist',
|
|
40
|
+
'build',
|
|
41
|
+
'out',
|
|
42
|
+
'.vercel',
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const SCAN_EXTS = new Set(['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts', '.tsx', '.jsx']);
|
|
46
|
+
const LAYOUT_EXTS = new Set(['.tsx', '.jsx', '.astro', '.vue', '.svelte', '.html']);
|
|
47
|
+
const MAX_DEPTH = 6;
|
|
48
|
+
const MAX_READ_BYTES = 64 * 1024;
|
|
49
|
+
|
|
50
|
+
// append-arrays signals: CSP expressed as structured directive arrays
|
|
51
|
+
const MONOREPO_HELPER_SIGNALS = [
|
|
52
|
+
/\bbuildCSPConfig\b/,
|
|
53
|
+
/\bbuildSecurityHeaders\b/,
|
|
54
|
+
/\badditionalScriptSrc\b/,
|
|
55
|
+
/\badditionalConnectSrc\b/,
|
|
56
|
+
/\bcreateBaseNextConfig\b/,
|
|
57
|
+
];
|
|
58
|
+
const SVELTEKIT_CSP_SIGNALS = [
|
|
59
|
+
/\bkit\s*:/,
|
|
60
|
+
/\bcsp\s*:/,
|
|
61
|
+
/\bdirectives\s*:/,
|
|
62
|
+
];
|
|
63
|
+
const NUXT_SECURITY_SIGNALS = [
|
|
64
|
+
/['"]nuxt-security['"]/,
|
|
65
|
+
/\bcontentSecurityPolicy\b/,
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
// append-string signals: CSP written as a literal value string
|
|
69
|
+
const INLINE_HEADER_SIGNALS = [
|
|
70
|
+
/["']Content-Security-Policy["']/i,
|
|
71
|
+
/\bscript-src\b/,
|
|
72
|
+
/\bconnect-src\b/,
|
|
73
|
+
];
|
|
74
|
+
const NUXT_ROUTE_RULES_SIGNALS = [
|
|
75
|
+
/\brouteRules\b/,
|
|
76
|
+
/Content-Security-Policy/i,
|
|
77
|
+
/\bscript-src\b/,
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const MIDDLEWARE_HINT = /headers\.set\(\s*["']Content-Security-Policy["']/i;
|
|
81
|
+
const META_TAG_HINT = /http-equiv\s*=\s*["']Content-Security-Policy["']/i;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {string} cwd Project root.
|
|
85
|
+
* @returns {{ shape: string|null, signals: string[] }}
|
|
86
|
+
*/
|
|
87
|
+
export function detectCsp(cwd = process.cwd()) {
|
|
88
|
+
const hits = { appendArrays: [], appendString: [], middleware: [], metaTag: [] };
|
|
89
|
+
|
|
90
|
+
walk(cwd, cwd, 0, (absPath, relPath, body) => {
|
|
91
|
+
const ext = path.extname(absPath);
|
|
92
|
+
const base = path.basename(absPath).toLowerCase();
|
|
93
|
+
const isConfig = (name) =>
|
|
94
|
+
new RegExp('(^|/)' + name + '\\.config\\.').test(relPath);
|
|
95
|
+
|
|
96
|
+
// === append-arrays candidates ===
|
|
97
|
+
|
|
98
|
+
// Monorepo CSP helper: packages/*/src/.../(config|security)/*
|
|
99
|
+
if (SCAN_EXTS.has(ext) &&
|
|
100
|
+
/packages\/[^/]+\/src\/.*(config|next-config|security)/.test(relPath) &&
|
|
101
|
+
MONOREPO_HELPER_SIGNALS.some((re) => re.test(body))) {
|
|
102
|
+
hits.appendArrays.push(relPath);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// SvelteKit kit.csp.directives
|
|
107
|
+
if (SCAN_EXTS.has(ext) && isConfig('svelte') &&
|
|
108
|
+
SVELTEKIT_CSP_SIGNALS.every((re) => re.test(body))) {
|
|
109
|
+
hits.appendArrays.push(relPath);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Nuxt nuxt-security module
|
|
114
|
+
if (SCAN_EXTS.has(ext) && isConfig('nuxt') &&
|
|
115
|
+
NUXT_SECURITY_SIGNALS.every((re) => re.test(body))) {
|
|
116
|
+
hits.appendArrays.push(relPath);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// === append-string candidates ===
|
|
121
|
+
|
|
122
|
+
// Inline headers in Next/Nuxt/SvelteKit/Astro/Vite config
|
|
123
|
+
if (SCAN_EXTS.has(ext) &&
|
|
124
|
+
/(^|\/)(next|nuxt|vite|astro|svelte)\.config\./.test(relPath) &&
|
|
125
|
+
INLINE_HEADER_SIGNALS.every((re) => re.test(body))) {
|
|
126
|
+
// Nuxt routeRules is a sub-shape of append-string; we already covered
|
|
127
|
+
// nuxt-security above via return, so any remaining Nuxt CSP match here
|
|
128
|
+
// is a route-rules / inline-headers case. Either way, same patch
|
|
129
|
+
// mechanism.
|
|
130
|
+
hits.appendString.push(relPath);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// === detect-only shapes ===
|
|
135
|
+
|
|
136
|
+
if ((base === 'middleware.ts' || base === 'middleware.js' || base === 'middleware.mjs') &&
|
|
137
|
+
MIDDLEWARE_HINT.test(body)) {
|
|
138
|
+
hits.middleware.push(relPath);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (LAYOUT_EXTS.has(ext) && META_TAG_HINT.test(body)) {
|
|
142
|
+
hits.metaTag.push(relPath);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Priority: append-arrays > append-string > middleware > meta-tag.
|
|
147
|
+
// Structured patches are safer than string splices; runtime and HTML
|
|
148
|
+
// injection patches are less reliable and v1 doesn't auto-apply them.
|
|
149
|
+
if (hits.appendArrays.length > 0) {
|
|
150
|
+
return { shape: 'append-arrays', signals: hits.appendArrays };
|
|
151
|
+
}
|
|
152
|
+
if (hits.appendString.length > 0) {
|
|
153
|
+
return { shape: 'append-string', signals: hits.appendString };
|
|
154
|
+
}
|
|
155
|
+
if (hits.middleware.length > 0) {
|
|
156
|
+
return { shape: 'middleware', signals: hits.middleware };
|
|
157
|
+
}
|
|
158
|
+
if (hits.metaTag.length > 0) {
|
|
159
|
+
return { shape: 'meta-tag', signals: hits.metaTag };
|
|
160
|
+
}
|
|
161
|
+
return { shape: null, signals: [] };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function walk(root, dir, depth, visit) {
|
|
165
|
+
if (depth > MAX_DEPTH) return;
|
|
166
|
+
let entries;
|
|
167
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
|
|
168
|
+
catch { return; }
|
|
169
|
+
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
const abs = path.join(dir, entry.name);
|
|
172
|
+
if (entry.isDirectory()) {
|
|
173
|
+
if (SKIP_DIRS.has(entry.name)) continue;
|
|
174
|
+
walk(root, abs, depth + 1, visit);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (!entry.isFile()) continue;
|
|
178
|
+
const ext = path.extname(entry.name);
|
|
179
|
+
if (!SCAN_EXTS.has(ext) && !LAYOUT_EXTS.has(ext)) continue;
|
|
180
|
+
let body;
|
|
181
|
+
try {
|
|
182
|
+
const fd = fs.openSync(abs, 'r');
|
|
183
|
+
try {
|
|
184
|
+
const buf = Buffer.alloc(MAX_READ_BYTES);
|
|
185
|
+
const n = fs.readSync(fd, buf, 0, MAX_READ_BYTES, 0);
|
|
186
|
+
body = buf.slice(0, n).toString('utf-8');
|
|
187
|
+
} finally { fs.closeSync(fd); }
|
|
188
|
+
} catch { continue; }
|
|
189
|
+
visit(abs, path.relative(root, abs), body);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// CLI mode
|
|
194
|
+
const _running = process.argv[1];
|
|
195
|
+
if (_running?.endsWith('detect-csp.mjs') || _running?.endsWith('detect-csp.mjs/')) {
|
|
196
|
+
const result = detectCsp(process.cwd());
|
|
197
|
+
console.log(JSON.stringify(result, null, 2));
|
|
198
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decide whether a given file is "generated" (regenerated by a build step,
|
|
3
|
+
* unsafe to write variants into) or "source" (safe to edit, changes persist).
|
|
4
|
+
*
|
|
5
|
+
* Why this matters: when the user picks an element on a page whose underlying
|
|
6
|
+
* file is regenerated by a build step (e.g. `scripts/build-sub-pages.js`
|
|
7
|
+
* rewriting `public/docs/*.html`), writing variants or accepted changes into
|
|
8
|
+
* that file is silent data loss — the next build wipes them.
|
|
9
|
+
*
|
|
10
|
+
* Signals, in order of reliability:
|
|
11
|
+
* 1. Git check-ignore: gitignored files are assumed generated.
|
|
12
|
+
* 2. File-header markers ("GENERATED", "DO NOT EDIT", "AUTO-GENERATED")
|
|
13
|
+
* within the first ~300 characters — catches non-git projects.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
|
|
20
|
+
const HEADER_SCAN_BYTES = 300;
|
|
21
|
+
const HEADER_MARKERS = [
|
|
22
|
+
/@generated\b/i,
|
|
23
|
+
/\bGENERATED\s+FILE\b/,
|
|
24
|
+
/\bAUTO-?GENERATED\b/i,
|
|
25
|
+
/\bDO\s+NOT\s+EDIT\b/i,
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {string} filePath - absolute or cwd-relative path
|
|
30
|
+
* @param {object} [options]
|
|
31
|
+
* @param {string} [options.cwd] - project root (defaults to process.cwd())
|
|
32
|
+
*/
|
|
33
|
+
export function isGeneratedFile(filePath, options = {}) {
|
|
34
|
+
const cwd = options.cwd || process.cwd();
|
|
35
|
+
const absPath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
|
|
36
|
+
|
|
37
|
+
if (isGitIgnored(absPath, cwd)) return true;
|
|
38
|
+
if (hasGeneratedHeader(absPath)) return true;
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isGitIgnored(absPath, cwd) {
|
|
43
|
+
try {
|
|
44
|
+
execSync(`git check-ignore --quiet ${JSON.stringify(absPath)}`, {
|
|
45
|
+
cwd,
|
|
46
|
+
stdio: 'ignore',
|
|
47
|
+
});
|
|
48
|
+
return true; // exit 0 = ignored
|
|
49
|
+
} catch (err) {
|
|
50
|
+
// Exit code 1 = not ignored. Exit code 128 = not a git repo or other error.
|
|
51
|
+
// In both cases, treat as "not known to be ignored."
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function hasGeneratedHeader(absPath) {
|
|
57
|
+
let fd;
|
|
58
|
+
try {
|
|
59
|
+
fd = fs.openSync(absPath, 'r');
|
|
60
|
+
const buf = Buffer.alloc(HEADER_SCAN_BYTES);
|
|
61
|
+
const bytesRead = fs.readSync(fd, buf, 0, HEADER_SCAN_BYTES, 0);
|
|
62
|
+
const head = buf.slice(0, bytesRead).toString('utf-8');
|
|
63
|
+
return HEADER_MARKERS.some((re) => re.test(head));
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
} finally {
|
|
67
|
+
if (fd !== undefined) { try { fs.closeSync(fd); } catch {} }
|
|
68
|
+
}
|
|
69
|
+
}
|