shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

scripts/review-published-regression.mjs

import fs from "node:fs"
import crypto from "node:crypto"
import assert from "node:assert/strict"

const api = "https://registry-api.tscircuit.com/"
const name = "shibosoftwaredev/f1c100s-linux-nema17-stepper-controller"
const checkpointVersion = "0.4.46-checkpoint-20261019-current-sense"
const output = "reports/published-comparison"
fs.mkdirSync(output, { recursive: true })
async function request(endpoint, body) {
  const response = await fetch(api + endpoint, {
    method: body ? "POST" : "GET",
    headers: body ? { "content-type": "application/json" } : undefined,
    body: body ? JSON.stringify(body) : undefined,
    signal: AbortSignal.timeout(45000),
  })
  if (!response.ok) throw new Error(`${endpoint}: HTTP ${response.status}`)
  return response.json()
}
const pkg = (await request("packages/get", { name })).package
const versions = { latest: pkg.latest_version, checkpoint: checkpointVersion }
const summary = { checkedAt: new Date().toISOString(), packageName: name,
  latestVersion: pkg.latest_version, releases: {} }
for (const [key, version] of Object.entries(versions)) {
  const release = (await request("package_releases/get", {
    package_name_with_version: `${name}@${version}`,
  })).package_release
  assert.ok(release)
  fs.writeFileSync(`${output}/${key}-release.json`, JSON.stringify(release, null, 2) + "\n")
  const files = (await request("package_files/list?" + new URLSearchParams({
    package_release_id: release.package_release_id,
  }))).package_files
  fs.writeFileSync(`${output}/${key}-files.json`, JSON.stringify(files, null, 2) + "\n")
  const wanted = ["dist/index/circuit.json", "index.circuit.tsx", "routing/complete-routes.json",
    "routing/expected-input.json", "assembly-models.json", "assembly-parts.json",
    "assembly-metadata.ts", "package.json", "firmware/stm32/main.c", "firmware/stm32/motion.c",
    "firmware/stm32/motion.h", "firmware/motor-control.py"]
  const downloaded = []
  const missing = []
  for (const path of wanted) {
    const file = files.find(file => file.file_path === path)
    if (!file) { missing.push(path); continue }
    const record = (await request("package_files/get?" + new URLSearchParams({
      package_file_id: file.package_file_id,
    }))).package_file
    const bytes = record.content_text != null ? Buffer.from(record.content_text)
      : Buffer.from(record.content_base64 ?? "", "base64")
    const local = `${output}/${key}-${path.replaceAll("/", "_")}`
    fs.writeFileSync(local, bytes)
    downloaded.push({ path, local, sha256: crypto.createHash("sha256").update(bytes).digest("hex") })
  }
  summary.releases[key] = { version, id: release.package_release_id, isLatest: release.is_latest,
    ready: release.ready_to_build, circuitBuildCompleted: release.circuit_json_build_completed_at,
    circuitBuildError: release.circuit_json_build_error, userCodeJobCompleted: release.user_code_job_completed_at,
    userCodeJobError: release.user_code_job_error, downloaded, missing }
}
fs.writeFileSync(`${output}/remote-comparison-inputs.json`, JSON.stringify(summary, null, 2) + "\n")
console.log(JSON.stringify({ latest: versions.latest,
  releases: Object.fromEntries(Object.entries(summary.releases).map(([key, r]) => [key, {
    version: r.version, isLatest: r.isLatest, circuitBuildCompleted: r.circuitBuildCompleted,
    circuitBuildError: r.circuitBuildError, userCodeJobCompleted: r.userCodeJobCompleted,
    userCodeJobError: r.userCodeJobError, missing: r.missing,
  }])) }, null, 2))