Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4be2361
improved the readme, added diagrams
galliani Jun 28, 2025
a097435
added videos and images, one left placeholder for curation demo
galliani Jun 28, 2025
f4b4f23
added logo
galliani Jun 29, 2025
ffcc457
fix: 'context:' prefix gets displayed in the composer after loaded fr…
galliani Jun 29, 2025
cbc4197
added architecture diagrams
galliani Jun 29, 2025
e49726c
improved ux of ContextSetListManager: auto-move active context set to…
galliani Jun 29, 2025
1ed6764
ux: moved processing mode to editor as floating select
galliani Jun 29, 2025
ad5b18e
removed unused auto-saved feature
galliani Jun 29, 2025
e4f65b7
simplified the project header
galliani Jun 29, 2025
d33d874
refined the ui of the project header's action buttons
galliani Jun 29, 2025
dd5fb55
ui: made the app more compact by reducing the size of the context set…
galliani Jun 29, 2025
937f3f3
Merge dd5fb55602b0db48863e2cf6e7d1ef6c3bef7142 into 1a83df1c37ac07a86…
galliani Jun 29, 2025
dce3bb1
Update coverage badge [skip ci]
actions-user Jun 29, 2025
0f2099c
updated main interface image
galliani Jun 29, 2025
c4ac269
fix: system architecture mermaidjs diagram syntax error
galliani Jun 29, 2025
285d584
Merge branch 'improve-readme' of github.com:galliani/contextmax into …
galliani Jun 29, 2025
c4b4fd7
added table of contents
galliani Jun 29, 2025
7273c6c
updated, moving some parts
galliani Jun 29, 2025
5909ca8
added gif to the top of the readme
galliani Jun 29, 2025
95f8463
updated readme
galliani Jun 29, 2025
ed14366
moved some bits
galliani Jun 29, 2025
8d9c79e
fix unterminated syntax
galliani Jun 29, 2025
0656e47
removed table of contents
galliani Jun 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
504 changes: 409 additions & 95 deletions README.md

Large diffs are not rendered by default.

16 changes: 11 additions & 5 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,17 @@
</div>

<!-- Application Footer -->
<footer role="contentinfo" class="app-footer sr-only">
<div class="container mx-auto px-4 py-4">
<p class="text-sm text-muted-foreground text-center">
contextMax - Enhancing LLM workflows with curated context
</p>
<footer role="contentinfo" class="app-footer bg-background/90 backdrop-blur-sm py-8">
<div class="container mx-auto px-4 py-3">
<div class="flex items-center justify-center gap-3">
<img src="/logo-transparent.png" alt="ContextMax Logo" class="w-5 h-5" />
<p class="text-sm text-muted-foreground text-center">
contextMax 2025, created by
<a href="https://github.com/galliani" target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 transition-colors duration-200">Galih</a>
of
<a href="https://51newyork.com" target="_blank" rel="noopener noreferrer" class="text-primary hover:text-primary/80 transition-colors duration-200">51NewYork</a>
</p>
</div>
</div>
</footer>

Expand Down
2 changes: 1 addition & 1 deletion badges/coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 14 additions & 59 deletions components/ActiveContextComposer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
<div class="flex items-start justify-between">
<div class="flex-1 min-w-0">
<!-- Editable Context Set Name -->
<div v-if="activeContextSetName" class="mt-4 mb-2">
<div v-if="activeContextSetName" class="mt-2 mb-0">
<div v-if="!isEditingName" class="flex items-center group">
<Icon name="lucide:folder-open" class="w-12 h-12 mr-2 text-primary" />
<h3 class="visual-hierarchy-3 mb-1 text-mobile-subheading sm:text-xl lg:text-3xl font-bold" @click="startEditingName">
Context Set: {{ activeContextSetName }}
Composer: <span class="text-primary font-extrabold bg-primary/10 px-2 py-1 rounded-md border border-primary/20 animate-pulse">{{ getContextDisplayName(activeContextSetName) }}</span>
</h3>
<Button
@click="startEditingName"
Expand Down Expand Up @@ -57,7 +57,7 @@
</h3>

<!-- Editable Context Set Description -->
<div v-if="activeContextSetName" class="mb-1">
<div v-if="activeContextSetName" class="mb-0">
<div v-if="!isEditingDescription && activeContextSetDescription" class="flex items-start group">
<p class="text-lg text-slate-300 cursor-pointer hover:text-slate-200 transition-colors" @click="startEditingDescription">
{{ activeContextSetDescription }}
Expand All @@ -66,7 +66,7 @@
@click="startEditingDescription"
variant="ghost"
size="sm"
class="ml-2 opacity-0 group-hover:opacity-100 transition-opacity"
class="ml-0 opacity-0 group-hover:opacity-100 transition-opacity"
title="Edit description"
>
<Icon name="lucide:edit-2" class="w-3 h-3" aria-hidden="true" />
Expand All @@ -77,7 +77,7 @@
@click="startEditingDescription"
variant="ghost"
size="sm"
class="text-muted-foreground hover:text-foreground transition-colors"
class="ml-0 pl-0 text-muted-foreground hover:text-foreground transition-colors"
title="Add description"
>
<Icon name="lucide:plus" class="w-4 h-4 mr-2" aria-hidden="true" />
Expand Down Expand Up @@ -106,31 +106,10 @@
</div>
</div>

<!-- Processing Mode Selection -->
<div v-if="activeContextSetName" class="mb-4">
<div class="flex items-center space-x-3">
<label class="text-sm font-medium text-foreground whitespace-nowrap">
Processing Mode
</label>
<select
v-model="processingMode"
class="w-64 px-3 py-2 text-sm border border-input rounded-md bg-background focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2"
>
<option value="">Not specified</option>
<option value="synchronous">Synchronous - Returns result immediately</option>
<option value="asynchronous">Asynchronous - Processes in background</option>
<option value="streaming">Streaming - Returns data progressively</option>
<option value="batch">Batch - Processes multiple items together</option>
</select>
</div>
<p class="text-xs text-muted-foreground mt-1 ml-0">
Defines how the system should handle processing requests
</p>
</div>
</div>

<!-- Token Estimation & Export Actions -->
<div v-if="activeContextSetName" class="flex flex-col items-end space-y-3 ml-6">
<div v-if="activeContextSetName" class="flex flex-col items-end space-y-3 ml-6 mt-2">
<!-- Token Estimation & Copy Button -->
<div class="flex items-center space-x-3">
<p class="text-sm text-muted-foreground">
Expand All @@ -139,13 +118,13 @@
<Button
@click="handleExportToClipboard"
:disabled="isExporting || !activeContextSet || !activeContextSet.files || activeContextSet.files.length === 0"
class="flex items-center space-x-2"
class="flex items-center space-x-2 text-xs px-3 py-2.5 font-medium transition-all duration-200 bg-primary hover:bg-primary/90 text-primary-foreground shadow-md hover:shadow-lg"
variant="default"
size="sm"
>
<Icon
:name="isExporting ? 'lucide:loader-2' : 'lucide:clipboard-copy'"
:class="['w-4 h-4', { 'animate-spin': isExporting }]"
:class="['w-1 h-1', { 'animate-spin': isExporting }]"
/>
<span>{{ isExporting ? 'Exporting...' : 'Copy as Snippet' }}</span>
</Button>
Expand All @@ -155,9 +134,9 @@
<div class="text-right">
<div class="text-sm font-medium text-foreground">
{{ activeContextSet?.files?.length || 0 }} files •
{{ activeContextSet?.workflows?.length || 0 }} workflows
{{ activeContextSet?.workflows?.length || 0 }} workflows
<span v-if="activeContextSet?.systemBehavior?.processing?.mode" class="ml-2 px-2 py-0.5 text-xs rounded-full bg-primary/10 text-primary">
{{ activeContextSet.systemBehavior.processing.mode }}
{{ activeContextSet.systemBehavior.processing.mode }}
</span>
</div>
</div>
Expand Down Expand Up @@ -190,6 +169,7 @@

<script setup lang="ts">
import { logger } from '~/utils/logger'
import { getContextDisplayName } from '~/utils/contextName'
import Editor from './active-context-set/Editor.vue'
import TabbedFileBrowser from './TabbedFileBrowser.vue'

Expand Down Expand Up @@ -242,18 +222,11 @@ const activeContextSetDescription = computed(() => {
return activeContextSet.value?.description || ''
})

// Computed for processing mode
const processingMode = computed({
get: () => activeContextSet.value?.systemBehavior?.processing?.mode || '',
set: (value: string) => {
updateProcessingMode(value)
}
})

// Methods for editing
const startEditingName = async () => {
isEditingName.value = true
editingName.value = activeContextSetName.value
editingName.value = getContextDisplayName(activeContextSetName.value)
await nextTick()
safeFocus(nameInput.value)
safeSelect(nameInput.value)
Expand Down Expand Up @@ -284,7 +257,7 @@ const saveContextSetName = () => {
try {
updateActiveContextSet({ name: newName })
isEditingName.value = false
announceStatus(`Context set renamed to: ${newName}`)
announceStatus(`Context set renamed to: ${getContextDisplayName(newName)}`)
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to rename context set'
announceError(message)
Expand Down Expand Up @@ -322,24 +295,6 @@ const cancelEditingDescription = () => {
editingDescription.value = ''
}

// Update processing mode
const updateProcessingMode = (mode: string) => {
if (!activeContextSet.value) return

const newSystemBehavior = (mode && mode.trim()) ? {
processing: {
mode: mode as 'synchronous' | 'asynchronous' | 'streaming' | 'batch'
}
} : null

try {
updateActiveContextSet({ systemBehavior: newSystemBehavior })
announceStatus('Processing mode updated')
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to update processing mode'
announceError(message)
}
}

// Export functionality
const handleExportToClipboard = async () => {
Expand Down Expand Up @@ -390,7 +345,7 @@ const handleExportToClipboard = async () => {
if (result.success) {
success(
'Snippet Copied',
`Context set "${prefixedContextSetName}" copied to clipboard as Markdown (${result.tokenCount.toLocaleString()} tokens)`
`Context set "${getContextDisplayName(prefixedContextSetName)}" copied to clipboard as Markdown (${result.tokenCount.toLocaleString()} tokens)`
)
announceStatus(`Context set exported to clipboard with ${result.tokenCount} tokens`)
} else {
Expand Down
27 changes: 24 additions & 3 deletions components/AppNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
<template>
<!-- Enhanced Floating Navbar with Navigation -->
<nav class="absolute top-6 left-1/2 transform -translate-x-1/2 z-50 bg-card/90 backdrop-blur-xl border border-muted-foreground/20 rounded-full shadow-2xl max-w-4xl">
<div class="flex items-center justify-between px-8 py-4">
<div class="flex items-center justify-between px-8 py-4 gap-4">
<!-- Logo/Brand and AI Status -->
<div class="flex items-center gap-4">
<a
href="https://contextmax.dev" target="_blank" rel="noopener noreferrer"
class="text-2xl font-bold text-foreground tracking-wide hover:text-primary transition-colors duration-200"
class="flex items-center gap-1 text-xl font-bold text-foreground tracking-wide hover:text-primary transition-colors duration-200"
>
contextMax <span class="text-xs text-muted-foreground font-normal">by 51NewYork</span>
<img src="/logo-transparent.png" alt="ContextMax Logo" class="w-8 h-8" />
contextMax<span class="text-xs text-muted-foreground font-normal self-end -ml-0"><a href="https://51newyork.com" target="_blank" rel="noopener noreferrer" class="hover:text-primary transition-colors duration-200">by 51NewYork</a></span>
</a>

<!-- AI Models Status -->
Expand Down Expand Up @@ -83,6 +84,18 @@
<Icon name="lucide:plus" class="w-4 h-4 mr-2" />
Add
</Button>

<!-- Remove Project Button -->
<Button
v-if="selectedFolder"
@click="handleClearProjectWithConfirmation"
variant="outline"
size="sm"
class="px-3 py-2 bg-destructive/5 hover:bg-destructive/10 border-destructive/20 text-destructive hover:text-destructive"
>
<Icon name="lucide:trash-2" class="w-4 h-4 mr-2" />
Remove
</Button>
</div>
</div>
</nav>
Expand Down Expand Up @@ -164,6 +177,7 @@ const _props = withDefaults(defineProps<Props>(), {

const _emit = defineEmits<{
(e: 'select-project'): void
(e: 'clear-project'): void
}>()

// Use the project store
Expand Down Expand Up @@ -335,6 +349,13 @@ const getModelTooltip = (modelKey: string) => {
return `${displayName}: Unknown status`
}
}

// Handle clear project
const handleClearProjectWithConfirmation = () => {
_emit('clear-project')
success('Project Cleared', 'Project has been cleared successfully')
announceStatus('Project cleared')
}
</script>

<style scoped>
Expand Down
Loading