@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +226 -0
  2. package/LICENSE +21 -0
  3. package/README.md +318 -0
  4. package/agents/openkan.md +254 -0
  5. package/bin/install-agent.mjs +63 -0
  6. package/bin/ok.mjs +17 -0
  7. package/bin/openkan.mjs +10 -0
  8. package/dist/.claude/skills/ok-planning/SKILL.md +285 -0
  9. package/dist/.claude/skills/ok-planning/references/integration.md +153 -0
  10. package/dist/.claude/skills/ok-planning/references/schemas.md +270 -0
  11. package/dist/.claude/skills/ok-planning/references/workflows.md +185 -0
  12. package/dist/.claude/skills/ok-planning/scripts/ok-init.sh +14 -0
  13. package/dist/.claude/skills/ok-planning/scripts/ok-resume.sh +38 -0
  14. package/dist/.claude/skills/ok-planning/scripts/ok-status.sh +24 -0
  15. package/dist/agents/openkan.md +254 -0
  16. package/dist/bin/install-agent.mjs +76 -0
  17. package/dist/bin/ok-install.js +58 -0
  18. package/dist/bin/ok.js +138 -0
  19. package/dist/bin/openkan.js +804 -0
  20. package/dist/commands/organize.md +15 -0
  21. package/dist/kanban/agent-profile.js +8 -0
  22. package/dist/kanban/archive.js +49 -0
  23. package/dist/kanban/bizar.js +242 -0
  24. package/dist/kanban/board.js +367 -0
  25. package/dist/kanban/bulk.js +139 -0
  26. package/dist/kanban/changelog.js +186 -0
  27. package/dist/kanban/chat.js +1280 -0
  28. package/dist/kanban/claude-state.js +974 -0
  29. package/dist/kanban/comments.js +80 -0
  30. package/dist/kanban/docs.js +144 -0
  31. package/dist/kanban/fs.js +163 -0
  32. package/dist/kanban/git.js +196 -0
  33. package/dist/kanban/images.js +140 -0
  34. package/dist/kanban/import.js +295 -0
  35. package/dist/kanban/inputs.js +94 -0
  36. package/dist/kanban/insights.js +140 -0
  37. package/dist/kanban/io.js +75 -0
  38. package/dist/kanban/mdx-render.js +348 -0
  39. package/dist/kanban/mdx.js +231 -0
  40. package/dist/kanban/projects.js +545 -0
  41. package/dist/kanban/search.js +121 -0
  42. package/dist/kanban/server.js +3296 -0
  43. package/dist/kanban/tags.js +124 -0
  44. package/dist/kanban/template.js +145 -0
  45. package/dist/kanban/tsx-sandbox.js +187 -0
  46. package/dist/kanban/watcher.js +270 -0
  47. package/dist/ok/commands/goal.js +65 -0
  48. package/dist/ok/commands/index.js +87 -0
  49. package/dist/ok/commands/init.js +15 -0
  50. package/dist/ok/commands/plan.js +155 -0
  51. package/dist/ok/commands/prd.js +202 -0
  52. package/dist/ok/commands/progress.js +31 -0
  53. package/dist/ok/commands/task.js +377 -0
  54. package/dist/ok/ids.js +98 -0
  55. package/dist/ok/lock.js +156 -0
  56. package/dist/ok/migrate.js +197 -0
  57. package/dist/ok/schemas.js +402 -0
  58. package/dist/ok/storage.js +222 -0
  59. package/dist/skills/openkan/SKILL.md +111 -0
  60. package/dist/skills/openkan/agents/openai.yaml +4 -0
  61. package/dist/skills/openkan/examples/simple-task.mdx +34 -0
  62. package/dist/skills/openkan/examples/with-ask.mdx +32 -0
  63. package/dist/skills/openkan/examples/with-choice.mdx +51 -0
  64. package/dist/skills/openkan/examples/with-preview.mdx +54 -0
  65. package/dist/skills/openkan/references/api.md +169 -0
  66. package/dist/skills/openkan/templates/task.mdx +46 -0
  67. package/dist/web/api.js +257 -0
  68. package/dist/web/app.js +4251 -0
  69. package/dist/web/bizar.js +39 -0
  70. package/dist/web/brand/agent-activity-sprite.svg +1 -0
  71. package/dist/web/brand/banner-docs.svg +24 -0
  72. package/dist/web/brand/banner.svg +32 -0
  73. package/dist/web/brand/empty-sessions.svg +17 -0
  74. package/dist/web/brand/empty-tasks.svg +17 -0
  75. package/dist/web/brand/favicon.svg +9 -0
  76. package/dist/web/brand/infinity-loader-animated.svg +220 -0
  77. package/dist/web/brand/infinity-loader-spritesheet.svg +230 -0
  78. package/dist/web/brand/logo-wordmark.svg +10 -0
  79. package/dist/web/brand/logo.svg +9 -0
  80. package/dist/web/brand/pixel-infinity-track.svg +1 -0
  81. package/dist/web/brand/social-card.svg +26 -0
  82. package/dist/web/changelog-view.js +456 -0
  83. package/dist/web/charts.js +269 -0
  84. package/dist/web/chat-sidebar.js +2397 -0
  85. package/dist/web/chat-status-motion.js +154 -0
  86. package/dist/web/claude-pane.js +820 -0
  87. package/dist/web/command-palette.js +381 -0
  88. package/dist/web/contributors-view.js +317 -0
  89. package/dist/web/cross-tab.js +102 -0
  90. package/dist/web/docs-view.js +168 -0
  91. package/dist/web/experience.css +165 -0
  92. package/dist/web/goals-view.js +45 -0
  93. package/dist/web/home-view.js +113 -0
  94. package/dist/web/images.js +311 -0
  95. package/dist/web/index.html +485 -0
  96. package/dist/web/insights.js +217 -0
  97. package/dist/web/keyboard.js +446 -0
  98. package/dist/web/mdx-viewer.js +600 -0
  99. package/dist/web/path-picker.js +787 -0
  100. package/dist/web/preview-frame.html +187 -0
  101. package/dist/web/settings.js +582 -0
  102. package/dist/web/style.css +8545 -0
  103. package/dist/web/task-view.js +1759 -0
  104. package/dist/web/vendor/gsap.min.js +11 -0
  105. package/dist/web/workspace.css +1513 -0
  106. package/package.json +71 -0
  107. package/skills/openkan/SKILL.md +111 -0
  108. package/skills/openkan/agents/openai.yaml +4 -0
  109. package/skills/openkan/examples/simple-task.mdx +34 -0
  110. package/skills/openkan/examples/with-ask.mdx +32 -0
  111. package/skills/openkan/examples/with-choice.mdx +51 -0
  112. package/skills/openkan/examples/with-preview.mdx +54 -0
  113. package/skills/openkan/references/api.md +169 -0
  114. package/skills/openkan/templates/task.mdx +46 -0
@@ -0,0 +1,187 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>OpenKan · Preview Frame</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0d1117;
10
+ --bg-elev: #161b22;
11
+ --bg-elev-2: #1f242c;
12
+ --border: #2a313a;
13
+ --text: #e6edf3;
14
+ --text-dim: #9aa4af;
15
+ --text-mute: #6b7480;
16
+ --accent: #4493f8;
17
+ --danger: #f85149;
18
+ }
19
+ * { box-sizing: border-box; }
20
+ html, body {
21
+ margin: 0;
22
+ background: var(--bg);
23
+ color: var(--text);
24
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
25
+ height: 100%;
26
+ }
27
+ body {
28
+ display: flex;
29
+ flex-direction: column;
30
+ padding: 24px;
31
+ gap: 16px;
32
+ }
33
+ h1 { margin: 0; font-size: 16px; font-weight: 600; }
34
+ .toolbar {
35
+ display: flex;
36
+ gap: 8px;
37
+ align-items: center;
38
+ flex-wrap: wrap;
39
+ }
40
+ .toolbar label { font-size: 12px; color: var(--text-dim); display: flex; gap: 6px; align-items: center; }
41
+ .toolbar input {
42
+ background: var(--bg-elev);
43
+ color: var(--text);
44
+ border: 1px solid var(--border);
45
+ border-radius: 4px;
46
+ padding: 4px 8px;
47
+ font-size: 13px;
48
+ min-width: 240px;
49
+ }
50
+ .toolbar button {
51
+ background: var(--accent);
52
+ color: white;
53
+ border: 0;
54
+ border-radius: 4px;
55
+ padding: 6px 14px;
56
+ font-size: 13px;
57
+ cursor: pointer;
58
+ }
59
+ textarea {
60
+ flex: 1;
61
+ width: 100%;
62
+ min-height: 200px;
63
+ background: var(--bg-elev);
64
+ color: var(--text);
65
+ border: 1px solid var(--border);
66
+ border-radius: 4px;
67
+ padding: 12px;
68
+ font-family: ui-monospace, "SF Mono", "Menlo", "Consolas", monospace;
69
+ font-size: 12.5px;
70
+ line-height: 1.45;
71
+ resize: vertical;
72
+ }
73
+ .stage {
74
+ flex: 1;
75
+ min-height: 280px;
76
+ background: white;
77
+ border: 1px solid var(--border);
78
+ border-radius: 6px;
79
+ overflow: hidden;
80
+ }
81
+ .stage iframe {
82
+ width: 100%;
83
+ height: 100%;
84
+ min-height: 280px;
85
+ border: 0;
86
+ }
87
+ .stage .error {
88
+ padding: 16px;
89
+ color: var(--danger);
90
+ font-family: ui-monospace, "SF Mono", "Menlo", "Consolas", monospace;
91
+ font-size: 12.5px;
92
+ white-space: pre-wrap;
93
+ }
94
+ .meta { font-size: 12px; color: var(--text-mute); }
95
+ </style>
96
+ </head>
97
+ <body>
98
+ <header>
99
+ <h1>OpenKan · TSX Preview Sandbox</h1>
100
+ <p class="meta">
101
+ This page is a developer convenience for testing <code>&lt;Preview&gt;</code> snippets
102
+ outside the kanban board. Paste TSX below (or pass <code>?tsx=…</code> in the URL); the
103
+ server's <code>/api/preview</code> endpoint compiles it and renders the sandboxed iframe here.
104
+ </p>
105
+ </header>
106
+
107
+ <div class="toolbar">
108
+ <label>
109
+ Props (JSON)
110
+ <input id="props-input" type="text" value="{}" placeholder='e.g. {"name":"world"}' />
111
+ </label>
112
+ <button id="run-btn" type="button">Compile &amp; Run</button>
113
+ </div>
114
+
115
+ <textarea id="tsx-input" placeholder="Paste your TSX here. Example:&#10;&#10;return h('div', { class: 'ok-card' }, [&#10; h('h3', {}, 'Hello'),&#10; h('p', {}, 'From the sandbox.')&#10;]);"></textarea>
116
+
117
+ <div class="stage" id="stage">
118
+ <iframe id="sandbox" sandbox="allow-scripts" referrerpolicy="no-referrer" title="Sandbox"></iframe>
119
+ </div>
120
+
121
+ <script>
122
+ (() => {
123
+ "use strict";
124
+
125
+ const tsxInput = document.getElementById("tsx-input");
126
+ const propsInput = document.getElementById("props-input");
127
+ const runBtn = document.getElementById("run-btn");
128
+ const stage = document.getElementById("stage");
129
+ const sandbox = document.getElementById("sandbox");
130
+
131
+ // Pre-fill from ?tsx= query string.
132
+ const url = new URL(window.location.href);
133
+ const initialTsx = url.searchParams.get("tsx");
134
+ if (initialTsx) tsxInput.value = initialTsx;
135
+
136
+ async function run() {
137
+ const tsx = tsxInput.value;
138
+ let props = {};
139
+ try { props = JSON.parse(propsInput.value || "{}"); } catch (e) {
140
+ stage.innerHTML = '<div class="error">Invalid props JSON: ' + e.message + '</div>';
141
+ return;
142
+ }
143
+ stage.innerHTML = '<div class="meta" style="padding:16px;color:#9aa4af;">Compiling…</div>';
144
+ let res;
145
+ try {
146
+ res = await fetch("/api/preview", {
147
+ method: "POST",
148
+ headers: { "Content-Type": "application/json" },
149
+ body: JSON.stringify({ tsx, props }),
150
+ });
151
+ } catch (err) {
152
+ stage.innerHTML = '<div class="error">Network error: ' + err.message + '</div>';
153
+ return;
154
+ }
155
+ let body;
156
+ try { body = await res.json(); } catch (e) {
157
+ stage.innerHTML = '<div class="error">Bad response from server.</div>';
158
+ return;
159
+ }
160
+ if (!res.ok || body.error) {
161
+ stage.innerHTML = '<div class="error">' + (body.error || res.statusText) + '</div>';
162
+ return;
163
+ }
164
+ stage.innerHTML = "";
165
+ const iframe = document.createElement("iframe");
166
+ iframe.setAttribute("sandbox", "allow-scripts");
167
+ iframe.setAttribute("referrerpolicy", "no-referrer");
168
+ iframe.setAttribute("title", "Sandbox");
169
+ iframe.style.width = "100%";
170
+ iframe.style.height = "100%";
171
+ iframe.style.minHeight = "280px";
172
+ iframe.style.border = "0";
173
+ iframe.srcdoc = body.sandboxHtml;
174
+ stage.append(iframe);
175
+ }
176
+
177
+ runBtn.addEventListener("click", run);
178
+ tsxInput.addEventListener("keydown", (e) => {
179
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
180
+ e.preventDefault();
181
+ run();
182
+ }
183
+ });
184
+ })();
185
+ </script>
186
+ </body>
187
+ </html>