@floomhq/floom 1.0.33 → 1.0.35
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/package.js +26 -3
- package/dist/push-watch.js +8 -1
- package/dist/secrets.js +7 -1
- package/package.json +1 -1
package/dist/package.js
CHANGED
|
@@ -216,7 +216,7 @@ async function collectPackageFiles(root) {
|
|
|
216
216
|
continue;
|
|
217
217
|
if (await isIgnored(entry.name))
|
|
218
218
|
continue;
|
|
219
|
-
if (entry.isDirectory() && await
|
|
219
|
+
if (entry.isDirectory() && await hasNestedSkillDir(join(root, entry.name)))
|
|
220
220
|
continue;
|
|
221
221
|
if (entry.isSymbolicLink())
|
|
222
222
|
continue;
|
|
@@ -287,16 +287,39 @@ async function collectDir(root, dir, files, isIgnored, addBytes) {
|
|
|
287
287
|
await collectFile(fullPath, rel, files, addBytes);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
|
-
async function
|
|
290
|
+
async function hasNestedSkillDir(path) {
|
|
291
|
+
return hasNestedSkillDirInner(path, 0);
|
|
292
|
+
}
|
|
293
|
+
async function hasNestedSkillDirInner(path, depth) {
|
|
294
|
+
if (depth > 8)
|
|
295
|
+
return false;
|
|
291
296
|
try {
|
|
292
297
|
const stat = await lstat(join(path, "SKILL.md"));
|
|
293
|
-
|
|
298
|
+
if (stat.isFile())
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
if (err.code !== "ENOENT")
|
|
303
|
+
throw err;
|
|
304
|
+
}
|
|
305
|
+
let entries;
|
|
306
|
+
try {
|
|
307
|
+
entries = await readdir(path, { withFileTypes: true });
|
|
294
308
|
}
|
|
295
309
|
catch (err) {
|
|
296
310
|
if (err.code === "ENOENT")
|
|
297
311
|
return false;
|
|
298
312
|
throw err;
|
|
299
313
|
}
|
|
314
|
+
for (const entry of entries) {
|
|
315
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
316
|
+
continue;
|
|
317
|
+
if (isGeneratedPackageEntry(entry.name, true))
|
|
318
|
+
continue;
|
|
319
|
+
if (await hasNestedSkillDirInner(join(path, entry.name), depth + 1))
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
return false;
|
|
300
323
|
}
|
|
301
324
|
async function collectFile(fullPath, rel, files, addBytes) {
|
|
302
325
|
const normalized = rel.split(sep).join("/");
|
package/dist/push-watch.js
CHANGED
|
@@ -155,7 +155,14 @@ export async function pushWatchOnce(opts) {
|
|
|
155
155
|
const hash = hashPackage(key, skillPackage.skillBody, skillPackage.packageFiles);
|
|
156
156
|
const pushed = pushManifest.files[pushKey];
|
|
157
157
|
if (pushed?.hash === hash) {
|
|
158
|
-
|
|
158
|
+
if (!isUnchangedSyncedPackage(root, skillPackage, syncManifest)) {
|
|
159
|
+
markPackageSynced(root, skillPackage, syncManifest, pushed.slug);
|
|
160
|
+
await writeSyncManifest(syncManifest);
|
|
161
|
+
adopted += 1;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
skipped += 1;
|
|
165
|
+
}
|
|
159
166
|
continue;
|
|
160
167
|
}
|
|
161
168
|
if (!opts.yolo) {
|
package/dist/secrets.js
CHANGED
|
@@ -23,7 +23,6 @@ const PROMPT_INJECTION_PATTERNS = [
|
|
|
23
23
|
];
|
|
24
24
|
const DATA_EXFILTRATION_PATTERNS = [
|
|
25
25
|
{ label: "Data exfiltration instruction", regex: /\b(?:send|post|upload|exfiltrate|copy) (?:[^.\n]{0,80})\b(?:api keys?|tokens?|secrets?|environment variables|\.env|credentials)\b(?:[^.\n]{0,120})\b(?:to|into) https?:\/\//gi },
|
|
26
|
-
{ label: "Data exfiltration instruction", regex: /\b(?:curl|wget|fetch)\b[^\n]{0,160}\b(?:api keys?|tokens?|secrets?|environment variables|\.env|credentials)\b/gi },
|
|
27
26
|
{ label: "Credential harvesting instruction", regex: /\b(?:collect|harvest|steal|extract) (?:[^.\n]{0,80})\b(?:api keys?|tokens?|secrets?|environment variables|\.env|credentials)\b/gi },
|
|
28
27
|
];
|
|
29
28
|
function redact(value) {
|
|
@@ -46,6 +45,9 @@ function pushFinding(findings, seen, label, line, value) {
|
|
|
46
45
|
seen.add(key);
|
|
47
46
|
findings.push({ label, line, preview: redact(value) });
|
|
48
47
|
}
|
|
48
|
+
function isDocumentedEnvReference(value) {
|
|
49
|
+
return /\b(?:process\.env|import\.meta\.env|os\.environ)\b/.test(value);
|
|
50
|
+
}
|
|
49
51
|
export function detectSecrets(input) {
|
|
50
52
|
const findings = [];
|
|
51
53
|
const seen = new Set();
|
|
@@ -61,6 +63,8 @@ export function detectSecrets(input) {
|
|
|
61
63
|
const value = match[1] ?? "";
|
|
62
64
|
if (!value || PLACEHOLDER_RE.test(value))
|
|
63
65
|
continue;
|
|
66
|
+
if (isDocumentedEnvReference(value))
|
|
67
|
+
continue;
|
|
64
68
|
pushFinding(findings, seen, "Possible secret assignment", lineNumberAt(input, match.index ?? 0), value);
|
|
65
69
|
}
|
|
66
70
|
PROVIDER_LIKE_ASSIGNMENT_RE.lastIndex = 0;
|
|
@@ -68,6 +72,8 @@ export function detectSecrets(input) {
|
|
|
68
72
|
const value = match[1] ?? "";
|
|
69
73
|
if (!value)
|
|
70
74
|
continue;
|
|
75
|
+
if (isDocumentedEnvReference(value))
|
|
76
|
+
continue;
|
|
71
77
|
pushFinding(findings, seen, "Provider-like secret assignment", lineNumberAt(input, match.index ?? 0), value);
|
|
72
78
|
}
|
|
73
79
|
return findings.sort((a, b) => a.line - b.line || a.label.localeCompare(b.label));
|