@galda/cli 0.10.71 → 0.10.72
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/app/index.html +35 -2
- package/engine/lib.mjs +14 -1
- package/engine/server.mjs +12 -1
- package/package.json +1 -1
package/app/index.html
CHANGED
|
@@ -2120,6 +2120,12 @@
|
|
|
2120
2120
|
/* the note is body prose like every other section's — same 14px / −.012em / --ink as
|
|
2121
2121
|
.rbody (Masa 2026-07-22: it was a shade lighter and read as a different kind of text) */
|
|
2122
2122
|
.redesign .ropen .v{margin:4px 0 0 !important}
|
|
2123
|
+
/* A malformed .manager-run.json advisory (goal #733, Masa 2026-07-26): plain
|
|
2124
|
+
danger-red text, no box — this must not read as calm/resolved like a normal
|
|
2125
|
+
note (Masa: "めっちゃdoneっぽい"). Same --danger token .prfail already uses
|
|
2126
|
+
for a blocked PR, so it speaks the SAME "needs your attention" language the
|
|
2127
|
+
app already has, rather than inventing a new one. */
|
|
2128
|
+
.redesign .ropen.rdeclerr .v{color:var(--danger) !important}
|
|
2123
2129
|
/* sections — Linear-docs bold sentence-case headings + high-contrast body.
|
|
2124
2130
|
margins are !important: the app's pre-existing .lg / .sa-item rules load first and
|
|
2125
2131
|
otherwise tie/beat these on specificity, flattening the Linear-docs rhythm. */
|
|
@@ -6308,7 +6314,16 @@ const FS_ICONS = {
|
|
|
6308
6314
|
// per-project count icons (HANDOFF-v45 §10): To Do = rounded square, Review = Scan
|
|
6309
6315
|
// (magnifier) — both stroked, NEUTRAL ink (never green); shape is the only distinction.
|
|
6310
6316
|
const FS_ICO_TD = '<svg class="pcg" viewBox="0 0 24 24"><rect x="5" y="5" width="14" height="14" rx="3.5"/></svg>';
|
|
6311
|
-
|
|
6317
|
+
// Eye, not magnifying glass or checkmark (Masa 2026-07-26): the magnifying-glass
|
|
6318
|
+
// read as "search". The first replacement — a square with a checkmark inside,
|
|
6319
|
+
// matching FS_ICO_TD's (To Do) frame — read as "done" instead ("あれ、これだと
|
|
6320
|
+
// めっちゃdoneっぽいわ"): a checkmark is universally a completion signal, and
|
|
6321
|
+
// pairing it with To Do's exact square made it worse, not better. An eye carries
|
|
6322
|
+
// neither "search" nor "done" — it says "look at this", which is what Review
|
|
6323
|
+
// actually is. Standard minimal eye glyph (outline + pupil), legible at the real
|
|
6324
|
+
// 11px render size (verified: a smaller pupil or added detail merges into a
|
|
6325
|
+
// blob at that size — this is the simplest shape that still reads as an eye).
|
|
6326
|
+
const FS_ICO_SCAN = '<svg class="pcg" viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>';
|
|
6312
6327
|
// hover-only Reply / Edit / Delete on a To Do row (§1.5-10; flagship ACTS port)
|
|
6313
6328
|
function fsActs(goalId){
|
|
6314
6329
|
if (goalId == null || !state.goals.some((g) => g.id === goalId)) return '';
|
|
@@ -9177,6 +9192,15 @@ function saRowFromDigest(r, gs, ts){
|
|
|
9177
9192
|
run: (() => {
|
|
9178
9193
|
return latestGoalRunForOutcome(g?.id, ts, outcome);
|
|
9179
9194
|
})(),
|
|
9195
|
+
// The worker DID try to declare something but it came out unusable (goal #733,
|
|
9196
|
+
// 2026-07-26: a Write followed by an Edit broke the JSON mid-edit; Review showed
|
|
9197
|
+
// no "Open it" section and no explanation, indistinguishable from "nothing to
|
|
9198
|
+
// run"). engine/server.mjs's readRunDeclaration sets task.runDeclError in that
|
|
9199
|
+
// case; only shown when there's no successful `run` to display instead.
|
|
9200
|
+
runDeclError: (() => {
|
|
9201
|
+
const t = ts.find((x) => r.goalIds.includes(x.goalId) && x.runDeclError);
|
|
9202
|
+
return t?.runDeclError ?? null;
|
|
9203
|
+
})(),
|
|
9180
9204
|
// Explicit review-summary display fields (spec §11: the card's shape follows the
|
|
9181
9205
|
// task). A goal's reviewSummary may carry them directly (e.g. a conversational task
|
|
9182
9206
|
// that reports an Answer + its Activity, or a ticket whose test count / diff totals
|
|
@@ -9603,11 +9627,20 @@ function saItemHtml(it, i){
|
|
|
9603
9627
|
// failure reason land after the press. Nothing declared → no section (§1.5-3). ──
|
|
9604
9628
|
// it.run?.compare/title alone (no cmd/url) has nothing a press can start — a
|
|
9605
9629
|
// compare-only or title-only declaration must not draw the "Start it" button.
|
|
9630
|
+
// it.runDeclError (2026-07-26, goal #733): the worker DID try to declare an
|
|
9631
|
+
// artifact/command, but .manager-run.json came out unusable (e.g. a Write then
|
|
9632
|
+
// an Edit broke the JSON mid-edit) — this must not look identical to "nothing
|
|
9633
|
+
// to run" (§1.5-3 no empty box still applies: don't invent a fake Open it, but
|
|
9634
|
+
// don't stay silent about a real attempt either). Same honest-advisory shape as
|
|
9635
|
+
// prRepairBody below. A reply is the repair path: the worker rewrites the file.
|
|
9636
|
+
const runDeclErrorBody = (!((it.run?.cmd || it.run?.url)) && it.runDeclError)
|
|
9637
|
+
? `<div class="ropen rdeclerr"><p class="rbody v">${failureLang() === 'ja' ? 'AIが開けるものを用意しようとしましたが、記録が読み取れませんでした。返信して直させてください。' : 'The AI tried to declare something to open here, but the record was unreadable. Reply to have it rewritten.'}</p></div>`
|
|
9638
|
+
: '';
|
|
9606
9639
|
const openBody = (it.run?.cmd || it.run?.url)
|
|
9607
9640
|
? `<div class="ropen" id="runlocal${i}"><button type="button" class="olink" data-saact="preview:${i}" id="prevlink${i}">${esc(it.run.url || 'Start it')}<span class="ar">↗</span></button><p class="rbody v">${esc(it.run.note || it.run.cmd || 'Starts when you press it.')}</p></div>`
|
|
9608
9641
|
: it.pr
|
|
9609
9642
|
? `<div class="ropen"><a class="olink" href="${esc(it.pr)}" target="_blank" rel="noopener">${esc(it.pr)}<span class="ar">↗</span></a><p class="rbody v">Review and merge this pull request to finish the item.</p></div>`
|
|
9610
|
-
:
|
|
9643
|
+
: runDeclErrorBody;
|
|
9611
9644
|
const prRepairBody = it.goal?.prError
|
|
9612
9645
|
? `<div class="prfail"><b>${esc(it.goal.prRepair?.title || 'PR blocked')}</b> <span class="dim">${esc(it.goal.prError)}</span>${it.goal.prRepair?.steps?.length ? `<ul>${it.goal.prRepair.steps.map((s) => `<li>${esc(s)}</li>`).join('')}</ul>` : ''}${it.goal.prRepair?.dirtyFiles?.length ? `<div class="dim">dirty: ${it.goal.prRepair.dirtyFiles.map(esc).join(' · ')}</div>` : ''}<div class="acts2"><button class="errbtn" data-saact="retrypr:${i}">${failureLang() === 'ja' ? 'PR再試行' : 'Retry PR'}</button><button class="errbtn" data-saact="glog:${i}">${failureLang() === 'ja' ? 'ログ確認' : 'View log'}</button></div></div>`
|
|
9613
9646
|
: '';
|
package/engine/lib.mjs
CHANGED
|
@@ -3151,8 +3151,21 @@ export function workerPrompt(task, goal, lastFailure, agentName = 'claude-code',
|
|
|
3151
3151
|
// (research, summaries, answers) simply skip this — the worker decides,
|
|
3152
3152
|
// never us.
|
|
3153
3153
|
`- 人が実際に動かして結果を見られる依頼なら、最後にプロジェクト直下へ ${RUN_DECL_FILE} を書く: {"cmd": "<起動コマンド>", "url": "<開くURL>", "note": "<何が見えるか1行>", "check": "<人に何を見て判断してほしいか1行>", "title": "<この作業のチケット名。対象が分かる程度に説明的で動作を含む短い名前。例「看板モードの追加」「ヘッダのズレの修正」。依頼文をそのまま写さない>"}。Manager はこれを使って人に「動かして見る」と「何を見ればいいか」を出す。動かして見せるものが無い依頼(調査・要約・質問への回答など)では書かなくてよい。`,
|
|
3154
|
+
// Root-cause prevention (goal #733, 2026-07-26): the worker Wrote this file,
|
|
3155
|
+
// then Edit'd it, and the edit broke the JSON mid-edit — Manager silently
|
|
3156
|
+
// dropped the whole declaration (fixed separately: it now surfaces an honest
|
|
3157
|
+
// note instead of vanishing). But the honest note is a recovery, not a fix —
|
|
3158
|
+
// the real fix is stopping the corruption before it happens. Edit requires an
|
|
3159
|
+
// exact byte-for-byte match against the file's current content; a small slip
|
|
3160
|
+
// (a stray character, a stale in-memory copy) breaks the JSON with no error
|
|
3161
|
+
// the worker would notice, because it happens in the tool call, not in
|
|
3162
|
+
// anything it reads back. Write overwrites the whole file atomically — there
|
|
3163
|
+
// is no "current content" to mismatch against — so telling the worker to
|
|
3164
|
+
// always fully overwrite rather than partially edit removes the failure mode
|
|
3165
|
+
// structurally, not just its symptom.
|
|
3166
|
+
`- ${RUN_DECL_FILE} は毎回 Write で全文を書き直すこと。Edit で一部だけ直さない(既存内容と一致しないと壊れたJSONになり、Managerに握りつぶされて人に何も表示されない)。`,
|
|
3154
3167
|
`- Markdown・設計文書・調査メモなど文章そのものが成果物なら、${RUN_DECL_FILE} に別のHTMLや過去のURLを書かない。最終回答に成果物の本文も貼り、保存先のMarkdownリンクを添えること。「ファイルに書きました」だけで終わらない。`,
|
|
3155
|
-
`- 「ローカルで見れない」というフィードバックには、ターミナル操作や npx の再実行を案内して終わらないこと。${RUN_DECL_FILE}
|
|
3168
|
+
`- 「ローカルで見れない」というフィードバックには、ターミナル操作や npx の再実行を案内して終わらないこと。${RUN_DECL_FILE} を Write で全文書き直して実際に開ける内容へ更新し、可能なら自分でURLへ接続確認してから完了すること。`,
|
|
3156
3169
|
// Links are rendered as links. The product cannot tell a real one from a
|
|
3157
3170
|
// decorative one, so the only place this can be held is here.
|
|
3158
3171
|
`- 自分が作っていない場所へのリンクを報告に書かない(存在しないURLや「詳しくはここ」のような飾りのリンクは、そのままリンクとして人に表示される)。`,
|
package/engine/server.mjs
CHANGED
|
@@ -2407,7 +2407,18 @@ function readRunDeclaration(task, workDir) {
|
|
|
2407
2407
|
try { unlinkSync(file); } catch { /* best effort — never fail a task over cleanup */ }
|
|
2408
2408
|
const run = parseRunDeclaration(raw);
|
|
2409
2409
|
if (!run) {
|
|
2410
|
-
|
|
2410
|
+
// The worker DID try to declare something (the file exists) but it came out
|
|
2411
|
+
// unusable — e.g. a Write followed by an Edit that broke the JSON mid-edit
|
|
2412
|
+
// (goal #733, 2026-07-26: Masa saw a working artifact with no "Open it" and
|
|
2413
|
+
// no explanation at all — the Review card just silently had no section,
|
|
2414
|
+
// indistinguishable from "nothing to run"). Silence was already the honest
|
|
2415
|
+
// answer for a request with nothing to run; it stops being honest the moment
|
|
2416
|
+
// a declaration was attempted and swallowed. Keep a short snippet of what was
|
|
2417
|
+
// actually written (raw content is deleted above and never otherwise
|
|
2418
|
+
// recoverable) so both the activity log and the Review card can say WHY,
|
|
2419
|
+
// instead of the human having to guess or dig through file loss.
|
|
2420
|
+
task.runDeclError = { snippet: String(raw ?? '').slice(0, 200) };
|
|
2421
|
+
sendAct(task, `run declaration ignored — ${RUN_DECL_FILE} was not usable JSON: ${task.runDeclError.snippet.slice(0, 80)}`);
|
|
2411
2422
|
return;
|
|
2412
2423
|
}
|
|
2413
2424
|
task.run = { ...run, dir: workDir };
|
package/package.json
CHANGED