@kirosnn/mosaic 0.0.7

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 (154) hide show
  1. package/.mosaic/mosaic.local.jsonc +0 -0
  2. package/MOSAIC.md +188 -0
  3. package/README.md +127 -0
  4. package/docs/mosaic.png +0 -0
  5. package/package.json +42 -0
  6. package/src/agent/Agent.ts +131 -0
  7. package/src/agent/context.ts +96 -0
  8. package/src/agent/index.ts +2 -0
  9. package/src/agent/prompts/systemPrompt.ts +138 -0
  10. package/src/agent/prompts/toolsPrompt.ts +139 -0
  11. package/src/agent/provider/anthropic.ts +122 -0
  12. package/src/agent/provider/google.ts +124 -0
  13. package/src/agent/provider/mistral.ts +117 -0
  14. package/src/agent/provider/ollama.ts +531 -0
  15. package/src/agent/provider/openai.ts +220 -0
  16. package/src/agent/provider/xai.ts +122 -0
  17. package/src/agent/tools/bash.ts +20 -0
  18. package/src/agent/tools/definitions.ts +27 -0
  19. package/src/agent/tools/edit.ts +23 -0
  20. package/src/agent/tools/executor.ts +751 -0
  21. package/src/agent/tools/explore.ts +18 -0
  22. package/src/agent/tools/exploreExecutor.ts +320 -0
  23. package/src/agent/tools/glob.ts +16 -0
  24. package/src/agent/tools/grep.ts +19 -0
  25. package/src/agent/tools/index.ts +4 -0
  26. package/src/agent/tools/list.ts +20 -0
  27. package/src/agent/tools/question.ts +20 -0
  28. package/src/agent/tools/read.ts +15 -0
  29. package/src/agent/tools/write.ts +21 -0
  30. package/src/agent/types.ts +155 -0
  31. package/src/components/App.tsx +174 -0
  32. package/src/components/CommandsModal.tsx +77 -0
  33. package/src/components/CustomInput.tsx +328 -0
  34. package/src/components/Main.tsx +1112 -0
  35. package/src/components/Notification.tsx +91 -0
  36. package/src/components/SelectList.tsx +47 -0
  37. package/src/components/Setup.tsx +528 -0
  38. package/src/components/ShortcutsModal.tsx +67 -0
  39. package/src/components/Welcome.tsx +39 -0
  40. package/src/components/main/ApprovalPanel.tsx +134 -0
  41. package/src/components/main/ChatPage.tsx +516 -0
  42. package/src/components/main/HomePage.tsx +111 -0
  43. package/src/components/main/QuestionPanel.tsx +85 -0
  44. package/src/components/main/ThinkingIndicator.tsx +101 -0
  45. package/src/components/main/types.ts +55 -0
  46. package/src/components/main/wrapText.ts +41 -0
  47. package/src/index.tsx +212 -0
  48. package/src/utils/approvalBridge.ts +129 -0
  49. package/src/utils/commands/echo.ts +22 -0
  50. package/src/utils/commands/help.ts +25 -0
  51. package/src/utils/commands/index.ts +68 -0
  52. package/src/utils/commands/init.ts +68 -0
  53. package/src/utils/commands/redo.ts +74 -0
  54. package/src/utils/commands/registry.ts +29 -0
  55. package/src/utils/commands/sessions.ts +129 -0
  56. package/src/utils/commands/types.ts +20 -0
  57. package/src/utils/commands/undo.ts +75 -0
  58. package/src/utils/commands/web.ts +77 -0
  59. package/src/utils/config.ts +357 -0
  60. package/src/utils/diff.ts +201 -0
  61. package/src/utils/diffRendering.tsx +62 -0
  62. package/src/utils/exploreBridge.ts +87 -0
  63. package/src/utils/fileChangeTracker.ts +98 -0
  64. package/src/utils/fileChangesBridge.ts +18 -0
  65. package/src/utils/history.ts +106 -0
  66. package/src/utils/markdown.tsx +232 -0
  67. package/src/utils/models.ts +304 -0
  68. package/src/utils/questionBridge.ts +122 -0
  69. package/src/utils/terminalUtils.ts +25 -0
  70. package/src/utils/toolFormatting.ts +384 -0
  71. package/src/utils/undoRedo.ts +429 -0
  72. package/src/utils/undoRedoBridge.ts +45 -0
  73. package/src/utils/undoRedoDb.ts +338 -0
  74. package/src/utils/uninstall.ts +45 -0
  75. package/src/utils/version.ts +3 -0
  76. package/src/web/app.tsx +606 -0
  77. package/src/web/assets/css/ChatPage.css +212 -0
  78. package/src/web/assets/css/FileExplorer.css +202 -0
  79. package/src/web/assets/css/HomePage.css +119 -0
  80. package/src/web/assets/css/Markdown.css +178 -0
  81. package/src/web/assets/css/MessageItem.css +160 -0
  82. package/src/web/assets/css/Sidebar.css +208 -0
  83. package/src/web/assets/css/SidebarModal.css +137 -0
  84. package/src/web/assets/css/ThinkingIndicator.css +47 -0
  85. package/src/web/assets/css/ToolMessage.css +148 -0
  86. package/src/web/assets/css/global.css +226 -0
  87. package/src/web/assets/fonts/Geist-Black.woff2 +0 -0
  88. package/src/web/assets/fonts/Geist-BlackItalic.woff2 +0 -0
  89. package/src/web/assets/fonts/Geist-Bold.woff2 +0 -0
  90. package/src/web/assets/fonts/Geist-BoldItalic.woff2 +0 -0
  91. package/src/web/assets/fonts/Geist-ExtraBold.woff2 +0 -0
  92. package/src/web/assets/fonts/Geist-ExtraBoldItalic.woff2 +0 -0
  93. package/src/web/assets/fonts/Geist-ExtraLight.woff2 +0 -0
  94. package/src/web/assets/fonts/Geist-ExtraLightItalic.woff2 +0 -0
  95. package/src/web/assets/fonts/Geist-Italic[wght].woff2 +0 -0
  96. package/src/web/assets/fonts/Geist-Light.woff2 +0 -0
  97. package/src/web/assets/fonts/Geist-LightItalic.woff2 +0 -0
  98. package/src/web/assets/fonts/Geist-Medium.woff2 +0 -0
  99. package/src/web/assets/fonts/Geist-MediumItalic.woff2 +0 -0
  100. package/src/web/assets/fonts/Geist-Regular.woff2 +0 -0
  101. package/src/web/assets/fonts/Geist-RegularItalic.woff2 +0 -0
  102. package/src/web/assets/fonts/Geist-SemiBold.woff2 +0 -0
  103. package/src/web/assets/fonts/Geist-SemiBoldItalic.woff2 +0 -0
  104. package/src/web/assets/fonts/Geist-Thin.woff2 +0 -0
  105. package/src/web/assets/fonts/Geist-ThinItalic.woff2 +0 -0
  106. package/src/web/assets/fonts/GeistMono-Black.woff2 +0 -0
  107. package/src/web/assets/fonts/GeistMono-BlackItalic.woff2 +0 -0
  108. package/src/web/assets/fonts/GeistMono-Bold.woff2 +0 -0
  109. package/src/web/assets/fonts/GeistMono-BoldItalic.woff2 +0 -0
  110. package/src/web/assets/fonts/GeistMono-ExtraBold.woff2 +0 -0
  111. package/src/web/assets/fonts/GeistMono-ExtraBoldItalic.woff2 +0 -0
  112. package/src/web/assets/fonts/GeistMono-ExtraLight.woff2 +0 -0
  113. package/src/web/assets/fonts/GeistMono-ExtraLightItalic.woff2 +0 -0
  114. package/src/web/assets/fonts/GeistMono-Italic.woff2 +0 -0
  115. package/src/web/assets/fonts/GeistMono-Italic[wght].woff2 +0 -0
  116. package/src/web/assets/fonts/GeistMono-Light.woff2 +0 -0
  117. package/src/web/assets/fonts/GeistMono-LightItalic.woff2 +0 -0
  118. package/src/web/assets/fonts/GeistMono-Medium.woff2 +0 -0
  119. package/src/web/assets/fonts/GeistMono-MediumItalic.woff2 +0 -0
  120. package/src/web/assets/fonts/GeistMono-Regular.woff2 +0 -0
  121. package/src/web/assets/fonts/GeistMono-SemiBold.woff2 +0 -0
  122. package/src/web/assets/fonts/GeistMono-SemiBoldItalic.woff2 +0 -0
  123. package/src/web/assets/fonts/GeistMono-Thin.woff2 +0 -0
  124. package/src/web/assets/fonts/GeistMono-ThinItalic.woff2 +0 -0
  125. package/src/web/assets/fonts/GeistMono[wght].woff2 +0 -0
  126. package/src/web/assets/fonts/Geist[wght].woff2 +0 -0
  127. package/src/web/assets/fonts/blauer-nue-regular.woff2 +0 -0
  128. package/src/web/assets/fonts/neue-montreal-regular.woff2 +0 -0
  129. package/src/web/assets/images/favicon-v2.svg +6 -0
  130. package/src/web/assets/images/favicon.png +0 -0
  131. package/src/web/assets/images/foruse.svg +5 -0
  132. package/src/web/assets/images/logo_black.svg +5 -0
  133. package/src/web/assets/images/logo_white.svg +5 -0
  134. package/src/web/assets/images/logoblack.png +0 -0
  135. package/src/web/assets/images/logowhite.png +0 -0
  136. package/src/web/build.ts +23 -0
  137. package/src/web/components/ApprovalPanel.tsx +191 -0
  138. package/src/web/components/ChatPage.tsx +273 -0
  139. package/src/web/components/FileExplorer.tsx +162 -0
  140. package/src/web/components/HomePage.tsx +121 -0
  141. package/src/web/components/MessageItem.tsx +178 -0
  142. package/src/web/components/Modal.tsx +30 -0
  143. package/src/web/components/QuestionPanel.tsx +149 -0
  144. package/src/web/components/Setup.tsx +211 -0
  145. package/src/web/components/Sidebar.tsx +292 -0
  146. package/src/web/components/ThinkingIndicator.tsx +85 -0
  147. package/src/web/logo_black.svg +5 -0
  148. package/src/web/logo_white.svg +5 -0
  149. package/src/web/router.ts +46 -0
  150. package/src/web/server.tsx +662 -0
  151. package/src/web/storage.ts +92 -0
  152. package/src/web/types.ts +17 -0
  153. package/src/web/utils.ts +61 -0
  154. package/tsconfig.json +33 -0
@@ -0,0 +1,92 @@
1
+ import { Message } from './types';
2
+
3
+ export interface Conversation {
4
+ id: string;
5
+ title: string | null;
6
+ messages: Message[];
7
+ workspace: string | null;
8
+ createdAt: number;
9
+ updatedAt: number;
10
+ }
11
+
12
+ const STORAGE_KEY = 'mosaic_conversations';
13
+
14
+ export function generateConversationId(): string {
15
+ return `conv_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
16
+ }
17
+
18
+ export function getAllConversations(): Conversation[] {
19
+ try {
20
+ const data = localStorage.getItem(STORAGE_KEY);
21
+ if (!data) return [];
22
+ const conversations: Conversation[] = JSON.parse(data);
23
+ return conversations.sort((a, b) => b.createdAt - a.createdAt);
24
+ } catch {
25
+ return [];
26
+ }
27
+ }
28
+
29
+ export function getConversation(id: string): Conversation | null {
30
+ const conversations = getAllConversations();
31
+ return conversations.find(c => c.id === id) || null;
32
+ }
33
+
34
+ export function saveConversation(conversation: Conversation): void {
35
+ const conversations = getAllConversations();
36
+ const existingIndex = conversations.findIndex(c => c.id === conversation.id);
37
+
38
+ if (existingIndex !== -1) {
39
+ conversations[existingIndex] = conversation;
40
+ } else {
41
+ conversations.push(conversation);
42
+ }
43
+
44
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(conversations));
45
+ }
46
+
47
+ export function deleteConversation(id: string): void {
48
+ const conversations = getAllConversations();
49
+ const filtered = conversations.filter(c => c.id !== id);
50
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(filtered));
51
+ }
52
+
53
+ export function createNewConversation(workspace: string | null = null): Conversation {
54
+ return {
55
+ id: generateConversationId(),
56
+ title: null,
57
+ messages: [],
58
+ workspace,
59
+ createdAt: Date.now(),
60
+ updatedAt: Date.now(),
61
+ };
62
+ }
63
+
64
+ export function formatWorkspace(path: string | null | undefined): string {
65
+ if (!path) return '';
66
+
67
+ let normalized = path.replace(/\\/g, '/');
68
+
69
+ const homePatterns = [
70
+ /^\/Users\/[^/]+/,
71
+ /^\/home\/[^/]+/,
72
+ /^[A-Z]:\/Users\/[^/]+/i,
73
+ ];
74
+
75
+ for (const pattern of homePatterns) {
76
+ if (pattern.test(normalized)) {
77
+ normalized = normalized.replace(pattern, '~');
78
+ break;
79
+ }
80
+ }
81
+
82
+ const parts = normalized.split('/').filter(Boolean);
83
+ const maxLength = 30;
84
+
85
+ if (normalized.length > maxLength && parts.length > 3) {
86
+ const isHome = normalized.startsWith('~');
87
+ const lastParts = parts.slice(-2).join('/');
88
+ return isHome ? '~/.../' + lastParts : '.../' + lastParts;
89
+ }
90
+
91
+ return normalized;
92
+ }
@@ -0,0 +1,17 @@
1
+ export interface Message {
2
+ id: string;
3
+ role: 'user' | 'assistant' | 'tool';
4
+ content: string;
5
+ displayContent?: string;
6
+ isError?: boolean;
7
+ toolName?: string;
8
+ toolArgs?: Record<string, unknown>;
9
+ toolResult?: unknown;
10
+ success?: boolean;
11
+ timestamp?: number;
12
+ thinkingContent?: string;
13
+ isRunning?: boolean;
14
+ runningStartTime?: number;
15
+ responseDuration?: number;
16
+ blendWord?: string;
17
+ }
@@ -0,0 +1,61 @@
1
+ export {
2
+ formatToolMessage,
3
+ parseToolHeader,
4
+ formatToolResult,
5
+ isToolSuccess,
6
+ formatErrorMessage,
7
+ DEFAULT_MAX_TOOL_LINES,
8
+ } from '../utils/toolFormatting';
9
+
10
+ export { parseDiffLine, getDiffLineColors, type ParsedDiffLine } from '../utils/diff';
11
+
12
+ export const createId = () => `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
13
+
14
+ export function extractTitle(content: string, alreadyResolved: boolean): {
15
+ title: string | null;
16
+ cleanContent: string;
17
+ isPending: boolean;
18
+ noTitle: boolean
19
+ } {
20
+ const trimmed = content.trimStart();
21
+
22
+ const titleMatch = trimmed.match(/^<title>(.*?)<\/title>\s*/s);
23
+ if (titleMatch) {
24
+ const title = alreadyResolved ? null : (titleMatch[1]?.trim() || null);
25
+ const cleanContent = trimmed.replace(/^<title>.*?<\/title>\s*/s, '');
26
+ return { title, cleanContent, isPending: false, noTitle: false };
27
+ }
28
+
29
+ if (alreadyResolved) {
30
+ return { title: null, cleanContent: content, isPending: false, noTitle: false };
31
+ }
32
+
33
+ const partialTitlePattern = /^<(t(i(t(l(e(>.*)?)?)?)?)?)?$/i;
34
+ if (partialTitlePattern.test(trimmed) || (trimmed.startsWith('<title>') && !trimmed.includes('</title>'))) {
35
+ return { title: null, cleanContent: '', isPending: true, noTitle: false };
36
+ }
37
+
38
+ return { title: null, cleanContent: content, isPending: false, noTitle: true };
39
+ }
40
+
41
+ export function setDocumentTitle(title: string) {
42
+ document.title = `${title} - Mosaic`;
43
+ }
44
+
45
+ export const BLEND_WORDS = [
46
+ "Blended",
47
+ "Crafted",
48
+ "Brewed",
49
+ "Cooked",
50
+ "Forged",
51
+ "Woven",
52
+ "Composed",
53
+ "Rendered",
54
+ "Conjured",
55
+ "Distilled",
56
+ "Worked"
57
+ ];
58
+
59
+ export function getRandomBlendWord(): string {
60
+ return BLEND_WORDS[Math.floor(Math.random() * BLEND_WORDS.length)]!;
61
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "ESNext",
5
+ "DOM",
6
+ "DOM.Iterable"
7
+ ],
8
+ "target": "ESNext",
9
+ "module": "Preserve",
10
+ "moduleResolution": "bundler",
11
+ "jsx": "react-jsx",
12
+ "jsxImportSource": "@opentui/react",
13
+ "allowImportingTsExtensions": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+ "strict": true,
17
+ "skipLibCheck": true,
18
+ "noUncheckedIndexedAccess": true,
19
+ "noImplicitOverride": true,
20
+ "allowSyntheticDefaultImports": true,
21
+ "esModuleInterop": true,
22
+ "resolveJsonModule": true,
23
+ "types": [
24
+ "bun"
25
+ ]
26
+ },
27
+ "include": [
28
+ "src/**/*"
29
+ ],
30
+ "exclude": [
31
+ "node_modules"
32
+ ]
33
+ }