feat(ui): add content editor components for skills and thoughts
CI / build-and-test (push) Failing after -31m24s

* Implement ContentEditorField for inline editing of content
* Create ContentEditorModal for editing content in a modal
* Introduce FormerShell for managing forms related to skills and thoughts
* Enhance SkillsPage and ThoughtsPage with new components for better content management
This commit is contained in:
2026-05-02 19:35:27 +02:00
parent 442cc3ef53
commit 9e6d05e055
59 changed files with 4727 additions and 3430 deletions
+52 -5
View File
@@ -152,7 +152,10 @@ export const api = {
create: (name: string, description: string) =>
rsCall<import('./types').Project>('/api/rs/public/projects', 'create', {
data: { name, description }
})
}),
update: (id: string, data: { name?: string; description?: string }) =>
rsCall<void>(`/api/rs/public/projects/${id}`, 'update', { data }),
delete: (id: string) => rsCall<void>(`/api/rs/public/projects/${id}`, 'delete')
},
thoughts: {
list: (params: { q?: string; project_id?: string; limit?: number; offset?: number; include_archived?: boolean }) => {
@@ -232,7 +235,11 @@ export const api = {
archive: (id: string) =>
rsCall<void>(`/api/rs/public/thoughts/${id}`, 'update', {
data: { archived_at: new Date().toISOString() }
})
}),
create: (data: { content: string; project_id?: string }) =>
rsCall<import('./types').Thought>('/api/rs/public/thoughts', 'create', { data }),
update: (id: string, data: { content?: string }) =>
rsCall<void>(`/api/rs/public/thoughts/${id}`, 'update', { data })
},
skills: {
list: async (tag?: string) => {
@@ -243,7 +250,18 @@ export const api = {
});
return rows.map((row) => ({ ...row, tags: normalizeTags(row.tags) }));
},
delete: (id: string) => rsCall<void>(`/api/rs/public/agent_skills/${id}`, 'delete')
get: async (id: string) => {
const row = await rsCall<Omit<import('./types').AgentSkill, 'tags'> & { tags?: unknown }>(
`/api/rs/public/agent_skills/${id}`,
'read'
);
return { ...row, tags: normalizeTags(row.tags) };
},
create: (data: { name: string; description?: string; content: string; tags?: string[] }) =>
rsCall<import('./types').AgentSkill>('/api/rs/public/agent_skills', 'create', { data }),
delete: (id: string) => rsCall<void>(`/api/rs/public/agent_skills/${id}`, 'delete'),
update: (id: string, data: Partial<import('./types').AgentSkill>) =>
rsCall<void>(`/api/rs/public/agent_skills/${id}`, 'update', { data })
},
guardrails: {
list: async (params?: { tag?: string; severity?: string }) => {
@@ -258,7 +276,9 @@ export const api = {
});
return rows.map((row) => ({ ...row, tags: normalizeTags(row.tags) }));
},
delete: (id: string) => rsCall<void>(`/api/rs/public/agent_guardrails/${id}`, 'delete')
delete: (id: string) => rsCall<void>(`/api/rs/public/agent_guardrails/${id}`, 'delete'),
update: (id: string, data: Partial<import('./types').AgentGuardrail>) =>
rsCall<void>(`/api/rs/public/agent_guardrails/${id}`, 'update', { data })
},
files: {
list: (params?: { project_id?: string; thought_id?: string; kind?: string }) => {
@@ -326,7 +346,34 @@ export const api = {
sort: [{ column: 'updated_at', direction: 'desc' }]
});
return rows.map((row) => ({ ...row, tags: normalizeTags(row.tags) }));
}
},
get: async (id: string) => {
const row = await rsCall<Omit<import('./types').Plan, 'tags'> & { tags?: unknown }>(
`/api/rs/public/plans/${id}`,
'read'
);
return { ...row, tags: normalizeTags(row.tags) };
},
create: (data: object) =>
rsCall<import('./types').Plan>('/api/rs/public/plans', 'create', { data }),
update: (id: string, data: Partial<import('./types').Plan>) =>
rsCall<void>(`/api/rs/public/plans/${id}`, 'update', { data }),
delete: (id: string) => rsCall<void>(`/api/rs/public/plans/${id}`, 'delete')
},
learnings: {
list: (params?: { limit?: number; offset?: number }) =>
rsReadMany<import('./types').Learning>('learnings', {
limit: params?.limit ?? 500,
...(params?.offset !== undefined ? { offset: params.offset } : {}),
sort: [{ column: 'created_at', direction: 'desc' }]
}),
get: (id: string) =>
rsCall<import('./types').Learning>(`/api/rs/public/learnings/${id}`, 'read'),
create: (data: object) =>
rsCall<import('./types').Learning>('/api/rs/public/learnings', 'create', { data }),
update: (id: string, data: Partial<import('./types').Learning>) =>
rsCall<void>(`/api/rs/public/learnings/${id}`, 'update', { data }),
delete: (id: string) => rsCall<void>(`/api/rs/public/learnings/${id}`, 'delete')
},
stats: async () => {
type StatsThoughtRow = {