feat(api): one API for curl and MCP, REST reads with keys, origin badge with key name
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m16s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m16s
API keys reach tasks and lists over plain REST too (GET /task-lists, GET /tasks with
status/due filters, PATCH/DELETE /thoughts/{id}, GET /lists, list items), guarded by a route
table; notes and settings stay closed. Rights hold for every access alike (webhook:task also
allows create_task over MCP, tasks:write also task delivery).
Tasks, thoughts and list items record which key created them and which one changed them last
(migration 13 replaces agent_mark; origin stays after the user's own edits and survives the
triage into a list item). OriginBadge shows the key name with a webhook or robot icon, details
on hover and tap, and replaces the Webhook and KI badges everywhere, now also on list items.
Settings: category "API" with rights grouped by tasks, lists and inbox and two tabs
(curl / smart home with a Home Assistant sensor, AI agents over MCP). Docs, help, README and
changelog updated; v0.30.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0ca715ba64
commit
b883315914
36 files changed
+1119
-563
No files matched your search
@@ -11,7 +11,6 @@ import {
|
||||
AlertTriangle,
|
||||
Flame,
|
||||
Folder,
|
||||
Webhook,
|
||||
Lock,
|
||||
UserPlus,
|
||||
Repeat,
|
||||
@@ -20,7 +19,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { Thought, TaskList, TaskListMember, KanbanColumn, User, Recurrence } from '../../lib/types';
|
||||
import { UserAvatar } from '../../components/UserAvatar';
|
||||
import { AgentBadge } from '../../components/AgentBadge';
|
||||
import { OriginBadge, originDetails } from '../../components/OriginBadge';
|
||||
import { UserAutocomplete } from '../UserAutocomplete';
|
||||
import { api, triggerHaptic } from '../../lib/api';
|
||||
import { MarkdownViewer } from '../../lib/markdown';
|
||||
@@ -239,13 +238,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
||||
<span>Nur Lesen</span>
|
||||
</span>
|
||||
)}
|
||||
{task.source?.toLowerCase() === 'webhook' && (
|
||||
<span className="px-1.5 py-0.5 border border-border bg-canvas text-muted rounded-btn text-[10px] font-medium flex items-center gap-1 flex-shrink-0">
|
||||
<Webhook className="w-2.5 h-2.5 text-accent" />
|
||||
<span>Webhook</span>
|
||||
</span>
|
||||
)}
|
||||
<AgentBadge mark={task.agentMark} />
|
||||
<OriginBadge origin={task.origin} createdAt={task.createdAt} />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1.5">
|
||||
@@ -895,8 +888,8 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
|
||||
|
||||
{/* Modal Footer */}
|
||||
<div className="flex items-center justify-between px-4 py-2.5 border-t border-border bg-panel">
|
||||
<div className="text-[11px] text-faint">
|
||||
Erstellt: {new Date(task.createdAt).toLocaleDateString('de-DE')}
|
||||
<div className="text-[11px] text-faint min-w-0 pr-3">
|
||||
{originDetails(task.origin, task.createdAt) || `Erstellt: ${new Date(task.createdAt).toLocaleDateString('de-DE')}`}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
Settings,
|
||||
Folder,
|
||||
Filter,
|
||||
Webhook,
|
||||
Repeat,
|
||||
} from 'lucide-react';
|
||||
import { TaskList, Thought, SubTask, Team, User, TaskListMember, KanbanColumn, PriorityLevel, Recurrence, RECURRENCE_LABELS } from '../../lib/types';
|
||||
@@ -35,7 +34,7 @@ import { useKanbanTouchDrag } from './useKanbanTouchDrag';
|
||||
import { api, triggerHaptic } from '../../lib/api';
|
||||
import { UnifiedShareModal } from '../../components/UnifiedShareModal';
|
||||
import { TaskDetailModal } from './TaskDetailModal';
|
||||
import { AgentBadge } from '../../components/AgentBadge';
|
||||
import { OriginBadge } from '../../components/OriginBadge';
|
||||
import { ManageColumnsModal, DEFAULT_KANBAN_COLUMNS, columnDotClass } from './ManageColumnsModal';
|
||||
import { AvatarStack, AvatarPerson } from '../../components/AvatarStack';
|
||||
import { CountBadge } from '../../components/CountBadge';
|
||||
@@ -1362,16 +1361,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</button>
|
||||
)}
|
||||
|
||||
{task.source?.toLowerCase() === 'webhook' && (
|
||||
<span
|
||||
className="px-1.5 py-0.5 border border-border bg-canvas text-muted rounded-btn text-[10px] font-medium flex items-center gap-1 flex-shrink-0"
|
||||
title="Erstellt über Webhook"
|
||||
>
|
||||
<Webhook className="w-2.5 h-2.5 text-accent" />
|
||||
<span>Webhook</span>
|
||||
</span>
|
||||
)}
|
||||
<AgentBadge mark={task.agentMark} />
|
||||
<OriginBadge origin={task.origin} createdAt={task.createdAt} />
|
||||
|
||||
{/* Note indicator */}
|
||||
{task.notes && (
|
||||
@@ -2436,16 +2426,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
⚠️ Wichtig
|
||||
</button>
|
||||
)}
|
||||
{task.source?.toLowerCase() === 'webhook' && (
|
||||
<span
|
||||
className="px-1.5 py-0.2 border border-border bg-canvas text-muted rounded-btn text-[9px] font-medium flex items-center gap-1"
|
||||
title="Erstellt über Webhook"
|
||||
>
|
||||
<Webhook className="w-2.5 h-2.5 text-accent" />
|
||||
<span>Webhook</span>
|
||||
</span>
|
||||
)}
|
||||
<AgentBadge mark={task.agentMark} size="xs" />
|
||||
<OriginBadge origin={task.origin} createdAt={task.createdAt} size="xs" />
|
||||
{task.dueDate && (
|
||||
<span
|
||||
className={`inline-flex items-center gap-0.5 text-[9px] ${!task.isCompleted && isOverdue(task.dueDate) ? 'text-status-err font-semibold' : 'text-muted'}`}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
RotateCcw,
|
||||
Sparkles,
|
||||
Mic,
|
||||
Webhook,
|
||||
Keyboard,
|
||||
Tag,
|
||||
Clock,
|
||||
@@ -25,7 +24,7 @@ import {
|
||||
import { SharedList, Thought } from '../../lib/types';
|
||||
import { addDays, formatDue } from '../../lib/due';
|
||||
import { api, triggerHaptic } from '../../lib/api';
|
||||
import { AgentBadge } from '../../components/AgentBadge';
|
||||
import { OriginBadge } from '../../components/OriginBadge';
|
||||
|
||||
interface TriageDeckProps {
|
||||
deck: Thought[];
|
||||
@@ -149,17 +148,12 @@ const SwipeableQueueItem: React.FC<SwipeableQueueItemProps> = ({
|
||||
<span className="text-sm sm:text-xs font-medium text-main line-clamp-2 sm:truncate">
|
||||
{item.content}
|
||||
</span>
|
||||
{item.source?.toLowerCase() === 'webhook' && (
|
||||
<span className="px-1.5 py-0.5 text-[10px] bg-canvas text-muted border border-border rounded-btn flex items-center gap-1 flex-shrink-0">
|
||||
<Webhook className="w-2.5 h-2.5 text-accent" /> Webhook
|
||||
</span>
|
||||
)}
|
||||
{item.source?.toLowerCase() === 'voice' && (
|
||||
<span className="px-1.5 py-0.5 text-[10px] bg-canvas text-accent border border-border rounded-btn flex items-center gap-1 flex-shrink-0">
|
||||
<Mic className="w-2.5 h-2.5" /> Diktat
|
||||
</span>
|
||||
)}
|
||||
<AgentBadge mark={item.agentMark} />
|
||||
<OriginBadge origin={item.origin} createdAt={item.createdAt} />
|
||||
</div>
|
||||
|
||||
{/* Desktop quick buttons (hidden on mobile so queue items are clean & easy to tap/swipe) */}
|
||||
@@ -441,13 +435,6 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (s === 'webhook') {
|
||||
return (
|
||||
<span className="px-2 py-0.5 text-[11px] bg-canvas text-muted border border-border rounded-btn flex items-center gap-1">
|
||||
<Webhook className="w-3 h-3 text-accent" /> Webhook
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -523,7 +510,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
<div className="flex items-center gap-1.5">
|
||||
{priorityBadge(nextCard.priority)}
|
||||
{sourceBadge(nextCard.source)}
|
||||
<AgentBadge mark={nextCard.agentMark} />
|
||||
<OriginBadge origin={nextCard.origin} createdAt={nextCard.createdAt} size="md" />
|
||||
</div>
|
||||
<p className="text-sm text-muted line-clamp-2">{nextCard.content}</p>
|
||||
<div className="text-[11px] text-faint">Nächster Quick Dump…</div>
|
||||
@@ -593,7 +580,7 @@ export const TriageDeck: React.FC<TriageDeckProps> = ({
|
||||
<div className="flex items-center gap-1.5">
|
||||
{priorityBadge(activeCard.priority)}
|
||||
{sourceBadge(activeCard.source)}
|
||||
<AgentBadge mark={activeCard.agentMark} />
|
||||
<OriginBadge origin={activeCard.origin} createdAt={activeCard.createdAt} size="md" />
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center gap-2"
|
||||
|
||||
Reference in new issue
Block a user