tink-harness 1.9.10 → 1.9.12
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +20 -0
- package/README.ko.md +2 -2
- package/README.md +3 -3
- package/VERSIONING.md +1 -1
- package/package.json +1 -1
- package/templates/tink/tools/render-harness-health-report.mjs +86 -128
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,26 @@ All notable changes to Tink are tracked here.
|
|
|
6
6
|
|
|
7
7
|
No unreleased changes yet.
|
|
8
8
|
|
|
9
|
+
## [1.9.12] - 2026-06-11
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Restyled the dashboard with a warm editorial palette (charcoal/ivory/amber) in place of the generic black-and-blue look, with softer semantic tones and larger radii.
|
|
14
|
+
- Improved harness-tab readability: bigger card titles, labels, detail text, and history entries with more breathing room.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Next-action suggestions now provide copy-paste commands for both Claude Code (`/tink:...`) and Codex (`$tink:...`).
|
|
19
|
+
- README (EN/KO) refreshed: latest-package summary, release badge, and an up-to-date description of the tabbed dashboard, 3D harness map, and next-action panel.
|
|
20
|
+
|
|
21
|
+
## [1.9.11] - 2026-06-11
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Home health-group selection no longer carries over into the harness map or cards - it only opens the inline list and next-action suggestion on Home.
|
|
26
|
+
- Removed the Move/Rotate toggle: left-drag always pans, right-drag always rotates, and the in-map hint reflects this fixed mapping.
|
|
27
|
+
- The selected-node panel now starts empty ("no harness selected") instead of showing an arbitrary first harness, and uses the same tone-chip format as click selections; next-action phrasing was neutralized to fit single harnesses as well as groups.
|
|
28
|
+
|
|
9
29
|
## [1.9.10] - 2026-06-11
|
|
10
30
|
|
|
11
31
|
### Changed
|
package/README.ko.md
CHANGED
|
@@ -8,7 +8,7 @@ Claude Code와 Codex를 위한 작은 하네스 레이어입니다.
|
|
|
8
8
|
|
|
9
9
|
Tink는 지금 작업에 맞는 하네스를 고르고, 실행 상태를 보이게 만들고, 실제 사용 중 생긴 실패와 피드백으로 하네스 세트를 개선합니다.
|
|
10
10
|
|
|
11
|
-
**최신 패키지:** v1.9.
|
|
11
|
+
**최신 패키지:** v1.9.12 — 로컬 건강 리포트가 탭형 대시보드로 바뀌었습니다. 3D 하네스 지도, 쉬운 말 건강 요약, Claude Code와 Codex 양쪽 복사-붙여넣기 명령이 포함된 다음 행동 제안을 제공합니다. 전체 변경 이력은 [CHANGELOG](CHANGELOG.md)를 확인하세요.
|
|
12
12
|
|
|
13
13
|
[English](README.md) · **한국어** · [변경 이력](CHANGELOG.md)
|
|
14
14
|
|
|
@@ -131,7 +131,7 @@ node .tink/tools/generate-harness-lifecycle-summary.mjs
|
|
|
131
131
|
node .tink/tools/render-harness-health-report.mjs
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
리포트는
|
|
134
|
+
리포트는 정적인 탭형 로컬 페이지입니다. 홈 요약, 사용량 순 하네스 카드와 평가·생성 히스토리, 메모리 참조, run 활동 피드, 그리고 인터랙티브 3D 하네스 지도(드래그 이동, 우클릭 드래그 회전, 휠 확대 — three.js를 CDN에서 불러오며 오프라인이면 안내가 표시됩니다)를 제공합니다. 하네스나 건강 그룹을 선택하면 쉬운 말 요약과 함께 Claude Code(`/tink:...`)·Codex(`$tink:...`) 양쪽 복사용 명령이 포함된 다음 행동을 제안합니다. 여전히 서버를 시작하거나, 파일을 감시하거나, hidden cache를 만들거나, 새 public `tink index` 명령을 추가하지 않습니다 — 제안만 하며, 재사용 상태 변경은 기존 승인 절차를 그대로 따릅니다.
|
|
135
135
|
|
|
136
136
|
선택된 하네스에 따라 `.tink/current/goals.json`에는 현재 실행의 목표 체크포인트가, `.tink/current/delegation.md`에는 인수인계 패킷이 추가될 수 있습니다. Tink는 이런 브리프를 보이는 상태로 준비하지만, 별도 승인된 워크플로가 아니면 worker, tmux pane, worktree를 시작하지 않습니다.
|
|
137
137
|
|
package/README.md
CHANGED
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
<p>
|
|
20
|
-
<a href="https://github.com/dotoricode/tink-harness/releases/tag/v1.9.
|
|
20
|
+
<a href="https://github.com/dotoricode/tink-harness/releases/tag/v1.9.12"><img src="https://img.shields.io/github/v/release/dotoricode/tink-harness?label=release&color=2ea44f" alt="GitHub release"></a>
|
|
21
21
|
<a href="https://www.npmjs.com/package/tink-harness"><img src="https://img.shields.io/npm/v/tink-harness?label=npm&color=cb3837" alt="npm version"></a>
|
|
22
22
|
<a href="https://github.com/dotoricode/tink-harness/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/dotoricode/tink-harness/ci.yml?branch=main&label=ci" alt="CI"></a>
|
|
23
23
|
<a href="https://github.com/dotoricode/tink-harness/blob/main/LICENSE"><img src="https://img.shields.io/github/license/dotoricode/tink-harness" alt="License"></a>
|
|
24
24
|
<a href="https://github.com/dotoricode/tink-harness/stargazers"><img src="https://img.shields.io/github/stars/dotoricode/tink-harness?style=social" alt="GitHub stars"></a>
|
|
25
25
|
</p>
|
|
26
26
|
|
|
27
|
-
<p><strong>Latest package:</strong> v1.9.
|
|
27
|
+
<p><strong>Latest package:</strong> v1.9.12 - The local health report is now a tabbed dashboard with a 3D harness map, plain-language health summaries, and next-action suggestions with copy-paste commands for both Claude Code and Codex. See <a href="CHANGELOG.md">CHANGELOG</a> for release history.</p>
|
|
28
28
|
|
|
29
29
|
**English** · [한국어](README.ko.md) · [Changelog](CHANGELOG.md)
|
|
30
30
|
|
|
@@ -210,7 +210,7 @@ node .tink/tools/generate-harness-lifecycle-summary.mjs
|
|
|
210
210
|
node .tink/tools/render-harness-health-report.mjs
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
The report is a static
|
|
213
|
+
The report is a static, tabbed local page: a home overview, usage-sorted harness cards with an evaluation/maintenance history, memory references, a run activity feed, and an interactive 3D harness map (drag to move, right-drag to rotate, wheel to zoom; rendered with three.js from a CDN, with an offline notice when unavailable). Selecting a harness or health group shows a plain-language summary plus a suggested next action with copy-paste commands for both Claude Code (`/tink:...`) and Codex (`$tink:...`). It still does not start a server, watch files, create a hidden cache, or add a public `tink index` command - suggestions only; reusable-state changes keep their approval gates.
|
|
214
214
|
|
|
215
215
|
When selected, current-run artifacts may also include `.tink/current/goals.json` for goal checkpoints or `.tink/current/delegation.md` for handoff packets. Tink prepares those briefs as visible state; it does not start workers, tmux panes, or worktrees unless a separate approved workflow does so.
|
|
216
216
|
|
package/VERSIONING.md
CHANGED
package/package.json
CHANGED
|
@@ -161,11 +161,11 @@ const COPY = {
|
|
|
161
161
|
frog_candidate: ['Cleanup review', 'bad']
|
|
162
162
|
},
|
|
163
163
|
actions: {
|
|
164
|
-
keep: { what: '
|
|
165
|
-
observe: { what: 'Not enough records to judge yet.', next: 'Keep working normally with /tink:cast so records accumulate.', command: '
|
|
166
|
-
weave: { what: 'Repeated friction
|
|
167
|
-
merge_candidate: { what: '
|
|
168
|
-
frog_candidate: { what: 'Repeated trouble plus high cost - cleanup candidates.', next: 'Run /tink:frog to review archive/delete with approval.', command: '
|
|
164
|
+
keep: { what: 'Healthy and proven by records.', next: 'No action needed - just keep using it.', command: '', expect: '' },
|
|
165
|
+
observe: { what: 'Not enough records to judge yet.', next: 'Keep working normally with /tink:cast so records accumulate.', command: 'tink:cast', expect: 'What happens: it picks the right harness for your task, plans the run, and the work gets recorded - improving future judgments.' },
|
|
166
|
+
weave: { what: 'Repeated friction shows up in the records.', next: 'Run /tink:weave to prepare a small improvement proposal.', command: 'tink:weave', expect: 'What happens: it drafts an improvement (e.g. updated instructions) from the recorded friction and shows it to you. Nothing changes until you approve.' },
|
|
167
|
+
merge_candidate: { what: 'Often used together with another harness.', next: 'Run /tink:weave to check the overlap and decide whether to combine them.', command: 'tink:weave', expect: 'What happens: it inspects the overlap evidence and proposes whether to combine or keep separate. Nothing changes until you approve.' },
|
|
168
|
+
frog_candidate: { what: 'Repeated trouble plus high cost - cleanup candidates.', next: 'Run /tink:frog to review archive/delete with approval.', command: 'tink:frog', expect: 'What happens: it lists cleanup candidates with their evidence. Archiving or deleting only happens after your explicit approval.' }
|
|
169
169
|
},
|
|
170
170
|
recPlain: {
|
|
171
171
|
keep: 'Working well - keep using it as is.',
|
|
@@ -299,11 +299,11 @@ COPY.ko = {
|
|
|
299
299
|
frog_candidate: ['정리 검토', 'bad']
|
|
300
300
|
},
|
|
301
301
|
actions: {
|
|
302
|
-
keep: { what: '기록으로
|
|
303
|
-
observe: { what: '아직 판단할 기록이 부족해요.', next: '/tink:cast로 평소처럼 작업하면 기록이 쌓여 판단이 정확해져요.', command: '
|
|
304
|
-
weave: { what: '반복되는 마찰이
|
|
305
|
-
merge_candidate: { what: '다른 하네스와 자주 함께
|
|
306
|
-
frog_candidate: { what: '반복 문제와 높은 비용이 기록됐어요 — 정리 후보예요.', next: '/tink:frog로 보관/삭제 검토를 승인 절차와 함께 진행하세요.', command: '
|
|
302
|
+
keep: { what: '기록으로 잘 검증되어 있어요.', next: '별도 행동이 필요 없어요 — 계속 사용하면 됩니다.', command: '', expect: '' },
|
|
303
|
+
observe: { what: '아직 판단할 기록이 부족해요.', next: '/tink:cast로 평소처럼 작업하면 기록이 쌓여 판단이 정확해져요.', command: 'tink:cast', expect: '실행하면: 작업에 맞는 하네스를 골라 계획을 세우고, 끝나면 이번 작업이 기록으로 남아 다음 판단이 정확해져요.' },
|
|
304
|
+
weave: { what: '반복되는 마찰이 기록되어 있어요.', next: '/tink:weave를 실행해 작은 개선 제안을 준비하세요.', command: 'tink:weave', expect: '실행하면: 기록된 마찰을 바탕으로 개선안(지침 수정 등)을 만들어 보여줘요. 승인하기 전에는 아무것도 바뀌지 않아요.' },
|
|
305
|
+
merge_candidate: { what: '다른 하네스와 자주 함께 쓰여요.', next: '/tink:weave로 겹침을 확인하고 합칠지 검토하세요.', command: 'tink:weave', expect: '실행하면: 겹침 근거를 살펴보고 합칠지 따로 둘지 제안해 줘요. 승인 전에는 아무것도 바뀌지 않아요.' },
|
|
306
|
+
frog_candidate: { what: '반복 문제와 높은 비용이 기록됐어요 — 정리 후보예요.', next: '/tink:frog로 보관/삭제 검토를 승인 절차와 함께 진행하세요.', command: 'tink:frog', expect: '실행하면: 정리 후보와 근거를 정리해 보여줘요. 보관·삭제는 명시적으로 승인해야만 실제로 진행돼요.' }
|
|
307
307
|
},
|
|
308
308
|
recPlain: {
|
|
309
309
|
keep: '잘 쓰이고 있어요 — 그대로 유지하면 됩니다.',
|
|
@@ -874,10 +874,6 @@ function renderGraphCanvas(summary, copy) {
|
|
|
874
874
|
<button class="active" type="button" data-mode="full" aria-pressed="true">${escapeHtml(copy.full)}</button>
|
|
875
875
|
<button type="button" data-mode="core" aria-pressed="false">${escapeHtml(copy.core)}</button>
|
|
876
876
|
</div>
|
|
877
|
-
<div class="map-controls" aria-label="drag mode">
|
|
878
|
-
<button class="active" type="button" data-drag="pan" aria-pressed="true">${escapeHtml(copy.dragPan || 'Move')}</button>
|
|
879
|
-
<button type="button" data-drag="rotate" aria-pressed="false">${escapeHtml(copy.dragRotate || 'Rotate')}</button>
|
|
880
|
-
</div>
|
|
881
877
|
<div class="map-controls" aria-label="zoom">
|
|
882
878
|
<button type="button" data-zoom="in" aria-label="${escapeAttr(copy.zoomIn || 'Zoom in')}" title="${escapeAttr(copy.zoomIn || 'Zoom in')}">+</button>
|
|
883
879
|
<button type="button" data-zoom="out" aria-label="${escapeAttr(copy.zoomOut || 'Zoom out')}" title="${escapeAttr(copy.zoomOut || 'Zoom out')}">−</button>
|
|
@@ -1069,24 +1065,7 @@ function renderImportantHarnesses(harnesses, copy) {
|
|
|
1069
1065
|
}
|
|
1070
1066
|
|
|
1071
1067
|
function renderSelectedPanel(harnesses, copy) {
|
|
1072
|
-
|
|
1073
|
-
if (!first) {
|
|
1074
|
-
return `<section class="insight-card selected" id="selected-panel"><p class="eyebrow">${escapeHtml(copy.selected)}</p><h2>${escapeHtml(copy.noHarnessSelected)}</h2><p>${escapeHtml(copy.clickNode)}</p></section>`;
|
|
1075
|
-
}
|
|
1076
|
-
const plain = (copy.recPlain && copy.recPlain[first.recommendation]) || normalizeReason(first.reason, copy) || copy.clickNode;
|
|
1077
|
-
const stateText = (copy.statePlain && copy.statePlain[first.lifecycle_state]) || renderCopyValue(first.lifecycle_state, copy);
|
|
1078
|
-
return `
|
|
1079
|
-
<section class="insight-card selected" id="selected-panel">
|
|
1080
|
-
<p class="eyebrow">${escapeHtml(copy.selected)}</p>
|
|
1081
|
-
<h2>${escapeHtml(first.id)}</h2>
|
|
1082
|
-
<p>${escapeHtml(plain)}</p>
|
|
1083
|
-
<div class="stat-chips">
|
|
1084
|
-
<span class="stat-chip">${escapeHtml(copy.uses)} ${escapeHtml(first.signals?.uses || 0)}${escapeHtml(copy.timesSuffix || '')}</span>
|
|
1085
|
-
<span class="stat-chip">${escapeHtml(copy.score)} ${escapeHtml(first.candidate_score?.total || 0)}</span>
|
|
1086
|
-
<span class="stat-chip">${escapeHtml(stateText)}</span>
|
|
1087
|
-
</div>
|
|
1088
|
-
</section>
|
|
1089
|
-
`;
|
|
1068
|
+
return `<section class="insight-card selected" id="selected-panel"><p class="eyebrow">${escapeHtml(copy.selected)}</p><h2>${escapeHtml(copy.noHarnessSelected)}</h2><p>${escapeHtml(copy.clickNode)}</p></section>`;
|
|
1090
1069
|
}
|
|
1091
1070
|
|
|
1092
1071
|
function renderHarness(item, copy) {
|
|
@@ -1579,14 +1558,17 @@ function renderScript(harnesses, copy) {
|
|
|
1579
1558
|
actionPanel.innerHTML = head + '<p class="action-body">' + esc(copy.actionDefault || '') + '</p>';
|
|
1580
1559
|
return;
|
|
1581
1560
|
}
|
|
1582
|
-
const
|
|
1561
|
+
const suffix = harnessId ? ' ' + harnessId : '';
|
|
1562
|
+
const cmdRow = (label, value) =>
|
|
1563
|
+
'<div class="cmd-row"><span class="cmd-label">' + esc(label) + '</span><code>' + esc(value) + '</code>' +
|
|
1564
|
+
'<button class="copy-btn" type="button" data-copy-cmd="' + esc(value) + '">' + esc(copy.copyCmd || 'Copy') + '</button></div>';
|
|
1583
1565
|
actionPanel.innerHTML = head +
|
|
1584
1566
|
(harnessId ? '<p class="action-target">' + esc(copy.actionTarget || 'Target') + ': <strong>' + esc(harnessId) + '</strong></p>' : '') +
|
|
1585
1567
|
'<p class="action-body">' + esc(action.what || '') + '</p>' +
|
|
1586
1568
|
'<p class="action-next">' + esc(action.next || '') + '</p>' +
|
|
1587
|
-
(command
|
|
1588
|
-
? '
|
|
1589
|
-
'
|
|
1569
|
+
(action.command
|
|
1570
|
+
? cmdRow('Claude Code', '/' + action.command + suffix) +
|
|
1571
|
+
cmdRow('Codex', '$' + action.command + suffix) +
|
|
1590
1572
|
(action.expect ? '<p class="action-expect">' + esc(action.expect) + '</p>' : '') +
|
|
1591
1573
|
'<p class="action-caveat">' + esc(copy.actionCaveat || '') + '</p>'
|
|
1592
1574
|
: '');
|
|
@@ -1629,10 +1611,6 @@ function renderScript(harnesses, copy) {
|
|
|
1629
1611
|
item.setAttribute('aria-pressed', 'false');
|
|
1630
1612
|
});
|
|
1631
1613
|
if (alreadyActive) {
|
|
1632
|
-
cards.forEach((card) => card.classList.remove('is-filtered-out'));
|
|
1633
|
-
window.__tinkGraphState.filter = null;
|
|
1634
|
-
if (window.__tinkGraph) window.__tinkGraph.setFilter(null);
|
|
1635
|
-
setStatus(copy.showingAll);
|
|
1636
1614
|
setFilterStatus(copy.showingAll);
|
|
1637
1615
|
updateActionPanel(null, null);
|
|
1638
1616
|
updateGroupDetail(null);
|
|
@@ -1640,11 +1618,7 @@ function renderScript(harnesses, copy) {
|
|
|
1640
1618
|
}
|
|
1641
1619
|
button.classList.add('active-filter');
|
|
1642
1620
|
button.setAttribute('aria-pressed', 'true');
|
|
1643
|
-
cards.forEach((card) => card.classList.toggle('is-filtered-out', card.dataset.recommendation !== value));
|
|
1644
|
-
window.__tinkGraphState.filter = value;
|
|
1645
|
-
if (window.__tinkGraph) window.__tinkGraph.setFilter(value);
|
|
1646
1621
|
const label = recLabelByFilter[value] || value;
|
|
1647
|
-
setStatus(copy.filteredTo + ': ' + label);
|
|
1648
1622
|
setFilterStatus(copy.filteredTo + ': ' + label);
|
|
1649
1623
|
updateActionPanel(value, null);
|
|
1650
1624
|
updateGroupDetail(value);
|
|
@@ -1656,24 +1630,8 @@ function renderScript(harnesses, copy) {
|
|
|
1656
1630
|
else window.__tinkGraph.zoom(button.dataset.zoom === 'in' ? 0.78 : 1.28);
|
|
1657
1631
|
});
|
|
1658
1632
|
});
|
|
1659
|
-
document.querySelectorAll('[data-drag]').forEach((button) => {
|
|
1660
|
-
button.addEventListener('click', () => {
|
|
1661
|
-
const mode = button.dataset.drag;
|
|
1662
|
-
document.querySelectorAll('[data-drag]').forEach((item) => {
|
|
1663
|
-
const active = item.dataset.drag === mode;
|
|
1664
|
-
item.classList.toggle('active', active);
|
|
1665
|
-
item.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
1666
|
-
});
|
|
1667
|
-
window.__tinkGraphState.dragMode = mode;
|
|
1668
|
-
if (window.__tinkGraph) window.__tinkGraph.setDragMode(mode);
|
|
1669
|
-
updateGraphHint();
|
|
1670
|
-
});
|
|
1671
|
-
});
|
|
1672
1633
|
const graphHint = document.getElementById('graph-hint');
|
|
1673
|
-
|
|
1674
|
-
if (graphHint) graphHint.textContent = window.__tinkGraphState.dragMode === 'rotate' ? (copy.hintRotate || '') : (copy.hintPan || '');
|
|
1675
|
-
}
|
|
1676
|
-
updateGraphHint();
|
|
1634
|
+
if (graphHint) graphHint.textContent = copy.hintPan || '';
|
|
1677
1635
|
const rail = document.querySelector('.right-rail');
|
|
1678
1636
|
const railResizer = document.getElementById('rail-resizer');
|
|
1679
1637
|
if (rail && railResizer) {
|
|
@@ -1812,19 +1770,15 @@ function renderGraph3DModule(copy) {
|
|
|
1812
1770
|
controls.zoomSpeed = 1.1;
|
|
1813
1771
|
controls.screenSpacePanning = true;
|
|
1814
1772
|
controls.panSpeed = 1.1;
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
TWO: THREE.TOUCH.DOLLY_ROTATE
|
|
1825
|
-
};
|
|
1826
|
-
}
|
|
1827
|
-
applyDragMode((window.__tinkGraphState && window.__tinkGraphState.dragMode) || 'pan');
|
|
1773
|
+
controls.mouseButtons = {
|
|
1774
|
+
LEFT: THREE.MOUSE.PAN,
|
|
1775
|
+
MIDDLE: THREE.MOUSE.DOLLY,
|
|
1776
|
+
RIGHT: THREE.MOUSE.ROTATE
|
|
1777
|
+
};
|
|
1778
|
+
controls.touches = {
|
|
1779
|
+
ONE: THREE.TOUCH.PAN,
|
|
1780
|
+
TWO: THREE.TOUCH.DOLLY_ROTATE
|
|
1781
|
+
};
|
|
1828
1782
|
controls.autoRotate = false;
|
|
1829
1783
|
controls.minDistance = 8;
|
|
1830
1784
|
controls.maxDistance = 220;
|
|
@@ -2184,9 +2138,6 @@ function renderGraph3DModule(copy) {
|
|
|
2184
2138
|
camera.position.copy(INITIAL_CAM);
|
|
2185
2139
|
controls.target.copy(INITIAL_TARGET);
|
|
2186
2140
|
controls.update();
|
|
2187
|
-
},
|
|
2188
|
-
setDragMode(mode) {
|
|
2189
|
-
applyDragMode(mode);
|
|
2190
2141
|
}
|
|
2191
2142
|
};
|
|
2192
2143
|
applyState();
|
|
@@ -2332,30 +2283,30 @@ function renderStyles() {
|
|
|
2332
2283
|
return `<style>
|
|
2333
2284
|
:root {
|
|
2334
2285
|
color-scheme: dark;
|
|
2335
|
-
--bg-page: #
|
|
2336
|
-
--bg-card: #
|
|
2337
|
-
--bg-hover: #
|
|
2338
|
-
--bg-selected: #
|
|
2339
|
-
--border-default: #
|
|
2340
|
-
--border-hover: #
|
|
2341
|
-
--border-strong: #
|
|
2342
|
-
--text-primary: #
|
|
2343
|
-
--text-secondary: #
|
|
2344
|
-
--text-muted: #
|
|
2345
|
-
--accent: #
|
|
2346
|
-
--accent-dim: #
|
|
2347
|
-
--accent-text: #
|
|
2348
|
-
--success: #
|
|
2349
|
-
--success-dim: #
|
|
2350
|
-
--warning: #
|
|
2351
|
-
--warning-dim: #
|
|
2352
|
-
--danger: #
|
|
2353
|
-
--danger-dim: #
|
|
2354
|
-
--font-ui: 'IBM Plex Sans', -apple-system, sans-serif;
|
|
2286
|
+
--bg-page: #171511;
|
|
2287
|
+
--bg-card: #1E1B16;
|
|
2288
|
+
--bg-hover: #25211A;
|
|
2289
|
+
--bg-selected: #2C2720;
|
|
2290
|
+
--border-default: #2D2820;
|
|
2291
|
+
--border-hover: #3B342A;
|
|
2292
|
+
--border-strong: #4C4336;
|
|
2293
|
+
--text-primary: #EBE4D6;
|
|
2294
|
+
--text-secondary: #A2988A;
|
|
2295
|
+
--text-muted: #645B4E;
|
|
2296
|
+
--accent: #C9913F;
|
|
2297
|
+
--accent-dim: #3A2F1B;
|
|
2298
|
+
--accent-text: #E2B873;
|
|
2299
|
+
--success: #8FAE76;
|
|
2300
|
+
--success-dim: #28301F;
|
|
2301
|
+
--warning: #D2A24A;
|
|
2302
|
+
--warning-dim: #342917;
|
|
2303
|
+
--danger: #C97862;
|
|
2304
|
+
--danger-dim: #34221C;
|
|
2305
|
+
--font-ui: 'Avenir Next', 'Pretendard', 'IBM Plex Sans', -apple-system, 'Segoe UI', sans-serif;
|
|
2355
2306
|
--font-mono: 'IBM Plex Mono', 'Fira Code', monospace;
|
|
2356
|
-
--radius-sm:
|
|
2357
|
-
--radius-md:
|
|
2358
|
-
--radius-lg:
|
|
2307
|
+
--radius-sm: 5px;
|
|
2308
|
+
--radius-md: 8px;
|
|
2309
|
+
--radius-lg: 12px;
|
|
2359
2310
|
--border-width: 1px;
|
|
2360
2311
|
--space-1: 4px;
|
|
2361
2312
|
--space-2: 8px;
|
|
@@ -2363,12 +2314,12 @@ function renderStyles() {
|
|
|
2363
2314
|
--space-4: 16px;
|
|
2364
2315
|
--space-6: 24px;
|
|
2365
2316
|
--space-8: 32px;
|
|
2366
|
-
--chart-line: #
|
|
2317
|
+
--chart-line: #C9913F;
|
|
2367
2318
|
--chart-line-w: 1.5px;
|
|
2368
|
-
--chart-area: rgba(
|
|
2369
|
-
--chart-grid: #
|
|
2370
|
-
--chart-dot-fill: #
|
|
2371
|
-
--chart-dot-stroke: #
|
|
2319
|
+
--chart-area: rgba(201, 145, 63, 0.07);
|
|
2320
|
+
--chart-grid: #2D2820;
|
|
2321
|
+
--chart-dot-fill: #1E1B16;
|
|
2322
|
+
--chart-dot-stroke: #C9913F;
|
|
2372
2323
|
}
|
|
2373
2324
|
|
|
2374
2325
|
* { box-sizing: border-box; }
|
|
@@ -3099,7 +3050,7 @@ function renderStyles() {
|
|
|
3099
3050
|
padding: 6px 12px;
|
|
3100
3051
|
border-radius: var(--radius-md);
|
|
3101
3052
|
border: 1px solid var(--border-default);
|
|
3102
|
-
background: rgba(
|
|
3053
|
+
background: rgba(23, 21, 17, 0.82);
|
|
3103
3054
|
color: var(--text-secondary);
|
|
3104
3055
|
font-size: 12px;
|
|
3105
3056
|
pointer-events: none;
|
|
@@ -3240,6 +3191,13 @@ function renderStyles() {
|
|
|
3240
3191
|
flex-wrap: wrap;
|
|
3241
3192
|
}
|
|
3242
3193
|
|
|
3194
|
+
.cmd-label {
|
|
3195
|
+
min-width: 78px;
|
|
3196
|
+
color: var(--text-muted);
|
|
3197
|
+
font-size: 11.5px;
|
|
3198
|
+
white-space: nowrap;
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3243
3201
|
.cmd-row code {
|
|
3244
3202
|
background: var(--bg-hover);
|
|
3245
3203
|
border: 1px solid var(--border-default);
|
|
@@ -3537,13 +3495,14 @@ function renderStyles() {
|
|
|
3537
3495
|
|
|
3538
3496
|
.harness-summary:hover { background: var(--bg-hover); }
|
|
3539
3497
|
|
|
3540
|
-
.harness-summary .eyebrow { margin: 0 0
|
|
3498
|
+
.harness-summary .eyebrow { margin: 0 0 3px; font-size: 11.5px; letter-spacing: 0.03em; }
|
|
3541
3499
|
|
|
3542
3500
|
.harness-summary h3 {
|
|
3543
3501
|
margin: 0;
|
|
3544
|
-
font-size:
|
|
3545
|
-
line-height: 1.
|
|
3502
|
+
font-size: 15.5px;
|
|
3503
|
+
line-height: 1.3;
|
|
3546
3504
|
font-weight: 600;
|
|
3505
|
+
letter-spacing: -0.01em;
|
|
3547
3506
|
overflow-wrap: anywhere;
|
|
3548
3507
|
}
|
|
3549
3508
|
|
|
@@ -3555,12 +3514,12 @@ function renderStyles() {
|
|
|
3555
3514
|
|
|
3556
3515
|
.harness-mini span {
|
|
3557
3516
|
color: var(--text-secondary);
|
|
3558
|
-
font-size:
|
|
3517
|
+
font-size: 12.5px;
|
|
3559
3518
|
white-space: nowrap;
|
|
3560
3519
|
}
|
|
3561
3520
|
|
|
3562
3521
|
.harness-mini strong {
|
|
3563
|
-
font-size:
|
|
3522
|
+
font-size: 20px;
|
|
3564
3523
|
line-height: 1;
|
|
3565
3524
|
font-family: var(--font-mono);
|
|
3566
3525
|
font-weight: 600;
|
|
@@ -3604,16 +3563,15 @@ function renderStyles() {
|
|
|
3604
3563
|
.harness-reason {
|
|
3605
3564
|
margin: 0;
|
|
3606
3565
|
color: var(--text-secondary);
|
|
3607
|
-
font-size:
|
|
3608
|
-
line-height: 1.
|
|
3566
|
+
font-size: 13.5px;
|
|
3567
|
+
line-height: 1.6;
|
|
3609
3568
|
}
|
|
3610
3569
|
|
|
3611
3570
|
.detail-label {
|
|
3612
|
-
margin: var(--space-
|
|
3571
|
+
margin: var(--space-2) 0 0;
|
|
3613
3572
|
color: var(--text-secondary);
|
|
3614
|
-
font-size:
|
|
3615
|
-
|
|
3616
|
-
letter-spacing: 0.06em;
|
|
3573
|
+
font-size: 11.5px;
|
|
3574
|
+
letter-spacing: 0.04em;
|
|
3617
3575
|
}
|
|
3618
3576
|
|
|
3619
3577
|
.co-used-chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
@@ -3640,7 +3598,7 @@ function renderStyles() {
|
|
|
3640
3598
|
display: flex;
|
|
3641
3599
|
justify-content: space-between;
|
|
3642
3600
|
gap: var(--space-2);
|
|
3643
|
-
font-size:
|
|
3601
|
+
font-size: 13px;
|
|
3644
3602
|
color: var(--text-secondary);
|
|
3645
3603
|
}
|
|
3646
3604
|
|
|
@@ -3649,17 +3607,17 @@ function renderStyles() {
|
|
|
3649
3607
|
.harness-next {
|
|
3650
3608
|
margin: 0;
|
|
3651
3609
|
color: var(--text-primary);
|
|
3652
|
-
font-size:
|
|
3653
|
-
line-height: 1.
|
|
3610
|
+
font-size: 13.5px;
|
|
3611
|
+
line-height: 1.6;
|
|
3654
3612
|
}
|
|
3655
3613
|
|
|
3656
3614
|
.evidence-list {
|
|
3657
3615
|
margin: 0;
|
|
3658
3616
|
padding-left: 16px;
|
|
3659
3617
|
color: var(--text-secondary);
|
|
3660
|
-
font-size:
|
|
3618
|
+
font-size: 12.5px;
|
|
3661
3619
|
display: grid;
|
|
3662
|
-
gap:
|
|
3620
|
+
gap: 4px;
|
|
3663
3621
|
}
|
|
3664
3622
|
|
|
3665
3623
|
.harness-card .link-button { margin-top: var(--space-1); justify-self: start; }
|
|
@@ -3680,19 +3638,19 @@ function renderStyles() {
|
|
|
3680
3638
|
|
|
3681
3639
|
.history-feed li {
|
|
3682
3640
|
display: grid;
|
|
3683
|
-
grid-template-columns:
|
|
3641
|
+
grid-template-columns: 120px 1fr;
|
|
3684
3642
|
gap: var(--space-3);
|
|
3685
3643
|
align-items: start;
|
|
3686
3644
|
border: 1px solid var(--border-default);
|
|
3687
3645
|
border-radius: var(--radius-md);
|
|
3688
3646
|
background: var(--bg-card);
|
|
3689
|
-
padding: var(--space-
|
|
3647
|
+
padding: var(--space-3) var(--space-4);
|
|
3690
3648
|
}
|
|
3691
3649
|
|
|
3692
3650
|
.history-type {
|
|
3693
3651
|
display: inline-block;
|
|
3694
3652
|
font-family: var(--font-mono);
|
|
3695
|
-
font-size:
|
|
3653
|
+
font-size: 11px;
|
|
3696
3654
|
text-transform: uppercase;
|
|
3697
3655
|
letter-spacing: 0.05em;
|
|
3698
3656
|
color: var(--text-secondary);
|
|
@@ -3709,12 +3667,12 @@ function renderStyles() {
|
|
|
3709
3667
|
.history-type.harness-create,
|
|
3710
3668
|
.history-type.harness-edit { color: var(--success); border-color: var(--success-dim); }
|
|
3711
3669
|
|
|
3712
|
-
.history-feed strong { font-size:
|
|
3670
|
+
.history-feed strong { font-size: 13.5px; font-weight: 500; }
|
|
3713
3671
|
|
|
3714
3672
|
.history-harnesses {
|
|
3715
|
-
margin:
|
|
3673
|
+
margin: 3px 0 0;
|
|
3716
3674
|
color: var(--text-secondary);
|
|
3717
|
-
font-size:
|
|
3675
|
+
font-size: 12.5px;
|
|
3718
3676
|
font-family: var(--font-mono);
|
|
3719
3677
|
}
|
|
3720
3678
|
|