issue-map 0.3.1 → 0.5.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.
- package/README.ja.md +87 -111
- package/README.md +94 -115
- package/README.zh-CN.md +80 -81
- package/README.zh-TW.md +80 -81
- package/package.json +10 -15
- package/{scripts → src}/issue-map-i18n.ts +11 -5
- package/{scripts → src}/issue-map-model.ts +55 -26
- package/src/issue-map-page.ts +411 -0
- package/{scripts → src}/issue-map-serve.ts +33 -19
- package/src/issue-map-view.ts +694 -0
- package/{scripts → src}/issue-map.html +33 -6
- package/src/issue-map.ts +657 -0
- package/scripts/issue-map-page.ts +0 -991
- package/scripts/issue-map.ts +0 -446
package/README.zh-CN.md
CHANGED
|
@@ -6,128 +6,127 @@
|
|
|
6
6
|
|
|
7
7
|
把 GitHub Issues 的阻挡关系画成一页开发地图:**哪几张票现在可以动、哪几张在等谁、关键路径是哪一条。**
|
|
8
8
|
|
|
9
|
-
状态的权威永远是 GitHub Issues。这一页只是快照,页面上不能改状态——所以不会长出第二个事实来源。
|
|
10
|
-
|
|
11
|
-
## 为什么有这个项目
|
|
12
|
-
|
|
13
|
-
起点是 [mattpocock/skills](https://github.com/mattpocock/skills)。团队照它那套「把工作流写成
|
|
14
|
-
skill、让 agent 照着跑」开始做事之后,开票变得很便宜:想到一件事就开一张票,交给 skill 去接。
|
|
15
|
-
票因此长得很快——那是流程在运作的证据,不是问题。
|
|
16
|
-
|
|
17
|
-
问题在下一步。Agent 一轮吃一张票,所以每一轮真正要决定的是**派哪一张**,而这个答案不在任何
|
|
18
|
-
单一张票里,它在票与票之间:谁挡着谁、哪一组子票还差几张、最长的那条链有多长。GitHub Issues
|
|
19
|
-
一次只让你读一张票,要凑出那张图就得一张一张点开来,而且每天都要重凑一次。
|
|
20
|
-
|
|
21
|
-
这一页就是那张图。
|
|
22
|
-
|
|
23
|
-
## 用法
|
|
24
|
-
|
|
25
|
-
在**要看的那个 repo** 里跑:
|
|
26
|
-
|
|
27
9
|
```bash
|
|
28
10
|
bunx issue-map@latest
|
|
29
11
|
```
|
|
30
12
|
|
|
31
|
-
|
|
13
|
+
在要看的那个 repo 里跑。会直接开浏览器标签页,每次刷新都重抓 GitHub。状态的权威永远是 GitHub
|
|
14
|
+
Issues——这一页只是快照,不能改状态。
|
|
32
15
|
|
|
33
|
-
|
|
16
|
+
## 为什么有这个项目
|
|
34
17
|
|
|
35
|
-
|
|
18
|
+
Agent 一轮吃一张票,所以每一轮真正要决定的是**派哪一张**。这个答案不在任何单一张票里,它在票与
|
|
19
|
+
票之间:谁挡着谁、哪一组子票还差几张、最长的那条链有多长。GitHub 一次只让你读一张票。这一页就是
|
|
20
|
+
那张图。
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
它是绕着 [mattpocock/skills](https://github.com/mattpocock/skills) 那套做法建的——把工作流写成
|
|
23
|
+
skill、让 agent 照着跑——默认的标签与指令也是从那里来的。
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
bunx -p issue-map@latest issue-map-build # 写到 dist/issue-map.html
|
|
41
|
-
bunx -p issue-map@latest issue-map-build out.html
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
快照就是快照——状态会过期,要看现在的状态就用上面的 server。
|
|
25
|
+
## 用法
|
|
45
26
|
|
|
46
|
-
|
|
27
|
+
| 指令 | 得到什么 |
|
|
28
|
+
| --------------------------------------------------- | -------------------------------- |
|
|
29
|
+
| `bunx issue-map@latest` | server 起在空端口,自动开浏览器 |
|
|
30
|
+
| `bunx -p issue-map@latest issue-map-build` | 静态文件到 `dist/issue-map.html` |
|
|
31
|
+
| `bunx -p issue-map@latest issue-map-build out.html` | 静态文件到你指定的路径 |
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
- repo 是 `gh` 从 cwd 的 git 推断的,不必填。
|
|
34
|
+
- `ISSUE_MAP_PORT` 固定端口。固定就是严格的:被占住时直接失败,不会偷偷换一个。
|
|
35
|
+
- `ISSUE_MAP_OPEN=0` 不自动开标签页。
|
|
36
|
+
- 静态文件会过期,要看现在的状态就用 server。
|
|
37
|
+
- 在跑不了 script 的地方(严格 CSP、某些预览窗),文件会退回一份纯文字的票清单,而不是一片空白。
|
|
38
|
+
- `@latest` 取 npm 上最新的一版;要钉住就写 `bunx issue-map@0.2.0`。
|
|
51
39
|
|
|
52
|
-
|
|
40
|
+
## 前置条件
|
|
53
41
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
- 英文要分单复数的键写成 `{ one, other }`,中日文写一句字符串就好(`Intl.PluralRules` 对这几种
|
|
58
|
-
语言只有 `other`)。
|
|
42
|
+
- **Bun**——这几支用了 `Bun.build`、`Bun.serve`、`Bun.file`,Node 跑不起来。
|
|
43
|
+
- **`gh` CLI 已登录**,而且对目标 repo 有读取权。
|
|
44
|
+
- 目标 repo 有 git remote 指向 GitHub。
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
的值,分组名字也一样,话在 i18n 那一层才组出来。快照里存中文句子的话,换一次语言就得重抓一次
|
|
62
|
-
GitHub。
|
|
46
|
+
没有 runtime 依赖。
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
## 语言
|
|
65
49
|
|
|
66
|
-
|
|
50
|
+
页面右上角切换:英文(默认)、繁体中文、简体中文、日文。选了哪一种记在浏览器,跟 repo 无关——语言
|
|
51
|
+
是看的人的偏好,不是某个项目的设置。
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
- **`gh` CLI 已登录**,而且对目标 repo 有读取权。
|
|
70
|
-
- 目标 repo 有 git remote 指向 GitHub。
|
|
71
|
-
- 没有 runtime 依赖;devDependencies 只有类型与 lint/format 工具。
|
|
53
|
+
CLI 那一侧(产文件消息、错误)只有英文。
|
|
72
54
|
|
|
73
55
|
## 配置
|
|
74
56
|
|
|
75
|
-
全部有默认值,一个都不设也跑得起来。默认值长在 `
|
|
76
|
-
|
|
77
|
-
| 环境变量 | 默认 | 意思
|
|
78
|
-
| -------------------------- | --------------------------------- |
|
|
79
|
-
| `GH_REPO` | 从 cwd 的 git 推断 | 要画别的 repo 时设它(`gh` 自己的变量,fork
|
|
80
|
-
| `ISSUE_MAP_PARENT_HEADING` |
|
|
81
|
-
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` |
|
|
82
|
-
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` |
|
|
83
|
-
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` |
|
|
84
|
-
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` |
|
|
85
|
-
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 可以动工时图上叫人跑的指令
|
|
86
|
-
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | 还要评估时图上叫人跑的指令
|
|
87
|
-
| `ISSUE_MAP_PORT` |
|
|
88
|
-
| `ISSUE_MAP_OPEN` | 开 | 设 `0`
|
|
57
|
+
全部有默认值,一个都不设也跑得起来。默认值长在 `src/issue-map.ts` 的 `CONFIG`。
|
|
58
|
+
|
|
59
|
+
| 环境变量 | 默认 | 意思 |
|
|
60
|
+
| -------------------------- | --------------------------------- | ------------------------------------------------------ |
|
|
61
|
+
| `GH_REPO` | 从 cwd 的 git 推断 | 要画别的 repo 时设它(`gh` 自己的变量,fork 也交给它) |
|
|
62
|
+
| `ISSUE_MAP_PARENT_HEADING` | 未设(不抓正文) | 子票在正文指向母票的段落标题。设了才会读正文 |
|
|
63
|
+
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` | 还没评估完,不能交给谁做 |
|
|
64
|
+
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` | 评估完、可以动工 |
|
|
65
|
+
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` | 有人在做,不必有 assignee |
|
|
66
|
+
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` | 要人做,下一步不写实作指令 |
|
|
67
|
+
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 可以动工时图上叫人跑的指令 |
|
|
68
|
+
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | 还要评估时图上叫人跑的指令 |
|
|
69
|
+
| `ISSUE_MAP_PORT` | OS 指派的空端口 | server 的端口 |
|
|
70
|
+
| `ISSUE_MAP_OPEN` | 开 | 设 `0` 就不自动开浏览器 |
|
|
89
71
|
|
|
90
72
|
三个要特别想过的:
|
|
91
73
|
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
-
|
|
74
|
+
- **标签词汇。** ready/unready 的默认值是 mattpocock/skills 五个[标准 triage 标签](https://github.com/mattpocock/skills/blob/main/skills/engineering/setup-matt-pocock-skills/triage-labels.md)
|
|
75
|
+
里的四个。目标 repo 没在用这套就换成它自己的名字。快照里完全没出现这些标签时,就不拿 triage 当
|
|
76
|
+
闸门,否则每张票都会变成「待评估」。(`in-progress` 是这个工具自己加的,那套 skill 没有「有人在
|
|
77
|
+
做」这个标签。)
|
|
78
|
+
- **指令名。** `/implement`、`/triage` 就是那边的 [`implement`](https://github.com/mattpocock/skills/tree/main/skills/engineering/implement) 与
|
|
79
|
+
[`triage`](https://github.com/mattpocock/skills/tree/main/skills/engineering/triage) skill。要指向目标 repo 真的有的东西,不然图上会叫人跑不存在的。
|
|
80
|
+
- **正文惯例要明讲才生效。** 正文占了 GitHub 响应九成以上的重量,而它只喂一条 regex,页面上
|
|
81
|
+
没有别的地方用得到。所以只有设了 `ISSUE_MAP_PARENT_HEADING` 才会去抓正文。原生 sub-issue
|
|
82
|
+
不必设置,而且一律优先。
|
|
83
|
+
- **已完成的兄弟票要靠原生 sub-issue。** 地图只跟 GitHub 要 open 票还牵着的 closed 票,而子票是从
|
|
84
|
+
原生的 sub-issue 关系拿的。用 `## Parent` 正文惯例的 repo 看不到一组里**已完成**的子票,那一组的
|
|
85
|
+
进度会比实际少。把子票在票页的 Sub-issues 关联上去一次就会回来;正文惯例可以留着,原生的本来
|
|
86
|
+
就优先。
|
|
95
87
|
|
|
96
88
|
## 常见失败
|
|
97
89
|
|
|
98
|
-
|
|
90
|
+
`gh api graphql failed: …` — `gh` 没登录,或 cwd 不在目标 repo 的 git 树里。
|
|
99
91
|
|
|
100
92
|
## 文件
|
|
101
93
|
|
|
102
|
-
| 文件
|
|
103
|
-
|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
94
|
+
| 文件 | 职责 |
|
|
95
|
+
| ------------------------ | -------------------------------------------------------- |
|
|
96
|
+
| `src/issue-map.ts` | 抓快照、算状态与下一步、产出 HTML。配置在里面的 `CONFIG` |
|
|
97
|
+
| `src/issue-map-model.ts` | 纯数据模型:分组、关键路径、排版。前后端共用 |
|
|
98
|
+
| `src/issue-map-i18n.ts` | 四种语言的文案与查表 |
|
|
99
|
+
| `src/issue-map-page.ts` | 浏览器端代码,构建时被打包进 HTML |
|
|
100
|
+
| `src/issue-map.html` | 模板。两个占位区块会被填入 |
|
|
101
|
+
| `src/issue-map-serve.ts` | 本机 server,每个请求重抓一次 |
|
|
102
|
+
| `tools/mutate.ts` | 变异测试:改坏一行看测试会不会红 |
|
|
111
103
|
|
|
112
104
|
## 在这个 repo 里开发
|
|
113
105
|
|
|
114
106
|
```bash
|
|
115
107
|
bun install
|
|
116
|
-
bun run issue-map:serve # --watch
|
|
108
|
+
bun run issue-map:serve # --watch;不自动开标签页(每存一次档就会多一个)
|
|
117
109
|
bun run issue-map # 只产文件到 dist/issue-map.html
|
|
118
110
|
bun run check # lint + format:check + typecheck
|
|
119
|
-
bun test #
|
|
111
|
+
bun test # 纯模型那一层
|
|
120
112
|
```
|
|
121
113
|
|
|
122
114
|
这个 repo 自己还没有 issue,`GH_REPO=<owner>/<repo>` 指到有票的 repo 才画得出东西。
|
|
123
115
|
|
|
124
|
-
`tests/`
|
|
116
|
+
**测试。** `tests/` 只守会让地图说谎或不能看的事,外观(颜色、形状、间距)刻意不验。新增守门测试
|
|
117
|
+
要走反向验证——把它宣称要挡的缺陷放回产品代码,确认它会红:
|
|
125
118
|
|
|
126
119
|
```bash
|
|
127
|
-
bun run mutate
|
|
120
|
+
bun run mutate src/issue-map-model.ts tests/issue-map-layout.test.ts
|
|
128
121
|
```
|
|
129
122
|
|
|
130
|
-
|
|
123
|
+
**要动 `src/issue-map-i18n.ts`。** `EN` 是原稿,也是键的定义处;三份翻译的类型由它推导,少一个
|
|
124
|
+
键或少一个 `{n}` 代入名,`bun run typecheck` 就会红。英文要分单复数的键写成 `{ one, other }`,中日
|
|
125
|
+
文写一句字符串就好。模型那一侧不算句子——`nextStep` 是 `{ kind: 'waitChildren', count: 2 }` 这种结构
|
|
126
|
+
化的值,话在这里才组出来。
|
|
127
|
+
|
|
128
|
+
## 两个设计上的决定
|
|
131
129
|
|
|
132
|
-
- **这一页不能改状态。** 没有按钮会回写 GitHub
|
|
133
|
-
-
|
|
130
|
+
- **这一页不能改状态。** 没有按钮会回写 GitHub。状态只有一个事实来源,多一个入口就会不一致。
|
|
131
|
+
- **不另设短名字段。** 站点标的是标题的开头几个字。在票里手动维护一个短名会变成票名的第二个
|
|
132
|
+
事实来源,改标题不会跟着改。完整标题在下方清单。
|
package/README.zh-TW.md
CHANGED
|
@@ -6,128 +6,127 @@
|
|
|
6
6
|
|
|
7
7
|
把 GitHub Issues 的阻擋關係畫成一頁開發地圖:**哪幾張票現在可以動、哪幾張在等誰、關鍵路徑是哪一條。**
|
|
8
8
|
|
|
9
|
-
狀態的權威永遠是 GitHub Issues。這一頁只是快照,頁面上不能改狀態——所以不會長出第二個事實來源。
|
|
10
|
-
|
|
11
|
-
## 為什麼有這個專案
|
|
12
|
-
|
|
13
|
-
起點是 [mattpocock/skills](https://github.com/mattpocock/skills)。團隊照它那套「把工作流寫成
|
|
14
|
-
skill、讓 agent 照著跑」開始做事之後,開票變得很便宜:想到一件事就開一張票,交給 skill 去接。
|
|
15
|
-
票因此長得很快——那是流程在運作的證據,不是問題。
|
|
16
|
-
|
|
17
|
-
問題在下一步。Agent 一輪吃一張票,所以每一輪真正要決定的是**派哪一張**,而這個答案不在任何
|
|
18
|
-
單一張票裡,它在票與票之間:誰擋著誰、哪一組子票還差幾張、最長的那條鏈有多長。GitHub Issues
|
|
19
|
-
一次只讓你讀一張票,要湊出那張圖就得一張一張點開來,而且每天都要重湊一次。
|
|
20
|
-
|
|
21
|
-
這一頁就是那張圖。
|
|
22
|
-
|
|
23
|
-
## 用法
|
|
24
|
-
|
|
25
|
-
在**要看的那個 repo** 裡跑:
|
|
26
|
-
|
|
27
9
|
```bash
|
|
28
10
|
bunx issue-map@latest
|
|
29
11
|
```
|
|
30
12
|
|
|
31
|
-
|
|
13
|
+
在要看的那個 repo 裡跑。會直接開瀏覽器分頁,每次重新整理都重抓 GitHub。狀態的權威永遠是 GitHub
|
|
14
|
+
Issues——這一頁只是快照,不能改狀態。
|
|
32
15
|
|
|
33
|
-
|
|
16
|
+
## 為什麼有這個專案
|
|
34
17
|
|
|
35
|
-
|
|
18
|
+
Agent 一輪吃一張票,所以每一輪真正要決定的是**派哪一張**。這個答案不在任何單一張票裡,它在票與
|
|
19
|
+
票之間:誰擋著誰、哪一組子票還差幾張、最長的那條鏈有多長。GitHub 一次只讓你讀一張票。這一頁就是
|
|
20
|
+
那張圖。
|
|
36
21
|
|
|
37
|
-
|
|
22
|
+
它是繞著 [mattpocock/skills](https://github.com/mattpocock/skills) 那套做法建的——把工作流寫成
|
|
23
|
+
skill、讓 agent 照著跑——預設的標籤與指令也是從那裡來的。
|
|
38
24
|
|
|
39
|
-
|
|
40
|
-
bunx -p issue-map@latest issue-map-build # 寫到 dist/issue-map.html
|
|
41
|
-
bunx -p issue-map@latest issue-map-build out.html
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
快照就是快照——狀態會過期,要看現在的狀態就用上面的 server。
|
|
25
|
+
## 用法
|
|
45
26
|
|
|
46
|
-
|
|
27
|
+
| 指令 | 得到什麼 |
|
|
28
|
+
| --------------------------------------------------- | -------------------------------- |
|
|
29
|
+
| `bunx issue-map@latest` | server 起在空 port,自動開瀏覽器 |
|
|
30
|
+
| `bunx -p issue-map@latest issue-map-build` | 靜態檔到 `dist/issue-map.html` |
|
|
31
|
+
| `bunx -p issue-map@latest issue-map-build out.html` | 靜態檔到你指定的路徑 |
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
- repo 是 `gh` 從 cwd 的 git 推斷的,不必填。
|
|
34
|
+
- `ISSUE_MAP_PORT` 固定 port。固定就是嚴格的:被佔住時直接失敗,不會偷偷換一個。
|
|
35
|
+
- `ISSUE_MAP_OPEN=0` 不自動開分頁。
|
|
36
|
+
- 靜態檔會過期,要看現在的狀態就用 server。
|
|
37
|
+
- 在跑不了 script 的地方(嚴格 CSP、某些預覽窗),檔案會退回一份純文字的票清單,而不是一片空白。
|
|
38
|
+
- `@latest` 取 npm 上最新的一版;要釘住就寫 `bunx issue-map@0.2.0`。
|
|
51
39
|
|
|
52
|
-
|
|
40
|
+
## 前置條件
|
|
53
41
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
- 英文要分單複數的鍵寫成 `{ one, other }`,中日文寫一句字串就好(`Intl.PluralRules` 對這幾種
|
|
58
|
-
語言只有 `other`)。
|
|
42
|
+
- **Bun**——這幾支用了 `Bun.build`、`Bun.serve`、`Bun.file`,Node 跑不起來。
|
|
43
|
+
- **`gh` CLI 已登入**,而且對目標 repo 有讀取權。
|
|
44
|
+
- 目標 repo 有 git remote 指向 GitHub。
|
|
59
45
|
|
|
60
|
-
|
|
61
|
-
的值,分組名字也一樣,話在 i18n 那一層才組出來。快照裡存中文句子的話,換一次語言就得重抓一次
|
|
62
|
-
GitHub。
|
|
46
|
+
沒有 runtime 依賴。
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
## 語言
|
|
65
49
|
|
|
66
|
-
|
|
50
|
+
頁面右上角切換:英文(預設)、繁體中文、簡體中文、日文。選了哪一種記在瀏覽器,跟 repo 無關——語言
|
|
51
|
+
是看的人的偏好,不是某個專案的設定。
|
|
67
52
|
|
|
68
|
-
|
|
69
|
-
- **`gh` CLI 已登入**,而且對目標 repo 有讀取權。
|
|
70
|
-
- 目標 repo 有 git remote 指向 GitHub。
|
|
71
|
-
- 沒有 runtime 依賴;devDependencies 只有型別與 lint/format 工具。
|
|
53
|
+
CLI 那一側(產檔訊息、錯誤)只有英文。
|
|
72
54
|
|
|
73
55
|
## 設定
|
|
74
56
|
|
|
75
|
-
全部有預設值,一個都不設也跑得起來。預設值長在 `
|
|
76
|
-
|
|
77
|
-
| 環境變數 | 預設 | 意思
|
|
78
|
-
| -------------------------- | --------------------------------- |
|
|
79
|
-
| `GH_REPO` | 從 cwd 的 git 推斷 | 要畫別的 repo 時設它(`gh` 自己的變數,fork
|
|
80
|
-
| `ISSUE_MAP_PARENT_HEADING` |
|
|
81
|
-
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` |
|
|
82
|
-
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` |
|
|
83
|
-
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` |
|
|
84
|
-
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` |
|
|
85
|
-
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 可以動工時圖上叫人跑的指令
|
|
86
|
-
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | 還要評估時圖上叫人跑的指令
|
|
87
|
-
| `ISSUE_MAP_PORT` |
|
|
88
|
-
| `ISSUE_MAP_OPEN` | 開 | 設 `0`
|
|
57
|
+
全部有預設值,一個都不設也跑得起來。預設值長在 `src/issue-map.ts` 的 `CONFIG`。
|
|
58
|
+
|
|
59
|
+
| 環境變數 | 預設 | 意思 |
|
|
60
|
+
| -------------------------- | --------------------------------- | ------------------------------------------------------ |
|
|
61
|
+
| `GH_REPO` | 從 cwd 的 git 推斷 | 要畫別的 repo 時設它(`gh` 自己的變數,fork 也交給它) |
|
|
62
|
+
| `ISSUE_MAP_PARENT_HEADING` | 未設(不抓內文) | 子票在內文指向母票的段落標題。設了才會讀內文 |
|
|
63
|
+
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` | 還沒評估完,不能交給誰做 |
|
|
64
|
+
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` | 評估完、可以動工 |
|
|
65
|
+
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` | 有人在做,不必有 assignee |
|
|
66
|
+
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` | 要人做,下一步不寫實作指令 |
|
|
67
|
+
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 可以動工時圖上叫人跑的指令 |
|
|
68
|
+
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | 還要評估時圖上叫人跑的指令 |
|
|
69
|
+
| `ISSUE_MAP_PORT` | OS 指派的空 port | server 的 port |
|
|
70
|
+
| `ISSUE_MAP_OPEN` | 開 | 設 `0` 就不自動開瀏覽器 |
|
|
89
71
|
|
|
90
72
|
三個要特別想過的:
|
|
91
73
|
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
-
|
|
74
|
+
- **標籤字彙。** ready/unready 的預設值是 mattpocock/skills 五個[標準 triage 標籤](https://github.com/mattpocock/skills/blob/main/skills/engineering/setup-matt-pocock-skills/triage-labels.md)
|
|
75
|
+
裡的四個。目標 repo 沒在用這套就換成它自己的名字。快照裡完全沒出現這些標籤時,就不拿 triage 當
|
|
76
|
+
閘門,否則每張票都會變成「待評估」。(`in-progress` 是這個工具自己加的,那套 skill 沒有「有人在
|
|
77
|
+
做」這個標籤。)
|
|
78
|
+
- **指令名。** `/implement`、`/triage` 就是那邊的 [`implement`](https://github.com/mattpocock/skills/tree/main/skills/engineering/implement) 與
|
|
79
|
+
[`triage`](https://github.com/mattpocock/skills/tree/main/skills/engineering/triage) skill。要指向目標 repo 真的有的東西,不然圖上會叫人跑不存在的。
|
|
80
|
+
- **內文慣例要明講才生效。** 內文佔了 GitHub 回應九成以上的重量,而它只餵一條 regex,頁面上
|
|
81
|
+
沒有別的地方用得到。所以只有設了 `ISSUE_MAP_PARENT_HEADING` 才會去抓內文。原生 sub-issue
|
|
82
|
+
不必設定,而且一律優先。
|
|
83
|
+
- **已完成的兄弟票要靠原生 sub-issue。** 地圖只跟 GitHub 要 open 票還牽著的 closed 票,而子票是從
|
|
84
|
+
原生的 sub-issue 關係拿的。用 `## Parent` 內文慣例的 repo 看不到一組裡**已完成**的子票,那一組的
|
|
85
|
+
進度會比實際少。把子票在票頁的 Sub-issues 關聯上去一次就會回來;內文慣例可以留著,原生的本來
|
|
86
|
+
就優先。
|
|
95
87
|
|
|
96
88
|
## 常見失敗
|
|
97
89
|
|
|
98
|
-
|
|
90
|
+
`gh api graphql failed: …` — `gh` 沒登入,或 cwd 不在目標 repo 的 git 樹裡。
|
|
99
91
|
|
|
100
92
|
## 檔案
|
|
101
93
|
|
|
102
|
-
| 檔案
|
|
103
|
-
|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
94
|
+
| 檔案 | 責任 |
|
|
95
|
+
| ------------------------ | -------------------------------------------------------- |
|
|
96
|
+
| `src/issue-map.ts` | 抓快照、算狀態與下一步、產出 HTML。設定在裡面的 `CONFIG` |
|
|
97
|
+
| `src/issue-map-model.ts` | 純資料模型:分組、關鍵路徑、排版。前後端共用 |
|
|
98
|
+
| `src/issue-map-i18n.ts` | 四種語言的文案與查表 |
|
|
99
|
+
| `src/issue-map-page.ts` | 瀏覽器端程式碼,建置時被打包進 HTML |
|
|
100
|
+
| `src/issue-map.html` | 樣板。兩個佔位區塊會被填入 |
|
|
101
|
+
| `src/issue-map-serve.ts` | 本機 server,每個請求重抓一次 |
|
|
102
|
+
| `tools/mutate.ts` | 突變測試:改壞一行看測試會不會紅 |
|
|
111
103
|
|
|
112
104
|
## 在這個 repo 裡開發
|
|
113
105
|
|
|
114
106
|
```bash
|
|
115
107
|
bun install
|
|
116
|
-
bun run issue-map:serve # --watch
|
|
108
|
+
bun run issue-map:serve # --watch;不自動開分頁(每存一次檔就會多一個)
|
|
117
109
|
bun run issue-map # 只產檔到 dist/issue-map.html
|
|
118
110
|
bun run check # lint + format:check + typecheck
|
|
119
|
-
bun test #
|
|
111
|
+
bun test # 純模型那一層
|
|
120
112
|
```
|
|
121
113
|
|
|
122
114
|
這個 repo 自己還沒有 issue,`GH_REPO=<owner>/<repo>` 指到有票的 repo 才畫得出東西。
|
|
123
115
|
|
|
124
|
-
`tests/`
|
|
116
|
+
**測試。** `tests/` 只守會讓地圖說謊或不能看的事,外觀(顏色、形狀、間距)刻意不驗。新增守門測試
|
|
117
|
+
要走反向驗證——把它宣稱要擋的缺陷放回產品碼,確認它會紅:
|
|
125
118
|
|
|
126
119
|
```bash
|
|
127
|
-
bun run mutate
|
|
120
|
+
bun run mutate src/issue-map-model.ts tests/issue-map-layout.test.ts
|
|
128
121
|
```
|
|
129
122
|
|
|
130
|
-
|
|
123
|
+
**要動 `src/issue-map-i18n.ts`。** `EN` 是原稿,也是鍵的定義處;三份翻譯的型別由它推導,少一個
|
|
124
|
+
鍵或少一個 `{n}` 代入名,`bun run typecheck` 就會紅。英文要分單複數的鍵寫成 `{ one, other }`,中日
|
|
125
|
+
文寫一句字串就好。模型那一側不算句子——`nextStep` 是 `{ kind: 'waitChildren', count: 2 }` 這種結構
|
|
126
|
+
化的值,話在這裡才組出來。
|
|
127
|
+
|
|
128
|
+
## 兩個設計上的決定
|
|
131
129
|
|
|
132
|
-
- **這一頁不能改狀態。** 沒有按鈕會回寫 GitHub
|
|
133
|
-
-
|
|
130
|
+
- **這一頁不能改狀態。** 沒有按鈕會回寫 GitHub。狀態只有一個事實來源,多一個入口就會不一致。
|
|
131
|
+
- **不另設短名欄位。** 站點標的是標題的開頭幾個字。在票裡手動維護一個短名會變成票名的第二個
|
|
132
|
+
事實來源,改標題不會跟著改。完整標題在下方清單。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "issue-map",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Draws the blocking relationships between your GitHub Issues as a one-page dev map: which issues can be picked up now, which are waiting on what, and where the critical path runs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -15,26 +15,21 @@
|
|
|
15
15
|
"url": "git+https://github.com/gunter1020/issue-map.git"
|
|
16
16
|
},
|
|
17
17
|
"bin": {
|
|
18
|
-
"issue-map": "./
|
|
19
|
-
"issue-map-build": "./
|
|
18
|
+
"issue-map": "./src/issue-map-serve.ts",
|
|
19
|
+
"issue-map-build": "./src/issue-map.ts"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
22
|
"README.zh-TW.md",
|
|
23
23
|
"README.zh-CN.md",
|
|
24
24
|
"README.ja.md",
|
|
25
|
-
"
|
|
26
|
-
"scripts/issue-map-i18n.ts",
|
|
27
|
-
"scripts/issue-map-model.ts",
|
|
28
|
-
"scripts/issue-map-page.ts",
|
|
29
|
-
"scripts/issue-map-serve.ts",
|
|
30
|
-
"scripts/issue-map.html"
|
|
25
|
+
"src"
|
|
31
26
|
],
|
|
32
27
|
"type": "module",
|
|
33
28
|
"scripts": {
|
|
34
|
-
"issue-map": "bun run
|
|
35
|
-
"issue-map:serve": "ISSUE_MAP_OPEN=0 bun --watch
|
|
29
|
+
"issue-map": "bun run src/issue-map.ts",
|
|
30
|
+
"issue-map:serve": "ISSUE_MAP_OPEN=0 bun --watch src/issue-map-serve.ts",
|
|
36
31
|
"typecheck": "tsc --noEmit",
|
|
37
|
-
"mutate": "bun run
|
|
32
|
+
"mutate": "bun run tools/mutate.ts",
|
|
38
33
|
"format": "oxfmt .",
|
|
39
34
|
"format:check": "oxfmt --check .",
|
|
40
35
|
"lint": "oxlint .",
|
|
@@ -42,10 +37,10 @@
|
|
|
42
37
|
"check": "bun run lint && bun run format:check && bun run typecheck"
|
|
43
38
|
},
|
|
44
39
|
"devDependencies": {
|
|
45
|
-
"@types/bun": "
|
|
46
|
-
"oxfmt": "^0.
|
|
40
|
+
"@types/bun": "^1.4.2",
|
|
41
|
+
"oxfmt": "^0.67.0",
|
|
47
42
|
"oxlint": "^1.76.0",
|
|
48
|
-
"typescript": "^
|
|
43
|
+
"typescript": "^7.0.2"
|
|
49
44
|
},
|
|
50
45
|
"engines": {
|
|
51
46
|
"bun": ">=1.0.0"
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* 頁面文案。**沒有 Bun、沒有 DOM**——它只是字典與一個查表函式,所以抓資料那一側與畫面那一側
|
|
3
3
|
* 都能 import。
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* 這裡是頁面上所有給人看的字的唯一來源。畫面那一側不寫死任何一句話,模型那一側送的是結構化
|
|
6
|
+
* 的值(`nextStep`、分組名字),句子在這裡才組出來——否則同一句話會同時長在模型、樣板與畫面
|
|
7
|
+
* 三處,換語言只會換到其中一處。
|
|
8
8
|
*
|
|
9
|
-
* `en` 是原稿,也是鍵的定義處:`Messages`
|
|
9
|
+
* `en` 是原稿,也是鍵的定義處:`Messages` 由它推導,少翻一個鍵就編不過。翻譯缺鍵不 fallback
|
|
10
10
|
* 成英文——那會安靜地留下半英半中的畫面。
|
|
11
11
|
*
|
|
12
12
|
* 字典的值會進 `innerHTML`(`lede.*` 刻意帶 `<strong>`),所以**翻譯裡不要放意料外的標記**;
|
|
13
|
-
*
|
|
13
|
+
* 代入的值由呼叫端負責逃脫。
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/** 支援的語言。第一個是預設。 */
|
|
@@ -100,6 +100,8 @@ const EN = {
|
|
|
100
100
|
'group.linkedSub': 'linked by prerequisites, but under no parent issue',
|
|
101
101
|
'group.spec': '#{n} parent spec',
|
|
102
102
|
'group.progress': 'sub-issues {done} / {total} done · parent closes only when all do',
|
|
103
|
+
'group.undrawn':
|
|
104
|
+
'Map not drawn — nothing here blocks anything. The issues are in the list below.',
|
|
103
105
|
|
|
104
106
|
'status.ready': 'ready',
|
|
105
107
|
'status.active': 'in progress',
|
|
@@ -199,6 +201,7 @@ const ZH_TW: Messages = {
|
|
|
199
201
|
'group.linkedSub': '有前置關係,但不屬於任何母票',
|
|
200
202
|
'group.spec': '#{n} 母票規格',
|
|
201
203
|
'group.progress': '子票 {done} / {total} 已完成 · 全關後才關 parent',
|
|
204
|
+
'group.undrawn': '沒有畫圖——這一組裡沒有任何阻擋關係。票在下方清單。',
|
|
202
205
|
|
|
203
206
|
'status.ready': '可接手',
|
|
204
207
|
'status.active': '進行中',
|
|
@@ -288,6 +291,7 @@ const ZH_CN: Messages = {
|
|
|
288
291
|
'group.linkedSub': '有前置关系,但不属于任何母票',
|
|
289
292
|
'group.spec': '#{n} 母票规格',
|
|
290
293
|
'group.progress': '子票 {done} / {total} 已完成 · 全关后才关 parent',
|
|
294
|
+
'group.undrawn': '没有画图——这一组里没有任何阻挡关系。票在下方清单。',
|
|
291
295
|
|
|
292
296
|
'status.ready': '可接手',
|
|
293
297
|
'status.active': '进行中',
|
|
@@ -381,6 +385,8 @@ const JA: Messages = {
|
|
|
381
385
|
'group.linkedSub': '依存関係はあるが、親チケットには属さない',
|
|
382
386
|
'group.spec': '#{n} 親チケットの仕様',
|
|
383
387
|
'group.progress': 'サブチケット {done} / {total} 完了 · すべて閉じてから親を閉じる',
|
|
388
|
+
'group.undrawn':
|
|
389
|
+
'図は描いていません——このグループにはブロック関係がありません。チケットは下の一覧にあります。',
|
|
384
390
|
|
|
385
391
|
'status.ready': '着手可',
|
|
386
392
|
'status.active': '対応中',
|