issue-map 0.3.0 → 0.4.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 +85 -108
- package/README.md +88 -108
- package/README.zh-CN.md +77 -83
- package/README.zh-TW.md +77 -81
- package/package.json +5 -4
- package/scripts/issue-map-i18n.ts +11 -5
- package/scripts/issue-map-model.ts +11 -4
- package/scripts/issue-map-page.ts +109 -713
- package/scripts/issue-map-serve.ts +17 -18
- package/scripts/issue-map-view.ts +650 -0
- package/scripts/issue-map.html +31 -5
- package/scripts/issue-map.ts +272 -84
package/README.ja.md
CHANGED
|
@@ -7,157 +7,134 @@
|
|
|
7
7
|
GitHub Issues のブロック関係を 1 ページの開発マップにします:**いま着手できるのはどれか、どれが
|
|
8
8
|
何を待っているか、クリティカルパスはどこを通るか。**
|
|
9
9
|
|
|
10
|
-
状態の正は常に GitHub Issues です。このページはスナップショットにすぎず、ここでは状態を変えられ
|
|
11
|
-
ません——だから 2 つ目の正が生まれません。
|
|
12
|
-
|
|
13
|
-
## なぜこれを作ったか
|
|
14
|
-
|
|
15
|
-
出発点は [mattpocock/skills](https://github.com/mattpocock/skills) です。「ワークフローを skill と
|
|
16
|
-
して書き、agent に走らせる」というやり方をチームで採り入れてから、チケットを起票するコストが
|
|
17
|
-
下がりました。思いついたら 1 枚起票して skill に渡す。結果としてチケットは一気に増えます。それは
|
|
18
|
-
プロセスが機能している証拠であって、問題ではありません。
|
|
19
|
-
|
|
20
|
-
問題は次の一手です。Agent は 1 ラウンドに 1 枚しか扱えないので、毎ラウンド実際に決めるのは**どれを
|
|
21
|
-
渡すか**です。その答えはどの 1 枚の中にもなく、チケットとチケットの間にあります——誰が誰を
|
|
22
|
-
ブロックしているか、親はあと何枚のサブチケットを待っているか、いちばん長い鎖は何段か。GitHub
|
|
23
|
-
Issues は一度に 1 枚しか見せてくれないので、その絵を組み立てるには 1 枚ずつ開くしかなく、しかも
|
|
24
|
-
明日もまた同じことをします。
|
|
25
|
-
|
|
26
|
-
このページがその絵です。
|
|
27
|
-
|
|
28
|
-
## 使い方
|
|
29
|
-
|
|
30
|
-
**見たい repo の中で**実行します:
|
|
31
|
-
|
|
32
10
|
```bash
|
|
33
11
|
bunx issue-map@latest
|
|
34
12
|
```
|
|
35
13
|
|
|
36
|
-
|
|
14
|
+
見たい repo の中で実行します。ブラウザのタブが開き、更新するたびに GitHub を取り直します。状態の
|
|
15
|
+
正は常に GitHub Issues——このページはスナップショットで、状態は変えられません。
|
|
37
16
|
|
|
38
|
-
|
|
39
|
-
ので、見えているのは常に現在の状態です。repo は `gh` が cwd の git から推測するため、指定は不要
|
|
40
|
-
です。
|
|
41
|
-
|
|
42
|
-
タブを勝手に開いてほしくなければ `ISSUE_MAP_OPEN=0` を設定します。
|
|
17
|
+
## なぜこれを作ったか
|
|
43
18
|
|
|
44
|
-
|
|
45
|
-
|
|
19
|
+
Agent は 1 ラウンドに 1 枚しか扱えないので、毎ラウンド実際に決めるのは**どれを渡すか**です。その
|
|
20
|
+
答えはどの 1 枚の中にもなく、チケットとチケットの間にあります——誰が誰をブロックしているか、親は
|
|
21
|
+
あと何枚のサブチケットを待っているか、いちばん長い鎖は何段か。GitHub は一度に 1 枚しか見せてくれ
|
|
22
|
+
ません。このページがその絵です。
|
|
46
23
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
bunx -p issue-map@latest issue-map-build out.html
|
|
50
|
-
```
|
|
24
|
+
[mattpocock/skills](https://github.com/mattpocock/skills) のやり方——ワークフローを skill として
|
|
25
|
+
書き、agent に走らせる——を前提に作っており、既定のラベルとコマンドもそこから来ています。
|
|
51
26
|
|
|
52
|
-
|
|
53
|
-
を使ってください。
|
|
27
|
+
## 使い方
|
|
54
28
|
|
|
55
|
-
|
|
29
|
+
| コマンド | 得られるもの |
|
|
30
|
+
| --------------------------------------------------- | ---------------------------------------- |
|
|
31
|
+
| `bunx issue-map@latest` | 空き port で server 起動、ブラウザも開く |
|
|
32
|
+
| `bunx -p issue-map@latest issue-map-build` | 静的ファイルを `dist/issue-map.html` へ |
|
|
33
|
+
| `bunx -p issue-map@latest issue-map-build out.html` | 静的ファイルを指定したパスへ |
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
35
|
+
- repo は `gh` が cwd の git から推測するので、指定は不要です。
|
|
36
|
+
- `ISSUE_MAP_PORT` で port を固定できます。固定は厳密で、埋まっていれば黙って移らず失敗します。
|
|
37
|
+
- `ISSUE_MAP_OPEN=0` でタブを開きません。
|
|
38
|
+
- 静的ファイルは古くなります。いまの状態を見たいときは server を使ってください。
|
|
39
|
+
- スクリプトが動かせない場所(厳しい CSP、一部のプレビュー)では、空白ではなくチケットの
|
|
40
|
+
プレーンな一覧にフォールバックします。
|
|
41
|
+
- `@latest` は npm 上の最新版です。固定するなら `bunx issue-map@0.2.0`。
|
|
61
42
|
|
|
62
|
-
|
|
43
|
+
## 前提条件
|
|
63
44
|
|
|
64
|
-
- `
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
そうでなければ、欠けたものが `{n}` のまま画面に出てしまい、そのマスに到達して初めて気づくことに
|
|
68
|
-
なります。
|
|
69
|
-
- 英語で単複を分けるキーは `{ one, other }` で書き、中国語と日本語は 1 本の文字列で構いません
|
|
70
|
-
(`Intl.PluralRules` はこれらの言語では `other` しか返しません)。
|
|
45
|
+
- **Bun**——`Bun.build`、`Bun.serve`、`Bun.file` を使っているので、Node では動きません。
|
|
46
|
+
- **`gh` CLI にログイン済み**で、対象 repo への読み取り権限があること。
|
|
47
|
+
- 対象 repo に GitHub を指す git remote があること。
|
|
71
48
|
|
|
72
|
-
|
|
73
|
-
`{ kind: 'waitChildren', count: 2 }` のような構造化された値で、グループ名も同じです。言葉になるのは
|
|
74
|
-
i18n の層です。スナップショットに文を保存していたら、言語を切り替えるたびに GitHub を取り直す
|
|
75
|
-
ことになります。
|
|
49
|
+
runtime 依存はありません。
|
|
76
50
|
|
|
77
|
-
|
|
78
|
-
あって、ページの一部ではありません。
|
|
51
|
+
## 言語
|
|
79
52
|
|
|
80
|
-
|
|
53
|
+
右上で切り替えます:英語(既定)、繁体字中国語、簡体字中国語、日本語。選んだ言語はブラウザに記憶
|
|
54
|
+
され、repo ごとではありません——言語は読む人の好みであって、プロジェクトの設定ではないからです。
|
|
81
55
|
|
|
82
|
-
|
|
83
|
-
動きません。
|
|
84
|
-
- **`gh` CLI にログイン済み**で、対象 repo への読み取り権限があること。
|
|
85
|
-
- 対象 repo に GitHub を指す git remote があること。
|
|
86
|
-
- runtime 依存はなし。devDependencies は型と lint/format のツールだけです。
|
|
56
|
+
CLI 側(生成メッセージ、エラー)は英語のみです。
|
|
87
57
|
|
|
88
58
|
## 設定
|
|
89
59
|
|
|
90
60
|
すべて既定値があり、何も設定しなくても動きます。既定値は `scripts/issue-map.ts` の `CONFIG` に
|
|
91
61
|
あります。
|
|
92
62
|
|
|
93
|
-
| 環境変数 | 既定 | 意味
|
|
94
|
-
| -------------------------- | --------------------------------- |
|
|
95
|
-
| `GH_REPO` | cwd の git から推測 | 別の repo を描くときに設定(`gh` 自身の変数。fork
|
|
96
|
-
| `ISSUE_MAP_PARENT_HEADING` | `Parent` |
|
|
97
|
-
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` |
|
|
98
|
-
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` |
|
|
99
|
-
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` |
|
|
100
|
-
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` | 人がやるもの。次の一手に実装コマンドを出さない
|
|
101
|
-
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 着手できるときにマップが促すコマンド
|
|
102
|
-
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | まだ評価が要るときにマップが促すコマンド
|
|
103
|
-
| `ISSUE_MAP_PORT` |
|
|
104
|
-
| `ISSUE_MAP_OPEN` | 有効 | `0`
|
|
105
|
-
|
|
106
|
-
とくに考えておくべきものが
|
|
107
|
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
|
|
63
|
+
| 環境変数 | 既定 | 意味 |
|
|
64
|
+
| -------------------------- | --------------------------------- | ---------------------------------------------------------- |
|
|
65
|
+
| `GH_REPO` | cwd の git から推測 | 別の repo を描くときに設定(`gh` 自身の変数。fork も同様) |
|
|
66
|
+
| `ISSUE_MAP_PARENT_HEADING` | `Parent` | サブチケットが本文で親を指す見出し |
|
|
67
|
+
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` | 未評価で、まだ誰にも渡せない |
|
|
68
|
+
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` | 評価済み・着手可 |
|
|
69
|
+
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` | 誰かが対応中(assignee がなくてもよい) |
|
|
70
|
+
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` | 人がやるもの。次の一手に実装コマンドを出さない |
|
|
71
|
+
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | 着手できるときにマップが促すコマンド |
|
|
72
|
+
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | まだ評価が要るときにマップが促すコマンド |
|
|
73
|
+
| `ISSUE_MAP_PORT` | OS が割り当てる空き port | server のポート |
|
|
74
|
+
| `ISSUE_MAP_OPEN` | 有効 | `0` にするとブラウザを開かない |
|
|
75
|
+
|
|
76
|
+
とくに考えておくべきものが 3 つ:
|
|
77
|
+
|
|
78
|
+
- **ラベルの語彙。** ready/unready の既定値は mattpocock/skills の 5 つの[標準 triage ラベル](https://github.com/mattpocock/skills/blob/main/skills/engineering/setup-matt-pocock-skills/triage-labels.md)
|
|
79
|
+
のうち 4 つです。対象 repo が別の名前を使っているなら差し替えてください。これらのラベルが 1 つも
|
|
80
|
+
現れないときは triage をゲートにしません。そうしないと全チケットが「未評価」になってしまいます
|
|
81
|
+
(`in-progress` はこのツール独自で、skill 側に「対応中」のラベルはありません)。
|
|
82
|
+
- **コマンド名。** `/implement` と `/triage` は向こうの [`implement`](https://github.com/mattpocock/skills/tree/main/skills/engineering/implement) と
|
|
83
|
+
[`triage`](https://github.com/mattpocock/skills/tree/main/skills/engineering/triage) skill です。対象 repo に実在するものを指すようにしてください。さもないと、
|
|
84
|
+
存在しないものを走らせろとマップが指示します。
|
|
85
|
+
- **クローズ済みの兄弟にはネイティブ sub-issue が要る。** マップが問い合わせるクローズ済みチケット
|
|
86
|
+
は、open なチケットがまだ指しているものだけで、子チケットはネイティブの sub-issue 関係から取り
|
|
87
|
+
ます。`## Parent` の本文慣例を使う repo ではグループ内の**クローズ済み**の子が出てこず、進捗が
|
|
88
|
+
実際より少なく見えます。チケットの Sub-issues で一度リンクし直せば戻ります。本文の慣例は残して
|
|
89
|
+
おいて構いません——ネイティブのほうが優先されます。
|
|
113
90
|
|
|
114
91
|
## よくある失敗
|
|
115
92
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- `open issue 超過 100 張,這支要改成分頁抓` — GraphQL の `first` の上限が 100 です。それ以上の
|
|
119
|
-
チケットに対応するには `issue-map.ts` の `query()` にページングを足す必要があります。これは設定
|
|
120
|
-
ではなくコードの変更です。
|
|
121
|
-
|
|
122
|
-
(CLI のメッセージは中国語なので、実際に出力される通りに引用しています。)
|
|
93
|
+
`gh api graphql failed: …` — `gh` にログインしていないか、cwd が対象 repo の git ツリーの中に
|
|
94
|
+
ありません。
|
|
123
95
|
|
|
124
96
|
## ファイル
|
|
125
97
|
|
|
126
|
-
| ファイル | 責務
|
|
127
|
-
| ---------------------------- |
|
|
128
|
-
| `scripts/issue-map.ts` |
|
|
129
|
-
| `scripts/issue-map-model.ts` |
|
|
130
|
-
| `scripts/issue-map-i18n.ts` | 4
|
|
131
|
-
| `scripts/issue-map-page.ts` | ブラウザ側のコード。ビルド時に HTML へバンドルされる
|
|
132
|
-
| `scripts/issue-map.html` | テンプレート。2
|
|
133
|
-
| `scripts/issue-map-serve.ts` | ローカル server。リクエストごとに取り直す
|
|
134
|
-
| `scripts/mutate.ts` | ミューテーションテスト:1
|
|
98
|
+
| ファイル | 責務 |
|
|
99
|
+
| ---------------------------- | ---------------------------------------------------------------------- |
|
|
100
|
+
| `scripts/issue-map.ts` | スナップショット取得、状態と次の一手の導出、HTML 生成。設定は `CONFIG` |
|
|
101
|
+
| `scripts/issue-map-model.ts` | 純粋なデータモデル:グルーピング、クリティカルパス、レイアウト |
|
|
102
|
+
| `scripts/issue-map-i18n.ts` | 4 言語の文言と引き当て |
|
|
103
|
+
| `scripts/issue-map-page.ts` | ブラウザ側のコード。ビルド時に HTML へバンドルされる |
|
|
104
|
+
| `scripts/issue-map.html` | テンプレート。2 つのプレースホルダが埋められる |
|
|
105
|
+
| `scripts/issue-map-serve.ts` | ローカル server。リクエストごとに取り直す |
|
|
106
|
+
| `scripts/mutate.ts` | ミューテーションテスト:1 行を壊してテストが赤くなるか見る |
|
|
135
107
|
|
|
136
108
|
## この repo で開発する
|
|
137
109
|
|
|
138
110
|
```bash
|
|
139
111
|
bun install
|
|
140
|
-
bun run issue-map:serve # --watch
|
|
112
|
+
bun run issue-map:serve # --watch。ブラウザは開かない(保存のたびにタブが増えるため)
|
|
141
113
|
bun run issue-map # dist/issue-map.html を生成するだけ
|
|
142
114
|
bun run check # lint + format:check + typecheck
|
|
143
|
-
bun test #
|
|
115
|
+
bun test # 純粋なモデル層
|
|
144
116
|
```
|
|
145
117
|
|
|
146
118
|
この repo 自体にはまだ issue がないので、`GH_REPO=<owner>/<repo>` でチケットのある repo を指さない
|
|
147
119
|
と何も描けません。
|
|
148
120
|
|
|
149
|
-
`tests/`
|
|
150
|
-
|
|
151
|
-
|
|
121
|
+
**テスト。** `tests/` が守るのは「マップが嘘をつく」「読めなくなる」ことだけで、見た目(色・形・
|
|
122
|
+
間隔)は意図的に検証しません。ガードテストを足すときは逆検証で——そのテストが防ぐと主張する欠陥を
|
|
123
|
+
製品コードに戻し、赤くなることを確かめます:
|
|
152
124
|
|
|
153
125
|
```bash
|
|
154
126
|
bun run mutate scripts/issue-map-model.ts tests/issue-map-layout.test.ts
|
|
155
127
|
```
|
|
156
128
|
|
|
157
|
-
|
|
129
|
+
**`scripts/issue-map-i18n.ts` を触るとき。** `EN` が原稿であり、キーの定義場所です。3 つの翻訳の型
|
|
130
|
+
はそこから導かれるので、キーや `{n}` の差し込み名が 1 つ欠けると `bun run typecheck` が赤くなります。
|
|
131
|
+
英語で単複を分けるキーは `{ one, other }`、中国語と日本語は 1 本の文字列で構いません。モデル側は文
|
|
132
|
+
を組み立てません——`nextStep` は `{ kind: 'waitChildren', count: 2 }` のような構造化された値で、
|
|
133
|
+
言葉になるのはここです。
|
|
134
|
+
|
|
135
|
+
## 2 つの設計判断
|
|
158
136
|
|
|
159
|
-
- **このページでは状態を変えられません。** GitHub
|
|
160
|
-
|
|
161
|
-
-
|
|
162
|
-
|
|
163
|
-
せん。機械的に短縮したものは読めませんでした。
|
|
137
|
+
- **このページでは状態を変えられません。** GitHub に書き戻すボタンはありません。状態の正は 1 つだけ
|
|
138
|
+
で、入口が増えれば必ず食い違います。
|
|
139
|
+
- **短縮名の欄は設けません。** 駅にはタイトルの先頭数文字を出します。本文に短縮名を手で書くと
|
|
140
|
+
タイトルの 2 つ目の正になり、タイトルを直しても追随しません。完全なタイトルは下の一覧にあります。
|
package/README.md
CHANGED
|
@@ -5,157 +5,137 @@
|
|
|
5
5
|
Draws the blocking relationships between your GitHub Issues as a one-page dev map: **which issues
|
|
6
6
|
can be picked up now, which are waiting on what, and where the critical path runs.**
|
|
7
7
|
|
|
8
|
-
GitHub Issues stays the source of truth. This page is only a snapshot — you cannot change status on
|
|
9
|
-
it, so no second source of truth grows out of it.
|
|
10
|
-
|
|
11
|
-
## Why this exists
|
|
12
|
-
|
|
13
|
-
It started with [mattpocock/skills](https://github.com/mattpocock/skills). Once the team adopted
|
|
14
|
-
that way of working — write the workflow as a skill, let the agent run it — filing an issue got
|
|
15
|
-
cheap: think of something, open a ticket, hand it to a skill. So the issue count grew fast. That is
|
|
16
|
-
the process working, not a problem.
|
|
17
|
-
|
|
18
|
-
The problem is the next step. An agent takes one issue per round, so what you actually decide each
|
|
19
|
-
round is **which one**. That answer is in no single issue; it lives between them: who blocks whom,
|
|
20
|
-
how many sub-issues a parent is still waiting on, how long the longest chain is. GitHub Issues only
|
|
21
|
-
ever shows you one issue at a time, so assembling that picture means opening them one by one — and
|
|
22
|
-
doing it again tomorrow.
|
|
23
|
-
|
|
24
|
-
This page is that picture.
|
|
25
|
-
|
|
26
|
-
## Usage
|
|
27
|
-
|
|
28
|
-
Run it inside **the repo you want to look at**:
|
|
29
|
-
|
|
30
8
|
```bash
|
|
31
9
|
bunx issue-map@latest
|
|
32
10
|
```
|
|
33
11
|
|
|
34
|
-
|
|
12
|
+
Run it inside the repo you want to look at. A browser tab opens; every refresh re-fetches from
|
|
13
|
+
GitHub. GitHub Issues stays the source of truth — this page is a snapshot and cannot change status.
|
|
35
14
|
|
|
36
|
-
|
|
37
|
-
so what you see is the current state. The repo is what `gh` infers from the git remote in your cwd —
|
|
38
|
-
nothing to fill in.
|
|
15
|
+
## Why
|
|
39
16
|
|
|
40
|
-
|
|
17
|
+
An agent takes one issue per round, so what you decide each round is **which one**. That answer is
|
|
18
|
+
in no single issue; it lives between them — who blocks whom, how many sub-issues a parent is still
|
|
19
|
+
waiting on, how long the longest chain is. GitHub shows you one issue at a time. This page shows
|
|
20
|
+
the picture.
|
|
41
21
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
bunx -p issue-map@latest issue-map-build # writes dist/issue-map.html
|
|
47
|
-
bunx -p issue-map@latest issue-map-build out.html
|
|
48
|
-
```
|
|
22
|
+
It is built around [mattpocock/skills](https://github.com/mattpocock/skills) — write the workflow
|
|
23
|
+
as a skill, let the agent run it — which is where the default labels and commands come from.
|
|
49
24
|
|
|
50
|
-
|
|
25
|
+
## Usage
|
|
51
26
|
|
|
52
|
-
|
|
27
|
+
| Command | What you get |
|
|
28
|
+
| --------------------------------------------------- | ------------------------------------ |
|
|
29
|
+
| `bunx issue-map@latest` | Server on a free port, browser opens |
|
|
30
|
+
| `bunx -p issue-map@latest issue-map-build` | Static file at `dist/issue-map.html` |
|
|
31
|
+
| `bunx -p issue-map@latest issue-map-build out.html` | Static file at a path you name |
|
|
53
32
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
33
|
+
- The repo comes from `gh` reading the git remote in your cwd — nothing to fill in.
|
|
34
|
+
- `ISSUE_MAP_PORT` pins the port. Pinned is strict: it fails rather than moving if taken.
|
|
35
|
+
- `ISSUE_MAP_OPEN=0` stops the browser tab.
|
|
36
|
+
- A static file goes stale. Use the server when you need the current state.
|
|
37
|
+
- Where scripts cannot run (a strict CSP, some preview panes) the file falls back to a plain
|
|
38
|
+
listing of the issues rather than a blank page.
|
|
39
|
+
- `@latest` takes the newest version on npm; pin one with `bunx issue-map@0.2.0`.
|
|
59
40
|
|
|
60
|
-
|
|
41
|
+
## Requirements
|
|
61
42
|
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
and it will not compile. Otherwise the missing one prints as a literal `{n}` on the page, and
|
|
66
|
-
you would only find it by reaching that exact cell.
|
|
67
|
-
- Keys that need English plurals are written `{ one, other }`; Chinese and Japanese take a single
|
|
68
|
-
string (`Intl.PluralRules` only has `other` for those languages).
|
|
43
|
+
- **Bun** — these scripts use `Bun.build`, `Bun.serve` and `Bun.file`; Node will not run them.
|
|
44
|
+
- **`gh` CLI, logged in**, with read access to the target repo.
|
|
45
|
+
- A git remote pointing at GitHub.
|
|
69
46
|
|
|
70
|
-
|
|
71
|
-
`{ kind: 'waitChildren', count: 2 }`, and so are group names. The words are assembled in the i18n
|
|
72
|
-
layer. If the snapshot stored sentences, switching language would mean re-fetching from GitHub.
|
|
47
|
+
No runtime dependencies.
|
|
73
48
|
|
|
74
|
-
|
|
75
|
-
develops this tool, not part of the page.
|
|
49
|
+
## Language
|
|
76
50
|
|
|
77
|
-
|
|
51
|
+
Switch in the top right: English (default), 繁體中文, 简体中文, 日本語. The choice is remembered in
|
|
52
|
+
the browser and is not tied to a repo — language is the reader's preference, not a project setting.
|
|
78
53
|
|
|
79
|
-
|
|
80
|
-
not run them.
|
|
81
|
-
- **`gh` CLI, logged in**, with read access to the target repo.
|
|
82
|
-
- The target repo has a git remote pointing at GitHub.
|
|
83
|
-
- No runtime dependencies; devDependencies are only types and lint/format tools.
|
|
54
|
+
CLI output (build messages, errors) is English only.
|
|
84
55
|
|
|
85
56
|
## Configuration
|
|
86
57
|
|
|
87
58
|
Everything has a default — it runs with nothing set. The defaults live in `CONFIG` in
|
|
88
59
|
`scripts/issue-map.ts`.
|
|
89
60
|
|
|
90
|
-
| Environment variable | Default | Meaning
|
|
91
|
-
| -------------------------- | --------------------------------- |
|
|
92
|
-
| `GH_REPO` | inferred from the git in cwd |
|
|
93
|
-
| `ISSUE_MAP_PARENT_HEADING` | `Parent` |
|
|
94
|
-
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` |
|
|
95
|
-
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` |
|
|
96
|
-
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` |
|
|
97
|
-
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` |
|
|
98
|
-
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` |
|
|
99
|
-
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` |
|
|
100
|
-
| `ISSUE_MAP_PORT` |
|
|
101
|
-
| `ISSUE_MAP_OPEN` | on |
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- **Label vocabulary
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
61
|
+
| Environment variable | Default | Meaning |
|
|
62
|
+
| -------------------------- | --------------------------------- | ------------------------------------------------------------------------------ |
|
|
63
|
+
| `GH_REPO` | inferred from the git in cwd | Map another repo (`gh`'s own variable; forks and multiple remotes are its job) |
|
|
64
|
+
| `ISSUE_MAP_PARENT_HEADING` | `Parent` | Body heading under which a sub-issue points at its parent |
|
|
65
|
+
| `ISSUE_MAP_LABELS_UNREADY` | `needs-triage,needs-info` | Not assessed yet, cannot be handed to anyone |
|
|
66
|
+
| `ISSUE_MAP_LABELS_READY` | `ready-for-agent,ready-for-human` | Assessed and ready to work on |
|
|
67
|
+
| `ISSUE_MAP_LABELS_ACTIVE` | `in-progress` | Somebody is on it, with or without an assignee |
|
|
68
|
+
| `ISSUE_MAP_LABELS_HUMAN` | `ready-for-human` | Needs a person, so the next step is not an implementation command |
|
|
69
|
+
| `ISSUE_MAP_CMD_IMPLEMENT` | `/implement` | Command the map suggests when an issue is ready |
|
|
70
|
+
| `ISSUE_MAP_CMD_TRIAGE` | `/triage` | Command the map suggests when it still needs assessing |
|
|
71
|
+
| `ISSUE_MAP_PORT` | an OS-assigned free port | Port for the server |
|
|
72
|
+
| `ISSUE_MAP_OPEN` | on | `0` stops the browser tab |
|
|
73
|
+
|
|
74
|
+
Three worth knowing:
|
|
75
|
+
|
|
76
|
+
- **Label vocabulary.** The ready/unready defaults are four of the five canonical
|
|
77
|
+
[triage labels](https://github.com/mattpocock/skills/blob/main/skills/engineering/setup-matt-pocock-skills/triage-labels.md)
|
|
78
|
+
from mattpocock/skills. If the target repo uses different names, set them. When none of these
|
|
79
|
+
labels appear at all, triage stops being a gate — otherwise every issue would come out as "needs
|
|
80
|
+
triage". (`in-progress` is this tool's own; the skills have no "somebody is on it" label.)
|
|
81
|
+
- **Command names.** `/implement` and `/triage` are the
|
|
82
|
+
[`implement`](https://github.com/mattpocock/skills/tree/main/skills/engineering/implement) and
|
|
83
|
+
[`triage`](https://github.com/mattpocock/skills/tree/main/skills/engineering/triage) skills. Point
|
|
84
|
+
them at something that exists in the target repo, or the map tells people to run what isn't there.
|
|
85
|
+
- **Closed siblings need native sub-issues.** The map asks GitHub only for the closed issues an
|
|
86
|
+
open one still points at, and children come from the native sub-issue relation. With the
|
|
87
|
+
`## Parent` body convention a group's _closed_ children never appear, so its progress looks
|
|
88
|
+
smaller than it is. Linking them once in the issue's Sub-issues panel brings them back; the body
|
|
89
|
+
convention can stay, the native relation wins anyway.
|
|
111
90
|
|
|
112
91
|
## When it fails
|
|
113
92
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
- `open issue 超過 100 張,這支要改成分頁抓` — 100 is the hard cap on GraphQL's `first`. Supporting
|
|
117
|
-
more issues means adding pagination to `query()` in `issue-map.ts`; that is a code change, not
|
|
118
|
-
configuration.
|
|
119
|
-
|
|
120
|
-
(CLI messages are in Chinese, so they are quoted here as they actually appear.)
|
|
93
|
+
`gh api graphql failed: …` — `gh` is not logged in, or your cwd is not inside the target repo's git
|
|
94
|
+
tree.
|
|
121
95
|
|
|
122
96
|
## Files
|
|
123
97
|
|
|
124
|
-
| File | Responsibility
|
|
125
|
-
| ---------------------------- |
|
|
126
|
-
| `scripts/issue-map.ts` |
|
|
127
|
-
| `scripts/issue-map-model.ts` | Pure data model: grouping, critical path. Shared by both sides
|
|
128
|
-
| `scripts/issue-map-i18n.ts` | Strings for the four languages, plus the lookup
|
|
129
|
-
| `scripts/issue-map-page.ts` | Browser-side code, bundled into the HTML at build time
|
|
130
|
-
| `scripts/issue-map.html` | The template. Two placeholder blocks
|
|
131
|
-
| `scripts/issue-map-serve.ts` | Local server, re-fetches on every request
|
|
132
|
-
| `scripts/mutate.ts` | Mutation testing: break one line
|
|
98
|
+
| File | Responsibility |
|
|
99
|
+
| ---------------------------- | ------------------------------------------------------------------------ |
|
|
100
|
+
| `scripts/issue-map.ts` | Snapshot, status and next step, produces the HTML. Knobs in its `CONFIG` |
|
|
101
|
+
| `scripts/issue-map-model.ts` | Pure data model: grouping, critical path, layout. Shared by both sides |
|
|
102
|
+
| `scripts/issue-map-i18n.ts` | Strings for the four languages, plus the lookup |
|
|
103
|
+
| `scripts/issue-map-page.ts` | Browser-side code, bundled into the HTML at build time |
|
|
104
|
+
| `scripts/issue-map.html` | The template. Two placeholder blocks get filled in |
|
|
105
|
+
| `scripts/issue-map-serve.ts` | Local server, re-fetches on every request |
|
|
106
|
+
| `scripts/mutate.ts` | Mutation testing: break one line, see whether a test goes red |
|
|
133
107
|
|
|
134
108
|
## Developing in this repo
|
|
135
109
|
|
|
136
110
|
```bash
|
|
137
111
|
bun install
|
|
138
|
-
bun run issue-map:serve # --watch
|
|
112
|
+
bun run issue-map:serve # --watch; no browser tab (you would get one per save)
|
|
139
113
|
bun run issue-map # build the file only, to dist/issue-map.html
|
|
140
114
|
bun run check # lint + format:check + typecheck
|
|
141
|
-
bun test # the pure model layer
|
|
115
|
+
bun test # the pure model layer
|
|
142
116
|
```
|
|
143
117
|
|
|
144
118
|
This repo has no issues of its own yet, so point `GH_REPO=<owner>/<repo>` at one that has tickets to
|
|
145
119
|
get anything drawn.
|
|
146
120
|
|
|
147
|
-
`tests/` only guards
|
|
148
|
-
spacing) are deliberately not asserted. A new guard test has to be verified in reverse — put
|
|
149
|
-
defect it claims to catch back into the product code and confirm it goes red:
|
|
121
|
+
**Tests.** `tests/` only guards what would make the map lie or make it unreadable; looks (colour,
|
|
122
|
+
shape, spacing) are deliberately not asserted. A new guard test has to be verified in reverse — put
|
|
123
|
+
the defect it claims to catch back into the product code and confirm it goes red:
|
|
150
124
|
|
|
151
125
|
```bash
|
|
152
126
|
bun run mutate scripts/issue-map-model.ts tests/issue-map-layout.test.ts
|
|
153
127
|
```
|
|
154
128
|
|
|
155
|
-
|
|
129
|
+
**Adding to `scripts/issue-map-i18n.ts`.** `EN` is the original and defines the keys; the three
|
|
130
|
+
translations are typed from it, so a missing key or a missing `{n}` placeholder turns
|
|
131
|
+
`bun run typecheck` red. Keys needing English plurals are written `{ one, other }`; Chinese and
|
|
132
|
+
Japanese take a single string. The model never builds sentences — `nextStep` is a structured value
|
|
133
|
+
like `{ kind: 'waitChildren', count: 2 }`, assembled into words here.
|
|
134
|
+
|
|
135
|
+
## Two design decisions
|
|
156
136
|
|
|
157
|
-
- **
|
|
158
|
-
|
|
159
|
-
- **
|
|
160
|
-
short
|
|
161
|
-
|
|
137
|
+
- **The page cannot change status.** No button writes back to GitHub. Status has exactly one source
|
|
138
|
+
of truth, and a second entry point makes them disagree.
|
|
139
|
+
- **No separate short name.** Stations are labelled with the first few characters of the title.
|
|
140
|
+
A hand-maintained short name in the issue body would be a second source of truth — editing the
|
|
141
|
+
title would not update it. The list below carries the full titles.
|