@devalok/shilp-sutra-karm 0.18.0 → 0.18.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.
Files changed (36) hide show
  1. package/docs/components/admin/admin-dashboard.md +215 -0
  2. package/docs/components/admin/admin-types.md +167 -0
  3. package/docs/components/admin/admin-utils.md +165 -0
  4. package/docs/components/admin/break-admin.md +167 -0
  5. package/docs/components/board/board-column.md +35 -0
  6. package/docs/components/board/board-provider.md +73 -0
  7. package/docs/components/board/board-toolbar.md +36 -0
  8. package/docs/components/board/board-types.md +62 -0
  9. package/docs/components/board/bulk-action-bar.md +38 -0
  10. package/docs/components/board/column-empty.md +33 -0
  11. package/docs/components/board/column-header.md +36 -0
  12. package/docs/components/board/kanban-board.md +53 -0
  13. package/docs/components/board/task-card.md +58 -0
  14. package/docs/components/board/task-context-menu.md +36 -0
  15. package/docs/components/chat/chat-input.md +37 -0
  16. package/docs/components/chat/chat-panel.md +58 -0
  17. package/docs/components/chat/conversation-list.md +47 -0
  18. package/docs/components/chat/message-list.md +44 -0
  19. package/docs/components/chat/streaming-text.md +29 -0
  20. package/docs/components/client/accent-provider.md +29 -0
  21. package/docs/components/client/client-portal-header.md +40 -0
  22. package/docs/components/client/project-card.md +39 -0
  23. package/docs/components/dashboard/attendance-cta.md +47 -0
  24. package/docs/components/dashboard/daily-brief.md +45 -0
  25. package/docs/components/dashboard/scratchpad-widget.md +52 -0
  26. package/docs/components/dashboard/sidebar-scratchpad.md +39 -0
  27. package/docs/components/other/karm-command-registry.md +61 -0
  28. package/docs/components/other/page-skeletons.md +52 -0
  29. package/docs/components/tasks/activity-tab.md +41 -0
  30. package/docs/components/tasks/conversation-tab.md +52 -0
  31. package/docs/components/tasks/files-tab.md +51 -0
  32. package/docs/components/tasks/review-tab.md +49 -0
  33. package/docs/components/tasks/subtasks-tab.md +56 -0
  34. package/docs/components/tasks/task-detail-panel.md +103 -0
  35. package/docs/components/tasks/task-properties.md +79 -0
  36. package/package.json +4 -2
@@ -0,0 +1,58 @@
1
+ # ChatPanel
2
+
3
+ - Import: @devalok/shilp-sutra-karm/chat
4
+ - Server-safe: No
5
+ - Category: chat
6
+
7
+ ## Props
8
+ isOpen: boolean (REQUIRED)
9
+ onOpenChange: (open: boolean) => void (REQUIRED)
10
+ messages: ChatMessage[] (REQUIRED)
11
+ conversations: Conversation[] (REQUIRED)
12
+ agents: Agent[] (default: DEFAULT_AGENTS — Devadoot, Prahari, Sutradhar, Sahayak, Vidwan, Sanchalak, Dwar-Palak)
13
+ selectedAgentId: string (default: "devadoot")
14
+ activeConversationId: string | null
15
+ isStreaming: boolean (default: false)
16
+ streamingText: string (default: "")
17
+ isLoadingMessages: boolean (default: false)
18
+ isLoadingConversations: boolean (default: false)
19
+ onSendMessage: (message: string) => void (REQUIRED)
20
+ onCancelStream: () => void
21
+ onSelectAgent: (agentId: string) => void
22
+ onStartNewChat: () => void
23
+ onSelectConversation: (id: string) => void
24
+ onArchiveConversation: (id: string) => void
25
+ onDeleteConversation: (id: string) => void
26
+ className: string
27
+
28
+ ## Related Types
29
+ Agent: { id: string; name: string; desc: string }
30
+ ChatMessage: { id: string; role: "USER" | "ASSISTANT" | "SYSTEM"; content: string }
31
+ Conversation: { id: string; title: string | null; updatedAt: string }
32
+
33
+ ## Defaults
34
+ agents=DEFAULT_AGENTS, selectedAgentId="devadoot", isStreaming=false, streamingText="", isLoadingMessages=false, isLoadingConversations=false
35
+
36
+ ## Example
37
+ ```jsx
38
+ <ChatPanel
39
+ isOpen={chatOpen}
40
+ onOpenChange={setChatOpen}
41
+ messages={messages}
42
+ conversations={conversations}
43
+ selectedAgentId="devadoot"
44
+ onSendMessage={(msg) => sendMessage(msg)}
45
+ onSelectConversation={(id) => loadConversation(id)}
46
+ />
47
+ ```
48
+
49
+ ## Gotchas
50
+ - Renders inside a Sheet (right side panel), capped at 480px max-width
51
+ - Toggles between MessageList (chat view) and ConversationList (history view) internally
52
+ - The Agent type is exported from this module — use it for custom agent arrays
53
+ - ChatMessage and Conversation types are re-exported from message-list and conversation-list respectively
54
+ - Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> — children are not accepted
55
+
56
+ ## Changes
57
+ ### v0.18.0
58
+ - **Added** Initial release
@@ -0,0 +1,47 @@
1
+ # ConversationList
2
+
3
+ - Import: @devalok/shilp-sutra-karm/chat
4
+ - Server-safe: No
5
+ - Category: chat
6
+
7
+ ## Props
8
+ conversations: Conversation[] (REQUIRED)
9
+ activeConversationId: string | null
10
+ isLoading: boolean (default: false)
11
+ onSelect: (id: string) => void (REQUIRED)
12
+ onNewChat: () => void (REQUIRED)
13
+ onArchive: (id: string) => void
14
+ onDelete: (id: string) => void
15
+ className: string
16
+
17
+ ## Related Types
18
+ Conversation: { id: string; title: string | null; updatedAt: string }
19
+
20
+ ## Defaults
21
+ isLoading=false
22
+
23
+ ## Example
24
+ ```jsx
25
+ <ConversationList
26
+ conversations={conversations}
27
+ activeConversationId={currentConvoId}
28
+ onSelect={(id) => loadConversation(id)}
29
+ onNewChat={() => startNewChat()}
30
+ onArchive={(id) => archiveConversation(id)}
31
+ onDelete={(id) => deleteConversation(id)}
32
+ />
33
+ ```
34
+
35
+ ## Gotchas
36
+ - Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> — the native onSelect is replaced
37
+ - Archive and delete buttons appear on hover for each conversation row
38
+ - If onArchive or onDelete are not provided, the corresponding action buttons are hidden
39
+ - Conversations with null title display as "Untitled conversation"
40
+ - updatedAt is formatted using formatRelativeTime (e.g., "2 hours ago")
41
+ - The active conversation is highlighted with bg-surface-2
42
+ - Shows a loading spinner when isLoading=true
43
+ - Shows "No conversations yet" empty state when the array is empty
44
+
45
+ ## Changes
46
+ ### v0.18.0
47
+ - **Added** Initial release
@@ -0,0 +1,44 @@
1
+ # MessageList
2
+
3
+ - Import: @devalok/shilp-sutra-karm/chat
4
+ - Server-safe: No
5
+ - Category: chat
6
+
7
+ ## Props
8
+ messages: ChatMessage[] (REQUIRED)
9
+ isStreaming: boolean (default: false)
10
+ streamingText: string (default: "")
11
+ isLoadingMessages: boolean (default: false)
12
+ emptyTitle: string (default: "Karm AI")
13
+ emptyDescription: string (default: "Ask me about tasks, projects, attendance, or anything else.")
14
+ className: string
15
+
16
+ ## Related Types
17
+ ChatMessage: { id: string; role: "USER" | "ASSISTANT" | "SYSTEM"; content: string }
18
+
19
+ ## Defaults
20
+ isStreaming=false, streamingText="", isLoadingMessages=false, emptyTitle="Karm AI", emptyDescription="Ask me about tasks, projects, attendance, or anything else."
21
+
22
+ ## Example
23
+ ```jsx
24
+ <MessageList
25
+ messages={messages}
26
+ isStreaming={isStreaming}
27
+ streamingText={currentStreamText}
28
+ isLoadingMessages={loading}
29
+ />
30
+ ```
31
+
32
+ ## Gotchas
33
+ - Auto-scrolls to bottom when messages or streamingText change
34
+ - Three message roles render differently: USER (right-aligned, accent bubble), ASSISTANT (left-aligned, markdown-rendered), SYSTEM (centered, error-styled)
35
+ - When isStreaming=true and streamingText is non-empty, renders a StreamingText component below the message list
36
+ - When isStreaming=true and streamingText is empty, shows animated bouncing dots
37
+ - ASSISTANT messages are rendered with ReactMarkdown — supports markdown formatting
38
+ - Shows a loading spinner when isLoadingMessages=true
39
+ - Shows an empty state with robot icon when no messages and not streaming
40
+ - Uses framer-motion AnimatePresence for enter/exit animations
41
+
42
+ ## Changes
43
+ ### v0.18.0
44
+ - **Added** Initial release
@@ -0,0 +1,29 @@
1
+ # StreamingText
2
+
3
+ - Import: @devalok/shilp-sutra-karm/chat
4
+ - Server-safe: No
5
+ - Category: chat
6
+
7
+ ## Props
8
+ text: string (REQUIRED)
9
+ isComplete: boolean (default: false)
10
+ className: string
11
+
12
+ ## Defaults
13
+ isComplete=false
14
+
15
+ ## Example
16
+ ```jsx
17
+ <StreamingText text={partialResponse} isComplete={!isStreaming} />
18
+ ```
19
+
20
+ ## Gotchas
21
+ - Shows a pulsing cursor block after the text while isComplete=false
22
+ - When isComplete=true, the cursor disappears and the full text is announced to screen readers via aria-live="polite"
23
+ - While streaming (isComplete=false), aria-live is set to "off" to avoid flooding screen readers
24
+ - Text is rendered with ReactMarkdown — supports markdown formatting
25
+ - Extends React.HTMLAttributes<HTMLDivElement>
26
+
27
+ ## Changes
28
+ ### v0.18.0
29
+ - **Added** Initial release
@@ -0,0 +1,29 @@
1
+ # AccentProvider
2
+
3
+ - Import: @devalok/shilp-sutra-karm/client
4
+ - Server-safe: No
5
+ - Category: client
6
+
7
+ ## Props
8
+ accentCss: string | null (default: undefined)
9
+
10
+ ## Defaults
11
+ (no visual defaults — renders nothing)
12
+
13
+ ## Example
14
+ ```jsx
15
+ <AccentProvider accentCss="--color-accent: #d33163; --color-accent-light: #f7e9e9;" />
16
+ ```
17
+
18
+ ## Gotchas
19
+ - Renders null — this is a headless component with no visual output
20
+ - Does NOT accept children — it is not a wrapper/provider component in the React context sense
21
+ - Injects CSS custom properties directly onto document.documentElement via useEffect
22
+ - Properties are cleaned up (removed) when the component unmounts or when accentCss changes
23
+ - Pass a semicolon-separated CSS custom property string (e.g., "--color-accent: #d33163; --color-accent-light: #f7e9e9;")
24
+ - If accentCss is null or undefined, no properties are applied
25
+ - Does NOT extend React.HTMLAttributes — only accepts the accentCss prop
26
+
27
+ ## Changes
28
+ ### v0.18.0
29
+ - **Added** Initial release
@@ -0,0 +1,40 @@
1
+ # ClientPortalHeader
2
+
3
+ - Import: @devalok/shilp-sutra-karm/client
4
+ - Server-safe: No
5
+ - Category: client
6
+
7
+ ## Props
8
+ orgName: string (REQUIRED)
9
+ orgLogo: string | null
10
+ userName: string (REQUIRED)
11
+ userAvatar: string | null
12
+ children: ReactNode
13
+ className: string
14
+
15
+ ## Defaults
16
+ (no prop defaults)
17
+
18
+ ## Example
19
+ ```jsx
20
+ <ClientPortalHeader
21
+ orgName="Acme Corp"
22
+ orgLogo="/logos/acme.png"
23
+ userName="Jane Doe"
24
+ userAvatar="/avatars/jane.jpg"
25
+ >
26
+ <Button variant="ghost" size="sm">Settings</Button>
27
+ </ClientPortalHeader>
28
+ ```
29
+
30
+ ## Gotchas
31
+ - Renders a <header> element — extends React.HTMLAttributes<HTMLElement>
32
+ - If orgLogo is null/undefined, shows a fallback with the first two initials of orgName on an accent background
33
+ - If userAvatar is null/undefined, shows an Avatar fallback with the first two initials of userName
34
+ - children are rendered between the org branding (left) and user avatar (right) — use this slot for action buttons or navigation
35
+ - The user's full name is hidden on small screens (shown only on sm: and above)
36
+ - Fixed height of h-ds-lg with bottom border
37
+
38
+ ## Changes
39
+ ### v0.18.0
40
+ - **Added** Initial release
@@ -0,0 +1,39 @@
1
+ # ProjectCard
2
+
3
+ - Import: @devalok/shilp-sutra-karm/client
4
+ - Server-safe: No
5
+ - Category: client
6
+
7
+ ## Props
8
+ name: string (REQUIRED)
9
+ description: string | null
10
+ status: "active" | "completed" | "paused" (REQUIRED)
11
+ taskCount: number (default: 0)
12
+ completedTasks: number (default: 0)
13
+ className: string
14
+
15
+ ## Defaults
16
+ taskCount=0, completedTasks=0
17
+
18
+ ## Example
19
+ ```jsx
20
+ <ProjectCard
21
+ name="Website Redesign"
22
+ description="Complete overhaul of the marketing site"
23
+ status="active"
24
+ taskCount={24}
25
+ completedTasks={18}
26
+ />
27
+ ```
28
+
29
+ ## Gotchas
30
+ - Status maps to Badge colors: active=success, completed=info, paused=warning
31
+ - Progress bar shows completedTasks/taskCount as a percentage (rounded)
32
+ - If taskCount is 0, progress is 0% regardless of completedTasks
33
+ - Description is clamped to 2 lines with line-clamp-2
34
+ - Has cursor-pointer and hover shadow — attach onClick via spread props for navigation
35
+ - Extends React.HTMLAttributes<HTMLDivElement>
36
+
37
+ ## Changes
38
+ ### v0.18.0
39
+ - **Added** Initial release
@@ -0,0 +1,47 @@
1
+ # AttendanceCTA
2
+
3
+ - Import: @devalok/shilp-sutra-karm/dashboard
4
+ - Server-safe: No
5
+ - Category: dashboard
6
+
7
+ ## Props
8
+ userName: string (REQUIRED)
9
+ attendance: AttendanceData | null (REQUIRED)
10
+ canMarkAttendance: boolean (REQUIRED)
11
+ onMarkAttendance: () => void
12
+ isSubmitting: boolean (default: false)
13
+ formatTime: (timeStr: string) => string (default: IST toLocaleTimeString)
14
+ className: string
15
+
16
+ ## Related Types
17
+ AttendanceData: { attendance: { id: string; status: string; timeIn: string | null; timeOut: string | null }; breakReason: string | null }
18
+
19
+ ## Defaults
20
+ isSubmitting=false, formatTime=defaultFormatTime (IST, 12-hour)
21
+
22
+ ## Example
23
+ ```jsx
24
+ <AttendanceCTA
25
+ userName="Mudit Sharma"
26
+ attendance={attendanceData}
27
+ canMarkAttendance={true}
28
+ onMarkAttendance={() => markAttendance()}
29
+ isSubmitting={isMarking}
30
+ />
31
+ ```
32
+
33
+ ## Gotchas
34
+ - Renders four different states based on attendance data:
35
+ 1. **Unmarked + canMark**: Large greeting card with gradient background and "Mark Attendance" button
36
+ 2. **Marked (PRESENT)**: Compact strip showing check-in time in a success badge
37
+ 3. **On Break (BREAK)**: Compact strip with warning badge showing break reason
38
+ 4. **Unmarked + cannot mark**: Compact strip with "Attendance window closed" message
39
+ - Greeting is time-based: "Good morning" (before 12), "Good afternoon" (12-17), "Good evening" (after 17)
40
+ - Only the first name (split on space) is displayed in the greeting
41
+ - Date is formatted in en-IN locale with IST timezone
42
+ - The default formatTime uses en-IN locale with IST timezone and 12-hour format
43
+ - Extends React.HTMLAttributes<HTMLDivElement>
44
+
45
+ ## Changes
46
+ ### v0.18.0
47
+ - **Added** Initial release
@@ -0,0 +1,45 @@
1
+ # DailyBrief
2
+
3
+ - Import: @devalok/shilp-sutra-karm/dashboard
4
+ - Server-safe: No
5
+ - Category: dashboard
6
+
7
+ ## Props
8
+ data: BriefData | null (REQUIRED)
9
+ loading: boolean (default: false)
10
+ onRefresh: () => void
11
+ unavailable: boolean (default: false)
12
+ collapsible: boolean (default: true)
13
+ defaultCollapsed: boolean (default: false)
14
+ title: string (default: "Morning Brief")
15
+ className: string
16
+
17
+ ## Related Types
18
+ BriefData: { brief: string[]; generatedAt: string }
19
+
20
+ ## Defaults
21
+ loading=false, unavailable=false, collapsible=true, defaultCollapsed=false, title="Morning Brief"
22
+
23
+ ## Example
24
+ ```jsx
25
+ <DailyBrief
26
+ data={{ brief: ["3 tasks due today", "Team standup at 10am"], generatedAt: new Date().toISOString() }}
27
+ onRefresh={() => refetchBrief()}
28
+ loading={isRefreshing}
29
+ />
30
+ ```
31
+
32
+ ## Gotchas
33
+ - Returns null if data is null or data.brief is empty (and not loading/unavailable)
34
+ - When loading=true and data is null, shows a shimmer skeleton placeholder
35
+ - When unavailable=true, shows a minimal "AI brief unavailable" strip
36
+ - Each brief item is rendered with ReactMarkdown — supports inline markdown (bold, code, links)
37
+ - Brief items get rotating colored dots (amber, teal, cyan, accent)
38
+ - Shows "Generated X ago" timestamp using formatRelativeTime
39
+ - The refresh button only appears when onRefresh is provided; it spins while loading=true
40
+ - Collapse/expand uses framer-motion AnimatePresence for smooth height animation
41
+ - Extends React.HTMLAttributes<HTMLDivElement>
42
+
43
+ ## Changes
44
+ ### v0.18.0
45
+ - **Added** Initial release
@@ -0,0 +1,52 @@
1
+ # ScratchpadWidget
2
+
3
+ - Import: @devalok/shilp-sutra-karm/dashboard
4
+ - Server-safe: No
5
+ - Category: dashboard
6
+
7
+ ## Props
8
+ items: ScratchpadItem[] (REQUIRED)
9
+ maxItems: number (default: 5)
10
+ onToggle: (id: string, done: boolean) => void (REQUIRED)
11
+ onAdd: (text: string) => void (REQUIRED)
12
+ onDelete: (id: string) => void (REQUIRED)
13
+ title: string (default: "My Scratchpad")
14
+ resetLabel: string
15
+ emptyText: string (default: "Nothing here yet. Add a task!")
16
+ emptyIcon: React.ComponentType<{ className?: string }>
17
+ loading: boolean (default: false)
18
+ className: string
19
+
20
+ ## Related Types
21
+ ScratchpadItem: { id: string; text: string; done: boolean }
22
+
23
+ ## Defaults
24
+ maxItems=5, title="My Scratchpad", emptyText="Nothing here yet. Add a task!", loading=false
25
+
26
+ ## Example
27
+ ```jsx
28
+ <ScratchpadWidget
29
+ items={scratchpadItems}
30
+ onToggle={(id, done) => toggleItem(id, done)}
31
+ onAdd={(text) => addItem(text)}
32
+ onDelete={(id) => deleteItem(id)}
33
+ maxItems={5}
34
+ />
35
+ ```
36
+
37
+ ## Gotchas
38
+ - Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> — the native title attribute is replaced by the title prop
39
+ - The "Add a task" input appears only when items.length < maxItems
40
+ - After adding an item, the input stays open for rapid entry; press Escape to close
41
+ - Enter submits the new item; Escape cancels the add flow
42
+ - Blurring the input with empty text closes the add flow
43
+ - Shows a progress ring in the header displaying items.length / maxItems with accent/success color
44
+ - When all items are done, the progress ring pulses with a scale animation
45
+ - Each item has a delete button that appears on hover
46
+ - resetLabel renders as footer text below the item list (e.g., "Resets daily at midnight")
47
+ - When loading=true, shows a shimmer skeleton placeholder
48
+ - Uses framer-motion AnimatePresence for item enter/exit animations
49
+
50
+ ## Changes
51
+ ### v0.18.0
52
+ - **Added** Initial release
@@ -0,0 +1,39 @@
1
+ # SidebarScratchpad
2
+
3
+ - Import: @devalok/shilp-sutra-karm/dashboard
4
+ - Server-safe: No
5
+ - Category: dashboard
6
+
7
+ ## Props
8
+ items: ScratchpadItem[] (REQUIRED)
9
+ onToggle: (id: string, done: boolean) => void (REQUIRED)
10
+ defaultOpen: boolean (default: true)
11
+ badgeCount: number
12
+ className: string
13
+
14
+ ## Related Types
15
+ ScratchpadItem: { id: string; text: string; done: boolean } (imported from scratchpad-widget)
16
+
17
+ ## Defaults
18
+ defaultOpen=true
19
+
20
+ ## Example
21
+ ```jsx
22
+ <SidebarScratchpad
23
+ items={scratchpadItems}
24
+ onToggle={(id, done) => toggleItem(id, done)}
25
+ badgeCount={scratchpadItems.filter(i => !i.done).length}
26
+ />
27
+ ```
28
+
29
+ ## Gotchas
30
+ - This is a compact, read-only version of ScratchpadWidget designed for the app sidebar
31
+ - Does NOT support adding or deleting items — use ScratchpadWidget for full CRUD
32
+ - Only supports toggling done state via checkboxes
33
+ - Collapsible header with chevron; uses CSS grid-rows transition for smooth collapse
34
+ - badgeCount shows a pill badge in the header; hidden when badgeCount is undefined, null, or 0
35
+ - Extends React.HTMLAttributes<HTMLDivElement>
36
+
37
+ ## Changes
38
+ ### v0.18.0
39
+ - **Added** Initial release
@@ -0,0 +1,61 @@
1
+ # karmCommandRegistry
2
+
3
+ - Import: @devalok/shilp-sutra-karm (top-level export)
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ Pre-configured command registry for the Karm app's AppCommandPalette. Contains all page routes and admin routes.
8
+
9
+ Exports: karmCommandRegistry
10
+
11
+ ## Type
12
+ ```ts
13
+ const karmCommandRegistry: CommandRegistry
14
+ ```
15
+
16
+ Where `CommandRegistry` is `{ pages: CommandPageItem[], adminPages: CommandPageItem[] }` from `@devalok/shilp-sutra/shell/command-registry`.
17
+
18
+ ## Pages
19
+ | id | label | path | keywords |
20
+ |----|-------|------|----------|
21
+ | nav-dashboard | Dashboard | / | home |
22
+ | nav-attendance | Attendance | /attendance | clock, time |
23
+ | nav-breaks | Breaks | /breaks | leave, vacation |
24
+ | nav-projects | Projects | /projects | board, kanban |
25
+ | nav-my-tasks | My Tasks | /my-tasks | todo |
26
+ | nav-devsabha | Devsabha | /devsabha | standup, meeting |
27
+ | nav-adjustments | Adjustments | /adjustments | corrections |
28
+ | nav-profile | Profile | /profile | account, settings |
29
+
30
+ ## Admin Pages
31
+ | id | label | path | keywords |
32
+ |----|-------|------|----------|
33
+ | nav-admin-dashboard | Admin Dashboard | /admin | admin, overview |
34
+ | nav-admin-breaks | Manage Breaks | /admin/breaks | admin, leave |
35
+ | nav-admin-attendance | Manage Attendance | /admin/attendance | admin, time |
36
+ | nav-admin-lokwasi | Lokwasi | /admin/lokwasi | admin, onboarding |
37
+ | nav-admin-onboarding | Onboarding | /admin/onboarding | admin, new hire |
38
+ | nav-admin-config | System Config | /admin/system-config | admin, settings, configuration |
39
+
40
+ ## Example
41
+ ```jsx
42
+ import { CommandRegistryProvider } from '@devalok/shilp-sutra/shell/command-registry'
43
+ import { karmCommandRegistry } from '@devalok/shilp-sutra-karm'
44
+
45
+ <CommandRegistryProvider registry={karmCommandRegistry}>
46
+ <AppCommandPalette
47
+ user={user}
48
+ onNavigate={(path) => router.push(path)}
49
+ />
50
+ </CommandRegistryProvider>
51
+ ```
52
+
53
+ ## Gotchas
54
+ - Each entry includes a Tabler icon (e.g. `IconLayoutDashboard`, `IconUmbrella`) — these are bundled, not tree-shaken
55
+ - The registry is a plain object, not a React component — pass it to `CommandRegistryProvider`
56
+ - Admin pages are only shown in the command palette when the user has admin role (handled by AppCommandPalette)
57
+ - To add new routes, extend the registry object in your app rather than modifying this export
58
+
59
+ ## Changes
60
+ ### v0.9.0
61
+ - **Added** Initial release with 8 pages and 6 admin pages
@@ -0,0 +1,52 @@
1
+ # Page Skeletons (Karm)
2
+
3
+ - Import: @devalok/shilp-sutra-karm
4
+ - Server-safe: No
5
+ - Category: other
6
+
7
+ Domain-specific loading skeleton components for Karm pages.
8
+
9
+ Exports: DevsabhaSkeleton, BandwidthSkeleton
10
+
11
+ ## Props
12
+
13
+ ### DevsabhaSkeleton
14
+ ...HTMLDivElement attributes (className, etc.)
15
+
16
+ Renders a 5-section skeleton grid mimicking the Devsabha (standup) page layout:
17
+ 1. Main large card (lg:col-span-2) with 4 rows
18
+ 2. Side card with 3 avatar rows
19
+ 3. Full-width card (lg:col-span-3) with 3 sub-cards
20
+ 4. Stats row (lg:col-span-2) with 4 stat blocks
21
+ 5. Timeline card with 3 entries
22
+
23
+ ### BandwidthSkeleton
24
+ ...HTMLDivElement attributes (className, etc.)
25
+
26
+ Renders a skeleton mimicking the Bandwidth page layout:
27
+ 1. 3 summary cards (sm:grid-cols-3) with progress bars
28
+ 2. Table with 5-column header and 6 rows with avatar + name
29
+
30
+ ## Defaults
31
+ None
32
+
33
+ ## Example
34
+ ```jsx
35
+ import { DevsabhaSkeleton, BandwidthSkeleton } from '@devalok/shilp-sutra-karm'
36
+
37
+ // Use while data loads
38
+ if (isLoading) return <DevsabhaSkeleton />
39
+
40
+ // Bandwidth page loading
41
+ if (isLoading) return <BandwidthSkeleton className="p-6" />
42
+ ```
43
+
44
+ ## Gotchas
45
+ - These are top-level exports from the karm package, not from the admin sub-path
46
+ - Both use the core `Skeleton` component internally
47
+ - Layout uses `gap-ds-06` spacing and `rounded-ds-xl` border radius
48
+ - Pass `className` to customize outer container styles
49
+
50
+ ## Changes
51
+ ### v0.9.0
52
+ - **Added** Initial release
@@ -0,0 +1,41 @@
1
+ # ActivityTab
2
+
3
+ - Import: @devalok/shilp-sutra-karm/tasks
4
+ - Server-safe: No
5
+ - Category: tasks
6
+
7
+ ## Props
8
+ activities: AuditLogEntry[] (REQUIRED)
9
+ ...HTMLAttributes<HTMLDivElement>
10
+
11
+ ## AuditLogEntry Shape
12
+ id: string
13
+ timestamp: string
14
+ actorType: 'USER' | 'CLIENT' | 'SYSTEM' | 'AGENT'
15
+ actorId: string | null
16
+ action: string
17
+ entityType: string
18
+ entityId: string
19
+ projectId: string | null
20
+ metadata: Record<string, unknown> | null
21
+
22
+ ## Supported Actions
23
+ task.created, task.updated, task.moved, task.assigned, task.unassigned,
24
+ task.commented, task.file_uploaded, task.review_requested, task.review_completed,
25
+ task.visibility_changed, task.priority_changed, task.labels_changed, task.due_date_changed
26
+
27
+ ## Example
28
+ ```jsx
29
+ <ActivityTab activities={auditLogEntries} />
30
+ ```
31
+
32
+ ## Gotchas
33
+ - Renders a vertical timeline with colored dots and icons per action type.
34
+ - Unknown actions fall back to a generic icon and use entry.action as the description.
35
+ - Actor name is derived from metadata.actorName, falling back to "System", "AI Agent", or "Someone".
36
+ - Empty state uses EmptyState component: "No activity yet".
37
+ - Forwards ref to outer div.
38
+
39
+ ## Changes
40
+ ### v0.18.0
41
+ - **Added** Initial release
@@ -0,0 +1,52 @@
1
+ # ConversationTab
2
+
3
+ - Import: @devalok/shilp-sutra-karm/tasks
4
+ - Server-safe: No
5
+ - Category: tasks
6
+
7
+ ## Props
8
+ comments: Comment[] (REQUIRED)
9
+ taskVisibility: 'INTERNAL' | 'EVERYONE' (REQUIRED)
10
+ onPostComment: (content: string, authorType: 'INTERNAL' | 'CLIENT') => void (REQUIRED)
11
+ clientMode: boolean (default: false)
12
+ richText: boolean (default: true) — enable built-in RichTextEditor/Viewer
13
+ renderEditor: (props: { content: string; onChange: (content: string) => void; placeholder: string }) => ReactNode
14
+ renderViewer: (props: { content: string; className?: string }) => ReactNode
15
+ ...HTMLAttributes<HTMLDivElement>
16
+
17
+ ## Comment Shape
18
+ id: string
19
+ taskId: string
20
+ authorType: 'INTERNAL' | 'CLIENT'
21
+ authorId: string
22
+ content: string
23
+ createdAt: string
24
+ updatedAt: string
25
+ internalAuthor: { id: string; name: string; email?: string; image?: string | null } | null (optional)
26
+ clientAuthor: { id: string; name: string; email: string } | null (optional)
27
+
28
+ ## Defaults
29
+ clientMode=false, richText=true
30
+
31
+ ## Example
32
+ ```jsx
33
+ <ConversationTab
34
+ comments={task.comments}
35
+ taskVisibility={task.visibility}
36
+ onPostComment={(content, type) => postComment(content, type)}
37
+ />
38
+ ```
39
+
40
+ ## Gotchas
41
+ - In clientMode, comments are posted with authorType='CLIENT'. In staff mode, authorType='INTERNAL'.
42
+ - When taskVisibility='EVERYONE' and not clientMode, a warning is shown: "Comments may be seen by external users."
43
+ - In clientMode, staff comments show a "Team" badge. In staff mode, client comments show a "Client" badge.
44
+ - Editor resolution priority: renderEditor prop > built-in RichTextEditor (when richText=true) > plain textarea fallback.
45
+ - Viewer resolution priority: renderViewer prop > built-in RichTextViewer (when richText=true) > plain text with HTML stripped.
46
+ - Auto-scrolls to bottom when new comments arrive.
47
+ - Empty state: "No comments yet".
48
+ - Forwards ref to outer div.
49
+
50
+ ## Changes
51
+ ### v0.18.0
52
+ - **Added** Initial release