tink-harness 1.9.14 → 1.9.15

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tink",
3
3
  "description": "A small harness layer for Claude Code and Codex.",
4
- "version": "1.9.14",
4
+ "version": "1.9.15",
5
5
  "author": {
6
6
  "name": "dotori"
7
7
  }
package/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ All notable changes to Tink are tracked here.
6
6
 
7
7
  No unreleased changes yet.
8
8
 
9
+ ## [1.9.15] - 2026-06-11
10
+
11
+ ### Changed
12
+
13
+ - Harness map controls now match common 3D-tool conventions by default: left-drag rotates, right-drag moves. On Mac trackpads and Magic Mouse, two-finger scroll moves the map and pinch zooms (trackpads are detected from wheel-event characteristics); classic mouse wheels still zoom. The in-map hint, map help text, and README were updated accordingly.
14
+
9
15
  ## [1.9.14] - 2026-06-11
10
16
 
11
17
  ### Changed
package/README.ko.md CHANGED
@@ -8,7 +8,7 @@ Claude Code와 Codex를 위한 작은 하네스 레이어입니다.
8
8
 
9
9
  Tink는 지금 작업에 맞는 하네스를 고르고, 실행 상태를 보이게 만들고, 실제 사용 중 생긴 실패와 피드백으로 하네스 세트를 개선합니다.
10
10
 
11
- **최신 패키지:** v1.9.14 — 로컬 건강 리포트가 탭형 대시보드로 바뀌었습니다. 3D 하네스 지도, 쉬운 말 건강 요약, Claude Code와 Codex 양쪽 복사-붙여넣기 명령이 포함된 다음 행동 제안을 제공합니다. 전체 변경 이력은 [CHANGELOG](CHANGELOG.md)를 확인하세요.
11
+ **최신 패키지:** v1.9.15 — 로컬 건강 리포트가 탭형 대시보드로 바뀌었습니다. 3D 하네스 지도, 쉬운 말 건강 요약, Claude Code와 Codex 양쪽 복사-붙여넣기 명령이 포함된 다음 행동 제안을 제공합니다. 전체 변경 이력은 [CHANGELOG](CHANGELOG.md)를 확인하세요.
12
12
 
13
13
  [English](README.md) · **한국어** · [변경 이력](CHANGELOG.md)
14
14
 
@@ -183,7 +183,7 @@ node .tink/tools/generate-harness-lifecycle-summary.mjs
183
183
  node .tink/tools/render-harness-health-report.mjs
184
184
  ```
185
185
 
186
- 리포트는 정적인 탭형 로컬 페이지입니다. 홈 요약, 사용량 순 하네스 카드와 평가·생성 히스토리, 메모리 참조, run 활동 피드, 그리고 인터랙티브 3D 하네스 지도(드래그 이동, 우클릭 드래그 회전, 확대 — three.js를 CDN에서 불러오며 오프라인이면 안내가 표시됩니다)를 제공합니다. 하네스나 건강 그룹을 선택하면 쉬운 말 요약과 함께 Claude Code(`/tink:...`)·Codex(`$tink:...`) 양쪽 복사용 명령이 포함된 다음 행동을 제안합니다. 여전히 서버를 시작하거나, 파일을 감시하거나, hidden cache를 만들거나, 새 public `tink index` 명령을 추가하지 않습니다 — 제안만 하며, 재사용 상태 변경은 기존 승인 절차를 그대로 따릅니다.
186
+ 리포트는 정적인 탭형 로컬 페이지입니다. 홈 요약, 사용량 순 하네스 카드와 평가·생성 히스토리, 메모리 참조, run 활동 피드, 그리고 인터랙티브 3D 하네스 지도(드래그 회전, 우클릭 드래그·두 손가락 스크롤 이동, 휠·핀치 확대 — three.js를 CDN에서 불러오며 오프라인이면 안내가 표시됩니다)를 제공합니다. 하네스나 건강 그룹을 선택하면 쉬운 말 요약과 함께 Claude Code(`/tink:...`)·Codex(`$tink:...`) 양쪽 복사용 명령이 포함된 다음 행동을 제안합니다. 여전히 서버를 시작하거나, 파일을 감시하거나, hidden cache를 만들거나, 새 public `tink index` 명령을 추가하지 않습니다 — 제안만 하며, 재사용 상태 변경은 기존 승인 절차를 그대로 따릅니다.
187
187
 
188
188
  선택된 하네스에 따라 `.tink/current/goals.json`에는 현재 실행의 목표 체크포인트가, `.tink/current/delegation.md`에는 인수인계 패킷이 추가될 수 있습니다. Tink는 이런 브리프를 보이는 상태로 준비하지만, 별도 승인된 워크플로가 아니면 worker, tmux pane, worktree를 시작하지 않습니다.
189
189
 
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.14"><img src="https://img.shields.io/github/v/release/dotoricode/tink-harness?label=release&color=2ea44f" alt="GitHub release"></a>
20
+ <a href="https://github.com/dotoricode/tink-harness/releases/tag/v1.9.15"><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.14 - 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>
27
+ <p><strong>Latest package:</strong> v1.9.15 - 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
 
@@ -254,7 +254,7 @@ node .tink/tools/generate-harness-lifecycle-summary.mjs
254
254
  node .tink/tools/render-harness-health-report.mjs
255
255
  ```
256
256
 
257
- 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.
257
+ 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 rotate, right-drag or two-finger scroll to move, wheel or pinch 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.
258
258
 
259
259
  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.
260
260
 
package/VERSIONING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Versioning
2
2
 
3
- Current version: `1.9.14`
3
+ Current version: `1.9.15`
4
4
 
5
5
  Tink follows semver from `1.0.0` onward.
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tink-harness",
3
- "version": "1.9.14",
3
+ "version": "1.9.15",
4
4
  "description": "Self-growing harnesses for Claude Code and Codex.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,7 +48,7 @@ const COPY = {
48
48
  heroText: 'Every visible Tink run, rule, memory reference, and harness relationship mapped into one local dashboard. This report only prepares suggestions and never edits reusable state.',
49
49
  generated: 'GENERATED',
50
50
  harnessMap: 'HARNESS MAP',
51
- mapHelp: 'Harnesses, rules, memory, and stages are mapped from visible Tink records in 3D. Drag to move, right-drag to rotate, scroll to zoom, click an orb to inspect it.',
51
+ mapHelp: 'Harnesses, rules, memory, and stages are mapped from visible Tink records in 3D. Drag to rotate, right-drag or two-finger scroll to move, wheel or pinch to zoom, click an orb to inspect it.',
52
52
  graph3dOffline: 'The 3D map needs an internet connection to load three.js. Reconnect and refresh this report.',
53
53
  graphControls: 'Graph controls',
54
54
  full: 'Full',
@@ -188,7 +188,7 @@ const COPY = {
188
188
  unknown: 'An item found in the records.'
189
189
  },
190
190
  timesSuffix: '',
191
- hintPan: 'drag = move · right-drag = rotate · wheel = zoom · double-click = reset',
191
+ hintPan: 'drag = rotate · right-drag / two-finger scroll = move · wheel / pinch = zoom · double-click = reset',
192
192
  hintRotate: 'drag = rotate · right-drag = move · wheel = zoom · double-click = reset',
193
193
  runWindow: 'Run window',
194
194
  totalRuns: 'Runs',
@@ -326,7 +326,7 @@ COPY.ko = {
326
326
  unknown: '기록에서 발견된 항목입니다.'
327
327
  },
328
328
  timesSuffix: '회',
329
- hintPan: '드래그 = 이동 · 우클릭 드래그 = 회전 · = 확대/축소 · 더블클릭 = 처음 시점',
329
+ hintPan: '드래그 = 회전 · 우클릭/두 손가락 = 이동 · 휠/핀치 = 확대 · 더블클릭 = 처음 시점',
330
330
  hintRotate: '드래그 = 회전 · 우클릭 드래그 = 이동 · 휠 = 확대/축소 · 더블클릭 = 처음 시점',
331
331
  runWindow: '기록 기간',
332
332
  totalRuns: 'Run 수',
@@ -371,7 +371,7 @@ COPY.ko = {
371
371
  heroText: '보이는 Tink run, rule, memory reference, harness 관계를 하나의 로컬 대시보드로 보여줍니다. 이 보고서는 제안만 준비하며 재사용 상태를 직접 수정하지 않습니다.',
372
372
  generated: '생성 시각',
373
373
  harnessMap: '하네스 지도',
374
- mapHelp: '보이는 Tink 기록에서 하네스, rule, memory, stage 관계를 3D로 그립니다. 드래그로 이동, 우클릭 드래그로 회전, 휠로 확대, 원을 클릭하면 자세히 볼 수 있습니다.',
374
+ mapHelp: '보이는 Tink 기록에서 하네스, rule, memory, stage 관계를 3D로 그립니다. 드래그로 회전, 우클릭 드래그나 손가락 스크롤로 이동, 휠·핀치로 확대, 원을 클릭하면 자세히 볼 수 있습니다.',
375
375
  graph3dOffline: '3D 지도를 불러오려면 인터넷 연결이 필요합니다 (three.js CDN). 연결 후 보고서를 새로고침하세요.',
376
376
  graphControls: '그래프 조작',
377
377
  full: '전체',
@@ -1766,19 +1766,53 @@ function renderGraph3DModule(copy) {
1766
1766
  const controls = new OrbitControls(camera, renderer.domElement);
1767
1767
  controls.enableDamping = true;
1768
1768
  controls.dampingFactor = 0.1;
1769
- controls.enableZoom = true;
1770
- controls.zoomSpeed = 1.1;
1769
+ controls.enableZoom = false;
1771
1770
  controls.screenSpacePanning = true;
1772
1771
  controls.panSpeed = 1.1;
1773
1772
  controls.mouseButtons = {
1774
- LEFT: THREE.MOUSE.PAN,
1773
+ LEFT: THREE.MOUSE.ROTATE,
1775
1774
  MIDDLE: THREE.MOUSE.DOLLY,
1776
- RIGHT: THREE.MOUSE.ROTATE
1775
+ RIGHT: THREE.MOUSE.PAN
1777
1776
  };
1778
1777
  controls.touches = {
1779
- ONE: THREE.TOUCH.PAN,
1780
- TWO: THREE.TOUCH.DOLLY_ROTATE
1778
+ ONE: THREE.TOUCH.ROTATE,
1779
+ TWO: THREE.TOUCH.DOLLY_PAN
1781
1780
  };
1781
+
1782
+ // wheel routing: mouse wheel = zoom, trackpad two-finger = pan, pinch (ctrlKey) = zoom
1783
+ let likelyTrackpad = false;
1784
+ const panRight = new THREE.Vector3();
1785
+ const panUp = new THREE.Vector3();
1786
+ const panMove = new THREE.Vector3();
1787
+ function panBy(deltaX, deltaY) {
1788
+ const height = renderer.domElement.clientHeight || 1;
1789
+ const distance = camera.position.distanceTo(controls.target);
1790
+ const factor = (2 * Math.tan((camera.fov * Math.PI / 180) / 2) * distance) / height;
1791
+ panRight.setFromMatrixColumn(camera.matrix, 0).multiplyScalar(-deltaX * factor);
1792
+ panUp.setFromMatrixColumn(camera.matrix, 1).multiplyScalar(deltaY * factor);
1793
+ panMove.copy(panRight).add(panUp);
1794
+ camera.position.add(panMove);
1795
+ controls.target.add(panMove);
1796
+ }
1797
+ function dollyBy(deltaY) {
1798
+ const offset = camera.position.clone().sub(controls.target);
1799
+ offset.multiplyScalar(Math.exp(deltaY * 0.0022));
1800
+ offset.setLength(Math.min(220, Math.max(8, offset.length())));
1801
+ camera.position.copy(controls.target).add(offset);
1802
+ }
1803
+ renderer.domElement.addEventListener('wheel', (event) => {
1804
+ event.preventDefault();
1805
+ const fractional = event.deltaY !== Math.round(event.deltaY) || event.deltaX !== Math.round(event.deltaX);
1806
+ if (event.deltaX !== 0 || fractional) likelyTrackpad = true;
1807
+ if (event.ctrlKey || event.metaKey) {
1808
+ dollyBy(event.deltaY * 2.4);
1809
+ } else if (likelyTrackpad || (event.deltaMode === 0 && event.deltaY !== 0 && Math.abs(event.deltaY) < 40)) {
1810
+ panBy(event.deltaX, event.deltaY);
1811
+ } else {
1812
+ dollyBy(event.deltaY);
1813
+ }
1814
+ controls.update();
1815
+ }, { passive: false });
1782
1816
  controls.autoRotate = false;
1783
1817
  controls.minDistance = 8;
1784
1818
  controls.maxDistance = 220;