clementine-agent 1.18.130 → 1.18.131

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.
@@ -4550,6 +4550,33 @@ export async function cmdDashboard(opts) {
4550
4550
  // GET /api/skills — full list with usedByTriggers join
4551
4551
  // GET /api/skills/:name — single skill detail (frontmatter + body)
4552
4552
  // Phase A is read-only; Phase B adds POST/PUT for editing.
4553
+ // 1.18.130 — fix: literal-named GET routes under /api/skills/* MUST be
4554
+ // registered BEFORE /api/skills/:name. Previously /api/skills/suppressions
4555
+ // was shadowed and 404'd because the parameterized :name handler caught
4556
+ // it first and looked up a skill literally named "suppressions". The
4557
+ // dashboard logged a 404 in console on every Skills-page load. Same issue
4558
+ // would have affected any future literal-named routes added to /api/skills.
4559
+ app.get('/api/skills/suppressions', async (_req, res) => {
4560
+ try {
4561
+ const { listAllSuppressions } = await import('../agent/skill-suppressions.js');
4562
+ res.json({ ok: true, suppressions: listAllSuppressions() });
4563
+ }
4564
+ catch (err) {
4565
+ res.status(500).json({ ok: false, error: String(err) });
4566
+ }
4567
+ });
4568
+ // /api/skills/pending was shadowed by :name in earlier revs (see comment
4569
+ // at the duplicate GET below — the duplicate is now superseded). Hoisted
4570
+ // up here so 'pending' isn't captured as :name="pending".
4571
+ app.get('/api/skills/pending', async (_req, res) => {
4572
+ try {
4573
+ const { listPendingSkills } = await import('../agent/skill-extractor.js');
4574
+ res.json({ skills: listPendingSkills() });
4575
+ }
4576
+ catch (err) {
4577
+ res.status(500).json({ error: String(err) });
4578
+ }
4579
+ });
4553
4580
  app.get('/api/skills', async (_req, res) => {
4554
4581
  try {
4555
4582
  const { listSkills } = await import('../agent/skill-store.js');
@@ -4587,15 +4614,9 @@ export async function cmdDashboard(opts) {
4587
4614
  // Lets the user manually suppress skills from auto-match retrieval —
4588
4615
  // a complement to the memory store's automatic feedback-driven
4589
4616
  // suppression. Storage is a single JSON file under ~/.clementine/.
4590
- app.get('/api/skills/suppressions', async (_req, res) => {
4591
- try {
4592
- const { listAllSuppressions } = await import('../agent/skill-suppressions.js');
4593
- res.json({ ok: true, suppressions: listAllSuppressions() });
4594
- }
4595
- catch (err) {
4596
- res.status(500).json({ ok: false, error: String(err) });
4597
- }
4598
- });
4617
+ // (GET /api/skills/suppressions registered earlier moved up to win
4618
+ // route precedence over /api/skills/:name. The PUT below stays here
4619
+ // because :name disambiguates it from the GET endpoint above.)
4599
4620
  app.put('/api/skills/suppressions/:name', async (req, res) => {
4600
4621
  try {
4601
4622
  const name = req.params.name;
@@ -10657,17 +10678,9 @@ If the tool returns nothing or errors, return an empty array \`[]\`.`,
10657
10678
  }
10658
10679
  });
10659
10680
  // ── Skills (Procedural Memory) API ──────────────────────────────────
10660
- // NOTE: /api/skills/pending routes must come before /api/skills/:name so
10661
- // Express doesn't capture "pending" as a :name param.
10662
- app.get('/api/skills/pending', async (_req, res) => {
10663
- try {
10664
- const { listPendingSkills } = await import('../agent/skill-extractor.js');
10665
- res.json({ skills: listPendingSkills() });
10666
- }
10667
- catch (err) {
10668
- res.status(500).json({ error: String(err) });
10669
- }
10670
- });
10681
+ // (GET /api/skills/pending hoisted earlier was shadowed by /api/skills/:name
10682
+ // in this file's previous order. POST routes below are unaffected because
10683
+ // verb differs from the GET :name handler.)
10671
10684
  app.post('/api/skills/pending/:name/approve', async (req, res) => {
10672
10685
  try {
10673
10686
  const { approvePendingSkill } = await import('../agent/skill-extractor.js');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.130",
3
+ "version": "1.18.131",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",