@tyhld/conductor 0.12.90 → 0.12.91
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/build-prompt.js
CHANGED
|
@@ -132,7 +132,10 @@ export function buildCraftsmanPrompt(input) {
|
|
|
132
132
|
// ★合流の作法は職人の鉄則7と同じ形にする(便 4a5bbb9f)。片方だけ古いと、
|
|
133
133
|
// 職人は毎便読む鉄則と、ここで渡される文の【両方】を受け取って食い違う。
|
|
134
134
|
// ★2026-09-17(便 01bd516b)に保護の有無で分けた形へ直した(鉄則7 と同じ中身)。
|
|
135
|
+
// ★push は上流の設定を書かない形(鉄則7-⓪・便 ec974d68)。`-u` は `.git/config` へ書き込むので、
|
|
136
|
+
// 囲いがそこを塞いでいる機体では push が成功しても「上流の設定を書けない」で止まる。
|
|
135
137
|
'・テストが緑になってから push → プルリクエストを作成 → 合流する。合流の仕方は職人の鉄則7のとおり:',
|
|
138
|
+
' push は `git push origin <作業ブランチ名>`(★`-u` を付けない=上流の設定を書かない形)。',
|
|
136
139
|
' 保護あり(必須の検査がある)… `gh pr merge <番号> --auto --merge --delete-branch` で予約する。',
|
|
137
140
|
' 保護なし … ★`--auto` を先に打たない。`gh pr checks <番号>` で CI(`/actions/runs/` の行)がすべて pass なのを',
|
|
138
141
|
' 確かめてから `gh pr merge <番号> --merge --delete-branch`。Vercel だけの緑は CI の緑と数えない。',
|
package/package.json
CHANGED
|
@@ -136,10 +136,20 @@ def read_report_text(command_id, env=None):
|
|
|
136
136
|
# 【★本文の言葉だけは別】下書きの印(作成中・TODO など)は関門だけの決まり。
|
|
137
137
|
# 報告の中身の言葉で完了を判定しない(えふさん確定 2026-09-23)ので、中継からは手が届かない
|
|
138
138
|
# ところ(この下の DRAFT_MARKERS)に置く。正本はここ1か所。
|
|
139
|
+
#
|
|
140
|
+
# 【★印を探す場所は本文の「頭」と evidence だけ(便 ec974d68)】
|
|
141
|
+
# 以前は本文の全体を見ていた。そのため【関門そのものを説明した報告】が、説明の中に出てくる
|
|
142
|
+
# 印の語(「作成中」など)に当たって差し戻された(実地・便 461be339=言い回しを替えて通した=
|
|
143
|
+
# 3手番の無駄)。仕上げ前の報告では、印は「頭(題の行とその次の段落)」か evidence に現れる
|
|
144
|
+
# (実地 915694ac はその形)。だから見る場所を頭と evidence に絞る=塞ぎたい物は塞いだまま、
|
|
145
|
+
# 説明での誤当たりだけが消える。★印の一覧(下)は1語も減らさない。
|
|
139
146
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
140
147
|
#: 「最終版で差し替える前」の印。★決まった字面の一覧だけを見る(文意は読まない)。
|
|
141
148
|
DRAFT_MARKERS = ('作成中', '下書き', '差し替える', 'あとで書く', '(未記入)', '(未記入)', 'TODO', 'TBD')
|
|
142
149
|
|
|
150
|
+
#: 見出しの行(`#` 〜 `######`)。★本文の「頭」を切り出すためだけに使う。
|
|
151
|
+
_HEADING_RE = re.compile(r'^ {0,3}#{1,6}\s')
|
|
152
|
+
|
|
143
153
|
#: 形の決まりの正本(★この python と同じフォルダに配られる)。
|
|
144
154
|
SHAPE_SPEC_NAME = 'report-shape.json'
|
|
145
155
|
|
|
@@ -262,6 +272,36 @@ def report_body(text):
|
|
|
262
272
|
return _parse_report(text)[2]
|
|
263
273
|
|
|
264
274
|
|
|
275
|
+
def _body_head(body):
|
|
276
|
+
"""本文の「頭」の行だけを並べる=最初の見出しの行と、その直後の1段落。★純粋関数。
|
|
277
|
+
|
|
278
|
+
見出しが無い本文では、最初の1段落だけ(頭は段落から始まっている)。
|
|
279
|
+
"""
|
|
280
|
+
lines = ('' if body is None else str(body)).split('\n')
|
|
281
|
+
i = 0
|
|
282
|
+
while i < len(lines) and lines[i].strip() == '':
|
|
283
|
+
i += 1
|
|
284
|
+
out = []
|
|
285
|
+
if i < len(lines) and _HEADING_RE.match(lines[i]):
|
|
286
|
+
out.append(lines[i])
|
|
287
|
+
i += 1
|
|
288
|
+
while i < len(lines) and lines[i].strip() == '':
|
|
289
|
+
i += 1
|
|
290
|
+
while i < len(lines) and lines[i].strip() != '':
|
|
291
|
+
out.append(lines[i])
|
|
292
|
+
i += 1
|
|
293
|
+
return out
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def report_draft_places(text):
|
|
297
|
+
"""下書きの印を探す場所だけを並べる(★本文の全体は見ない・便 ec974d68)。★純粋関数。
|
|
298
|
+
|
|
299
|
+
① 囲みのすぐ下の最初の見出しの行 ② その直後の1段落 ③ evidence の各行。
|
|
300
|
+
"""
|
|
301
|
+
_, evidence, body = _parse_report(text)
|
|
302
|
+
return [str(e) for e in evidence] + _body_head(body)
|
|
303
|
+
|
|
304
|
+
|
|
265
305
|
def report_residue(text, spec=None):
|
|
266
306
|
"""報告が「無い・形が整っていない・下書きのまま」なら理由、出来上がっていれば None。"""
|
|
267
307
|
if text is None or not text.strip():
|
|
@@ -270,9 +310,11 @@ def report_residue(text, spec=None):
|
|
|
270
310
|
if missing:
|
|
271
311
|
return ('報告の形が整っていない(足りない: '
|
|
272
312
|
+ '・'.join(_SHAPE_JA.get(k, k) for k in missing) + ')')
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
313
|
+
for place in report_draft_places(text):
|
|
314
|
+
hit = next((m for m in DRAFT_MARKERS if m in place), None)
|
|
315
|
+
if hit is not None:
|
|
316
|
+
return ('報告が下書きのまま(報告の頭か evidence に「'
|
|
317
|
+
+ hit + '」が残っている)')
|
|
276
318
|
return None
|
|
277
319
|
|
|
278
320
|
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
【ここで固定すること】
|
|
12
12
|
(A) 報告の判定 … 無い・空・囲みが無い・欄が足りない・outcome が変・evidence 0件・
|
|
13
13
|
本文が空・下書きの印が残っている → 残り。最終版 → 残り無し
|
|
14
|
+
(A2) ★下書きの印を見る場所(便 ec974d68) … 囲みのすぐ下の最初の見出しの行・その直後の
|
|
15
|
+
1段落・evidence の各行だけ。実地 915694ac の下書きは止まり、関門そのものを説明した
|
|
16
|
+
整った報告は止まらない(本文の全体を見ていたため誤って差し戻していた=便 461be339)
|
|
14
17
|
(B) 背景の待ちの数え方 … 始まった印(backgroundTaskId)と知らせ(task-notification)の差。
|
|
15
18
|
★実地 915694ac・47bdfe00 と同じ形の記録で確かめる
|
|
16
19
|
(C) PR の判定 … 開いたまま/合流の予約中 → 残り。空・合流済み → 残り無し。
|
|
@@ -23,6 +26,8 @@
|
|
|
23
26
|
★空振り確認(隔離した worktree の中だけ):
|
|
24
27
|
・finish_gate.decide の上限の判定(`counts[k] < cap`)を外す → (D) が落ちる
|
|
25
28
|
・report_residue の下書きの印の判定を外す → (A) が落ちる
|
|
29
|
+
・report_draft_places を空の一覧にする(どこも見ない) → (A2) の「実地の下書きを止める」が落ちる
|
|
30
|
+
・report_draft_places を本文の全体に戻す → (A2) の「説明した報告を止めない」が落ちる
|
|
26
31
|
・stop_hook.main から関門の呼び出しを外す → (G) の「止める」が落ちる
|
|
27
32
|
"""
|
|
28
33
|
import json
|
|
@@ -58,10 +63,13 @@ ENV = {'HOME': SANDBOX, 'XDG_STATE_HOME': os.path.join(SANDBOX, 'state'),
|
|
|
58
63
|
JOB = '7aa63a97-57e7-4c42-8b95-f3da87d88829'
|
|
59
64
|
|
|
60
65
|
|
|
61
|
-
def report_text(outcome='pushed', body='やりました。', header=True, evidence=True
|
|
66
|
+
def report_text(outcome='pushed', body='やりました。', header=True, evidence=True,
|
|
67
|
+
evidence_lines=None):
|
|
62
68
|
head = ['---', f'instruction_id: {JOB}', 'site: demo', f'outcome: {outcome}',
|
|
63
69
|
'created_at: 2026-10-03T09:00:00+09:00', 'evidence:']
|
|
64
|
-
if
|
|
70
|
+
if evidence_lines is not None:
|
|
71
|
+
head.extend(f' - {line}' for line in evidence_lines)
|
|
72
|
+
elif evidence:
|
|
65
73
|
head.append(' - PR https://github.com/tyhld/conductor/pull/999')
|
|
66
74
|
head.append('---')
|
|
67
75
|
return ('\n'.join(head) + '\n\n' + body) if header else body
|
|
@@ -124,6 +132,89 @@ truthy('実地の下書き → 残り', finish_gate.report_residue(report_text(b
|
|
|
124
132
|
for m in ('作成中', '下書き', '差し替える', 'あとで書く', '(未記入)', 'TODO', 'TBD'):
|
|
125
133
|
truthy(f'下書きの印「{m}」→ 残り', finish_gate.report_residue(report_text(body=f'あ{m}い')))
|
|
126
134
|
|
|
135
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
136
|
+
print('\n--- ★(A2) 下書きの印を見る場所(頭と evidence だけ・便 ec974d68) ---')
|
|
137
|
+
# 【なぜ要るか(実地・便 461be339)】本文の全体を見ていたので、★関門そのものを説明した
|
|
138
|
+
# 整った報告が、説明の中の語に当たって差し戻された(言い回しを替えて通した=3手番の無駄)。
|
|
139
|
+
# 見る場所を「囲みのすぐ下の最初の見出しの行・その直後の1段落・evidence の各行」に絞る。
|
|
140
|
+
# ★印の一覧(DRAFT_MARKERS)は1語も減らしていない=塞ぎたい物は塞いだまま。
|
|
141
|
+
# 【書き方】report-shape.json の cases と同じ流儀(name / text / 期待)で並べる。
|
|
142
|
+
# ★ただし言葉の決まりは正本(report-shape.json)に置かない(中継から手が届かない形を保つ)。
|
|
143
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
144
|
+
#: 実地 915694ac の報告の頭(囲みの evidence の行まで含めて、当時の実物のまま)。
|
|
145
|
+
REAL_DRAFT_EVIDENCE = '(CI・合流・公開版は下の「合流と公開」節に実物を書く)'
|
|
146
|
+
|
|
147
|
+
#: 関門を説明した「整った報告」の本文(★この便の報告そのものに近い形)。
|
|
148
|
+
GATE_EXPLAINED = '\n'.join([
|
|
149
|
+
'# 結論',
|
|
150
|
+
'',
|
|
151
|
+
'便の終わりの関門が、仕上げ前の印を見る場所を狭めました。',
|
|
152
|
+
'',
|
|
153
|
+
'## 狭めた後に見る場所',
|
|
154
|
+
'',
|
|
155
|
+
'囲みのすぐ下の最初の見出しの行と、その直後の1段落、evidence の各行だけです。',
|
|
156
|
+
'以前は本文の全体を見ていたので、印の語(作成中・下書き・差し替える・あとで書く・TODO・TBD)を',
|
|
157
|
+
'この表のように並べて説明した報告が、そのまま差し戻されました。',
|
|
158
|
+
])
|
|
159
|
+
|
|
160
|
+
DRAFT_CASES = [
|
|
161
|
+
{
|
|
162
|
+
'name': '★実地の下書き(見出しに印・次の行にも印)→ 止める',
|
|
163
|
+
'text': report_text(body=REAL_DRAFT, evidence=True),
|
|
164
|
+
'draft': True,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
'name': '★関門を説明した整った報告 → 止めない(これが直した本体)',
|
|
168
|
+
'text': report_text(body=GATE_EXPLAINED),
|
|
169
|
+
'draft': False,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
'name': '印が evidence の行に在る → 止める',
|
|
173
|
+
'text': report_text(body='# 結論\n\nやりました。',
|
|
174
|
+
evidence_lines=['CI の結果はあとで書く']),
|
|
175
|
+
'draft': True,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
'name': '印が見出しの直後の1段落に在る → 止める',
|
|
179
|
+
'text': report_text(body='# 結論\n\nここは作成中です。'),
|
|
180
|
+
'draft': True,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
'name': '見出しが無く最初の段落に印 → 止める(頭は段落から始まる)',
|
|
184
|
+
'text': report_text(body='まだ下書きです。\n\n# 結論\n\nやりました。'),
|
|
185
|
+
'draft': True,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
'name': '見出しの前に空行が在っても頭として見る → 止める',
|
|
189
|
+
'text': report_text(body='\n\n# 報告(作成中)\n\nやりました。'),
|
|
190
|
+
'draft': True,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
'name': '★頭より後ろの節の中の語は見ない → 止めない(狭めた結果・正直に書く)',
|
|
194
|
+
'text': report_text(body='# 結論\n\nやりました。\n\n## 補足\n\n印の語は TODO などです。'),
|
|
195
|
+
'draft': False,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
'name': '頭も evidence も印が無い最終版 → 止めない',
|
|
199
|
+
'text': report_text(body='# 結論\n\nやりました。'),
|
|
200
|
+
'draft': False,
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
for case in DRAFT_CASES:
|
|
205
|
+
check(case['name'][:64], finish_gate.report_residue(case['text']) is not None, case['draft'])
|
|
206
|
+
|
|
207
|
+
# 実地 915694ac の evidence の行は、狭めた後の「見る場所」に入っている(=見落とさない)。
|
|
208
|
+
truthy('実地 915694ac の evidence の行が見る場所に入る',
|
|
209
|
+
REAL_DRAFT_EVIDENCE in finish_gate.report_draft_places(
|
|
210
|
+
report_text(body=REAL_DRAFT, evidence_lines=[REAL_DRAFT_EVIDENCE])))
|
|
211
|
+
# ★見る場所は3種類だけ=頭より後ろの行は1行も入らない。
|
|
212
|
+
places = finish_gate.report_draft_places(
|
|
213
|
+
report_text(body='# 結論\n\nやりました。\n\n## 補足\n\nここは TODO と書いてある。'))
|
|
214
|
+
check('見る場所は evidence と頭だけ(後ろの節は入らない)',
|
|
215
|
+
any('TODO' in p for p in places), False)
|
|
216
|
+
check('見る場所に見出しの行が入る', any(p.startswith('# 結論') for p in places), True)
|
|
217
|
+
|
|
127
218
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
128
219
|
print('\n=== (B) 背景の待ちの数え方(★実地と同じ形の記録) ===')
|
|
129
220
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -29,7 +29,8 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
29
29
|
4. **壁に当たったら止まる** — サンドボックス制約・保護されたパスに当たったら回避せず中断して報告する(★通信で塞がれたときの読み方は鉄則12)。
|
|
30
30
|
5. **エージェント設定に書き込まない** — `.mcp.json`、`.claude/` 配下、hooks 等のエージェント設定パスには書き込まない。
|
|
31
31
|
6. **本番に触らない** — 本番DB・deploy・secret に触らない。SQL/DDL は作って提示のみ(適用は人間)。
|
|
32
|
-
7. **便の終点はマージまで(★保護を迂回しない)** — push → PR作成 →
|
|
32
|
+
7. **便の終点はマージまで(★保護を迂回しない)** — push → PR作成 → 合流する。★push は**上流の設定を書かない形**で打つ(⓪)。★合流の仕方は、そのリポの合流先に**保護(必須の検査)**があるかで分ける。リポの名前は覚えなくてよい。
|
|
33
|
+
- ⓪ **上流の設定を書かない形で push する**=`git push origin <作業ブランチ名>`。★`-u`(`--set-upstream`)を付けない。`-u` と `git checkout -b <枝> origin/main` は `.git/config` へ書き込むので、囲いがその書き込みを塞いでいるPCでは「上流の設定を書けない」で止まる(**push 自体は成功している**ので、打ち直すと食い違って見える=実測 便 2cb1adf6・ef8def38)。枝を切るときも同じで `git switch -c <枝> --no-track origin/main`(または `git branch --no-track <枝> origin/main` のあと `git switch <枝>`)。★これは回避の近道ではなく**どのPCでも同じに通る形**なので、塞がれていないPCでもこの形で打つ(上流の設定は職人の作業に要らない)。
|
|
33
34
|
- ① **保護があるかを読む。** 合流先は `gh pr view <番号> --json baseRefName -q .baseRefName`(ふつうは main)。`gh api 'repos/{owner}/{repo}/branches/<合流先>/protection/required_status_checks' --jq '.contexts | length'` が **1 以上の数を返したときだけ「保護あり」**。0・404(Branch not protected)・403・その他の失敗は、すべて**「保護なし」**として扱う。
|
|
34
35
|
- ② **保護あり** … `gh pr merge <番号> --auto --merge --delete-branch` で**合流を予約する**。必須の検査が緑になった後に GitHub が合流する(赤のままなら合流されない)。
|
|
35
36
|
- 「auto-merge が使えない」と断られたときは、`gh pr checks <番号>` で必須の検査が pass なのを確かめてから `gh pr merge <番号> --merge --delete-branch`。
|
|
@@ -163,7 +164,7 @@ description: 采配くんの便(プロンプト末尾に CONDUCTOR_JOB:<id>
|
|
|
163
164
|
- 通る例: `rm -r /tmp/claude-1000/作業名` / `rm -r node_modules/.tmp-作業名`(★`-f` を付けない・自分で作った物だけ)
|
|
164
165
|
- 止まる例: `rm -rf /tmp/claude-1000/作業名`(禁止の一覧)/ `rm -r "$DIR/x"`・`rm -r build/*`(番人)/ `rm -r .git`・`rm -r .claude/hooks`・`rm -r .tyhld`(番人=相対パスでも消せない)
|
|
165
166
|
- ★**探すだけの道具の「探す言葉」に `rm …` と書いても、もう止まらない**(便 915694ac で直した)。鉄則や台本を調べるときの `grep -rn 'rm -rf .git' skills`・`git grep -n 'rm -r' -- skills`・`rg 'rm -rf /' docs` は通る。★囲みの外に書いた `rm` は今までどおり測るので、`grep -rn 'x' docs; rm -rf .git` のように**後ろで消す形は止まる**。
|
|
166
|
-
- **作業場所が変数のままの `git push`**(`git -C "$DIR" push`・行き先のブランチを確かめられない形)→ 止まる。**リポの中で、ブランチを名指しして** `git push
|
|
167
|
+
- **作業場所が変数のままの `git push`**(`git -C "$DIR" push`・行き先のブランチを確かめられない形)→ 止まる。**リポの中で、ブランチを名指しして** `git push origin <作業ブランチ名>`(★`-u` は付けない=鉄則7-⓪。上流の設定を書くと、囲いが `.git/config` を塞いでいるPCで止まる)。
|
|
167
168
|
|
|
168
169
|
## 便の終え方
|
|
169
170
|
|