Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
175 commits
Select commit Hold shift + click to select a range
cacad42
wip add nested skills
dimaMachina Mar 11, 2026
834728c
wip skills page
dimaMachina Mar 12, 2026
f919ec6
update demo tree
dimaMachina Mar 12, 2026
1293cce
migration
dimaMachina Mar 12, 2026
faea8ef
migration
dimaMachina Mar 12, 2026
0978471
add a changeset
dimaMachina Mar 12, 2026
a688d9f
refactor
dimaMachina Mar 12, 2026
4c4cdbd
refactor
dimaMachina Mar 12, 2026
8c90262
refactor
dimaMachina Mar 12, 2026
392a4fc
refactor
dimaMachina Mar 12, 2026
8c60c3c
add arrows
dimaMachina Mar 12, 2026
cb1c945
add docs
dimaMachina Mar 12, 2026
ee9c975
upd page
dimaMachina Mar 12, 2026
ef1e05a
add text file writer
dimaMachina Mar 12, 2026
ccfa570
cleanup
dimaMachina Mar 12, 2026
01275b4
add tree node component
dimaMachina Mar 12, 2026
3bf3acd
upd
dimaMachina Mar 12, 2026
10e94e1
refactor
dimaMachina Mar 12, 2026
491c2bf
Merge branch 'main' into prd-6236
dimaMachina Mar 17, 2026
ee00dde
skill generator wip test
dimaMachina Mar 17, 2026
f874883
skill generator
dimaMachina Mar 17, 2026
c057ce9
polish skill generator
dimaMachina Mar 17, 2026
0530c0d
skills tests
dimaMachina Mar 17, 2026
3a4b72b
upd
dimaMachina Mar 17, 2026
4ba1ffc
Merge branch 'prd-6192-333' into prd-6236
dimaMachina Mar 17, 2026
7ffd874
upd
dimaMachina Mar 17, 2026
444f5fe
generation.test wip
dimaMachina Mar 17, 2026
9f5dec3
add generation.test
dimaMachina Mar 17, 2026
6e640c5
tree node
dimaMachina Mar 17, 2026
7c6cfbf
skill page
dimaMachina Mar 17, 2026
e9582ed
skill loader
dimaMachina Mar 17, 2026
99660be
skill loader refactor
dimaMachina Mar 17, 2026
7f1deb8
skill loader
dimaMachina Mar 17, 2026
4faa15e
move skills sidebar to layout
dimaMachina Mar 17, 2026
f8f7811
use pure monaco-editor component since we can have different file ext…
dimaMachina Mar 17, 2026
8beb630
add shadcn context menu component
dimaMachina Mar 17, 2026
1d4274e
format context menu
dimaMachina Mar 17, 2026
dd26c41
skills files and edit pages
dimaMachina Mar 17, 2026
c84445e
dry
dimaMachina Mar 17, 2026
2a2827f
update layout
dimaMachina Mar 17, 2026
c29601e
add docs
dimaMachina Mar 17, 2026
2c9cc78
add a changeset
dimaMachina Mar 17, 2026
fae2bb7
redirect to first skill
dimaMachina Mar 17, 2026
201167c
skill files utils
dimaMachina Mar 17, 2026
16edb18
skill selector
dimaMachina Mar 17, 2026
21af464
upd treenode
dimaMachina Mar 17, 2026
1580432
skill files
dimaMachina Mar 17, 2026
ab0282d
skill file editor
dimaMachina Mar 17, 2026
d5ce67a
delete skill confirmation
dimaMachina Mar 17, 2026
47df460
add skill files actions
dimaMachina Mar 17, 2026
64d399f
skills data
dimaMachina Mar 17, 2026
35701af
rm
dimaMachina Mar 17, 2026
640d79b
up skills route
dimaMachina Mar 17, 2026
158b085
upd
dimaMachina Mar 17, 2026
7e67975
upd
dimaMachina Mar 17, 2026
cf1383e
better project error message on dev
dimaMachina Mar 17, 2026
86ef481
types
dimaMachina Mar 17, 2026
62d8def
skill files
dimaMachina Mar 17, 2026
281c7ca
skill loader
dimaMachina Mar 17, 2026
7687e50
format
dimaMachina Mar 17, 2026
b410f66
project test
dimaMachina Mar 17, 2026
358bb93
entities
dimaMachina Mar 17, 2026
071f32b
project full tests
dimaMachina Mar 17, 2026
54de1f5
upd introspect
dimaMachina Mar 17, 2026
487a505
upd cliiii
dimaMachina Mar 17, 2026
1d932b3
nested skills tests
dimaMachina Mar 17, 2026
03987b2
remove edit page
dimaMachina Mar 17, 2026
9e8c78c
remove edit page
dimaMachina Mar 17, 2026
7074df5
update files page
dimaMachina Mar 17, 2026
744889e
upd
dimaMachina Mar 17, 2026
21130e1
upd file editor
dimaMachina Mar 17, 2026
4649df8
add SkillFileInsertSchema
dimaMachina Mar 18, 2026
c2c889b
superRefine
dimaMachina Mar 18, 2026
7c355d2
add transform
dimaMachina Mar 18, 2026
21f2810
rm some cases in superRefine
dimaMachina Mar 18, 2026
9540eed
use pipe
dimaMachina Mar 18, 2026
5aaf1cd
use pipe
dimaMachina Mar 18, 2026
d827cef
upd skill loader
dimaMachina Mar 18, 2026
287b994
validation skills
dimaMachina Mar 18, 2026
e96d775
upd
dimaMachina Mar 18, 2026
4375254
rm
dimaMachina Mar 18, 2026
ce7789e
upd
dimaMachina Mar 18, 2026
8eb3986
data access tests
dimaMachina Mar 18, 2026
21d8d64
skills db changes
dimaMachina Mar 18, 2026
b60b0fd
add
dimaMachina Mar 18, 2026
08088b5
skill files
dimaMachina Mar 18, 2026
37e13eb
upd
dimaMachina Mar 18, 2026
ef424e2
upd
dimaMachina Mar 18, 2026
bca6fc1
upd skill update
dimaMachina Mar 18, 2026
0aa7d7c
SkillUpdateSchema has required files
dimaMachina Mar 18, 2026
ebb09c0
upd skills manage
dimaMachina Mar 18, 2026
25ec4e0
upd
dimaMachina Mar 18, 2026
ebd659b
upd layout and page
dimaMachina Mar 18, 2026
4379732
Merge branch 'main' into prd-6236
dimaMachina Mar 18, 2026
b75fbee
style: auto-format with biome
github-actions[bot] Mar 18, 2026
ce84448
move empty state comp to page
dimaMachina Mar 18, 2026
2426479
upd schemas
dimaMachina Mar 18, 2026
620a43f
update schemas
dimaMachina Mar 18, 2026
2b6abc4
move to with-sidebar
dimaMachina Mar 18, 2026
e7152e4
polish
dimaMachina Mar 18, 2026
c5429d4
upd
dimaMachina Mar 18, 2026
7da634c
upd skill generator
dimaMachina Mar 18, 2026
fc48bd4
Make webhooks docs user friendly (#2752)
Gaurav-Narayan-Varma Mar 18, 2026
3c706f2
Use tag reference for pullfrog action instead of pinned SHA (#2757)
amikofalvy Mar 18, 2026
1182452
ci: provision PR preview environments in Railway (#2681)
vnv-varun Mar 18, 2026
6b369d8
fix(ci): correct Playwright cache restore-key prefix mismatch (#2760)
amikofalvy Mar 18, 2026
4753c9b
fix(ci): replace full git clone with shallow checkout in CI job (#2761)
amikofalvy Mar 18, 2026
4d3f611
format
dimaMachina Mar 18, 2026
84e4b90
Merge branch 'prd-6192-333' into prd-6236
dimaMachina Mar 18, 2026
cf620d3
rm migration
dimaMachina Mar 18, 2026
c9a66c6
Merge branch 'prd-6192-333' into prd-6236
dimaMachina Mar 19, 2026
97fdf7b
add new migrations
dimaMachina Mar 18, 2026
d0928e9
validation for skill is ok
dimaMachina Mar 18, 2026
08ddef8
move empty state to page
dimaMachina Mar 18, 2026
65c5c82
delete skill
dimaMachina Mar 18, 2026
c69831d
delete skill revalidate path
dimaMachina Mar 18, 2026
8f7a155
move skills schemas to own file
dimaMachina Mar 19, 2026
a94a2b2
upd
dimaMachina Mar 19, 2026
35e5ff6
upd
dimaMachina Mar 19, 2026
c383c1d
upd
dimaMachina Mar 19, 2026
93e5513
upd
dimaMachina Mar 19, 2026
c66b6ec
upd
dimaMachina Mar 19, 2026
61e9774
upd
dimaMachina Mar 19, 2026
06dd980
upd
dimaMachina Mar 19, 2026
2d0f520
upd
dimaMachina Mar 19, 2026
8405c23
upd
dimaMachina Mar 19, 2026
545b3ef
upd
dimaMachina Mar 19, 2026
b56f746
more typecheck fixes
dimaMachina Mar 19, 2026
5b867ec
more typecheck fixes
dimaMachina Mar 19, 2026
bbb0b2d
fix
dimaMachina Mar 19, 2026
2735c78
fix isRequired
dimaMachina Mar 19, 2026
82c2bf7
f1x
dimaMachina Mar 19, 2026
5431287
move skill sidebar
dimaMachina Mar 19, 2026
e4abbfa
refactor skill sidebar
dimaMachina Mar 19, 2026
c8cb267
add collapse file tree button
dimaMachina Mar 19, 2026
6cbe1e9
upd
dimaMachina Mar 19, 2026
e87fd5c
upd
dimaMachina Mar 19, 2026
0bfb16d
upd
dimaMachina Mar 19, 2026
69a7433
deleteSkillFile
dimaMachina Mar 19, 2026
dbfe03f
upd
dimaMachina Mar 19, 2026
6ce533c
deleteSkillFile
dimaMachina Mar 19, 2026
76bda40
fileId
dimaMachina Mar 19, 2026
2027327
fileId
dimaMachina Mar 19, 2026
2dc8f81
upd schemas
dimaMachina Mar 19, 2026
d7a91b3
DeleteSkillFileConfirmation
dimaMachina Mar 19, 2026
d17ed3d
updateSkillFile
dimaMachina Mar 19, 2026
49e8629
rm simplematter from sdk
dimaMachina Mar 19, 2026
bb2a66a
Get Skill File
dimaMachina Mar 19, 2026
cd9a686
getSkillFileById
dimaMachina Mar 19, 2026
382e89a
add new skill file page
dimaMachina Mar 19, 2026
c635cd1
update skill file editor
dimaMachina Mar 19, 2026
8b5bce6
format
dimaMachina Mar 19, 2026
fe6fedc
Create Skill File
dimaMachina Mar 20, 2026
b76aeaf
upd
dimaMachina Mar 20, 2026
f51b590
createSkillFileAction
dimaMachina Mar 20, 2026
8e1fa7e
createSkillFileById
dimaMachina Mar 20, 2026
b653e82
fix: Make OpenTelemetry startup idempotent (#2684)
mike-inkeep Mar 19, 2026
7e81757
Fix scheduled trigger invocations being skipped (#2777)
shagun-singh-inkeep Mar 19, 2026
7ed5e6d
adding app id (#2779)
shagun-singh-inkeep Mar 19, 2026
cc08989
Update pullfrog to latest SHA and add daily dependabot group for high…
amikofalvy Mar 19, 2026
0fa612c
ci: seed preview auth in PR previews (#2775)
vnv-varun Mar 20, 2026
ae911bf
Fix scopes placeholder to show correct Nango format (#2784)
omar-inkeep Mar 20, 2026
57578ce
fix(manage-ui): fix URL validation bypass and permission guard in cre…
omar-inkeep Mar 20, 2026
d46d82e
feat(pdf): Support PDF attachments (#2709)
mike-inkeep Mar 20, 2026
8c24240
feat: Composio connected account ID pinning (#2783)
omar-inkeep Mar 20, 2026
b3e4aa2
Version Packages (#2778)
inkeep-internal-ci[bot] Mar 20, 2026
3166324
Add back link to projects sidebar, add org settings link to user drop…
sarah-inkeep Mar 20, 2026
4ebc877
fix: return FileUIPart-compliant file parts from /run conversations e…
amikofalvy Mar 20, 2026
a39ee21
fix: treat load_skill as internal tool to suppress false-positive Sen…
anubra266 Mar 20, 2026
7dbfdaf
fix for fetch trace (#2791)
shagun-singh-inkeep Mar 20, 2026
9d9ad43
Fix empty breadcrumb on `/[tenantId]/profile` page and replace prop-d…
dimaMachina Mar 20, 2026
6846de6
fix(manage-ui): fix user-scoped MCP credential card not refreshing af…
omar-inkeep Mar 20, 2026
c37bec3
reuse `useProjectsQuery` instead of `fetchProjectsAction` in `useEffe…
dimaMachina Mar 20, 2026
7b9e673
upd
dimaMachina Mar 20, 2026
310ecb4
Merge branch 'prd-6192-333' into prd-6236
dimaMachina Mar 20, 2026
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
5 changes: 5 additions & 0 deletions .changeset/file-routed-skills-ui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@inkeep/agents-manage-ui': patch
---

Add file-routed skill browsing and editing so synced skill files open in dedicated read-only and edit pages with file-level remove actions.
8 changes: 8 additions & 0 deletions .changeset/nested-skill-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@inkeep/agents-core': patch
'@inkeep/agents-sdk': patch
'@inkeep/agents-api': patch
'@inkeep/agents-manage-ui': patch
---

Add nested skill file persistence and syncing so skill directories keep auxiliary files alongside `SKILL.md` during API updates and `inkeep push`.
122 changes: 108 additions & 14 deletions agents-api/__snapshots__/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -7299,6 +7299,26 @@
"minLength": 1,
"type": "string"
},
"files": {
"items": {
"properties": {
"content": {
"type": "string"
},
"filePath": {
"maxLength": 1024,
"minLength": 1,
"type": "string"
}
},
"required": [
"filePath",
"content"
],
"type": "object"
},
"type": "array"
},
"metadata": {
"allOf": [
{
Expand All @@ -7323,6 +7343,39 @@
],
"type": "object"
},
"SkillFile": {
"properties": {
"content": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"filePath": {
"type": "string"
},
"id": {
"maxLength": 256,
"type": "string"
},
"skillId": {
"maxLength": 64,
"type": "string"
},
"updatedAt": {
"type": "string"
}
},
"required": [
"id",
"skillId",
"filePath",
"content",
"createdAt",
"updatedAt"
],
"type": "object"
},
"SkillListResponse": {
"properties": {
"data": {
Expand All @@ -7341,17 +7394,6 @@
],
"type": "object"
},
"SkillResponse": {
"properties": {
"data": {
"$ref": "#/components/schemas/Skill"
}
},
"required": [
"data"
],
"type": "object"
},
"SkillUpdate": {
"properties": {
"content": {
Expand All @@ -7363,6 +7405,26 @@
"minLength": 1,
"type": "string"
},
"files": {
"items": {
"properties": {
"content": {
"type": "string"
},
"filePath": {
"maxLength": 1024,
"minLength": 1,
"type": "string"
}
},
"required": [
"filePath",
"content"
],
"type": "object"
},
"type": "array"
},
"metadata": {
"allOf": [
{
Expand All @@ -7376,6 +7438,38 @@
},
"type": "object"
},
"SkillWithFiles": {
"allOf": [
{
"$ref": "#/components/schemas/Skill"
},
{
"properties": {
"files": {
"items": {
"$ref": "#/components/schemas/SkillFile"
},
"type": "array"
}
},
"required": [
"files"
],
"type": "object"
}
]
},
"SkillWithFilesResponse": {
"properties": {
"data": {
"$ref": "#/components/schemas/SkillWithFiles"
}
},
"required": [
"data"
],
"type": "object"
},
"StatusComponent": {
"properties": {
"description": {
Expand Down Expand Up @@ -36662,7 +36756,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SkillResponse"
"$ref": "#/components/schemas/SkillWithFilesResponse"
}
}
},
Expand Down Expand Up @@ -36883,7 +36977,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SkillResponse"
"$ref": "#/components/schemas/SkillWithFilesResponse"
}
}
},
Expand Down Expand Up @@ -37005,7 +37099,7 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SkillResponse"
"$ref": "#/components/schemas/SkillWithFilesResponse"
}
}
},
Expand Down
193 changes: 193 additions & 0 deletions agents-api/src/__tests__/manage/integration/skills.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { generateId } from '@inkeep/agents-core';
import { afterEach, describe, expect, it } from 'vitest';
import { cleanupTenants } from '../../utils/cleanup';
import { makeRequest } from '../../utils/testRequest';
import { createTestTenantWithOrg } from '../../utils/testTenant';

describe('Skill Routes - Integration Tests', () => {
const createdTenants = new Set<string>();

afterEach(async () => {
await cleanupTenants(createdTenants);
createdTenants.clear();
});

const createTrackedTenant = async (suffix: string) => {
const tenantId = await createTestTenantWithOrg(suffix);
createdTenants.add(tenantId);
return tenantId;
};

const createProject = async (tenantId: string, projectId: string) => {
const response = await makeRequest(`/manage/tenants/${tenantId}/projects`, {
method: 'POST',
body: JSON.stringify({
id: projectId,
name: 'Test Project',
description: 'Test project',
models: {
base: {
model: 'claude-sonnet-4',
providerOptions: {},
},
},
}),
});

expect(response.status).toBe(201);
};

it('should create, fetch, and update nested skill files', async () => {
const tenantId = await createTrackedTenant('skills-crud');
const projectId = `project-${generateId()}`;
await createProject(tenantId, projectId);

const createResponse = await makeRequest(
`/manage/tenants/${tenantId}/projects/${projectId}/skills`,
{
method: 'POST',
body: JSON.stringify({
name: 'weather-safety-guardrails',
description: 'Safety rules.',
content: 'Always check the weather.',
metadata: null,
files: [
{
filePath: 'SKILL.md',
content: `---
name: weather-safety-guardrails
description: "Safety rules."
---
Always check the weather.`,
},
{
filePath: 'reference/safety-checklist.txt',
content: 'Check alerts',
},
],
}),
}
);

expect(createResponse.status).toBe(201);
const createdBody = await createResponse.json();
expect(createdBody.data.files).toEqual([
expect.objectContaining({ filePath: 'SKILL.md' }),
expect.objectContaining({ filePath: 'reference/safety-checklist.txt' }),
]);

const listResponse = await makeRequest(
`/manage/tenants/${tenantId}/projects/${projectId}/skills`
);
expect(listResponse.status).toBe(200);
const listBody = await listResponse.json();
expect(listBody.data[0].files).toBeUndefined();

const detailResponse = await makeRequest(
`/manage/tenants/${tenantId}/projects/${projectId}/skills/weather-safety-guardrails`
);
expect(detailResponse.status).toBe(200);
const detailBody = await detailResponse.json();
expect(detailBody.data.files.map((file: any) => file.filePath)).toEqual([
'SKILL.md',
'reference/safety-checklist.txt',
]);

const updateResponse = await makeRequest(
`/manage/tenants/${tenantId}/projects/${projectId}/skills/weather-safety-guardrails`,
{
method: 'PUT',
body: JSON.stringify({
description: 'Updated safety rules.',
content: 'Always check alerts.',
files: [
{
filePath: 'SKILL.md',
content: `---
name: weather-safety-guardrails
description: "Updated safety rules."
---
Always check alerts.`,
},
{
filePath: 'templates/alert.md',
content: 'Alert template',
},
],
}),
}
);

expect(updateResponse.status).toBe(200);
const updatedBody = await updateResponse.json();
expect(updatedBody.data.files.map((file: any) => file.filePath)).toEqual([
'SKILL.md',
'templates/alert.md',
]);
});

it('should round-trip nested skill files through the full project API', async () => {
const tenantId = await createTrackedTenant('skills-project-full');
const projectId = `project-${generateId()}`;

const createResponse = await makeRequest(`/manage/tenants/${tenantId}/project-full`, {
method: 'POST',
body: JSON.stringify({
id: projectId,
name: 'Test Project',
description: 'Test project',
models: {
base: {
model: 'claude-sonnet-4',
providerOptions: {},
},
},
agents: {},
tools: {},
skills: {
'structured-itinerary-responses': {
id: 'structured-itinerary-responses',
name: 'structured-itinerary-responses',
description: 'Structured itineraries.',
content: 'Use itinerary templates.',
metadata: null,
files: [
{
filePath: 'SKILL.md',
content: `---
name: structured-itinerary-responses
description: "Structured itineraries."
---
Use itinerary templates.`,
},
{
filePath: 'templates/day/itinerary-card.html',
content: '<article>Plan</article>',
},
],
},
},
}),
});

expect(createResponse.status).toBe(201);

const getResponse = await makeRequest(`/manage/tenants/${tenantId}/project-full/${projectId}`);
expect(getResponse.status).toBe(200);
const getBody = await getResponse.json();
expect(getBody.data.skills['structured-itinerary-responses'].files).toEqual([
{
filePath: 'SKILL.md',
content: `---
name: structured-itinerary-responses
description: "Structured itineraries."
---
Use itinerary templates.`,
},
{
filePath: 'templates/day/itinerary-card.html',
content: '<article>Plan</article>',
},
]);
});
});
Loading
Loading