You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7bf9df7
Browse filesBrowse the repository at this point in the historyBrowse files
Release bundle: nothing the Claude directory reads as a credential read
The directory's scan of plugin 26.11.108 held 11 bundle files, and the plugin
with them, because it reads script text as shell: a template literal's
${...} with a credential-like name inside (a KV key, an API field) looks like a
variable expansion, .command("set") / .command("export") inside parentheses
looks like the set or export builtin dumping the environment, and
"...; pass a file" looks like the pass password manager.
- bundle-release.mjs emits template literals as "...".concat(...) (esbuild
supported: template-literal false), which converts each value exactly as a
template literal does; the bundle carries no ${...} at all.
- scripts/directory-scan.mjs lists the patterns; the bundler fails on any of
them in dist/ or assets/.
- Two pinned dependency spots are patched at bundle time, each asserted to
match exactly: commander's Option.env() lookup (the CLI declares no option
environment variables) and a "| env |" doc comment; ajv's SchemaEnv
constructor parameter named env.
- Source: set/export subcommands register through subcommand(); "pass a file"
reads "name a file"; screen fields' local `set` is `assigned`; the packer's
SSH key names are built from their key types, and its redundant .npmrc,
.pypirc and .netrc entries are gone (every dot path is already excluded).
Bundle: 62 files, largest 224,437 bytes, no scan findings.
Gates: vendor:check, typecheck, node --test over every live test (2073 pass,
5 skipped), check:public, package-release.sh (artifact check passed).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
if(found!==(patch.count??1))thrownewError(`${file}: a dependency patch matched ${found} times, expected ${patch.count??1}; update DEPENDENCY_PATCHES for the new version`);
banner: {js: 'import { createRequire as screenrigCreateRequire } from "node:module";\nconst require = screenrigCreateRequire(import.meta.url);'},
@@ -135,6 +215,14 @@ async function main() {
135
215
if(oversized.length){
136
216
thrownewError(`${oversized.map((output)=>`${output.file} is ${output.bytes} bytes`).join(", ")}; every bundled file must stay within ${MAX_OUTPUT_BYTES} bytes. A single module over the limit has to be split in source; otherwise move code behind a command bundle (src/cli-commands/index.ts).`);
thrownewError(`${scanned.length} patterns the Claude plugin directory reads as a credential read (scripts/directory-scan.mjs):\\n ${scanned.join("\\n ")}`);
["download and run",/(?:curl|wget)[^\n|]{0,200}\|\s*(?:sudo\s+)?(?:ba|z|da)?sh\b|\$\(\s*(?:curl|wget)|\x60\s*(?:curl|wget)|\b(?:iex|Invoke-Expression)\b/g],
18
+
];
19
+
20
+
function*interpolations(text){
21
+
letfrom=0;
22
+
for(;;){
23
+
conststart=text.indexOf("${",from);
24
+
if(start<0)return;
25
+
letdepth=0;
26
+
letend=start+1;
27
+
for(;end<text.length;end+=1){
28
+
if(text[end]==="{")depth+=1;
29
+
elseif(text[end]==="}"&&--depth===0)break;
30
+
}
31
+
yield{at: start,inner: text.slice(start+2,end)};
32
+
from=start+2;
33
+
}
34
+
}
35
+
36
+
/** Every pattern the directory's scan could read as a credential read, with its offset. */
.option("--actor <ID>","Only changes made by this person, agent or service client (its id)")
@@ -56,7 +57,7 @@ export function registerAuditCommands(root: Command, bind: CommandActionBinder):
56
57
.option("--anchor <SEQ:HASH>","A chain head you kept: also proves the history up to it is unchanged",auditAnchor)
57
58
.action(bind(handleAuditVerify));
58
59
59
-
filterOptions(audit.command("export").description("Write the filtered audit log as a CSV, XLSX or PDF file, one row per changed field, with the chain head in it"))
60
+
filterOptions(subcommand(audit,"export").description("Write the filtered audit log as a CSV, XLSX or PDF file, one row per changed field, with the chain head in it"))
constexportCommand=project.command("export").description("Write this project's data to a directory in open formats with each section's outcome")
49
+
constexportCommand=subcommand(project,"export").description("Write this project's data to a directory in open formats with each section's outcome")
49
50
.argument("<DIR>","Directory to write (created if needed; a rerun continues and refreshes it)")
50
51
.option("--no-media","Skip the original media files (the manifest still lists them with their hashes)")
51
52
.option("--since <YYYY-MM-DD>","First UTC day of the plays, uptime and playback CSV and of the event log (default: as far back as the plan keeps the CSV data, and the whole log)");
0 commit comments