issue-map 0.1.0

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.
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * 開發地圖的本機 server:每一次 GET / 都重新向 GitHub 抓快照再渲染,所以瀏覽器重新整理就是
4
+ * 最新狀態。資料抓取與渲染都在 `issue-map.ts`,這支只負責包成完整 HTML 文件並回應。
5
+ *
6
+ * 這是 package.json 的預設 bin,所以在**要看的那個 repo** 裡直接跑就會畫那個 repo:
7
+ * bunx github:gunter1020/issue-map
8
+ *
9
+ * 起來之後直接開瀏覽器。不要的話設 `ISSUE_MAP_OPEN=0`——`bun --watch` 的開發模式就是這樣關掉
10
+ * 的,否則每存一次檔就多一個分頁。
11
+ *
12
+ * 在這個 repo 裡開發時:
13
+ * bun run issue-map:serve # http://localhost:4747,不自動開
14
+ * ISSUE_MAP_PORT=5000 bun run issue-map:serve
15
+ */
16
+
17
+ import { spawnSync } from 'bun'
18
+
19
+ import { describe, renderFragment, takeSnapshot } from './issue-map.ts'
20
+
21
+ // `PORT` 是 Claude 桌面 app 的 launch.json 在 autoPort 換 port 時塞進來的。
22
+ const PORT = Number(process.env.ISSUE_MAP_PORT ?? process.env.PORT ?? 4747)
23
+ const OPEN = process.env.ISSUE_MAP_OPEN !== '0'
24
+
25
+ /**
26
+ * 開系統預設瀏覽器。**打不開不算失敗**:server 已經起來了,印出網址讓人自己開就好——把它
27
+ * 當錯誤收掉會讓「地圖其實好好地跑著」這件事被一個無關的問題蓋掉。
28
+ */
29
+ function openInBrowser(url: string): void {
30
+ const command =
31
+ process.platform === 'darwin'
32
+ ? ['open', url]
33
+ : process.platform === 'win32'
34
+ ? ['cmd', '/c', 'start', '', url]
35
+ : ['xdg-open', url]
36
+ const result = spawnSync(command, { stdout: 'ignore', stderr: 'pipe' })
37
+ if (!result.success) {
38
+ console.error(
39
+ `打不開瀏覽器(${command[0]}:${result.stderr.toString().trim()})——自己開上面那個網址`,
40
+ )
41
+ }
42
+ }
43
+
44
+ async function page(): Promise<string> {
45
+ const snapshot = takeSnapshot()
46
+ console.log(describe(snapshot))
47
+ // 樣板是 artifact 用的片段;本機直接看要補上完整文件與 charset。
48
+ const head =
49
+ '<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">'
50
+ return `<!doctype html><html lang="zh-Hant"><head>${head}</head><body>${await renderFragment(snapshot)}</body></html>`
51
+ }
52
+
53
+ const server = Bun.serve({
54
+ port: PORT,
55
+ async fetch(request) {
56
+ const { pathname } = new URL(request.url)
57
+ if (pathname !== '/') return new Response(null, { status: 404 })
58
+ try {
59
+ return new Response(await page(), {
60
+ headers: { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' },
61
+ })
62
+ } catch (error) {
63
+ const message = error instanceof Error ? error.message : String(error)
64
+ console.error(message)
65
+ return new Response(message, {
66
+ status: 502,
67
+ headers: { 'content-type': 'text/plain; charset=utf-8' },
68
+ })
69
+ }
70
+ },
71
+ })
72
+
73
+ const url = `http://localhost:${server.port}`
74
+ console.log(`開發地圖:${url}(重新整理就重抓 GitHub)`)
75
+ if (OPEN) openInBrowser(url)