tycono 0.1.15 → 0.1.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -127,37 +127,10 @@ skillsRouter.post('/registry/install', async (req: Request, res: Response, next:
127
127
  }
128
128
  });
129
129
 
130
- // GET /api/skills/:id — Skill detail
131
- skillsRouter.get('/:id', (req: Request, res: Response, next: NextFunction) => {
132
- try {
133
- const id = req.params.id as string;
134
-
135
- // Check installed first
136
- const installedPath = path.join(COMPANY_ROOT, '.claude', 'skills', '_shared', id, 'SKILL.md');
137
- if (fs.existsSync(installedPath)) {
138
- const content = fs.readFileSync(installedPath, 'utf-8');
139
- const meta = extractSkillMeta(content, id);
140
- res.json({ ...meta, installed: true, content });
141
- return;
142
- }
143
-
144
- // Check template
145
- const templateSkills = getAvailableSkills();
146
- const templateSkill = templateSkills.find(s => s.id === id);
147
- if (templateSkill) {
148
- res.json({ ...templateSkill, installed: false });
149
- return;
150
- }
151
-
152
- res.status(404).json({ error: `Skill not found: ${id}` });
153
- } catch (err) {
154
- next(err);
155
- }
156
- });
157
-
158
130
  /* ─── Skill Export (for Store publish) ──── */
159
131
 
160
132
  // GET /api/skills/export/:roleId — Export full SKILL.md content for publishing
133
+ // NOTE: Must be registered BEFORE /:id to avoid "export" matching as an id
161
134
  skillsRouter.get('/export/:roleId', (req: Request, res: Response, next: NextFunction) => {
162
135
  try {
163
136
  const roleId = req.params.roleId as string;
@@ -189,6 +162,34 @@ skillsRouter.get('/export/:roleId', (req: Request, res: Response, next: NextFunc
189
162
  }
190
163
  });
191
164
 
165
+ // GET /api/skills/:id — Skill detail (wildcard — must be LAST among GET routes)
166
+ skillsRouter.get('/:id', (req: Request, res: Response, next: NextFunction) => {
167
+ try {
168
+ const id = req.params.id as string;
169
+
170
+ // Check installed first
171
+ const installedPath = path.join(COMPANY_ROOT, '.claude', 'skills', '_shared', id, 'SKILL.md');
172
+ if (fs.existsSync(installedPath)) {
173
+ const content = fs.readFileSync(installedPath, 'utf-8');
174
+ const meta = extractSkillMeta(content, id);
175
+ res.json({ ...meta, installed: true, content });
176
+ return;
177
+ }
178
+
179
+ // Check template
180
+ const templateSkills = getAvailableSkills();
181
+ const templateSkill = templateSkills.find(s => s.id === id);
182
+ if (templateSkill) {
183
+ res.json({ ...templateSkill, installed: false });
184
+ return;
185
+ }
186
+
187
+ res.status(404).json({ error: `Skill not found: ${id}` });
188
+ } catch (err) {
189
+ next(err);
190
+ }
191
+ });
192
+
192
193
  /* ─── Role-Skill Management ─────────────── */
193
194
 
194
195
  // GET /api/roles/:id/skills — Skills equipped to a role