@fabrika/canvas-kernel 0.1.45 → 0.3.1
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/README.md +33 -67
- package/index.ts +20 -83
- package/package.json +69 -72
- package/src/client/AnnotationProvider.tsx +218 -255
- package/src/client/AnnotationSidebar.tsx +393 -338
- package/src/client/FileIcon.tsx +105 -66
- package/src/client/PlanRenderer.tsx +607 -551
- package/src/client/RenderErrorContext.ts +7 -7
- package/src/client/ResponsePreview.tsx +192 -173
- package/src/client/annotationDom.ts +43 -97
- package/src/client/annotationDraft.ts +106 -96
- package/src/client/appContext.tsx +40 -40
- package/src/client/components/Callout.tsx +20 -20
- package/src/client/components/Checklist.tsx +27 -29
- package/src/client/components/Choice.tsx +178 -159
- package/src/client/components/CodeBlock.tsx +27 -26
- package/src/client/components/Diff.tsx +16 -17
- package/src/client/components/FilePreview.tsx +102 -74
- package/src/client/components/Image.tsx +41 -39
- package/src/client/components/Markdown.tsx +33 -32
- package/src/client/components/Mermaid.tsx +593 -542
- package/src/client/components/Note.tsx +8 -8
- package/src/client/components/Priority.tsx +10 -12
- package/src/client/components/ResponseNote.tsx +16 -15
- package/src/client/components/Section.tsx +28 -26
- package/src/client/components/Table.tsx +33 -30
- package/src/client/components/Task.tsx +58 -60
- package/src/client/components/UserInput.tsx +169 -152
- package/src/client/components/index.ts +16 -16
- package/src/client/components/renderMarkdownChildren.tsx +86 -68
- package/src/client/diffLines.ts +51 -39
- package/src/client/generateMarkdown.ts +197 -191
- package/src/client/hostContext.tsx +39 -34
- package/src/client/index.ts +44 -125
- package/src/client/pageGlobals.ts +25 -0
- package/src/client/persistenceSchemas.ts +41 -0
- package/src/client/preact-all.ts +4 -4
- package/src/client/runtime.ts +58 -111
- package/src/client/styles.css +1 -74
- package/src/engine/compiler.ts +411 -323
- package/src/engine/file-admission.ts +25 -0
- package/src/engine/paths.ts +44 -44
- package/src/engine/session.ts +515 -626
- package/src/engine/sessionSchemas.ts +71 -0
- package/src/engine/watcher.ts +70 -60
- package/src/engine/websocket.ts +134 -132
- package/annotate.ts +0 -94
- package/daemon.ts +0 -46
- package/src/client/AnnotationDraftFooter.tsx +0 -76
- package/src/client/AnnotationEditor.tsx +0 -320
- package/src/client/AnnotationList.tsx +0 -190
- package/src/client/Popover.tsx +0 -361
- package/src/client/SessionContext.tsx +0 -3
- package/src/client/annotationContext.ts +0 -130
- package/src/client/annotationMarkdown.ts +0 -102
- package/src/client/annotationTarget.ts +0 -73
- package/src/client/blockTarget.ts +0 -127
- package/src/client/highlightRange.ts +0 -262
- package/src/client/popoverPosition.ts +0 -46
- package/src/client/regionTarget.ts +0 -180
- package/src/client/testing/dom.ts +0 -74
- package/src/client/textTarget.ts +0 -31
- package/src/client/useRegionAnnotation.tsx +0 -188
- package/src/client/useTextAnnotation.tsx +0 -194
- package/src/client/utils.ts +0 -33
- package/src/engine/channel.ts +0 -278
- package/src/engine/http-utils.ts +0 -14
- package/src/engine/lifecycle.ts +0 -302
- package/src/engine/router.ts +0 -16
- package/src/engine/waiter.ts +0 -188
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { renderMarkdownChildren } from
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderMarkdownChildren } from './renderMarkdownChildren'
|
|
3
3
|
|
|
4
4
|
interface NoteProps {
|
|
5
|
-
|
|
5
|
+
children?: React.ReactNode
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function Note({ children }: NoteProps) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
return (
|
|
10
|
+
<div className="relative bg-bg-elevated rounded-lg px-5 py-4 mt-3 text-body text-text-secondary italic leading-relaxed" data-md="note">
|
|
11
|
+
{renderMarkdownChildren(children)}
|
|
12
|
+
</div>
|
|
13
|
+
)
|
|
14
14
|
}
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
1
|
interface PriorityProps {
|
|
4
|
-
|
|
2
|
+
level: 'high' | 'medium' | 'low'
|
|
5
3
|
}
|
|
6
4
|
|
|
7
5
|
const config = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
6
|
+
high: 'text-accent-red bg-accent-red-muted',
|
|
7
|
+
medium: 'text-accent-amber bg-accent-amber-muted',
|
|
8
|
+
low: 'text-text-tertiary bg-border-subtle',
|
|
9
|
+
}
|
|
12
10
|
|
|
13
11
|
export function Priority({ level }: PriorityProps) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
return (
|
|
13
|
+
<span className={`inline text-tiny font-medium font-body ml-2 px-1.5 py-0.5 rounded ${config[level]}`} data-md="priority" data-md-level={level}>
|
|
14
|
+
{level}
|
|
15
|
+
</span>
|
|
16
|
+
)
|
|
19
17
|
}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { autoResizeTextarea } from "../utils";
|
|
1
|
+
import { autoResizeTextarea } from '@fabrika/annotations'
|
|
3
2
|
|
|
4
3
|
/** Seamless note input for response components */
|
|
5
4
|
export function ResponseNote({ note, onChange }: { show?: boolean; note: string; onToggle?: () => void; onChange: (n: string) => void }) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
return (
|
|
6
|
+
<div className="mt-1.5">
|
|
7
|
+
<textarea
|
|
8
|
+
value={note}
|
|
9
|
+
onChange={(e) => onChange(e.currentTarget.value)}
|
|
10
|
+
className="w-full bg-transparent text-[12px] font-body text-text-primary resize-none focus:outline-none border-none placeholder:text-text-disabled transition-colors min-h-[20px] p-0 leading-relaxed"
|
|
11
|
+
placeholder="Add a note..."
|
|
12
|
+
rows={1}
|
|
13
|
+
onInput={(e) => autoResizeTextarea(e.currentTarget)}
|
|
14
|
+
ref={(el) => {
|
|
15
|
+
if (el) autoResizeTextarea(el)
|
|
16
|
+
}}
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
19
20
|
}
|
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import React, { useState } from
|
|
2
|
-
import { renderMarkdownChildren } from
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { renderMarkdownChildren } from './renderMarkdownChildren'
|
|
3
3
|
|
|
4
4
|
interface SectionProps {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
title: string
|
|
6
|
+
children?: React.ReactNode
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function Section({ title, children }: SectionProps) {
|
|
10
|
-
|
|
10
|
+
const [collapsed, setCollapsed] = useState(false)
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
12
|
+
return (
|
|
13
|
+
<div className="relative mb-8 p-4 group/section" data-md="section" data-md-title={title}>
|
|
14
|
+
<div className="relative mb-2">
|
|
15
|
+
<button
|
|
16
|
+
onClick={() => setCollapsed(!collapsed)}
|
|
17
|
+
className={`absolute -left-8 top-1/2 -translate-y-1/2 text-text-tertiary opacity-0 group-hover/section:opacity-50 hover:!opacity-100 transition-all duration-150 p-0.5 ${
|
|
18
|
+
collapsed ? '-rotate-90' : ''
|
|
19
|
+
}`}
|
|
20
|
+
>
|
|
21
|
+
<svg width="14" height="14" viewBox="0 0 12 12" fill="none">
|
|
22
|
+
<path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
|
23
|
+
</svg>
|
|
24
|
+
</button>
|
|
25
|
+
<h2
|
|
26
|
+
className="font-heading text-section text-text-primary"
|
|
27
|
+
style={{ fontWeight: 400 }}
|
|
28
|
+
>
|
|
29
|
+
{title}
|
|
30
|
+
</h2>
|
|
31
|
+
</div>
|
|
32
|
+
<div className={collapsed ? 'mt-6 hidden' : 'mt-6'}>{renderMarkdownChildren(children)}</div>
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
33
35
|
}
|
|
@@ -1,35 +1,38 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
1
|
interface TableProps {
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
headers: string[]
|
|
3
|
+
rows: string[][]
|
|
6
4
|
}
|
|
7
5
|
|
|
8
6
|
export function Table({ headers, rows }: TableProps) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
7
|
+
return (
|
|
8
|
+
<div className="overflow-x-auto mt-3" data-md="table">
|
|
9
|
+
<table className="w-full text-body">
|
|
10
|
+
<thead>
|
|
11
|
+
<tr className="border-b border-border-subtle">
|
|
12
|
+
{headers.map((h, i) => (
|
|
13
|
+
<th key={i} className="text-left px-4 py-2.5 text-meta font-medium uppercase tracking-wider text-text-tertiary font-body">
|
|
14
|
+
{h}
|
|
15
|
+
</th>
|
|
16
|
+
))}
|
|
17
|
+
</tr>
|
|
18
|
+
</thead>
|
|
19
|
+
<tbody>
|
|
20
|
+
{rows.map((row, ri) => (
|
|
21
|
+
<tr
|
|
22
|
+
key={ri}
|
|
23
|
+
className={`relative border-b border-border-subtle last:border-b-0 transition-colors hover:bg-bg-surface/50 ${
|
|
24
|
+
ri % 2 === 1 ? 'bg-bg-surface/30' : ''
|
|
25
|
+
}`}
|
|
26
|
+
>
|
|
27
|
+
{row.map((cell, ci) => (
|
|
28
|
+
<td key={ci} className="px-4 py-2.5 text-text-secondary font-body">
|
|
29
|
+
{cell}
|
|
30
|
+
</td>
|
|
31
|
+
))}
|
|
32
|
+
</tr>
|
|
33
|
+
))}
|
|
34
|
+
</tbody>
|
|
35
|
+
</table>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
35
38
|
}
|
|
@@ -1,76 +1,74 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { renderMarkdownChildren } from
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderMarkdownChildren } from './renderMarkdownChildren'
|
|
3
3
|
|
|
4
|
-
type Status =
|
|
5
|
-
type BadgeVariant =
|
|
4
|
+
type Status = 'todo' | 'done' | 'blocked' | 'in-progress'
|
|
5
|
+
type BadgeVariant = 'info' | 'success' | 'warning' | 'danger' | 'neutral'
|
|
6
6
|
|
|
7
7
|
interface ItemProps {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
id: string
|
|
9
|
+
label: string
|
|
10
|
+
status?: Status
|
|
11
|
+
badge?: string
|
|
12
|
+
badgeVariant?: BadgeVariant
|
|
13
|
+
children?: React.ReactNode
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const dotColors: Record<Status, string> = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
17
|
+
todo: 'bg-border-hover',
|
|
18
|
+
done: 'bg-accent-green',
|
|
19
|
+
blocked: 'bg-accent-red',
|
|
20
|
+
'in-progress': 'bg-accent-blue',
|
|
21
|
+
}
|
|
22
22
|
|
|
23
23
|
const statusLabels: Record<Status, string> = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
24
|
+
todo: 'Todo',
|
|
25
|
+
done: 'Done',
|
|
26
|
+
blocked: 'Blocked',
|
|
27
|
+
'in-progress': 'In progress',
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
const badgeStyles: Record<BadgeVariant, string> = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
31
|
+
info: 'bg-accent-blue-muted text-accent-blue',
|
|
32
|
+
success: 'bg-accent-green-muted text-accent-green',
|
|
33
|
+
warning: 'bg-accent-amber-muted text-accent-amber',
|
|
34
|
+
danger: 'bg-accent-red-muted text-accent-red',
|
|
35
|
+
neutral: 'bg-border-subtle text-text-tertiary',
|
|
36
|
+
}
|
|
37
37
|
|
|
38
|
-
export function Item({ id, label, status, badge, badgeVariant =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
</div>
|
|
70
|
-
);
|
|
38
|
+
export function Item({ id, label, status, badge, badgeVariant = 'neutral', children }: ItemProps) {
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
className="group/task relative -mx-4 px-4 py-3 rounded-md transition-colors duration-150 hover:bg-bg-input"
|
|
42
|
+
data-task-id={id}
|
|
43
|
+
data-md="item"
|
|
44
|
+
data-md-label={label}
|
|
45
|
+
{...(status ? { 'data-md-status': status } : {})}
|
|
46
|
+
{...(badge ? { 'data-md-badge': badge } : {})}
|
|
47
|
+
>
|
|
48
|
+
<div className="flex items-start gap-3">
|
|
49
|
+
{status && <span className={`w-2 h-2 rounded-full mt-[7px] flex-shrink-0 ${dotColors[status]}`} />}
|
|
50
|
+
<div className="flex-1 min-w-0">
|
|
51
|
+
<div className="flex items-baseline gap-2">
|
|
52
|
+
<span className="font-body text-task-label font-semibold text-text-primary">{label}</span>
|
|
53
|
+
{status && (
|
|
54
|
+
<span className="font-body text-tiny uppercase tracking-wider text-text-tertiary opacity-0 group-hover/task:opacity-100 transition-opacity duration-150">
|
|
55
|
+
{statusLabels[status]}
|
|
56
|
+
</span>
|
|
57
|
+
)}
|
|
58
|
+
{badge && (
|
|
59
|
+
<span className={`font-body text-tiny font-medium px-1.5 py-px rounded-full ${badgeStyles[badgeVariant]}`}>
|
|
60
|
+
{badge}
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
{children && <div className="text-body text-text-secondary mt-1 leading-relaxed">{renderMarkdownChildren(children)}</div>}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
)
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
/** @deprecated Use <Item> instead */
|
|
74
72
|
export function Task(props: ItemProps) {
|
|
75
|
-
|
|
73
|
+
return <Item {...props} />
|
|
76
74
|
}
|