[DASH-1732] [templates] add build step to create javascript templates#75
[DASH-1732] [templates] add build step to create javascript templates#75syd-shields wants to merge 18 commits intodevfrom
Conversation
|
This change is part of the following stack: Change managed by git-spice. |
|
In the templates repo, all scripts should be runnable out of the box. Some templates have package.json files that need to be copied over to the JavaScript versions. However, we can't just copy them as-is — they still reference TypeScript. For example, they contain "start": "tsx index.ts" and TypeScript devDependencies. These need to be rewritten for JS (e.g., "start": "node index.js", remove tsx, typescript, @types/*). We should also copy over the READMEs if possible. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Build script copies READMEs without transforming TypeScript references
- The build script now rewrites README content when copying so TypeScript paths/extensions are converted to JavaScript equivalents and regenerated JavaScript READMEs contain correct
javascript/and.jsreferences.
- The build script now rewrites README content when copying so TypeScript paths/extensions are converted to JavaScript equivalents and regenerated JavaScript READMEs contain correct
Or push these changes by commenting:
@cursor push 94170f2cf4
Preview (94170f2cf4)
diff --git a/javascript/amazon-product-scraping/README.md b/javascript/amazon-product-scraping/README.md
--- a/javascript/amazon-product-scraping/README.md
+++ b/javascript/amazon-product-scraping/README.md
@@ -17,11 +17,11 @@
## QUICKSTART
-1. cd typescript/amazon-product-scraping
+1. cd javascript/amazon-product-scraping
2. npm install
3. cp .env.example .env (or create .env with required keys)
4. Add BROWSERBASE_PROJECT_ID, BROWSERBASE_API_KEY, and GOOGLE_API_KEY to .env
-5. Optionally edit SEARCH_QUERY in index.ts
+5. Optionally edit SEARCH_QUERY in index.js
6. npm start
## EXPECTED OUTPUT
@@ -49,7 +49,7 @@
## NEXT STEPS
-• Switch to direct URL: Uncomment the URL-based search block in index.ts for faster runs without LLM search actions.
+• Switch to direct URL: Uncomment the URL-based search block in index.js for faster runs without LLM search actions.
• Parameterize query: Accept SEARCH_QUERY from CLI or env for different products without editing code.
• Paginate: Extend extraction to multiple pages or increase the number of products per run.
diff --git a/javascript/company-address-finder/README.md b/javascript/company-address-finder/README.md
--- a/javascript/company-address-finder/README.md
+++ b/javascript/company-address-finder/README.md
@@ -27,7 +27,7 @@
2. npm install
3. cp .env.example .env
4. Add your Browserbase API key, Project ID, and Google Generative AI API key to .env
-5. Edit COMPANY_NAMES array in index.ts to specify which companies to process
+5. Edit COMPANY_NAMES array in index.js to specify which companies to process
6. npm start
## EXPECTED OUTPUT
diff --git a/javascript/company-value-prop-generator/README.md b/javascript/company-value-prop-generator/README.md
--- a/javascript/company-value-prop-generator/README.md
+++ b/javascript/company-value-prop-generator/README.md
@@ -16,7 +16,7 @@
## QUICKSTART
-1. cd typescript/company-value-prop-generator
+1. cd javascript/company-value-prop-generator
2. npm install
3. cp .env.example .env
4. Add required API keys/IDs to .env
diff --git a/javascript/dynamic-form-filling/README.md b/javascript/dynamic-form-filling/README.md
--- a/javascript/dynamic-form-filling/README.md
+++ b/javascript/dynamic-form-filling/README.md
@@ -21,7 +21,7 @@
1. pnpm install
2. cp .env.example .env
3. Add required API keys/IDs to .env (BROWSERBASE_PROJECT_ID, BROWSERBASE_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY)
-4. Customize the `tripDetails` variable in index.ts with your own form data
+4. Customize the `tripDetails` variable in index.js with your own form data
5. Update the form URL if using a different form
6. pnpm start
diff --git a/javascript/extend-browserbase/README.md b/javascript/extend-browserbase/README.md
--- a/javascript/extend-browserbase/README.md
+++ b/javascript/extend-browserbase/README.md
@@ -23,7 +23,7 @@
## QUICKSTART
-1. cd typescript/extend-browserbase
+1. cd javascript/extend-browserbase
2. pnpm install
3. cp .env.example .env
4. Add required API keys to .env:
diff --git a/javascript/getting-started-with-browserbase/README.md b/javascript/getting-started-with-browserbase/README.md
--- a/javascript/getting-started-with-browserbase/README.md
+++ b/javascript/getting-started-with-browserbase/README.md
@@ -31,7 +31,7 @@
### TypeScript
-1. cd typescript/getting-started-with-browserbase
+1. cd javascript/getting-started-with-browserbase
2. npm install
3. cp .env.example .env
4. Add BROWSERBASE_API_KEY to .env (get it from https://browserbase.com/settings)
diff --git a/javascript/image-url-download/README.md b/javascript/image-url-download/README.md
--- a/javascript/image-url-download/README.md
+++ b/javascript/image-url-download/README.md
@@ -15,7 +15,7 @@
Docs → https://docs.stagehand.dev/basics/extract
- page.evaluate: run a JavaScript function directly inside the browser context — inherits proxy, cookies, and headers.
Docs → https://playwright.dev/docs/evaluating
-- MAX_IMAGES: configurable cap (default: 10) on how many images to download per run. Set via the `MAX_IMAGES` env var or the constant at the top of `index.ts`.
+- MAX_IMAGES: configurable cap (default: 10) on how many images to download per run. Set via the `MAX_IMAGES` env var or the constant at the top of `index.js`.
## QUICKSTART
@@ -43,7 +43,7 @@
- Empty images folder: some pages load images lazily — try scrolling the page before extraction, or increase the page load wait
- Zero images found: the page may use CSS background images not captured by `<img>` tags — adjust the extract instruction to target specific selectors
- CORS / auth-gated images: images behind login walls or strict CORS policies may fail in `page.evaluate()` — ensure you are authenticated before running the script
-- MAX_IMAGES cap: if you need more than 10 images, set `MAX_IMAGES=50` in your .env or edit the constant at the top of `index.ts`
+- MAX_IMAGES cap: if you need more than 10 images, set `MAX_IMAGES=50` in your .env or edit the constant at the top of `index.js`
- Large pages: pages with hundreds of images may slow down `extract()` — use MAX_IMAGES to limit the download set
## USE CASES
@@ -58,7 +58,7 @@
• Scroll before extracting: call `page.evaluate(() => window.scrollTo(0, document.body.scrollHeight))` before `extract()` to trigger lazy-loaded images.
• Concurrent downloads: fan out the `page.evaluate` fetch calls with `Promise.allSettled` for faster bulk downloads.
• Metadata CSV: write a `manifest.csv` alongside the images recording original URL, filename, MIME type, byte size, and download timestamp.
-• Extend MIME support: add entries to the `MIME_TO_EXT` map at the top of `index.ts` for any formats not already covered.
+• Extend MIME support: add entries to the `MIME_TO_EXT` map at the top of `index.js` for any formats not already covered.
## HELPFUL RESOURCES
diff --git a/javascript/playwright/basic-recaptcha/README.md b/javascript/playwright/basic-recaptcha/README.md
--- a/javascript/playwright/basic-recaptcha/README.md
+++ b/javascript/playwright/basic-recaptcha/README.md
@@ -67,7 +67,7 @@
## QUICKSTART
-1. cd typescript/playwright/basic-recaptcha
+1. cd javascript/playwright/basic-recaptcha
2. pnpm install
3. cp .env.example .env
4. Add your Browserbase API key to .env
diff --git a/javascript/sec-filing-research/README.md b/javascript/sec-filing-research/README.md
--- a/javascript/sec-filing-research/README.md
+++ b/javascript/sec-filing-research/README.md
@@ -25,7 +25,7 @@
2. npm install
3. cp .env.example .env
4. Add BROWSERBASE_PROJECT_ID, BROWSERBASE_API_KEY, and GOOGLE_API_KEY to .env
-5. (Optional) Edit SEARCH_QUERY and NUM_FILINGS in index.ts
+5. (Optional) Edit SEARCH_QUERY and NUM_FILINGS in index.js
6. npm start
## EXPECTED OUTPUT
diff --git a/javascript/website-link-tester/README.md b/javascript/website-link-tester/README.md
--- a/javascript/website-link-tester/README.md
+++ b/javascript/website-link-tester/README.md
@@ -18,7 +18,7 @@
### QUICKSTART
1. **cd into the template**
- - `cd typescript/website-link-tester`
+ - `cd javascript/website-link-tester`
2. **Install dependencies**
- `npm install`
3. **Configure environment**
@@ -76,7 +76,7 @@
### TUNING BATCH SIZE & CONCURRENCY
-- **`MAX_CONCURRENT_LINKS` in `index.ts`**
+- **`MAX_CONCURRENT_LINKS` in `index.js`**
- Default: `1` → sequential link verification (works on all plans)
- Set to `> 1` → more concurrent link verifications per batch (requires higher Browserbase concurrency limits)
- **Using Semaphores for advanced control**
diff --git a/scripts/build-javascript.mjs b/scripts/build-javascript.mjs
--- a/scripts/build-javascript.mjs
+++ b/scripts/build-javascript.mjs
@@ -76,6 +76,15 @@
return pkg;
}
+function adaptReadmeForJavaScript(content) {
+ return content
+ .replaceAll("typescript/", "javascript/")
+ .replaceAll(/\.d\.ts\b/g, "__PRESERVE_D_TS__")
+ .replaceAll(/\.tsx\b/g, ".jsx")
+ .replaceAll(/\.ts\b/g, ".js")
+ .replaceAll(/__PRESERVE_D_TS__/g, ".d.ts");
+}
+
function normalizeRelativePath(filePath) {
return filePath.split(path.sep).join("/");
}
@@ -187,6 +196,15 @@
await writeFile(outputPath, `${JSON.stringify(adapted, null, 2)}\n`, "utf8");
}
+async function writeAdaptedReadme(sourcePath) {
+ const relativePath = path.relative(TYPESCRIPT_DIR, sourcePath);
+ const outputPath = path.join(JAVASCRIPT_DIR, relativePath);
+ const source = await readFile(sourcePath, "utf8");
+ const adapted = adaptReadmeForJavaScript(source);
+ await mkdir(path.dirname(outputPath), { recursive: true });
+ await writeFile(outputPath, adapted, "utf8");
+}
+
async function transpileFile(sourcePath) {
const relativePath = path.relative(TYPESCRIPT_DIR, sourcePath);
const outputPath = path
@@ -260,6 +278,8 @@
assetFiles.map(async (filePath) => {
if (path.basename(filePath) === "package.json") {
await writeAdaptedPackageJson(filePath);
+ } else if (path.basename(filePath) === "README.md") {
+ await writeAdaptedReadme(filePath);
} else {
await copyAssetFile(filePath);
}This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
…ed and rewritten with new build
8d8479e to
3173ce4
Compare
| const argv = ["scripts/build-javascript.mjs"]; | ||
| for (const name of dirs) { | ||
| argv.push("--include-template", name); | ||
| } |
There was a problem hiding this comment.
Empty API response causes CI to build all templates
Medium Severity
When fetchPlaygroundTypescriptDirNames returns an empty array (e.g., the templates API returns zero playground-runnable templates), the for loop adds no --include-template flags to argv. The build script then receives no filter arguments, causing includeTemplates.size to be 0 and falling through to the else branch that wipes javascript/ and rebuilds every template instead of none. The CI workflow would then commit all templates to the production branch, which is the opposite of the intended behavior.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit b17759b. Configure here.
| const argv = ["scripts/build-javascript.mjs"]; | ||
| for (const name of dirs) { | ||
| argv.push("--include-template", name); | ||
| } |
There was a problem hiding this comment.
Empty API response causes CI to build all templates
Medium Severity
When fetchPlaygroundTypescriptDirNames returns an empty array (e.g., the templates API returns zero playground-runnable templates), the for loop adds no --include-template flags to argv. The build script then receives no filter arguments, causing includeTemplates.size to be 0 and falling through to the else branch that wipes javascript/ and rebuilds every template instead of none. The CI workflow would then commit all templates to the production branch, which is the opposite of the intended behavior.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit b17759b. Configure here.
|
|
||
| const includeTemplates = new Set(parseListFlag(argv, "--include-template")); | ||
| const includePaths = parseListFlag(argv, "--include-path"); | ||
| const excludePathOnly = parseListFlag(argv, "--exclude-path"); |
There was a problem hiding this comment.
Flags parsed redundantly in filter and main function
Low Severity
parseListFlag is called for --include-template, --include-path, and --exclude-path in buildJavaScriptTemplates (lines 29–31), duplicating the exact same parsing already done inside createFileFilter (lines 92, 98, 99). This duplication means changes to flag names or parsing logic need to be synchronized in two places — if one is updated and the other is not, the file-filtering and directory-cleanup behaviors would silently diverge.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ed33a0c. Configure here.
| } | ||
| if (typeof scripts.build === "string" && /^\s*tsc(\s|$)/u.test(scripts.build)) { | ||
| delete scripts.build; | ||
| } |
There was a problem hiding this comment.
Build script deletion too aggressive for compound commands
Medium Severity
The regex /^\s*tsc(\s|$)/u deletes the entire build script if it merely starts with tsc, even in compound commands like "tsc && next build" or "tsc --noEmit && vite build". The (\s|$) after tsc matches a space, so tsc && next build passes the test and the whole script is removed — silently dropping the non-TypeScript next build step. The check intends to strip pure-tsc build scripts but doesn't account for &&/;/|| chained commands.
Reviewed by Cursor Bugbot for commit ed33a0c. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 6 total unresolved issues (including 4 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5d56277. Configure here.
| "dotenv": "^16.0.0", | ||
| "zod": "^3.22.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
Missing "type": "module" breaks ESM imports in generated templates
High Severity
The generated javascript/google-trends/package.json and javascript/mfa-handling/package.json are missing "type": "module", yet their index.js files use ESM import syntax. Without this field, Node.js treats .js files as CommonJS, so running node index.js will fail with a syntax error. The TypeScript sources worked because tsx handles ESM natively, but after the build adapts scripts from tsx to node, the "type": "module" field becomes required. Other generated templates like basic-caching and amazon-product-scraping work because their TypeScript sources already included the field. These templates are not runnable out of the box, contradicting a stated requirement from the PR discussion.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5d56277. Configure here.
| else | ||
| git commit -m "chore: regenerate playground javascript templates" | ||
| git push | ||
| fi |
There was a problem hiding this comment.
Duplicated CI workflow files with identical logic
Low Severity
playground-production.yml and playground-test-production.yml are nearly identical — the only differences are the branch name and workflow display name. This duplication means any future change to the CI steps must be applied in both files, increasing maintenance burden and risk of drift. A single workflow parameterized by branch (using a matrix or reusable workflow) would eliminate this redundancy.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 5d56277. Configure here.



This PR adds a playground-production CI workflow that builds Typescript templates into playground compatible templates as deemed by the website-api templates API.
In order to marke this Linear issue as done:
sydshields/dash-1732-turn-existing-templates-in-js-filesintodevproductionbranch, enable branch protectiondevintoproductionAdded a JS build script
build:javascript. This command runs build TS files into JS ones in CIscripts/build-javascript.mjswhich builds the JS files to /javascriptAdded a production branch for dashboard use
.github/workflows/playground-productiont.yml. This only runs on theproductionbranchscripts/playground-ci.mjswhich is ran in the playground-production workflow. It callsfetchPlaygroundTypescriptDirNamesand runsscripts/build-javascript.mjsEnsure playground compatibility by delegating templates API as source of truth
fetchPlaygroundTypescriptDirNameswhich uses the wesbite-api templates API to grab playground compatible templates from the source of truthhasStagehandUsageto ensure Stagehand is being used correctlyWhat's not included:
Note
Medium Risk
Adds GitHub Actions that write back to protected branches by committing generated
javascript/output, which can create unexpected diffs or workflow feedback loops if misconfigured. Also introduces a large generatedjavascript/tree whose contents must stay in sync with the templates API selection/validation logic.Overview
Introduces new branch-specific CI for
productionandtest-productionthat rebuilds only playground-runnable templates (as determined by the public templates API), validates them, and on pushes commits/pushes regeneratedjavascript/output back to the branch.Adds
CODEOWNERSrules to require Dashboard review for playground build/validation scripts, the new workflows, and changes underjavascript/, and updates the README to clarify thattypescript/is the source of truth whilejavascript/is CI-generated for playground releases.Reviewed by Cursor Bugbot for commit 5d56277. Bugbot is set up for automated code reviews on this repo. Configure here.