@lovelybunch/api 1.0.75-alpha.5 → 1.0.75-alpha.6

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 (108) hide show
  1. package/dist/routes/api/v1/ai/route.js +4 -3
  2. package/dist/routes/api/v1/events/status/route.d.ts +1 -1
  3. package/dist/routes/api/v1/jobs/[id]/run/route.d.ts +2 -2
  4. package/dist/routes/api/v1/jobs/[id]/runs/[runId]/route.d.ts +2 -2
  5. package/dist/routes/api/v1/jobs/status/route.d.ts +1 -1
  6. package/dist/routes/api/v1/proposals/[id]/route.d.ts +8 -8
  7. package/dist/routes/api/v1/skills/[id]/index.d.ts +1 -0
  8. package/dist/routes/api/v1/skills/[id]/index.js +1 -0
  9. package/dist/routes/api/v1/skills/[id]/route.d.ts +3 -0
  10. package/dist/routes/api/v1/skills/[id]/route.js +199 -0
  11. package/dist/routes/api/v1/skills/index.d.ts +1 -0
  12. package/dist/routes/api/v1/skills/index.js +1 -0
  13. package/dist/routes/api/v1/skills/route.d.ts +3 -0
  14. package/dist/routes/api/v1/skills/route.js +329 -0
  15. package/dist/server-with-static.js +4 -4
  16. package/dist/server.js +4 -4
  17. package/package.json +6 -4
  18. package/static/assets/{ActivityPage-6xf2Jxp0.js → ActivityPage-QmXUVEPm.js} +1 -1
  19. package/static/assets/{ApiKeysSettingsPage-DlWMBuQb.js → ApiKeysSettingsPage-qie8F6gb.js} +1 -1
  20. package/static/assets/{ArchitectureEditPage-C6MWFHCp.js → ArchitectureEditPage-CPQnvHk4.js} +1 -1
  21. package/static/assets/{ArchitecturePage-CxQtPG4d.js → ArchitecturePage-CJNygJU2.js} +1 -1
  22. package/static/assets/{AuthSettingsPage-w0blkw8Q.js → AuthSettingsPage-B204F8bT.js} +1 -1
  23. package/static/assets/{CallbackPage-ByjWTMuG.js → CallbackPage-MGCRI7r_.js} +1 -1
  24. package/static/assets/CodePage-BxEsUJP-.js +2 -0
  25. package/static/assets/{CollapsibleSection-B1AU3exJ.js → CollapsibleSection-CtALgJpu.js} +1 -1
  26. package/static/assets/{DashboardPage-CAToLPqr.js → DashboardPage-DbvVqN24.js} +1 -1
  27. package/static/assets/{GitPage-DGjEzIUs.js → GitPage-D2bnwXyJ.js} +1 -1
  28. package/static/assets/{GitSettingsPage-X1GEO1Ti.js → GitSettingsPage-ZDdKMZl1.js} +1 -1
  29. package/static/assets/{IdentityPage-L0foq6qN.js → IdentityPage-Bu-duoN6.js} +1 -1
  30. package/static/assets/{ImplementationStepsEditor-Dn88eiVP.js → ImplementationStepsEditor-PDSNPMod.js} +1 -1
  31. package/static/assets/{IntegrationsSettingsPage-WX1lSaWr.js → IntegrationsSettingsPage-DsM2vBgQ.js} +1 -1
  32. package/static/assets/{JobDetailPage-CvNs3cEP.js → JobDetailPage-BBCASAAb.js} +1 -1
  33. package/static/assets/{KnowledgeDetailPage-DXjmZdQl.js → KnowledgeDetailPage-D1EptY9f.js} +1 -1
  34. package/static/assets/{KnowledgeEditPage-C70yoVFM.js → KnowledgeEditPage-Dd4B0Zol.js} +1 -1
  35. package/static/assets/{KnowledgePage-EUJ9c9By.js → KnowledgePage-ibFc3y1K.js} +1 -1
  36. package/static/assets/{LoginPage-Df_q-ACP.js → LoginPage-v8StIMKr.js} +1 -1
  37. package/static/assets/{McpSettingsPage-4b5M8tpH.js → McpSettingsPage-m5Wzim08.js} +1 -1
  38. package/static/assets/{NewKnowledgePage-CqKz6_K-.js → NewKnowledgePage-rmXqT_ay.js} +1 -1
  39. package/static/assets/{NewProposalPage-DR9UZich.js → NewProposalPage-CmMTQLo5.js} +1 -1
  40. package/static/assets/NewSkillPage-D3Fffhkj.js +1 -0
  41. package/static/assets/{ProjectEditPage-5YxG7Xxd.js → ProjectEditPage-C37nAWFP.js} +1 -1
  42. package/static/assets/{ProjectPage-BBhGv2fS.js → ProjectPage--_Q_QLC1.js} +1 -1
  43. package/static/assets/{PromptsSettingsPage-DLrpZcDA.js → PromptsSettingsPage-CGXj9CAs.js} +1 -1
  44. package/static/assets/{ProposalDetailPage-C4tagoNE.js → ProposalDetailPage-BUHhxZ3l.js} +1 -1
  45. package/static/assets/{ProposalEditPage-Bz-oEsLL.js → ProposalEditPage-C0eEdxJc.js} +1 -1
  46. package/static/assets/{ProposalsPage-BKRjNF4y.js → ProposalsPage-DyQC5FFd.js} +1 -1
  47. package/static/assets/{ResourcesPage-BZrToY-V.js → ResourcesPage-IrMHiK53.js} +1 -1
  48. package/static/assets/{RoleEditPage-C2vWadxy.js → RoleEditPage-Bw35Wz-d.js} +1 -1
  49. package/static/assets/{RolePage-CE9y3rMd.js → RolePage-BOjMgEYI.js} +1 -1
  50. package/static/assets/{RulesSettingsPage-BidnZaAT.js → RulesSettingsPage-B0eW6OmX.js} +1 -1
  51. package/static/assets/{SchedulePage-DU7ng6Gq.js → SchedulePage-CrfWjM5k.js} +1 -1
  52. package/static/assets/SkillDetailPage-CKDNJYXm.js +1 -0
  53. package/static/assets/SkillEditPage-DnBv-wu9.js +1 -0
  54. package/static/assets/SkillsPage-C5VD2DNt.js +8 -0
  55. package/static/assets/SkillsSettingsPage-D3M6mo3a.js +1 -0
  56. package/static/assets/{SourceInput-CCa7okhU.js → SourceInput-BN8ZVkqs.js} +1 -1
  57. package/static/assets/{TagInput-Chn207ze.js → TagInput-CICgcKUW.js} +1 -1
  58. package/static/assets/{TerminalPage-CEYgdKT2.js → TerminalPage-PJ6jkMN5.js} +1 -1
  59. package/static/assets/TerminalSessionPage-DuJ2n3mT.js +13 -0
  60. package/static/assets/{UserPreferencesPage-lPgr1ngr.js → UserPreferencesPage-CyNuAJru.js} +1 -1
  61. package/static/assets/{UserSettingsPage-ctHFqz6e.js → UserSettingsPage-Bq2TlR-8.js} +1 -1
  62. package/static/assets/{UtilitiesPage-BVxyh0Ce.js → UtilitiesPage-mZb2CtxF.js} +1 -1
  63. package/static/assets/{alert-D5jzRTa5.js → alert-CrqaDLRU.js} +1 -1
  64. package/static/assets/{arrow-down-4I_8gyhd.js → arrow-down-CfqDgiIx.js} +1 -1
  65. package/static/assets/{arrow-left-DZzHrGWA.js → arrow-left-CIkDScAO.js} +1 -1
  66. package/static/assets/{arrow-up-B4VxSS3_.js → arrow-up-DoOW0Uek.js} +1 -1
  67. package/static/assets/{badge-DvLOhob-.js → badge-ikmjXCY_.js} +1 -1
  68. package/static/assets/{browser-modal-DzaD2oDW.js → browser-modal-BJ16icY9.js} +1 -1
  69. package/static/assets/{calendar-BNe2rz1T.js → calendar-B3EFURS-.js} +1 -1
  70. package/static/assets/{card-BguljVtN.js → card-C0a11V0T.js} +1 -1
  71. package/static/assets/{chevron-left-DZQ_tMvU.js → chevron-left-Cbq2vuK_.js} +1 -1
  72. package/static/assets/{chevrons-up-BCenbxtV.js → chevrons-up-C3zGaueJ.js} +1 -1
  73. package/static/assets/{circle-alert-CZtpB74t.js → circle-alert-BZyc7kNR.js} +1 -1
  74. package/static/assets/{circle-check-hWIEYAMH.js → circle-check-CC67C1b-.js} +1 -1
  75. package/static/assets/{circle-check-big-CTApxALS.js → circle-check-big-tNM4uoO8.js} +1 -1
  76. package/static/assets/{circle-play-BF3gDlvZ.js → circle-play-DgDKRctX.js} +1 -1
  77. package/static/assets/{circle-x-BtYTEkcT.js → circle-x-CbIXbCmI.js} +1 -1
  78. package/static/assets/{clipboard-B8Tnfm3W.js → clipboard-Bhg2iYmV.js} +1 -1
  79. package/static/assets/{clock-_sj3uVNp.js → clock-DUwjJehj.js} +1 -1
  80. package/static/assets/{download-CPGv4d5Q.js → download-CAr6POG8.js} +1 -1
  81. package/static/assets/{droid-BWtMgfPD.js → droid-DqWsM2dp.js} +5 -5
  82. package/static/assets/{external-link-CtxWkvSs.js → external-link-C552Tasx.js} +1 -1
  83. package/static/assets/{eye-_nXnan_b.js → eye-F-BxEo2B.js} +1 -1
  84. package/static/assets/{folder-git-2-C_Zkp5wq.js → folder-git-2-BCO-gmji.js} +1 -1
  85. package/static/assets/{index-BlLRLvWP.js → index-Cb4mP03_.js} +9 -9
  86. package/static/assets/{info-fJ-d5-p-.js → info-DZ6rfcGz.js} +1 -1
  87. package/static/assets/{label-PINvlQb-.js → label-VXwOLYGm.js} +1 -1
  88. package/static/assets/{markdown-editor-B7Zxgu1u.js → markdown-editor-DKBU3Sgf.js} +1 -1
  89. package/static/assets/{pause-C9zNWRax.js → pause-CJhh_zgy.js} +1 -1
  90. package/static/assets/{play-BpXD0Ub0.js → play-DqF_TESp.js} +1 -1
  91. package/static/assets/{plus-DBJTL6qk.js → plus-B-nP-2Bc.js} +1 -1
  92. package/static/assets/{radio-group-DBaY5DVP.js → radio-group-CkXoX9re.js} +1 -1
  93. package/static/assets/{refresh-cw-SQsUc3_C.js → refresh-cw-DNCHo2vd.js} +1 -1
  94. package/static/assets/{search-CBNlhD-8.js → search-pT3zGN1p.js} +1 -1
  95. package/static/assets/{switch-C3ys7mIF.js → switch-DKgMJKx9.js} +1 -1
  96. package/static/assets/{tabs-BpxOu6UL.js → tabs-LRqYZP6q.js} +1 -1
  97. package/static/assets/{tag-Cu4oj34X.js → tag-CNJNVCjj.js} +1 -1
  98. package/static/assets/{terminal-preview-B5-BekLC.js → terminal-preview-C_hF2vLs.js} +1 -1
  99. package/static/assets/{use-terminal-CDMgbskg.js → use-terminal-B3kcgG1Q.js} +1 -1
  100. package/static/assets/{zap-LrtVPxxV.js → zap-DeMKwLsi.js} +1 -1
  101. package/static/index.html +1 -1
  102. package/static/assets/AgentDetailPage-1hbFBTeB.js +0 -1
  103. package/static/assets/AgentEditPage-qMmg057j.js +0 -1
  104. package/static/assets/AgentsPage-DyyJrXqo.js +0 -3
  105. package/static/assets/AgentsSettingsPage-Bf61k6i0.js +0 -6
  106. package/static/assets/CodePage-aWl0jKwx.js +0 -2
  107. package/static/assets/NewAgentPage-BqvZZJmC.js +0 -1
  108. package/static/assets/TerminalSessionPage-C8YA0AmM.js +0 -13
@@ -39,7 +39,7 @@ function getGlobalApiKey(provider) {
39
39
  }
40
40
  export async function POST(c) {
41
41
  try {
42
- const { message: userMessage, history, context, contextContent, agentPersona, systemPrompt: systemOverride, attachedContextFiles } = await c.req.json();
42
+ const { message: userMessage, history, context, contextContent, skillPersona, agentPersona, systemPrompt: systemOverride, attachedContextFiles } = await c.req.json();
43
43
  if (!userMessage) {
44
44
  return c.json({ error: "Message is required" }, 400);
45
45
  }
@@ -55,8 +55,9 @@ export async function POST(c) {
55
55
  const anthropicClient = createAnthropic({ apiKey });
56
56
  const model = anthropicClient('claude-sonnet-4-5-20250929');
57
57
  const baseSystem = systemOverride || getSystemPrompt();
58
- const systemPrompt = agentPersona
59
- ? `${baseSystem}\n\nThe following persona is authoritative and overrides general guidance above. You must strictly follow it.\n\n${agentPersona}`
58
+ const persona = skillPersona || agentPersona; // Support both new and legacy field names
59
+ const systemPrompt = persona
60
+ ? `${baseSystem}\n\nThe following persona is authoritative and overrides general guidance above. You must strictly follow it.\n\n${persona}`
60
61
  : baseSystem;
61
62
  // Build context messages from attached files
62
63
  const contextMessages = [];
@@ -7,9 +7,9 @@ import { Context } from "hono";
7
7
  * Get logging system status and configuration
8
8
  */
9
9
  export declare function GET(c: Context): Promise<(Response & import("hono").TypedResponse<{
10
- [x: string]: any;
11
10
  currentFile: string;
12
11
  sizeBytes: number;
12
+ lastSeq: number;
13
13
  rotateBytes: number;
14
14
  logsDir: string;
15
15
  }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
@@ -12,8 +12,8 @@ export declare function POST(c: Context): Promise<(Response & import("hono").Typ
12
12
  run: {
13
13
  id: string;
14
14
  jobId: string;
15
- trigger: import("@lovelybunch/types").ScheduledJobTrigger;
16
- status: import("@lovelybunch/types").ScheduledJobRunStatus;
15
+ trigger: import("@lovelybunch/core").ScheduledJobTrigger;
16
+ status: import("@lovelybunch/core").ScheduledJobRunStatus;
17
17
  startedAt: string;
18
18
  finishedAt?: string;
19
19
  outputPath?: string;
@@ -10,8 +10,8 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
10
10
  data: {
11
11
  id: string;
12
12
  jobId: string;
13
- trigger: import("@lovelybunch/types").ScheduledJobTrigger;
14
- status: import("@lovelybunch/types").ScheduledJobRunStatus;
13
+ trigger: import("@lovelybunch/core").ScheduledJobTrigger;
14
+ status: import("@lovelybunch/core").ScheduledJobRunStatus;
15
15
  startedAt: string;
16
16
  finishedAt?: string;
17
17
  outputPath?: string;
@@ -7,7 +7,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
7
7
  runningCount: number;
8
8
  jobs: {
9
9
  id: string;
10
- status: import("@lovelybunch/types").ScheduledJobStatus;
10
+ status: import("@lovelybunch/core").ScheduledJobStatus;
11
11
  nextRunAt?: string;
12
12
  lastRunAt?: string;
13
13
  timerActive: boolean;
@@ -13,7 +13,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
13
13
  intent?: string;
14
14
  content?: string;
15
15
  author: {
16
- type: import("@lovelybunch/types").AuthorType;
16
+ type: import("@lovelybunch/core").AuthorType;
17
17
  id: string;
18
18
  name: string;
19
19
  email?: string;
@@ -48,7 +48,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
48
48
  version: string;
49
49
  name: string;
50
50
  description: string;
51
- type: import("@lovelybunch/types").FeatureFlagType;
51
+ type: import("@lovelybunch/core").FeatureFlagType;
52
52
  defaultValue: any;
53
53
  scopes: string[];
54
54
  targets: {
@@ -96,7 +96,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
96
96
  minimumSampleSize: number;
97
97
  testType: "two-tailed" | "one-tailed";
98
98
  };
99
- status: import("@lovelybunch/types").ExperimentStatus;
99
+ status: import("@lovelybunch/core").ExperimentStatus;
100
100
  startedAt?: string;
101
101
  endedAt?: string;
102
102
  }[];
@@ -134,7 +134,7 @@ export declare function GET(c: Context): Promise<(Response & import("hono").Type
134
134
  schedule?: string;
135
135
  rollbackPlan?: string;
136
136
  };
137
- status: import("@lovelybunch/types").CPStatus;
137
+ status: import("@lovelybunch/core").CPStatus;
138
138
  comments?: {
139
139
  id: string;
140
140
  author: string;
@@ -177,7 +177,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
177
177
  intent?: string;
178
178
  content?: string;
179
179
  author: {
180
- type: import("@lovelybunch/types").AuthorType;
180
+ type: import("@lovelybunch/core").AuthorType;
181
181
  id: string;
182
182
  name: string;
183
183
  email?: string;
@@ -212,7 +212,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
212
212
  version: string;
213
213
  name: string;
214
214
  description: string;
215
- type: import("@lovelybunch/types").FeatureFlagType;
215
+ type: import("@lovelybunch/core").FeatureFlagType;
216
216
  defaultValue: any;
217
217
  scopes: string[];
218
218
  targets: {
@@ -260,7 +260,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
260
260
  minimumSampleSize: number;
261
261
  testType: "two-tailed" | "one-tailed";
262
262
  };
263
- status: import("@lovelybunch/types").ExperimentStatus;
263
+ status: import("@lovelybunch/core").ExperimentStatus;
264
264
  startedAt?: string;
265
265
  endedAt?: string;
266
266
  }[];
@@ -298,7 +298,7 @@ export declare function PATCH(c: Context): Promise<(Response & import("hono").Ty
298
298
  schedule?: string;
299
299
  rollbackPlan?: string;
300
300
  };
301
- status: import("@lovelybunch/types").CPStatus;
301
+ status: import("@lovelybunch/core").CPStatus;
302
302
  comments?: {
303
303
  id: string;
304
304
  author: string;
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default app;
@@ -0,0 +1,199 @@
1
+ import { Hono } from 'hono';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import matter from 'gray-matter';
5
+ const app = new Hono();
6
+ function generateSkillId(name) {
7
+ return name
8
+ .toLowerCase()
9
+ .replace(/[^a-z0-9\s-]/g, '')
10
+ .replace(/\s+/g, '-')
11
+ .replace(/--+/g, '-')
12
+ .replace(/^-|-$/g, '');
13
+ }
14
+ function getSkillsPath() {
15
+ let basePath;
16
+ if (process.env.NODE_ENV === 'development' && process.env.GAIT_DEV_ROOT) {
17
+ basePath = process.env.GAIT_DEV_ROOT;
18
+ }
19
+ else if (process.env.GAIT_DATA_PATH) {
20
+ basePath = path.resolve(process.env.GAIT_DATA_PATH, '.nut');
21
+ }
22
+ else {
23
+ basePath = path.resolve(process.cwd(), '.nut');
24
+ }
25
+ return path.join(basePath, 'skills');
26
+ }
27
+ /**
28
+ * GET /api/v1/skills/:id
29
+ * Load a specific skill document
30
+ */
31
+ app.get('/', async (c) => {
32
+ try {
33
+ const id = c.req.param('id');
34
+ const skillsPath = getSkillsPath();
35
+ const skillFile = path.join(skillsPath, id, 'SKILL.md');
36
+ const fileContent = await fs.readFile(skillFile, 'utf-8');
37
+ const { data, content } = matter(fileContent);
38
+ const nestedMeta = typeof data.metadata === 'object' ? data.metadata : undefined;
39
+ const document = {
40
+ id,
41
+ name: data.name || id,
42
+ description: data.description || '',
43
+ license: data.license,
44
+ compatibility: data.compatibility,
45
+ allowedTools: data['allowed-tools'] || data.allowedTools,
46
+ metadata: {
47
+ name: data.name || id,
48
+ description: data.description || '',
49
+ license: data.license,
50
+ compatibility: data.compatibility,
51
+ allowedTools: data['allowed-tools'] || data.allowedTools,
52
+ ...(nestedMeta || {}),
53
+ metadata: nestedMeta,
54
+ },
55
+ content,
56
+ };
57
+ return c.json({
58
+ success: true,
59
+ document
60
+ });
61
+ }
62
+ catch (error) {
63
+ if (error.code === 'ENOENT') {
64
+ return c.json({ success: false, error: 'Skill document not found' }, 404);
65
+ }
66
+ console.error('Error loading skill document:', error);
67
+ return c.json({ success: false, error: 'Failed to load skill document' }, 500);
68
+ }
69
+ });
70
+ /**
71
+ * PUT /api/v1/skills/:id
72
+ * Update a specific skill document
73
+ */
74
+ app.put('/', async (c) => {
75
+ try {
76
+ const id = c.req.param('id');
77
+ const body = await c.req.json();
78
+ const skillsPath = getSkillsPath();
79
+ const skillDir = path.join(skillsPath, id);
80
+ const skillFile = path.join(skillDir, 'SKILL.md');
81
+ // Check if skill exists
82
+ try {
83
+ await fs.access(skillFile);
84
+ }
85
+ catch {
86
+ return c.json({ success: false, error: 'Skill document not found' }, 404);
87
+ }
88
+ // Read current content
89
+ const currentContent = await fs.readFile(skillFile, 'utf-8');
90
+ const { data: currentData, content: currentMarkdown } = matter(currentContent);
91
+ // Merge updates
92
+ const updatedContent = body.content !== undefined ? body.content : currentMarkdown;
93
+ const updatedDescription = body.description !== undefined ? body.description : (currentData.description || '');
94
+ const updatedLicense = body.license !== undefined ? body.license : currentData.license;
95
+ const updatedCompatibility = body.compatibility !== undefined ? body.compatibility : currentData.compatibility;
96
+ const updatedAllowedTools = body.allowedTools !== undefined ? body.allowedTools : (currentData['allowed-tools'] || currentData.allowedTools);
97
+ // Merge metadata
98
+ const currentMeta = typeof currentData.metadata === 'object' && currentData.metadata !== null ? currentData.metadata : {};
99
+ const updatedMeta = body.metadata
100
+ ? { ...currentMeta, ...body.metadata }
101
+ : currentMeta;
102
+ // Handle name change (directory rename)
103
+ let newId = id;
104
+ let newDir = skillDir;
105
+ if (body.name && body.name !== currentData.name) {
106
+ newId = generateSkillId(body.name);
107
+ newDir = path.join(skillsPath, newId);
108
+ if (newId !== id) {
109
+ try {
110
+ await fs.access(path.join(newDir, 'SKILL.md'));
111
+ return c.json({ success: false, error: 'A skill with this name already exists' }, 409);
112
+ }
113
+ catch {
114
+ // Doesn't exist, proceed with rename
115
+ }
116
+ }
117
+ }
118
+ // Build updated frontmatter
119
+ const frontmatter = {
120
+ name: newId,
121
+ description: updatedDescription,
122
+ };
123
+ if (updatedLicense)
124
+ frontmatter.license = updatedLicense;
125
+ if (updatedCompatibility)
126
+ frontmatter.compatibility = updatedCompatibility;
127
+ if (updatedAllowedTools)
128
+ frontmatter['allowed-tools'] = updatedAllowedTools;
129
+ // Clean metadata
130
+ const cleanMeta = {};
131
+ for (const [key, value] of Object.entries(updatedMeta)) {
132
+ if (value !== undefined && value !== null) {
133
+ cleanMeta[key] = value;
134
+ }
135
+ }
136
+ if (Object.keys(cleanMeta).length > 0) {
137
+ frontmatter.metadata = cleanMeta;
138
+ }
139
+ const fileContent = matter.stringify(updatedContent, frontmatter);
140
+ if (newId !== id) {
141
+ // Create new directory and write file
142
+ await fs.mkdir(newDir, { recursive: true });
143
+ await fs.writeFile(path.join(newDir, 'SKILL.md'), fileContent, 'utf-8');
144
+ // Remove old directory
145
+ await fs.rm(skillDir, { recursive: true, force: true });
146
+ }
147
+ else {
148
+ await fs.writeFile(skillFile, fileContent, 'utf-8');
149
+ }
150
+ return c.json({
151
+ success: true,
152
+ document: {
153
+ id: newId,
154
+ name: newId,
155
+ description: updatedDescription,
156
+ metadata: {
157
+ name: newId,
158
+ description: updatedDescription,
159
+ ...frontmatter,
160
+ ...(typeof cleanMeta === 'object' ? cleanMeta : {}),
161
+ },
162
+ content: updatedContent
163
+ }
164
+ });
165
+ }
166
+ catch (error) {
167
+ console.error('Error updating skill document:', error);
168
+ return c.json({ success: false, error: 'Failed to update skill document' }, 500);
169
+ }
170
+ });
171
+ /**
172
+ * DELETE /api/v1/skills/:id
173
+ * Delete a specific skill document (removes entire skill directory)
174
+ */
175
+ app.delete('/', async (c) => {
176
+ try {
177
+ const id = c.req.param('id');
178
+ const skillsPath = getSkillsPath();
179
+ const skillDir = path.join(skillsPath, id);
180
+ // Check if skill exists
181
+ try {
182
+ await fs.access(path.join(skillDir, 'SKILL.md'));
183
+ }
184
+ catch {
185
+ return c.json({ success: false, error: 'Skill document not found' }, 404);
186
+ }
187
+ // Remove entire skill directory
188
+ await fs.rm(skillDir, { recursive: true, force: true });
189
+ return c.json({
190
+ success: true,
191
+ message: 'Skill document deleted successfully'
192
+ });
193
+ }
194
+ catch (error) {
195
+ console.error('Error deleting skill document:', error);
196
+ return c.json({ success: false, error: 'Failed to delete skill document' }, 500);
197
+ }
198
+ });
199
+ export default app;
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1 @@
1
+ export { default } from './route.js';
@@ -0,0 +1,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default app;