@polderlabs/openkan 0.4.0
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/CHANGELOG.md +226 -0
- package/LICENSE +21 -0
- package/README.md +318 -0
- package/agents/openkan.md +254 -0
- package/bin/install-agent.mjs +63 -0
- package/bin/ok.mjs +17 -0
- package/bin/openkan.mjs +10 -0
- package/dist/.claude/skills/ok-planning/SKILL.md +285 -0
- package/dist/.claude/skills/ok-planning/references/integration.md +153 -0
- package/dist/.claude/skills/ok-planning/references/schemas.md +270 -0
- package/dist/.claude/skills/ok-planning/references/workflows.md +185 -0
- package/dist/.claude/skills/ok-planning/scripts/ok-init.sh +14 -0
- package/dist/.claude/skills/ok-planning/scripts/ok-resume.sh +38 -0
- package/dist/.claude/skills/ok-planning/scripts/ok-status.sh +24 -0
- package/dist/agents/openkan.md +254 -0
- package/dist/bin/install-agent.mjs +76 -0
- package/dist/bin/ok-install.js +58 -0
- package/dist/bin/ok.js +138 -0
- package/dist/bin/openkan.js +804 -0
- package/dist/commands/organize.md +15 -0
- package/dist/kanban/agent-profile.js +8 -0
- package/dist/kanban/archive.js +49 -0
- package/dist/kanban/bizar.js +242 -0
- package/dist/kanban/board.js +367 -0
- package/dist/kanban/bulk.js +139 -0
- package/dist/kanban/changelog.js +186 -0
- package/dist/kanban/chat.js +1280 -0
- package/dist/kanban/claude-state.js +974 -0
- package/dist/kanban/comments.js +80 -0
- package/dist/kanban/docs.js +144 -0
- package/dist/kanban/fs.js +163 -0
- package/dist/kanban/git.js +196 -0
- package/dist/kanban/images.js +140 -0
- package/dist/kanban/import.js +295 -0
- package/dist/kanban/inputs.js +94 -0
- package/dist/kanban/insights.js +140 -0
- package/dist/kanban/io.js +75 -0
- package/dist/kanban/mdx-render.js +348 -0
- package/dist/kanban/mdx.js +231 -0
- package/dist/kanban/projects.js +545 -0
- package/dist/kanban/search.js +121 -0
- package/dist/kanban/server.js +3296 -0
- package/dist/kanban/tags.js +124 -0
- package/dist/kanban/template.js +145 -0
- package/dist/kanban/tsx-sandbox.js +187 -0
- package/dist/kanban/watcher.js +270 -0
- package/dist/ok/commands/goal.js +65 -0
- package/dist/ok/commands/index.js +87 -0
- package/dist/ok/commands/init.js +15 -0
- package/dist/ok/commands/plan.js +155 -0
- package/dist/ok/commands/prd.js +202 -0
- package/dist/ok/commands/progress.js +31 -0
- package/dist/ok/commands/task.js +377 -0
- package/dist/ok/ids.js +98 -0
- package/dist/ok/lock.js +156 -0
- package/dist/ok/migrate.js +197 -0
- package/dist/ok/schemas.js +402 -0
- package/dist/ok/storage.js +222 -0
- package/dist/skills/openkan/SKILL.md +111 -0
- package/dist/skills/openkan/agents/openai.yaml +4 -0
- package/dist/skills/openkan/examples/simple-task.mdx +34 -0
- package/dist/skills/openkan/examples/with-ask.mdx +32 -0
- package/dist/skills/openkan/examples/with-choice.mdx +51 -0
- package/dist/skills/openkan/examples/with-preview.mdx +54 -0
- package/dist/skills/openkan/references/api.md +169 -0
- package/dist/skills/openkan/templates/task.mdx +46 -0
- package/dist/web/api.js +257 -0
- package/dist/web/app.js +4251 -0
- package/dist/web/bizar.js +39 -0
- package/dist/web/brand/agent-activity-sprite.svg +1 -0
- package/dist/web/brand/banner-docs.svg +24 -0
- package/dist/web/brand/banner.svg +32 -0
- package/dist/web/brand/empty-sessions.svg +17 -0
- package/dist/web/brand/empty-tasks.svg +17 -0
- package/dist/web/brand/favicon.svg +9 -0
- package/dist/web/brand/infinity-loader-animated.svg +220 -0
- package/dist/web/brand/infinity-loader-spritesheet.svg +230 -0
- package/dist/web/brand/logo-wordmark.svg +10 -0
- package/dist/web/brand/logo.svg +9 -0
- package/dist/web/brand/pixel-infinity-track.svg +1 -0
- package/dist/web/brand/social-card.svg +26 -0
- package/dist/web/changelog-view.js +456 -0
- package/dist/web/charts.js +269 -0
- package/dist/web/chat-sidebar.js +2397 -0
- package/dist/web/chat-status-motion.js +154 -0
- package/dist/web/claude-pane.js +820 -0
- package/dist/web/command-palette.js +381 -0
- package/dist/web/contributors-view.js +317 -0
- package/dist/web/cross-tab.js +102 -0
- package/dist/web/docs-view.js +168 -0
- package/dist/web/experience.css +165 -0
- package/dist/web/goals-view.js +45 -0
- package/dist/web/home-view.js +113 -0
- package/dist/web/images.js +311 -0
- package/dist/web/index.html +485 -0
- package/dist/web/insights.js +217 -0
- package/dist/web/keyboard.js +446 -0
- package/dist/web/mdx-viewer.js +600 -0
- package/dist/web/path-picker.js +787 -0
- package/dist/web/preview-frame.html +187 -0
- package/dist/web/settings.js +582 -0
- package/dist/web/style.css +8545 -0
- package/dist/web/task-view.js +1759 -0
- package/dist/web/vendor/gsap.min.js +11 -0
- package/dist/web/workspace.css +1513 -0
- package/package.json +71 -0
- package/skills/openkan/SKILL.md +111 -0
- package/skills/openkan/agents/openai.yaml +4 -0
- package/skills/openkan/examples/simple-task.mdx +34 -0
- package/skills/openkan/examples/with-ask.mdx +32 -0
- package/skills/openkan/examples/with-choice.mdx +51 -0
- package/skills/openkan/examples/with-preview.mdx +54 -0
- package/skills/openkan/references/api.md +169 -0
- package/skills/openkan/templates/task.mdx +46 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// OpenKan chat status motion — pixel-first GSAP cues. Live work loops with a
|
|
2
|
+
// distinct rhythm; terminal states run once, clear their timeline, and settle.
|
|
3
|
+
(() => {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const MODES = Object.freeze({
|
|
7
|
+
thinking: { label: "Thinking", cells: 8 },
|
|
8
|
+
searching: { label: "Searching the web", cells: 7 },
|
|
9
|
+
reading: { label: "Reading", cells: 6 },
|
|
10
|
+
command: { label: "Running command", cells: 7 },
|
|
11
|
+
editing: { label: "Editing", cells: 7 },
|
|
12
|
+
agent: { label: "Delegating", cells: 5 },
|
|
13
|
+
orchestration: { label: "Coordinating", cells: 5 },
|
|
14
|
+
mcp: { label: "Calling MCP", cells: 6 },
|
|
15
|
+
writing: { label: "Writing response", cells: 3 },
|
|
16
|
+
// A compact eight-point pixel flare: completion is a resolved signal,
|
|
17
|
+
// not a checkmark and never an idle loader.
|
|
18
|
+
complete: { label: "Completed", cells: 8 },
|
|
19
|
+
error: { label: "Needs attention", cells: 5 },
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function modeFor(status = {}) {
|
|
23
|
+
const value = `${status.phase || ""} ${status.label || ""} ${status.name || ""}`.toLowerCase();
|
|
24
|
+
if (/(error|failed|denied|cancel)/.test(value)) return "error";
|
|
25
|
+
if (/(complete|finished|done|success)/.test(value)) return "complete";
|
|
26
|
+
if (/(mcp)/.test(value)) return "mcp";
|
|
27
|
+
if (/(team|workflow|orchestrat)/.test(value)) return "orchestration";
|
|
28
|
+
if (/(subagent|delegat|agent)/.test(value)) return "agent";
|
|
29
|
+
if (/(websearch|searching the web|search the web)/.test(value)) return "searching";
|
|
30
|
+
if (/(read|search|find|fetch|glob|grep)/.test(value)) return "reading";
|
|
31
|
+
if (/(write|edit|patch|save)/.test(value)) return "editing";
|
|
32
|
+
if (/(bash|command|run(?:ning)?|terminal|exec)/.test(value)) return "command";
|
|
33
|
+
if (/(respond|stream|writing response)/.test(value)) return "writing";
|
|
34
|
+
return "thinking";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function markup(status = {}) {
|
|
38
|
+
const mode = modeFor(status);
|
|
39
|
+
const config = MODES[mode];
|
|
40
|
+
const pixels = Array.from({ length: config.cells }, (_, index) => `<i class="chat-status-motion__pixel chat-status-motion__pixel--${index}" aria-hidden="true"></i>`).join("");
|
|
41
|
+
return `<span class="chat-status-motion chat-status-motion--${mode}" data-chat-status-motion="${mode}" role="img" aria-label="${config.label}"><span class="chat-status-motion__pixels">${pixels}</span></span>`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function stop(node) {
|
|
45
|
+
if (!node) return;
|
|
46
|
+
const timeline = node._chatStatusTimeline;
|
|
47
|
+
if (timeline) timeline.kill();
|
|
48
|
+
const gsap = window.gsap;
|
|
49
|
+
const pixels = [...node.querySelectorAll?.(".chat-status-motion__pixel") || []];
|
|
50
|
+
gsap?.killTweensOf?.(pixels);
|
|
51
|
+
delete node._chatStatusTimeline;
|
|
52
|
+
delete node.dataset.chatStatusAnimating;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function reducedMotion() {
|
|
56
|
+
return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function animate(node) {
|
|
60
|
+
if (!node) return;
|
|
61
|
+
stop(node);
|
|
62
|
+
const gsap = window.gsap;
|
|
63
|
+
const mode = node.dataset.chatStatusMotion || "thinking";
|
|
64
|
+
const pixels = [...node.querySelectorAll(".chat-status-motion__pixel")];
|
|
65
|
+
const terminal = mode === "complete" || mode === "error";
|
|
66
|
+
if (!gsap || !pixels.length || reducedMotion()) {
|
|
67
|
+
gsap?.set?.(pixels, { autoAlpha: 1, x: 0, y: 0, scale: 1, scaleY: 1, rotation: 0 });
|
|
68
|
+
if (terminal) node.dataset.chatStatusSettled = "true";
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
delete node.dataset.chatStatusSettled;
|
|
73
|
+
if (terminal) node.dataset.chatStatusAnimating = "true";
|
|
74
|
+
gsap.set(pixels, { autoAlpha: 0.26, x: 0, y: 0, scale: 0.9, scaleY: 1, rotation: 0, transformOrigin: "50% 50%" });
|
|
75
|
+
// Only live states repeat. Terminal status always owns a finite timeline.
|
|
76
|
+
const tl = gsap.timeline({ repeat: terminal ? 0 : -1, defaults: { ease: "sine.inOut" } });
|
|
77
|
+
const even = pixels.filter((_, index) => index % 2 === 0);
|
|
78
|
+
const odd = pixels.filter((_, index) => index % 2 === 1);
|
|
79
|
+
|
|
80
|
+
switch (mode) {
|
|
81
|
+
case "thinking":
|
|
82
|
+
tl.to(pixels, { autoAlpha: 0.66, scale: 1, duration: 0.22, stagger: { each: 0.05, from: "center" } })
|
|
83
|
+
.to(even, { autoAlpha: 1, y: -2, scale: 1.2, duration: 0.24, stagger: { each: 0.075, from: "center" } }, "<.05")
|
|
84
|
+
.to(odd, { autoAlpha: 0.9, y: 2, scale: 1.1, duration: 0.24, stagger: { each: 0.075, from: "center" } }, "<")
|
|
85
|
+
.to(pixels, { autoAlpha: 0.3, x: 0, y: 0, scale: 0.9, duration: 0.34, stagger: { each: 0.04, from: "edges" } });
|
|
86
|
+
break;
|
|
87
|
+
case "reading":
|
|
88
|
+
tl.to(pixels, { autoAlpha: 0.36, duration: 0.1 })
|
|
89
|
+
.to(pixels, { autoAlpha: 1, scaleY: 1.45, duration: 0.14, stagger: { each: 0.065, from: "start" } })
|
|
90
|
+
.to(pixels, { autoAlpha: 0.32, scaleY: 0.92, duration: 0.16, stagger: { each: 0.065, from: "end" } });
|
|
91
|
+
break;
|
|
92
|
+
case "searching":
|
|
93
|
+
tl.to(pixels, { autoAlpha: 0.3, scale: 0.82, duration: 0.12 })
|
|
94
|
+
.to(pixels, { autoAlpha: 1, scale: 1.2, duration: 0.17, stagger: { each: 0.07, from: "center" } })
|
|
95
|
+
.to(pixels, { autoAlpha: 0.36, scale: 0.92, duration: 0.2, stagger: { each: 0.07, from: "edges" } });
|
|
96
|
+
break;
|
|
97
|
+
case "command":
|
|
98
|
+
tl.to(pixels, { autoAlpha: 0.34, duration: 0.1 })
|
|
99
|
+
.to(pixels, { autoAlpha: 1, x: 2, duration: 0.1, stagger: { each: 0.05, from: "start" } })
|
|
100
|
+
.to(pixels, { autoAlpha: 0.42, x: 0, duration: 0.13, stagger: { each: 0.05, from: "end" } });
|
|
101
|
+
break;
|
|
102
|
+
case "editing":
|
|
103
|
+
tl.to(pixels, { autoAlpha: 1, rotation: -24, y: -2, scale: 1.14, duration: 0.19, stagger: { each: 0.055, from: "start" } })
|
|
104
|
+
.to(pixels, { autoAlpha: 0.3, rotation: 0, y: 1, scale: 0.88, duration: 0.26, stagger: { each: 0.055, from: "end" } });
|
|
105
|
+
break;
|
|
106
|
+
case "agent":
|
|
107
|
+
tl.to(pixels, { autoAlpha: 1, scale: 1.28, duration: 0.23, stagger: { each: 0.085, from: "center" } })
|
|
108
|
+
.to(pixels, { autoAlpha: 0.35, scale: 0.76, duration: 0.28, stagger: { each: 0.085, from: "edges" } });
|
|
109
|
+
break;
|
|
110
|
+
case "orchestration":
|
|
111
|
+
tl.to(even, { autoAlpha: 1, x: 2, y: -1, duration: 0.19, stagger: { each: 0.09, from: "start" } })
|
|
112
|
+
.to(odd, { autoAlpha: 1, x: -2, y: 1, duration: 0.19, stagger: { each: 0.09, from: "end" } }, "<")
|
|
113
|
+
.to(pixels, { autoAlpha: 0.3, x: 0, y: 0, duration: 0.26 });
|
|
114
|
+
break;
|
|
115
|
+
case "mcp":
|
|
116
|
+
tl.to(even, { autoAlpha: 1, scale: 1.24, duration: 0.17 })
|
|
117
|
+
.to(odd, { autoAlpha: 1, scale: 1.24, duration: 0.17 }, "<.11")
|
|
118
|
+
.to(pixels, { autoAlpha: 0.32, scale: 0.86, duration: 0.22 });
|
|
119
|
+
break;
|
|
120
|
+
case "writing":
|
|
121
|
+
tl.to(pixels, { autoAlpha: 1, y: -2, scale: 1.2, duration: 0.19, stagger: { each: 0.11, from: "start" } })
|
|
122
|
+
.to(pixels, { autoAlpha: 0.34, y: 1, scale: 0.9, duration: 0.26, stagger: { each: 0.11, from: "end" } });
|
|
123
|
+
break;
|
|
124
|
+
case "complete": {
|
|
125
|
+
const points = [pixels[0], pixels[2], pixels[4], pixels[6]].filter(Boolean);
|
|
126
|
+
const diagonals = [pixels[1], pixels[3], pixels[5], pixels[7]].filter(Boolean);
|
|
127
|
+
tl.to(points, { autoAlpha: 1, scale: 1.35, duration: 0.12, stagger: { each: 0.055, from: "center" } })
|
|
128
|
+
.to(diagonals, { autoAlpha: 0.9, scale: 1.12, duration: 0.12, stagger: { each: 0.045, from: "center" } }, "<.045")
|
|
129
|
+
.to(pixels, { autoAlpha: 1, x: 0, y: 0, scale: 1, scaleY: 1, rotation: 0, duration: 0.2, stagger: { each: 0.018, from: "center" } });
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "error":
|
|
133
|
+
tl.to(pixels, { autoAlpha: 1, x: -2, duration: 0.09 })
|
|
134
|
+
.to(pixels, { x: 2, duration: 0.12, repeat: 2, yoyo: true })
|
|
135
|
+
.set(pixels, { autoAlpha: 1, x: 0, y: 0, scale: 1, scaleY: 1 });
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
node._chatStatusTimeline = tl;
|
|
140
|
+
if (terminal) {
|
|
141
|
+
tl.eventCallback("onComplete", () => {
|
|
142
|
+
gsap.killTweensOf(pixels);
|
|
143
|
+
gsap.set(pixels, { autoAlpha: 1, x: 0, y: 0, scale: 1, scaleY: 1, rotation: 0 });
|
|
144
|
+
delete node.dataset.chatStatusAnimating;
|
|
145
|
+
node.dataset.chatStatusSettled = "true";
|
|
146
|
+
if (node._chatStatusTimeline === tl) delete node._chatStatusTimeline;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function render(status = {}) { return markup(status); }
|
|
152
|
+
function animateWithin(root) { root?.querySelectorAll?.("[data-chat-status-motion]").forEach(animate); }
|
|
153
|
+
window.OpenKanChatMotion = { render, animate, animateWithin, stop, modeFor };
|
|
154
|
+
})();
|