@longtable/provider-claude 0.1.37 → 0.1.39

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/dist/skills.d.ts CHANGED
@@ -10,8 +10,9 @@ export interface InstalledClaudeSkill {
10
10
  path: string;
11
11
  description: string;
12
12
  }
13
+ export type LongTableSkillSurface = "compact" | "full";
13
14
  export declare function resolveClaudeSkillsDir(customDir?: string): string;
14
- export declare function buildClaudeSkillSpecs(roles: RoleDefinition[]): ClaudeSkillSpec[];
15
- export declare function installClaudeSkills(roles: RoleDefinition[], customDir?: string): Promise<InstalledClaudeSkill[]>;
15
+ export declare function buildClaudeSkillSpecs(roles: RoleDefinition[], surface?: LongTableSkillSurface): ClaudeSkillSpec[];
16
+ export declare function installClaudeSkills(roles: RoleDefinition[], customDir?: string, surface?: LongTableSkillSurface): Promise<InstalledClaudeSkill[]>;
16
17
  export declare function removeClaudeSkills(roles: RoleDefinition[], customDir?: string): Promise<string[]>;
17
- export declare function listInstalledClaudeSkills(roles: RoleDefinition[], customDir?: string): Promise<InstalledClaudeSkill[]>;
18
+ export declare function listInstalledClaudeSkills(roles: RoleDefinition[], customDir?: string, surface?: LongTableSkillSurface): Promise<InstalledClaudeSkill[]>;
package/dist/skills.js CHANGED
@@ -2,10 +2,20 @@ import { existsSync } from "node:fs";
2
2
  import { mkdir, readdir, rm, writeFile } from "node:fs/promises";
3
3
  import { homedir } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
+ const COMPACT_ROLE_SKILL_NAMES = {
6
+ methods_critic: "longtable-methods",
7
+ measurement_auditor: "longtable-measure",
8
+ theory_critic: "longtable-theory",
9
+ reviewer: "longtable-reviewer",
10
+ voice_keeper: "longtable-voice"
11
+ };
5
12
  export function resolveClaudeSkillsDir(customDir) {
6
13
  return customDir ? resolve(customDir) : join(homedir(), ".claude", "skills");
7
14
  }
8
- function skillNameForRole(role) {
15
+ function skillNameForRole(role, surface) {
16
+ if (surface === "compact" && COMPACT_ROLE_SKILL_NAMES[role.key]) {
17
+ return COMPACT_ROLE_SKILL_NAMES[role.key];
18
+ }
9
19
  return `longtable-${role.key.replaceAll("_", "-")}`;
10
20
  }
11
21
  function yamlString(value) {
@@ -25,8 +35,8 @@ function renderSkillFile(spec) {
25
35
  ...spec.body
26
36
  ].join("\n");
27
37
  }
28
- function baseSkillSpecs() {
29
- return [
38
+ function baseSkillSpecs(surface = "compact") {
39
+ const specs = [
30
40
  {
31
41
  name: "longtable",
32
42
  description: "Use for LongTable research conversations, project memory, checkpointing, and role routing.",
@@ -46,11 +56,13 @@ function baseSkillSpecs() {
46
56
  "- `lt panel: ...`",
47
57
  "- `longtable: deploy a research team to review this measurement plan, show the main disagreements, and ask me what decision should be recorded before you revise it.`",
48
58
  "- `longtable: use editor, reviewer, methods, measurement, and voice perspectives to evaluate this manuscript section. Do not collapse disagreement too early.`",
59
+ "- `$longtable-methods`, `$longtable-measure`, `$longtable-theory`, `$longtable-reviewer`, or `$longtable-voice` when the researcher explicitly wants that shortcut.",
49
60
  "- `$longtable-interview` to create or continue the first research-start interview.",
50
61
  "",
51
62
  "## Rules",
52
63
  "",
53
64
  "- Treat `.longtable/` state as the project source of truth when present.",
65
+ "- The compact visible shortcut set is methods, measure, theory, reviewer, and voice. Other roles remain available through this router when the request calls for them.",
54
66
  "- Prefer natural language over asking the researcher to run shell role commands.",
55
67
  "- For `$longtable-interview`, use natural-language turns for the interview and reserve structured options for final First Research Shape confirmation.",
56
68
  "- If a Researcher Checkpoint is needed, ask a short structured question with meaningful options and wait for the researcher.",
@@ -188,6 +200,9 @@ function baseSkillSpecs() {
188
200
  ]
189
201
  }
190
202
  ];
203
+ return surface === "full"
204
+ ? specs
205
+ : specs.filter((spec) => spec.name === "longtable" || spec.name === "longtable-interview");
191
206
  }
192
207
  function mustAskQuestionsForRole(role) {
193
208
  const common = [
@@ -222,10 +237,10 @@ function mustAskQuestionsForRole(role) {
222
237
  };
223
238
  return [...(byRole[role.key] ?? []), ...common];
224
239
  }
225
- function roleSkillSpec(role) {
240
+ function roleSkillSpec(role, surface = "compact") {
226
241
  const label = role.label;
227
242
  return {
228
- name: skillNameForRole(role),
243
+ name: skillNameForRole(role, surface),
229
244
  description: `Use the LongTable ${label} role: ${role.shortDescription}`,
230
245
  triggers: [
231
246
  ...role.synonyms.slice(0, 8),
@@ -273,14 +288,32 @@ function roleSkillSpec(role) {
273
288
  ]
274
289
  };
275
290
  }
276
- export function buildClaudeSkillSpecs(roles) {
277
- return [...baseSkillSpecs(), ...roles.map(roleSkillSpec)];
291
+ function compactRoles(roles) {
292
+ return roles.filter((role) => Object.hasOwn(COMPACT_ROLE_SKILL_NAMES, role.key));
293
+ }
294
+ function allClaudeSkillSpecs(roles) {
295
+ const byName = new Map();
296
+ for (const spec of [...buildClaudeSkillSpecs(roles, "compact"), ...buildClaudeSkillSpecs(roles, "full")]) {
297
+ byName.set(spec.name, spec);
298
+ }
299
+ return [...byName.values()];
278
300
  }
279
- export async function installClaudeSkills(roles, customDir) {
301
+ export function buildClaudeSkillSpecs(roles, surface = "compact") {
302
+ const roleSpecs = (surface === "compact" ? compactRoles(roles) : roles).map((role) => roleSkillSpec(role, surface));
303
+ return [...baseSkillSpecs(surface), ...roleSpecs];
304
+ }
305
+ export async function installClaudeSkills(roles, customDir, surface = "compact") {
280
306
  const skillsDir = resolveClaudeSkillsDir(customDir);
281
307
  await mkdir(skillsDir, { recursive: true });
308
+ const specs = buildClaudeSkillSpecs(roles, surface);
309
+ const selectedNames = new Set(specs.map((spec) => spec.name));
310
+ for (const spec of allClaudeSkillSpecs(roles)) {
311
+ if (!selectedNames.has(spec.name)) {
312
+ await rm(join(skillsDir, spec.name), { recursive: true, force: true });
313
+ }
314
+ }
282
315
  const installed = [];
283
- for (const spec of buildClaudeSkillSpecs(roles)) {
316
+ for (const spec of specs) {
284
317
  const skillDir = join(skillsDir, spec.name);
285
318
  await mkdir(skillDir, { recursive: true });
286
319
  const path = join(skillDir, "SKILL.md");
@@ -296,7 +329,7 @@ export async function installClaudeSkills(roles, customDir) {
296
329
  export async function removeClaudeSkills(roles, customDir) {
297
330
  const skillsDir = resolveClaudeSkillsDir(customDir);
298
331
  const removed = [];
299
- for (const spec of buildClaudeSkillSpecs(roles)) {
332
+ for (const spec of allClaudeSkillSpecs(roles)) {
300
333
  const skillDir = join(skillsDir, spec.name);
301
334
  if (existsSync(skillDir)) {
302
335
  await rm(skillDir, { recursive: true, force: true });
@@ -305,13 +338,13 @@ export async function removeClaudeSkills(roles, customDir) {
305
338
  }
306
339
  return removed;
307
340
  }
308
- export async function listInstalledClaudeSkills(roles, customDir) {
341
+ export async function listInstalledClaudeSkills(roles, customDir, surface = "compact") {
309
342
  const skillsDir = resolveClaudeSkillsDir(customDir);
310
343
  if (!existsSync(skillsDir)) {
311
344
  return [];
312
345
  }
313
346
  const entries = new Set(await readdir(skillsDir));
314
- return buildClaudeSkillSpecs(roles)
347
+ return buildClaudeSkillSpecs(roles, surface)
315
348
  .filter((spec) => entries.has(spec.name) && existsSync(join(skillsDir, spec.name, "SKILL.md")))
316
349
  .map((spec) => ({
317
350
  name: spec.name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longtable/provider-claude",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "private": false,
5
5
  "description": "Claude adapter surface for LongTable",
6
6
  "type": "module",
@@ -21,9 +21,9 @@
21
21
  "typecheck": "tsc -p tsconfig.json --noEmit"
22
22
  },
23
23
  "dependencies": {
24
- "@longtable/checkpoints": "0.1.37",
25
- "@longtable/core": "0.1.37",
26
- "@longtable/setup": "0.1.37"
24
+ "@longtable/checkpoints": "0.1.39",
25
+ "@longtable/core": "0.1.39",
26
+ "@longtable/setup": "0.1.39"
27
27
  },
28
28
  "devDependencies": {
29
29
  "typescript": "^5.6.0"