tink-harness 1.11.0 → 1.11.2
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 +8 -0
- package/README.ko.md +1 -1
- package/README.md +2 -2
- package/VERSIONING.md +1 -1
- package/bin/install.js +19 -15
- package/package.json +1 -1
- package/templates/tink/tools/generate-harness-lifecycle-summary.mjs +52 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Tink are tracked here.
|
|
4
4
|
|
|
5
|
+
## [1.11.2] - 2026-06-13
|
|
6
|
+
|
|
7
|
+
- Fixed: the 3D harness map showed no connections or signal pulses on fresh installs (or installs whose history was lost to the pre-1.11.0 record-wipe bug). The lifecycle summary's graph was built only from run/ledger evidence; it now also includes the static rule graph - every routing rule connects to its harness, and check/guard chains render - so the map is alive from the first open.
|
|
8
|
+
|
|
9
|
+
## [1.11.1] - 2026-06-12
|
|
10
|
+
|
|
11
|
+
- Installer component labels clarified after user confusion: "Claude Code commands (/tink:*)" and "Claude Code skill (operating rules)" now state their role and install path in the label/hint (`.claude/commands/tink/` vs `.claude/skills/tink/`), and Codex skills explicitly say `~/.codex/skills/ (CODEX_HOME)` - the two Claude items no longer look like duplicates, and the Codex item can't be mistaken for a Claude one.
|
|
12
|
+
|
|
5
13
|
## [1.11.0] - 2026-06-12
|
|
6
14
|
|
|
7
15
|
- **Fixed: update wiped run history.** `.tink/maintenance/` record files (`ledger.jsonl`, `friction.jsonl`, `weave-queue.json`) were in the always-overwrite set, so every npx `update` replaced the user's approval ledger and weave/friction signals with empty seeds - silently resetting dashboard usage history. They are now seed-only: created when missing, never overwritten.
|
package/README.ko.md
CHANGED
|
@@ -10,7 +10,7 @@ Tink는 사소하지 않은 모든 에이전트 작업을 눈에 보이는 파
|
|
|
10
10
|
|
|
11
11
|
<sub>Claude Code와 Codex를 위한 작은 하네스 레이어</sub>
|
|
12
12
|
|
|
13
|
-
**최신 패키지:** v1.11.
|
|
13
|
+
**최신 패키지:** v1.11.2 — 하네스 지도가 첫 설치 직후부터 살아 있습니다: run 기록이 없어도 라우팅 규칙과 check/guard 체인이 연결선·신호로 표시됩니다. 1.11.x의 한 줄 대시보드 명령과 update 기록 보존 수정도 포함. 전체 변경 이력은 [CHANGELOG](CHANGELOG.md)를 확인하세요.
|
|
14
14
|
|
|
15
15
|
[English](README.md) · **한국어** · [변경 이력](CHANGELOG.md)
|
|
16
16
|
|
package/README.md
CHANGED
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
<p><sub>A small harness layer for Claude Code and Codex</sub></p>
|
|
18
18
|
|
|
19
19
|
<p>
|
|
20
|
-
<a href="https://github.com/dotoricode/tink-harness/releases/tag/v1.11.
|
|
20
|
+
<a href="https://github.com/dotoricode/tink-harness/releases/tag/v1.11.2"><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.11.
|
|
27
|
+
<p><strong>Latest package:</strong> v1.11.2 - The 3D harness map is now alive from the very first install: routing rules and their check/guard chains always render as connections with signal pulses, even before any run history exists. Plus the one-line dashboard command and the update history-preservation fixes from 1.11.x. See <a href="CHANGELOG.md">CHANGELOG</a> for release history.</p>
|
|
28
28
|
|
|
29
29
|
**English** · [한국어](README.ko.md) · [Changelog](CHANGELOG.md)
|
|
30
30
|
|
package/VERSIONING.md
CHANGED
package/bin/install.js
CHANGED
|
@@ -79,24 +79,24 @@ const COPY = {
|
|
|
79
79
|
|
|
80
80
|
const COMPONENTS = {
|
|
81
81
|
en: [
|
|
82
|
-
{ value: 'commands', label: 'Claude Code commands', hint: '
|
|
82
|
+
{ value: 'commands', label: 'Claude Code commands (/tink:*)', hint: '7 slash commands (cast, verify, frog, ...) → .claude/commands/tink/' },
|
|
83
83
|
{ value: 'skill', label: 'Tink skill', hint: 'Tink operating rules for Claude Code' },
|
|
84
|
-
{ value: 'harnesses', label: 'Built-in harnesses', hint: '
|
|
85
|
-
{ value: 'memory', label: 'Memory templates', hint: 'Approved mistakes/preferences/lessons files' },
|
|
84
|
+
{ value: 'harnesses', label: 'Built-in harnesses', hint: 'Specialized task procedures → .tink/harnesses/' },
|
|
85
|
+
{ value: 'memory', label: 'Memory templates', hint: 'Approved mistakes/preferences/lessons files → .tink/memory/' },
|
|
86
86
|
{ value: 'hook', label: 'Hook recommendation (optional)', hint: 'Registers a safe UserPromptSubmit hook when selected. Off by default.' }
|
|
87
87
|
],
|
|
88
88
|
ko: [
|
|
89
|
-
{ value: 'commands', label: 'Claude Code 명령', hint: '
|
|
89
|
+
{ value: 'commands', label: 'Claude Code 명령 (/tink:*)', hint: '슬래시 명령 7개 (cast, verify, frog 등) → .claude/commands/tink/' },
|
|
90
90
|
{ value: 'skill', label: 'Tink skill', hint: 'Claude Code가 읽는 Tink 작업 원칙' },
|
|
91
|
-
{ value: 'harnesses', label: '기본 harness', hint: '
|
|
92
|
-
{ value: 'memory', label: 'Memory 템플릿', hint: '승인된 실수/선호/교훈 파일' },
|
|
91
|
+
{ value: 'harnesses', label: '기본 harness', hint: '기능 특화 작업 절차 → .tink/harnesses/' },
|
|
92
|
+
{ value: 'memory', label: 'Memory 템플릿', hint: '승인된 실수/선호/교훈 파일 → .tink/memory/' },
|
|
93
93
|
{ value: 'hook', label: 'Hook 추천 (선택)', hint: '선택하면 안전한 UserPromptSubmit hook으로 등록합니다. 기본 off.' }
|
|
94
94
|
],
|
|
95
95
|
zh: [
|
|
96
|
-
{ value: 'commands', label: 'Claude Code 命令', hint: '
|
|
96
|
+
{ value: 'commands', label: 'Claude Code 命令 (/tink:*)', hint: '7 个斜杠命令 (cast, verify, frog 等) → .claude/commands/tink/' },
|
|
97
97
|
{ value: 'skill', label: 'Tink skill', hint: 'Claude Code 读取的 Tink 工作规则' },
|
|
98
|
-
{ value: 'harnesses', label: '内置 harness', hint: '
|
|
99
|
-
{ value: 'memory', label: 'Memory 模板', hint: '经批准的错误/偏好/经验文件' },
|
|
98
|
+
{ value: 'harnesses', label: '内置 harness', hint: '功能特化任务流程 → .tink/harnesses/' },
|
|
99
|
+
{ value: 'memory', label: 'Memory 模板', hint: '经批准的错误/偏好/经验文件 → .tink/memory/' },
|
|
100
100
|
{ value: 'hook', label: 'Hook 推荐(可选)', hint: '选择后注册安全的 UserPromptSubmit hook。默认关闭。' }
|
|
101
101
|
]
|
|
102
102
|
};
|
|
@@ -270,17 +270,21 @@ function componentOptionsFor(agent, language) {
|
|
|
270
270
|
|
|
271
271
|
const claudeSkill = {
|
|
272
272
|
value: 'claude-skill',
|
|
273
|
-
label: 'Claude Code
|
|
273
|
+
label: language === 'ko' ? 'Claude Code skill (작업 원칙)' : language === 'zh' ? 'Claude Code skill(工作规则)' : 'Claude Code skill (operating rules)',
|
|
274
274
|
hint: language === 'ko'
|
|
275
|
-
? 'Claude Code가 읽는
|
|
276
|
-
:
|
|
275
|
+
? '명령과 별개 항목 — Claude Code가 항상 읽는 동작 규칙 문서 → .claude/skills/tink/'
|
|
276
|
+
: language === 'zh'
|
|
277
|
+
? '与命令不同的项目 — Claude Code 始终读取的工作规则 → .claude/skills/tink/'
|
|
278
|
+
: 'Different from the commands - the rules document Claude Code always reads → .claude/skills/tink/'
|
|
277
279
|
};
|
|
278
280
|
const codexSkills = {
|
|
279
281
|
value: 'codex-skills',
|
|
280
|
-
label: 'Codex
|
|
282
|
+
label: language === 'ko' ? 'Codex skills ($tink:*)' : 'Codex skills ($tink:*)',
|
|
281
283
|
hint: language === 'ko'
|
|
282
|
-
? 'Codex
|
|
283
|
-
:
|
|
284
|
+
? 'Codex 전용 — $tink:* action skills → ~/.codex/skills/ (CODEX_HOME)'
|
|
285
|
+
: language === 'zh'
|
|
286
|
+
? '仅用于 Codex — $tink:* action skills → ~/.codex/skills/ (CODEX_HOME)'
|
|
287
|
+
: 'Codex only - $tink:* action skills → ~/.codex/skills/ (CODEX_HOME)'
|
|
284
288
|
};
|
|
285
289
|
|
|
286
290
|
if (agent === 'claude') return [claudeSkill];
|
package/package.json
CHANGED
|
@@ -192,7 +192,7 @@ function addGraphEdge(edges, edge) {
|
|
|
192
192
|
if (!edges.has(key)) edges.set(key, edge);
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
function buildGraph(harnessSummaries) {
|
|
195
|
+
function buildGraph(harnessSummaries, ruleIndex) {
|
|
196
196
|
const nodes = new Map();
|
|
197
197
|
const edges = new Map();
|
|
198
198
|
|
|
@@ -268,6 +268,56 @@ function buildGraph(harnessSummaries) {
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
+
// Static structure from the rule graph: rules that route to a harness are
|
|
272
|
+
// always connected, so the map shows relationships (and signal pulses) even
|
|
273
|
+
// before any runs or ledger evidence exist.
|
|
274
|
+
const knownHarnesses = new Set(harnessSummaries.map((item) => item.id));
|
|
275
|
+
const ruleNodes = Array.isArray(ruleIndex?.nodes) ? ruleIndex.nodes : [];
|
|
276
|
+
for (const rule of ruleNodes) {
|
|
277
|
+
if (!rule || !rule.id) continue;
|
|
278
|
+
const targets = new Set();
|
|
279
|
+
if (Array.isArray(rule.select_harnesses)) {
|
|
280
|
+
for (const name of rule.select_harnesses) targets.add(name);
|
|
281
|
+
}
|
|
282
|
+
if (rule.type === 'harness' && rule.target) targets.add(rule.target);
|
|
283
|
+
const linked = [...targets].filter((name) => knownHarnesses.has(name));
|
|
284
|
+
if (!linked.length) continue;
|
|
285
|
+
const ruleNodeId = graphNodeId('rule', rule.id);
|
|
286
|
+
addGraphNode(nodes, {
|
|
287
|
+
id: ruleNodeId,
|
|
288
|
+
type: 'rule',
|
|
289
|
+
label: rule.id,
|
|
290
|
+
weight: 1
|
|
291
|
+
});
|
|
292
|
+
for (const name of linked) {
|
|
293
|
+
addGraphEdge(edges, {
|
|
294
|
+
source: graphNodeId('harness', name),
|
|
295
|
+
target: ruleNodeId,
|
|
296
|
+
type: 'uses_rule',
|
|
297
|
+
count: 1
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const ruleEdges = Array.isArray(ruleIndex?.edges) ? ruleIndex.edges : [];
|
|
302
|
+
for (const edge of ruleEdges) {
|
|
303
|
+
if (!edge || !edge.from || !edge.to) continue;
|
|
304
|
+
const fromId = graphNodeId('rule', edge.from);
|
|
305
|
+
if (!nodes.has(fromId)) continue;
|
|
306
|
+
const toId = graphNodeId('rule', edge.to);
|
|
307
|
+
addGraphNode(nodes, {
|
|
308
|
+
id: toId,
|
|
309
|
+
type: 'rule',
|
|
310
|
+
label: edge.to,
|
|
311
|
+
weight: 1
|
|
312
|
+
});
|
|
313
|
+
addGraphEdge(edges, {
|
|
314
|
+
source: fromId,
|
|
315
|
+
target: toId,
|
|
316
|
+
type: edge.relation || 'rule_edge',
|
|
317
|
+
count: 1
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
271
321
|
return {
|
|
272
322
|
nodes: [...nodes.values()].sort((a, b) => a.id.localeCompare(b.id)),
|
|
273
323
|
edges: [...edges.values()].sort((a, b) => (
|
|
@@ -559,7 +609,7 @@ function summarize(root) {
|
|
|
559
609
|
'.tink/maintenance/ledger.jsonl'
|
|
560
610
|
],
|
|
561
611
|
harnesses: harnessSummaries,
|
|
562
|
-
graph: buildGraph(harnessSummaries),
|
|
612
|
+
graph: buildGraph(harnessSummaries, ruleIndex),
|
|
563
613
|
timeline: buildTimeline(runs, root),
|
|
564
614
|
maintenance_events: maintenanceEvents
|
|
565
615
|
};
|