Add designlang public-shell pack; tighten auth capture checks

Ran authenticated extract against coulomb.social; session metadata
matched anonymous Bubble defaults, so treat docs/design-extract as a
public shell baseline (PROVENANCE.md). Capture script now refuses to
overwrite storage-state.json with thin anonymous sessions.
This commit is contained in:
tegwick 2026-08-09 01:22:15 +02:00
parent 0bf740017e
commit 319dd00465
28 changed files with 1524 additions and 6 deletions

View file

@ -137,16 +137,54 @@ async function main() {
}
const state = await context.storageState();
const cookieCount = state.cookies?.length ?? 0;
const originCount = state.origins?.length ?? 0;
const lsKeys = (state.origins || []).flatMap((o) =>
(o.localStorage || []).map((e) => e.name),
);
// Bubble always sets coulomb_* session cookies for anonymous visitors.
// A real login usually adds more localStorage keys and/or more cookies.
const onlyDefaultBubbleCookies =
cookieCount <= 3 &&
(state.cookies || []).every((c) =>
String(c.name || "").startsWith("coulomb_"),
);
const thinLocalStorage =
lsKeys.length === 0 ||
(lsKeys.length === 1 && lsKeys[0] === "algoliasearch-client-js");
if (onlyDefaultBubbleCookies && thinLocalStorage) {
console.error("");
console.error(
"WARNING: This looks like an anonymous Bubble session, not a logged-in user.",
);
console.error(
` cookies=${cookieCount} (only default coulomb_* names)`,
);
console.error(` localStorage keys: ${lsKeys.join(", ") || "(none)"}`);
console.error("");
console.error("Do not use this for authenticated design extract.");
console.error("Re-run, fully log in, wait until the app UI is loaded,");
console.error("then press Enter. If login uses a popup, complete it first.");
process.exitCode = 2;
// Still write so you can inspect, but mark filename
const weakPath = STATE_PATH.replace(/\.json$/, ".anonymous.json");
writeFileSync(weakPath, JSON.stringify(state, null, 2) + "\n", {
mode: 0o600,
});
chmodSync(weakPath, 0o600);
console.error(`Wrote weak session for inspection only: ${weakPath}`);
return;
}
writeFileSync(STATE_PATH, JSON.stringify(state, null, 2) + "\n", {
mode: 0o600,
});
chmodSync(STATE_PATH, 0o600);
const cookieCount = state.cookies?.length ?? 0;
const originCount = state.origins?.length ?? 0;
console.log("");
console.log(
`Saved storageState (${cookieCount} cookies, ${originCount} origins).`,
`Saved storageState (${cookieCount} cookies, ${originCount} origins, localStorage keys: ${lsKeys.length}).`,
);
console.log(`File: ${STATE_PATH}`);
console.log("Next: ./scripts/run-design-extract.sh");

View file

@ -30,10 +30,13 @@ echo " auth: $STATE_PATH (session file present; not printed)"
echo " out: $OUT_DIR"
echo " extra: $*"
# Default pack is useful for agent rebuild; caller can pass more flags.
# Global flags (auth, name) must precede the subcommand; pack only accepts -o/--with-clone/--open.
# --cookie-file accepts Playwright storageState JSON.
exec npx --yes designlang pack "$URL" \
# Extra args after -- are appended to pack (e.g. --with-clone).
mkdir -p "$(dirname "$OUT_DIR")"
exec npx --yes designlang \
--cookie-file "$STATE_PATH" \
-o "$OUT_DIR" \
--name coulomb-social \
pack "$URL" \
-o "$OUT_DIR" \
"$@"