@tscircuit/fake-snippets 0.0.81 → 0.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.js +4 -4
- package/fake-snippets-api/routes/api/packages/generate_from_jlcpcb.ts +3 -3
- package/package.json +1 -1
- package/src/components/JLCPCBImportDialog.tsx +164 -62
- package/src/components/PackageBuildsPage/LogContent.tsx +12 -5
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +8 -7
- package/src/components/PackageBuildsPage/build-preview-content.tsx +1 -1
- package/src/components/PackageBuildsPage/collapsible-section.tsx +14 -46
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +28 -10
- package/src/components/PackageBuildsPage/package-build-header.tsx +4 -4
- package/src/components/ViewPackagePage/components/build-status.tsx +24 -85
- package/src/components/ViewPackagePage/components/important-files-view.tsx +8 -1
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +28 -5
- package/src/components/package-port/CodeEditor.tsx +9 -1
- package/src/hooks/use-current-package-release.ts +4 -2
- package/src/hooks/use-now.ts +12 -0
- package/src/hooks/use-package-release.ts +3 -2
- package/src/pages/dashboard.tsx +3 -1
- package/src/pages/user-profile.tsx +9 -2
- package/.github/workflows/formatbot.yml +0 -63
|
@@ -1,99 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
Dialog,
|
|
4
|
-
DialogContent,
|
|
5
|
-
DialogHeader,
|
|
6
|
-
DialogTitle,
|
|
7
|
-
} from "@/components/ui/dialog"
|
|
8
|
-
import { CheckCircle, XCircle, Check, X } from "lucide-react"
|
|
9
|
-
import { cn } from "@/lib/utils"
|
|
1
|
+
import { CheckCircle, XCircle, Clock, Loader2 } from "lucide-react"
|
|
2
|
+
import { Link, useParams } from "wouter"
|
|
10
3
|
|
|
11
4
|
export interface BuildStep {
|
|
12
5
|
id: string
|
|
13
6
|
name: string
|
|
14
|
-
status: "success" | "
|
|
15
|
-
message?: string
|
|
7
|
+
status: "pending" | "running" | "success" | "error"
|
|
16
8
|
}
|
|
17
9
|
|
|
18
10
|
export interface BuildStatusProps {
|
|
19
11
|
step: BuildStep
|
|
12
|
+
packageReleaseId: string
|
|
20
13
|
}
|
|
21
14
|
|
|
22
|
-
export const BuildStatus = ({ step }: BuildStatusProps) => {
|
|
23
|
-
const
|
|
15
|
+
export const BuildStatus = ({ step, packageReleaseId }: BuildStatusProps) => {
|
|
16
|
+
const { author, packageName } = useParams()
|
|
17
|
+
const href = `/${author}/${packageName}/builds?package_release_id=${packageReleaseId}`
|
|
24
18
|
|
|
25
19
|
return (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<DialogHeader>
|
|
44
|
-
<DialogTitle className="flex items-center gap-2">
|
|
45
|
-
{step.status === "success" ? (
|
|
46
|
-
<>
|
|
47
|
-
<CheckCircle className="h-5 w-5 text-green-600" />
|
|
48
|
-
<span>Build Status: Passing</span>
|
|
49
|
-
</>
|
|
50
|
-
) : (
|
|
51
|
-
<>
|
|
52
|
-
<XCircle className="h-5 w-5 text-red-600" />
|
|
53
|
-
<span>Build Status: Failing</span>
|
|
54
|
-
</>
|
|
55
|
-
)}
|
|
56
|
-
</DialogTitle>
|
|
57
|
-
</DialogHeader>
|
|
58
|
-
|
|
59
|
-
<div className="space-y-4">
|
|
60
|
-
<div className="space-y-3">
|
|
61
|
-
<div
|
|
62
|
-
key={step.id}
|
|
63
|
-
className={cn(
|
|
64
|
-
"flex items-start gap-3 rounded-md border p-3",
|
|
65
|
-
step.status === "success"
|
|
66
|
-
? "bg-green-50 border-green-200"
|
|
67
|
-
: "bg-red-50 border-red-200",
|
|
68
|
-
)}
|
|
69
|
-
>
|
|
70
|
-
<div
|
|
71
|
-
className={cn(
|
|
72
|
-
"rounded-full p-1 mt-0.5",
|
|
73
|
-
step.status === "success"
|
|
74
|
-
? "bg-green-100 text-green-600"
|
|
75
|
-
: "bg-red-100 text-red-600",
|
|
76
|
-
)}
|
|
77
|
-
>
|
|
78
|
-
{step.status === "success" ? (
|
|
79
|
-
<Check className="h-4 w-4" />
|
|
80
|
-
) : (
|
|
81
|
-
<X className="h-4 w-4" />
|
|
82
|
-
)}
|
|
83
|
-
</div>
|
|
84
|
-
<div>
|
|
85
|
-
<div className="font-medium">{step.name}</div>
|
|
86
|
-
{step.message && (
|
|
87
|
-
<div className="text-sm text-muted-foreground mt-1">
|
|
88
|
-
{step.message}
|
|
89
|
-
</div>
|
|
90
|
-
)}
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
95
|
-
</DialogContent>
|
|
96
|
-
</Dialog>
|
|
97
|
-
</>
|
|
20
|
+
<Link href={href} className="flex items-center gap-2">
|
|
21
|
+
{step.status === "success" && (
|
|
22
|
+
<CheckCircle className="h-4 w-4 text-green-600 dark:text-[#8b949e]" />
|
|
23
|
+
)}
|
|
24
|
+
{step.status === "error" && (
|
|
25
|
+
<XCircle className="h-4 w-4 text-red-600 dark:text-[#8b949e]" />
|
|
26
|
+
)}
|
|
27
|
+
{step.status === "running" && (
|
|
28
|
+
<Loader2 className="h-4 w-4 text-blue-600 animate-spin dark:text-[#8b949e]" />
|
|
29
|
+
)}
|
|
30
|
+
{step.status === "pending" && (
|
|
31
|
+
<Clock className="h-4 w-4 text-yellow-600 dark:text-[#8b949e]" />
|
|
32
|
+
)}
|
|
33
|
+
<span className="text-sm text-gray-500 dark:text-[#8b949e]">
|
|
34
|
+
{step.name}
|
|
35
|
+
</span>
|
|
36
|
+
</Link>
|
|
98
37
|
)
|
|
99
38
|
}
|
|
@@ -51,8 +51,13 @@ export default function ImportantFilesView({
|
|
|
51
51
|
const hasAiContent = Boolean(aiDescription || aiUsageInstructions)
|
|
52
52
|
const hasAiReview = Boolean(aiReviewText)
|
|
53
53
|
|
|
54
|
-
// Select the appropriate tab/file when content changes
|
|
54
|
+
// Select the appropriate tab/file when content changes. Once the user has
|
|
55
|
+
// interacted with the tabs we keep their selection and only run this logic
|
|
56
|
+
// if no tab has been chosen yet.
|
|
55
57
|
useEffect(() => {
|
|
58
|
+
if (activeTab !== null) return
|
|
59
|
+
if (isLoading) return
|
|
60
|
+
|
|
56
61
|
// First priority: README file if it exists
|
|
57
62
|
const readmeFile = importantFiles.find(
|
|
58
63
|
(file) =>
|
|
@@ -82,6 +87,8 @@ export default function ImportantFilesView({
|
|
|
82
87
|
hasAiContent,
|
|
83
88
|
hasAiReview,
|
|
84
89
|
importantFiles,
|
|
90
|
+
activeTab,
|
|
91
|
+
isLoading,
|
|
85
92
|
])
|
|
86
93
|
|
|
87
94
|
// Get file name from path
|
|
@@ -4,6 +4,27 @@ import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
|
4
4
|
import { usePackageReleaseById } from "@/hooks/use-package-release"
|
|
5
5
|
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
6
6
|
import { BuildStatus, BuildStep } from "./build-status"
|
|
7
|
+
import type { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
8
|
+
|
|
9
|
+
function getTranspilationStatus(
|
|
10
|
+
pr?: PackageRelease | null,
|
|
11
|
+
): BuildStep["status"] {
|
|
12
|
+
if (!pr) return "pending"
|
|
13
|
+
if (pr.transpilation_error) return "error"
|
|
14
|
+
if (pr.transpilation_in_progress) return "running"
|
|
15
|
+
if (pr.transpilation_completed_at) return "success"
|
|
16
|
+
if (pr.transpilation_started_at) return "running"
|
|
17
|
+
return "pending"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getCircuitJsonStatus(pr?: PackageRelease | null): BuildStep["status"] {
|
|
21
|
+
if (!pr) return "pending"
|
|
22
|
+
if (pr.circuit_json_build_error) return "error"
|
|
23
|
+
if (pr.circuit_json_build_in_progress) return "running"
|
|
24
|
+
if (pr.circuit_json_build_completed_at) return "success"
|
|
25
|
+
if (pr.circuit_json_build_started_at) return "running"
|
|
26
|
+
return "pending"
|
|
27
|
+
}
|
|
7
28
|
|
|
8
29
|
export default function SidebarReleasesSection() {
|
|
9
30
|
const { packageInfo } = useCurrentPackageInfo()
|
|
@@ -15,14 +36,12 @@ export default function SidebarReleasesSection() {
|
|
|
15
36
|
{
|
|
16
37
|
id: "package_transpilation",
|
|
17
38
|
name: "Package Transpilation",
|
|
18
|
-
status: packageRelease
|
|
19
|
-
message: packageRelease?.transpilation_error || undefined,
|
|
39
|
+
status: getTranspilationStatus(packageRelease),
|
|
20
40
|
},
|
|
21
41
|
{
|
|
22
42
|
id: "circuit_json_build",
|
|
23
43
|
name: "Circuit JSON Build",
|
|
24
|
-
status: packageRelease
|
|
25
|
-
message: packageRelease?.circuit_json_build_error || undefined,
|
|
44
|
+
status: getCircuitJsonStatus(packageRelease),
|
|
26
45
|
},
|
|
27
46
|
]
|
|
28
47
|
|
|
@@ -56,7 +75,11 @@ export default function SidebarReleasesSection() {
|
|
|
56
75
|
</span>
|
|
57
76
|
</div>
|
|
58
77
|
{buildSteps.map((step) => (
|
|
59
|
-
<BuildStatus
|
|
78
|
+
<BuildStatus
|
|
79
|
+
key={step.id}
|
|
80
|
+
step={step}
|
|
81
|
+
packageReleaseId={packageRelease.package_release_id}
|
|
82
|
+
/>
|
|
60
83
|
))}
|
|
61
84
|
</div>
|
|
62
85
|
{/* <a href="#" className="text-blue-600 dark:text-[#58a6ff] hover:underline text-sm">
|
|
@@ -4,7 +4,7 @@ import { autocompletion } from "@codemirror/autocomplete"
|
|
|
4
4
|
import { indentWithTab } from "@codemirror/commands"
|
|
5
5
|
import { javascript } from "@codemirror/lang-javascript"
|
|
6
6
|
import { json } from "@codemirror/lang-json"
|
|
7
|
-
import { EditorState } from "@codemirror/state"
|
|
7
|
+
import { EditorState, Prec } from "@codemirror/state"
|
|
8
8
|
import { Decoration, hoverTooltip, keymap } from "@codemirror/view"
|
|
9
9
|
import { getImportsFromCode } from "@tscircuit/prompt-benchmarks/code-runner-utils"
|
|
10
10
|
import type { ATABootstrapConfig } from "@typescript/ata"
|
|
@@ -237,6 +237,14 @@ export const CodeEditor = ({
|
|
|
237
237
|
currentFile?.endsWith(".json")
|
|
238
238
|
? json()
|
|
239
239
|
: javascript({ typescript: true, jsx: true }),
|
|
240
|
+
Prec.high(
|
|
241
|
+
keymap.of([
|
|
242
|
+
{
|
|
243
|
+
key: "Mod-Enter",
|
|
244
|
+
run: () => true,
|
|
245
|
+
},
|
|
246
|
+
]),
|
|
247
|
+
),
|
|
240
248
|
keymap.of([indentWithTab]),
|
|
241
249
|
EditorState.readOnly.of(readOnly || isSaving),
|
|
242
250
|
EditorView.updateListener.of((update) => {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useParams } from "wouter"
|
|
2
2
|
import { useCurrentPackageId } from "./use-current-package-id"
|
|
3
|
-
import { useUrlParams } from "./use-url-params"
|
|
4
3
|
import { usePackageRelease } from "./use-package-release"
|
|
4
|
+
import { useUrlParams } from "./use-url-params"
|
|
5
5
|
|
|
6
6
|
export const useCurrentPackageRelease = (options?: {
|
|
7
|
-
include_logs
|
|
7
|
+
include_logs?: boolean
|
|
8
|
+
refetchInterval?: number
|
|
8
9
|
}) => {
|
|
9
10
|
const { packageId } = useCurrentPackageId()
|
|
10
11
|
const urlParams = useUrlParams()
|
|
@@ -27,6 +28,7 @@ export const useCurrentPackageRelease = (options?: {
|
|
|
27
28
|
|
|
28
29
|
const { data: packageRelease, ...rest } = usePackageRelease(query, {
|
|
29
30
|
include_logs: options?.include_logs ?? false,
|
|
31
|
+
refetchInterval: options?.refetchInterval,
|
|
30
32
|
})
|
|
31
33
|
return { packageRelease, ...rest }
|
|
32
34
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useEffect, useState } from "react"
|
|
2
|
+
|
|
3
|
+
export const useNow = (intervalMs: number = 1000) => {
|
|
4
|
+
const [now, setNow] = useState(Date.now())
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const id = setInterval(() => setNow(Date.now()), intervalMs)
|
|
8
|
+
return () => clearInterval(id)
|
|
9
|
+
}, [intervalMs])
|
|
10
|
+
|
|
11
|
+
return now
|
|
12
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
2
|
-
import { useQuery } from "react-query"
|
|
2
|
+
import { type UseQueryOptions, useQuery } from "react-query"
|
|
3
3
|
import { useAxios } from "./use-axios"
|
|
4
4
|
|
|
5
5
|
type PackageReleaseQuery =
|
|
@@ -20,7 +20,7 @@ type PackageReleaseQuery =
|
|
|
20
20
|
|
|
21
21
|
export const usePackageRelease = (
|
|
22
22
|
query: PackageReleaseQuery | null,
|
|
23
|
-
options?: { include_logs
|
|
23
|
+
options?: { include_logs?: boolean; refetchInterval?: number },
|
|
24
24
|
) => {
|
|
25
25
|
const axios = useAxios()
|
|
26
26
|
|
|
@@ -50,6 +50,7 @@ export const usePackageRelease = (
|
|
|
50
50
|
{
|
|
51
51
|
retry: false,
|
|
52
52
|
enabled: Boolean(query),
|
|
53
|
+
refetchInterval: options?.refetchInterval,
|
|
53
54
|
},
|
|
54
55
|
)
|
|
55
56
|
}
|
package/src/pages/dashboard.tsx
CHANGED
|
@@ -34,8 +34,9 @@ export const DashboardPage = () => {
|
|
|
34
34
|
data: myPackages,
|
|
35
35
|
isLoading,
|
|
36
36
|
error,
|
|
37
|
+
refetch: refetchUserPackages,
|
|
37
38
|
} = useQuery<Package[]>(
|
|
38
|
-
"userPackages",
|
|
39
|
+
["userPackages", currentUser],
|
|
39
40
|
async () => {
|
|
40
41
|
const response = await axios.post(`/packages/list`, {
|
|
41
42
|
owner_github_username: currentUser,
|
|
@@ -195,6 +196,7 @@ export const DashboardPage = () => {
|
|
|
195
196
|
packageId={packageToDelete.package_id}
|
|
196
197
|
packageName={packageToDelete.unscoped_name}
|
|
197
198
|
packageOwner={packageToDelete.owner_github_username ?? ""}
|
|
199
|
+
refetchUserPackages={refetchUserPackages}
|
|
198
200
|
/>
|
|
199
201
|
)}
|
|
200
202
|
</div>
|
|
@@ -48,7 +48,10 @@ export const UserProfilePage = () => {
|
|
|
48
48
|
})
|
|
49
49
|
return response.data
|
|
50
50
|
},
|
|
51
|
-
{
|
|
51
|
+
{
|
|
52
|
+
retry: false,
|
|
53
|
+
refetchOnWindowFocus: false,
|
|
54
|
+
},
|
|
52
55
|
)
|
|
53
56
|
|
|
54
57
|
// use the username stored in the database so the correct case is displayed
|
|
@@ -71,7 +74,10 @@ export const UserProfilePage = () => {
|
|
|
71
74
|
})
|
|
72
75
|
return response.data.packages
|
|
73
76
|
},
|
|
74
|
-
{
|
|
77
|
+
{
|
|
78
|
+
enabled: Boolean(githubUsername),
|
|
79
|
+
refetchOnWindowFocus: false,
|
|
80
|
+
},
|
|
75
81
|
)
|
|
76
82
|
|
|
77
83
|
const { data: starredPackages, isLoading: isLoadingStarredPackages } =
|
|
@@ -85,6 +91,7 @@ export const UserProfilePage = () => {
|
|
|
85
91
|
},
|
|
86
92
|
{
|
|
87
93
|
enabled: activeTab === "starred" && Boolean(githubUsername),
|
|
94
|
+
refetchOnWindowFocus: false,
|
|
88
95
|
},
|
|
89
96
|
)
|
|
90
97
|
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
name: Format PR
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
types: [opened, synchronize, reopened, ready_for_review]
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
format:
|
|
9
|
-
name: Format code
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
if: github.event.pull_request.draft == false
|
|
12
|
-
|
|
13
|
-
steps:
|
|
14
|
-
- name: Determine if fork
|
|
15
|
-
id: check_fork
|
|
16
|
-
run: |
|
|
17
|
-
if [ "${{ github.event.pull_request.head.repo.full_name }}" = "${{ github.repository }}" ]; then
|
|
18
|
-
echo "is_fork=false" >> $GITHUB_OUTPUT
|
|
19
|
-
else
|
|
20
|
-
echo "is_fork=true" >> $GITHUB_OUTPUT
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
- name: Checkout code
|
|
24
|
-
uses: actions/checkout@v4
|
|
25
|
-
with:
|
|
26
|
-
token: ${{ steps.check_fork.outputs.is_fork == 'true' && secrets.GITHUB_TOKEN || secrets.TSCIRCUIT_BOT_GITHUB_TOKEN }}
|
|
27
|
-
|
|
28
|
-
- name: Setup bun
|
|
29
|
-
uses: oven-sh/setup-bun@v2
|
|
30
|
-
with:
|
|
31
|
-
bun-version: latest
|
|
32
|
-
|
|
33
|
-
- name: Get @biomejs/biome version
|
|
34
|
-
id: get-biome-version
|
|
35
|
-
run: echo "BIOME_VERSION=$(node -p "require('./package.json').devDependencies['@biomejs/biome']")" >> $GITHUB_OUTPUT
|
|
36
|
-
|
|
37
|
-
- name: Install @biomejs/biome
|
|
38
|
-
run: bun install @biomejs/biome@${{ steps.get-biome-version.outputs.BIOME_VERSION }}
|
|
39
|
-
|
|
40
|
-
- name: Run Formatter and autofix
|
|
41
|
-
if: steps.check_fork.outputs.is_fork == 'false'
|
|
42
|
-
run: npx @biomejs/biome format . --write
|
|
43
|
-
|
|
44
|
-
- name: Format Check (cannot autofix against forks)
|
|
45
|
-
if: steps.check_fork.outputs.is_fork == 'true'
|
|
46
|
-
run: npx @biomejs/biome format .
|
|
47
|
-
|
|
48
|
-
- name: Restore lock files
|
|
49
|
-
if: steps.check_fork.outputs.is_fork == 'false'
|
|
50
|
-
run: |
|
|
51
|
-
git checkout -- *lock.json || true
|
|
52
|
-
git checkout -- *.lock || true
|
|
53
|
-
git checkout -- *.lockb || true
|
|
54
|
-
|
|
55
|
-
- name: Commit changes
|
|
56
|
-
if: steps.check_fork.outputs.is_fork == 'false'
|
|
57
|
-
uses: stefanzweifel/git-auto-commit-action@v4
|
|
58
|
-
with:
|
|
59
|
-
commit_message: "formatbot: Automatically format code"
|
|
60
|
-
branch: ${{ github.head_ref }}
|
|
61
|
-
commit_user_name: tscircuitbot
|
|
62
|
-
commit_user_email: tscircuitbot@users.noreply.github.com
|
|
63
|
-
commit_author: tscircuitbot <tscircuitbot@users.noreply.github.com>
|