@panaversity/ksor 0.0.26 → 0.0.28
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 +65 -0
- package/dist/cli.mjs +67 -4
- package/dist/{gateway-api-BF06IsJ--D-eI--yB.mjs → gateway-api-8lNruq9e-CuohjtoK.mjs} +1 -1
- package/dist/gateway.mjs +1 -1
- package/package.json +1 -1
- package/templates/scaffold/.agents/skills/format-checker/check.mjs +83 -2
- package/templates/scaffold/.claude/skills/format-checker/check.mjs +83 -2
- package/templates/scaffold/AGENTS.md +49 -0
- package/templates/scaffold/Dockerfile +10 -6
- package/templates/scaffold/README.md +3 -2
- package/templates/scaffold/dockerignore +5 -0
- package/templates/scaffold/knowledge/what-is-a-ksor.flashcards.yaml +25 -0
- package/templates/scaffold/knowledge/what-is-a-ksor.summary.md +15 -0
- package/templates/scaffold/system/site/app/docs/[[...slug]]/page.tsx +45 -7
- package/templates/scaffold/system/site/components/document-actions.tsx +106 -0
- package/templates/scaffold/system/site/components/flashcards.tsx +743 -0
- package/templates/scaffold/system/site/components/governance.tsx +17 -25
- package/templates/scaffold/system/site/components/record-views.tsx +241 -0
- package/templates/scaffold/system/site/components/study-aids.tsx +61 -0
- package/templates/scaffold/system/site/components/ui/card.tsx +76 -0
- package/templates/scaffold/system/site/components/ui/dropdown-menu.tsx +229 -0
- package/templates/scaffold/system/site/components/ui/progress.tsx +29 -0
- package/templates/scaffold/system/site/lib/attachment-rule.ts +124 -0
- package/templates/scaffold/system/site/lib/attachments.ts +105 -0
- package/templates/scaffold/system/site/lib/deck.ts +59 -0
- package/templates/scaffold/system/site/lib/reading-time.ts +45 -0
- package/templates/scaffold/system/site/lib/srs.ts +219 -0
- package/templates/scaffold/system/site/lib/stage-knowledge.ts +68 -0
- package/templates/scaffold/system/site/source.config.ts +54 -1
- package/templates/scaffold/system/site/components/copy-markdown.tsx +0 -70
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Check, ChevronDown, Copy, Download, FileText } from "lucide-react";
|
|
4
|
+
import { useCallback, useEffect, useRef, useState, type ReactElement } from "react";
|
|
5
|
+
|
|
6
|
+
import { Button } from "@/components/ui/button";
|
|
7
|
+
import {
|
|
8
|
+
DropdownMenu,
|
|
9
|
+
DropdownMenuContent,
|
|
10
|
+
DropdownMenuItem,
|
|
11
|
+
DropdownMenuTrigger,
|
|
12
|
+
} from "@/components/ui/dropdown-menu";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* What a reader can DO with this document, behind one control.
|
|
16
|
+
*
|
|
17
|
+
* Opening the markdown twin and handing it to an agent are different acts, and
|
|
18
|
+
* a reader who wants the second should not have to perform the first — but two
|
|
19
|
+
* bare controls sitting on a row of read-only facts made the row look half
|
|
20
|
+
* clickable. One trigger says "there are actions here" once, and the menu says
|
|
21
|
+
* what they are.
|
|
22
|
+
*
|
|
23
|
+
* Putting the markdown LINK behind a click is safe for the audience that reads
|
|
24
|
+
* bytes: `generateMetadata` already advertises the twin as
|
|
25
|
+
* `<link rel="alternate" type="text/markdown">` in the head, so a crawler and
|
|
26
|
+
* an agent find the address without opening anything. Verified in the built
|
|
27
|
+
* HTML before this moved.
|
|
28
|
+
*/
|
|
29
|
+
export function DocumentActions({ href }: { readonly href: string }): ReactElement {
|
|
30
|
+
const [failed, setFailed] = useState(false);
|
|
31
|
+
const [copied, setCopied] = useState(false);
|
|
32
|
+
const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
33
|
+
|
|
34
|
+
// The shell ships `useCopyButton`, which owns this timing — but it hands back
|
|
35
|
+
// a MouseEventHandler, and a menu item reports selection as a CustomEvent.
|
|
36
|
+
// Casting one to the other to reuse six lines is worse than the six lines.
|
|
37
|
+
useEffect(
|
|
38
|
+
() => () => {
|
|
39
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
40
|
+
},
|
|
41
|
+
[],
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const onCopy = useCallback(async () => {
|
|
45
|
+
try {
|
|
46
|
+
const markdown = await fetch(href).then((response) => response.text());
|
|
47
|
+
await navigator.clipboard.writeText(markdown);
|
|
48
|
+
setFailed(false);
|
|
49
|
+
setCopied(true);
|
|
50
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
51
|
+
timer.current = setTimeout(() => setCopied(false), 1600);
|
|
52
|
+
} catch {
|
|
53
|
+
// A refused clipboard or a failed fetch is not an error where a document
|
|
54
|
+
// should be: the menu says so, and View markdown still works.
|
|
55
|
+
setFailed(true);
|
|
56
|
+
}
|
|
57
|
+
}, [href]);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<DropdownMenu>
|
|
61
|
+
<DropdownMenuTrigger asChild>
|
|
62
|
+
<Button
|
|
63
|
+
variant="ghost"
|
|
64
|
+
size="sm"
|
|
65
|
+
className="h-auto gap-1.5 px-2 py-1 font-mono text-[0.6875rem] tracking-[0.14em] text-fd-muted-foreground uppercase hover:text-fd-foreground"
|
|
66
|
+
>
|
|
67
|
+
{/* "Export", not "Markdown": the word appeared three times in one
|
|
68
|
+
small control, and naming the FORMAT locks the trigger to it — a
|
|
69
|
+
later Download or Cite would make it wrong. Not "Source", which
|
|
70
|
+
collides with the provenance block below. Not "Share", which in a
|
|
71
|
+
record where `visibility:` decides who may read a document is the
|
|
72
|
+
wrong verb entirely. */}
|
|
73
|
+
<Download aria-hidden className="size-3.5" />
|
|
74
|
+
Export
|
|
75
|
+
<ChevronDown aria-hidden className="size-3 opacity-60" />
|
|
76
|
+
</Button>
|
|
77
|
+
</DropdownMenuTrigger>
|
|
78
|
+
|
|
79
|
+
<DropdownMenuContent align="start" className="w-52">
|
|
80
|
+
<DropdownMenuItem asChild>
|
|
81
|
+
<a href={href}>
|
|
82
|
+
<FileText aria-hidden className="size-4" />
|
|
83
|
+
View markdown
|
|
84
|
+
</a>
|
|
85
|
+
</DropdownMenuItem>
|
|
86
|
+
|
|
87
|
+
{/* onSelect is prevented so the menu stays open long enough to show
|
|
88
|
+
that the copy landed — closing on the click would take the only
|
|
89
|
+
feedback away with it. */}
|
|
90
|
+
<DropdownMenuItem
|
|
91
|
+
onSelect={(event) => {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
void onCopy();
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
{copied ? (
|
|
97
|
+
<Check aria-hidden className="size-4 text-fd-primary" />
|
|
98
|
+
) : (
|
|
99
|
+
<Copy aria-hidden className="size-4" />
|
|
100
|
+
)}
|
|
101
|
+
{failed ? "Copy failed — open it instead" : copied ? "Copied" : "Copy markdown"}
|
|
102
|
+
</DropdownMenuItem>
|
|
103
|
+
</DropdownMenuContent>
|
|
104
|
+
</DropdownMenu>
|
|
105
|
+
);
|
|
106
|
+
}
|