diff --git a/AGENTS.md b/AGENTS.md index a7894f2a2..72cdb9104 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -80,3 +80,15 @@ Test fixture provides: ## Runtime The CLI entrypoint (`cli/entrypoint.js`) selects between Bun and tsx as the TypeScript runner, preferring Bun when available. This allows hot-reload during development while maintaining Node.js compatibility. +# bump 1778256003 +# bump 1778299204 +# bump 1778342404 +# bump 1778385604 +# bump 1778428804 +# bump 1778472004 +# bump 1778515205 +# bump 1778558404 +# bump 1778601603 +# bump 1778644803 +# bump 1778688003 +# bump 1778731202 diff --git a/lib/shared/export-snippet.ts b/lib/shared/export-snippet.ts index d7459d0df..39de0194d 100644 --- a/lib/shared/export-snippet.ts +++ b/lib/shared/export-snippet.ts @@ -55,6 +55,8 @@ export const ALLOWED_EXPORT_FORMATS = [ "srj", "step", "assembly-svg", + "pnp-csv", + "bom-csv", ] as const export type ExportFormat = (typeof ALLOWED_EXPORT_FORMATS)[number] @@ -76,6 +78,8 @@ const OUTPUT_EXTENSIONS: Record = { "kicad-library": "", srj: ".simple-route.json", step: ".step", + "pnp-csv": "-pnp.csv", + "bom-csv": "-bom.csv", } const isRecord = (value: unknown): value is Record => @@ -345,6 +349,14 @@ export const exportSnippet = async ({ case "assembly-svg": outputContent = convertCircuitJsonToAssemblySvg(circuitJson) break + case "pnp-csv": + outputContent = await convertCircuitJsonToPickAndPlaceCsv(circuitJson) + break + case "bom-csv": + outputContent = await convertBomRowsToCsv( + await convertCircuitJsonToBomRows({ circuitJson }), + ) + break default: outputContent = JSON.stringify(circuitJson, null, 2) } diff --git a/lib/shared/push-snippet.ts b/lib/shared/push-snippet.ts index 158f0abbd..a56158be7 100644 --- a/lib/shared/push-snippet.ts +++ b/lib/shared/push-snippet.ts @@ -6,6 +6,7 @@ import semver from "semver" import Debug from "debug" import kleur from "kleur" import { getEntrypoint } from "./get-entrypoint" +import { globbySync } from "globby" import prompts from "lib/utils/prompts" import { getUnscopedPackageName } from "lib/utils/get-unscoped-package-name" import { getPackageAuthor } from "lib/utils/get-package-author" @@ -123,26 +124,62 @@ export const pushSnippet = async ({ return onExit(1) } + // Use findPushProject to get project info const pushProject = await findPushProject({ filePath, onError, }) - if (!pushProject) { - return onExit(1) + const pkgResult = pushProject ?? { + packageJsonPath: undefined, + projectDir: process.cwd(), } + const { packageJsonPath, projectDir } = pkgResult - const { snippetFilePath, packageJsonPath, projectDir } = pushProject - - if (!packageJsonPath) { + if (!filePath && !packageJsonPath) { onError( "No package.json found, try running 'tsci init' to bootstrap the project", ) return onExit(1) } + // Extract snippetFilePath, with fallback to getEntrypoint and globby + let snippetFilePath = pushProject?.snippetFilePath + + // Fallback 1: try getEntrypoint if findPushProject didn't find a file (silent) + if (!snippetFilePath) { + snippetFilePath = + (await getEntrypoint({ + filePath, + onSuccess: () => {}, + onError: () => {}, + })) ?? undefined + } + + // Fallback 2: use globby to find any circuit file if still not found + if (!snippetFilePath) { + const validFiles = globbySync( + ["**/*.tsx", "**/*.ts", "**/*.circuit.json"], + { + cwd: projectDir, + ignore: ["node_modules/**", "**/.*"], + }, + ).filter((relativePath) => + fs.existsSync(path.join(projectDir, relativePath)), + ) + + if (validFiles.length > 0) { + snippetFilePath = path.resolve(projectDir, validFiles[0]) + onSuccess(`Using fallback file: '${validFiles[0]}'`) + } + } + + if (!snippetFilePath && filePath) { + return onExit(1) + } + let packageJson: { name?: string; author?: string; version?: string } = {} - if (fs.existsSync(packageJsonPath)) { + if (packageJsonPath && fs.existsSync(packageJsonPath)) { try { packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()) } catch { @@ -204,7 +241,9 @@ export const pushSnippet = async ({ // Write the package name to the package.json file packageJson.name = `@tsci/${currentUsername}.${unscopedPackageName}` - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)) + if (packageJsonPath) { + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)) + } } // Determine the account name to use (either user or org) @@ -259,7 +298,9 @@ export const pushSnippet = async ({ const updatePackageJsonVersion = (newVersion?: string) => { try { packageJson.version = newVersion ?? `${packageVersion}` - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)) + if (packageJsonPath) { + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)) + } } catch (error) { onError(`Failed to update package.json version: ${error}`) }