devworkspace 0.1.1 → 0.2.1

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 (123) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +15 -2
  3. package/dist/agents/claude/content.js +3 -3
  4. package/dist/agents/claude/content.js.map +1 -1
  5. package/dist/cli/args.d.ts +19 -0
  6. package/dist/cli/args.js +6 -0
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/help.js +40 -5
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/render.d.ts +7 -0
  11. package/dist/cli/render.js +104 -17
  12. package/dist/cli/render.js.map +1 -1
  13. package/dist/cli/run.d.ts +6 -0
  14. package/dist/cli/run.js +65 -3
  15. package/dist/cli/run.js.map +1 -1
  16. package/dist/config/schemas.d.ts +7 -1
  17. package/dist/config/schemas.js +10 -0
  18. package/dist/config/schemas.js.map +1 -1
  19. package/dist/core/workspace.js +2 -1
  20. package/dist/core/workspace.js.map +1 -1
  21. package/dist/discovery/commands.d.ts +34 -3
  22. package/dist/discovery/commands.js +95 -33
  23. package/dist/discovery/commands.js.map +1 -1
  24. package/dist/discovery/detect.d.ts +17 -0
  25. package/dist/discovery/detect.js +101 -42
  26. package/dist/discovery/detect.js.map +1 -1
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.js +2 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/integrations/adapters/agent-skills.d.ts +8 -0
  31. package/dist/integrations/adapters/agent-skills.js +25 -0
  32. package/dist/integrations/adapters/agent-skills.js.map +1 -0
  33. package/dist/integrations/adapters/claudePlugin.d.ts +41 -0
  34. package/dist/integrations/adapters/claudePlugin.js +129 -0
  35. package/dist/integrations/adapters/claudePlugin.js.map +1 -0
  36. package/dist/integrations/adapters/graphify.d.ts +2 -0
  37. package/dist/integrations/adapters/graphify.js +277 -0
  38. package/dist/integrations/adapters/graphify.js.map +1 -0
  39. package/dist/integrations/adapters/omniroute.d.ts +6 -0
  40. package/dist/integrations/adapters/omniroute.js +32 -0
  41. package/dist/integrations/adapters/omniroute.js.map +1 -0
  42. package/dist/integrations/adapters/pluginSkill.d.ts +28 -0
  43. package/dist/integrations/adapters/pluginSkill.js +195 -0
  44. package/dist/integrations/adapters/pluginSkill.js.map +1 -0
  45. package/dist/integrations/adapters/ponytail.d.ts +8 -0
  46. package/dist/integrations/adapters/ponytail.js +33 -0
  47. package/dist/integrations/adapters/ponytail.js.map +1 -0
  48. package/dist/integrations/exec.d.ts +26 -0
  49. package/dist/integrations/exec.js +167 -0
  50. package/dist/integrations/exec.js.map +1 -0
  51. package/dist/integrations/index.d.ts +5 -6
  52. package/dist/integrations/index.js +3 -29
  53. package/dist/integrations/index.js.map +1 -1
  54. package/dist/integrations/manager.d.ts +62 -0
  55. package/dist/integrations/manager.js +261 -0
  56. package/dist/integrations/manager.js.map +1 -0
  57. package/dist/integrations/notices.d.ts +13 -0
  58. package/dist/integrations/notices.js +68 -0
  59. package/dist/integrations/notices.js.map +1 -0
  60. package/dist/integrations/persistentPath.d.ts +20 -0
  61. package/dist/integrations/persistentPath.js +47 -0
  62. package/dist/integrations/persistentPath.js.map +1 -0
  63. package/dist/integrations/protect.d.ts +20 -0
  64. package/dist/integrations/protect.js +131 -0
  65. package/dist/integrations/protect.js.map +1 -0
  66. package/dist/integrations/state.d.ts +10 -0
  67. package/dist/integrations/state.js +81 -0
  68. package/dist/integrations/state.js.map +1 -0
  69. package/dist/integrations/types.d.ts +139 -16
  70. package/dist/integrations/types.js +13 -1
  71. package/dist/integrations/types.js.map +1 -1
  72. package/dist/prompts/onboarding.d.ts +3 -3
  73. package/dist/prompts/onboarding.js +9 -8
  74. package/dist/prompts/onboarding.js.map +1 -1
  75. package/dist/services/analysis.d.ts +15 -3
  76. package/dist/services/analysis.js +21 -23
  77. package/dist/services/analysis.js.map +1 -1
  78. package/dist/services/common.d.ts +8 -5
  79. package/dist/services/common.js +2 -5
  80. package/dist/services/common.js.map +1 -1
  81. package/dist/services/doctor.d.ts +10 -0
  82. package/dist/services/doctor.js +87 -19
  83. package/dist/services/doctor.js.map +1 -1
  84. package/dist/services/init.d.ts +9 -2
  85. package/dist/services/init.js +10 -7
  86. package/dist/services/init.js.map +1 -1
  87. package/dist/services/integrations.d.ts +26 -0
  88. package/dist/services/integrations.js +35 -0
  89. package/dist/services/integrations.js.map +1 -0
  90. package/dist/services/refresh.js +1 -1
  91. package/dist/services/refresh.js.map +1 -1
  92. package/dist/services/status.d.ts +4 -2
  93. package/dist/services/status.js +4 -4
  94. package/dist/services/status.js.map +1 -1
  95. package/dist/utils/lock.d.ts +2 -0
  96. package/dist/utils/lock.js +2 -2
  97. package/dist/utils/lock.js.map +1 -1
  98. package/dist/utils/proc.d.ts +8 -1
  99. package/dist/utils/proc.js +31 -8
  100. package/dist/utils/proc.js.map +1 -1
  101. package/docs/architecture.md +1 -1
  102. package/docs/claude.md +4 -0
  103. package/docs/getting-started.md +2 -2
  104. package/docs/integrations.md +98 -33
  105. package/docs/security.md +5 -1
  106. package/docs/testing.md +6 -0
  107. package/docs/troubleshooting.md +11 -1
  108. package/package.json +1 -1
  109. package/dist/integrations/agent-skills.d.ts +0 -10
  110. package/dist/integrations/agent-skills.js +0 -45
  111. package/dist/integrations/agent-skills.js.map +0 -1
  112. package/dist/integrations/graphify.d.ts +0 -7
  113. package/dist/integrations/graphify.js +0 -54
  114. package/dist/integrations/graphify.js.map +0 -1
  115. package/dist/integrations/omniroute.d.ts +0 -7
  116. package/dist/integrations/omniroute.js +0 -24
  117. package/dist/integrations/omniroute.js.map +0 -1
  118. package/dist/integrations/ponytail.d.ts +0 -10
  119. package/dist/integrations/ponytail.js +0 -58
  120. package/dist/integrations/ponytail.js.map +0 -1
  121. package/dist/integrations/probe.d.ts +0 -6
  122. package/dist/integrations/probe.js +0 -41
  123. package/dist/integrations/probe.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/integrations/graphify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,IAAI,GAAG,2CAA2C,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,KAAK;IACf,KAAK,EACH,gJAAgJ;QAChJ,qIAAqI;IACvI,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACpD,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;YAC5E,UAAU,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,UAAU;gBAAE,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACxH,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QACD,IAAI,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC9C,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,2BAA2B,KAAK,GAAG,CAAC,CAAC;QAE7D,IAAI,KAAiC,CAAC;QACtC,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,UAAU;YAAE,KAAK,GAAG,OAAO,CAAC;aAC7C,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,GAAG,SAAS,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACnC,WAAW,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,UAAU,EAAE,CAAC;YACtB,KAAK,GAAG,SAAS,CAAC;YAClB,WAAW,CAAC,IAAI,CAAC,4GAA4G,CAAC,CAAC;QACjI,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,cAAc,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC,kEAAkE,EAAE,uDAAuD,EAAE,sCAAsC,CAAC,CAAC;QACxL,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3G,CAAC;CACF,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { Integration, IntegrationStatus } from './types.js';\nimport { skillDirExists } from './probe.js';\n\nconst DOCS = 'https://github.com/Graphify-Labs/graphify';\n\n/**\n * Graphify builds a queryable knowledge graph in graphify-out/ and registers a Claude Code skill.\n * Documented install: `uv tool install graphifyy` (or pipx/pip), then `graphify install --project`.\n * DevWorkspace only detects it and tells the agent when to use it; it never re-implements graph building.\n */\nexport const graphify: Integration = {\n id: 'graphify',\n name: 'Graphify',\n optional: false,\n usage:\n 'For \"where is X / what depends on Y\" questions, query the Graphify graph first (graphify query \"<question>\", graphify path, graphify explain) ' +\n 'or use the /graphify skill. The graph is a navigation aid, not a source of truth: confirm in the actual files before relying on it.',\n async detect(ctx): Promise<IntegrationStatus> {\n const details: string[] = [];\n const remediation: string[] = [];\n const cli = await ctx.which('graphify');\n const skill = await skillDirExists(ctx, 'graphify');\n let graphBuilt = false;\n try {\n const st = await fs.stat(path.join(ctx.root, 'graphify-out', 'graph.json'));\n graphBuilt = st.isFile();\n if (graphBuilt) details.push(`graph built (graphify-out/graph.json, updated ${st.mtime.toISOString().slice(0, 10)})`);\n } catch {\n /* not built */\n }\n if (cli) details.push('graphify CLI on PATH');\n if (skill) details.push(`Claude skill installed (${skill})`);\n\n let state: IntegrationStatus['state'];\n if ((cli || skill) && graphBuilt) state = 'READY';\n else if (cli || skill) {\n state = 'PARTIAL';\n details.push('no graph built yet');\n remediation.push('In Claude Code run: /graphify . (builds graphify-out/graph.json)');\n } else if (graphBuilt) {\n state = 'PARTIAL';\n remediation.push('Install the CLI: uv tool install graphifyy (or pipx install graphifyy), then: graphify install --project');\n } else {\n state = 'NOT_DETECTED';\n remediation.push('Install: uv tool install graphifyy (or pipx install graphifyy)', 'Register for this project: graphify install --project', 'Then in Claude Code run: /graphify .');\n }\n return { id: 'graphify', name: 'Graphify', optional: false, state, details, remediation, docsUrl: DOCS };\n },\n};\n"]}
@@ -1,7 +0,0 @@
1
- import type { Integration } from './types.js';
2
- /**
3
- * OmniRoute (model routing) is OPTIONAL and outside the V1 execution path.
4
- * This adapter only reports whether an `omniroute` executable exists so a future provider
5
- * boundary has somewhere to plug in. Nothing in DevWorkspace requires it, API keys, or model configuration.
6
- */
7
- export declare const omniroute: Integration;
@@ -1,24 +0,0 @@
1
- /**
2
- * OmniRoute (model routing) is OPTIONAL and outside the V1 execution path.
3
- * This adapter only reports whether an `omniroute` executable exists so a future provider
4
- * boundary has somewhere to plug in. Nothing in DevWorkspace requires it, API keys, or model configuration.
5
- */
6
- export const omniroute = {
7
- id: 'omniroute',
8
- name: 'OmniRoute',
9
- optional: true,
10
- usage: 'Not used by DevWorkspace V1.',
11
- async detect(ctx) {
12
- const exe = await ctx.which('omniroute');
13
- return {
14
- id: 'omniroute',
15
- name: 'OmniRoute',
16
- optional: true,
17
- state: exe ? 'PARTIAL' : 'NOT_DETECTED',
18
- details: exe ? ['executable found; not used by V1'] : ['optional; not required'],
19
- remediation: [],
20
- docsUrl: 'https://github.com/diegosouzapw/OmniRoute',
21
- };
22
- },
23
- };
24
- //# sourceMappingURL=omniroute.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omniroute.js","sourceRoot":"","sources":["../../src/integrations/omniroute.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAgB;IACpC,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,WAAW;IACjB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,8BAA8B;IACrC,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACzC,OAAO;YACL,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc;YACvC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC;YAChF,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,2CAA2C;SACrD,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["import type { Integration, IntegrationStatus } from './types.js';\n\n/**\n * OmniRoute (model routing) is OPTIONAL and outside the V1 execution path.\n * This adapter only reports whether an `omniroute` executable exists so a future provider\n * boundary has somewhere to plug in. Nothing in DevWorkspace requires it, API keys, or model configuration.\n */\nexport const omniroute: Integration = {\n id: 'omniroute',\n name: 'OmniRoute',\n optional: true,\n usage: 'Not used by DevWorkspace V1.',\n async detect(ctx): Promise<IntegrationStatus> {\n const exe = await ctx.which('omniroute');\n return {\n id: 'omniroute',\n name: 'OmniRoute',\n optional: true,\n state: exe ? 'PARTIAL' : 'NOT_DETECTED',\n details: exe ? ['executable found; not used by V1'] : ['optional; not required'],\n remediation: [],\n docsUrl: 'https://github.com/diegosouzapw/OmniRoute',\n };\n },\n};\n"]}
@@ -1,10 +0,0 @@
1
- import type { Integration } from './types.js';
2
- /**
3
- * Ponytail is a code-quality/simplification skill. Documented install for Claude Code:
4
- * /plugin marketplace add DietrichGebert/ponytail
5
- * /plugin install ponytail@ponytail
6
- * Commands: /ponytail [lite|full|ultra|off], /ponytail-review, /ponytail-audit, /ponytail-debt.
7
- * Other agents: copy AGENTS.md or install skills/ponytail/SKILL.md. Optional config: ~/.config/ponytail/config.json.
8
- * Ponytail assists quality review; it is never a substitute for tests.
9
- */
10
- export declare const ponytail: Integration;
@@ -1,58 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- import path from 'node:path';
3
- import { claudeConfigMentions, skillDirExists } from './probe.js';
4
- import { pathExists } from '../utils/fs.js';
5
- const DOCS = 'https://github.com/DietrichGebert/ponytail';
6
- /**
7
- * Ponytail is a code-quality/simplification skill. Documented install for Claude Code:
8
- * /plugin marketplace add DietrichGebert/ponytail
9
- * /plugin install ponytail@ponytail
10
- * Commands: /ponytail [lite|full|ultra|off], /ponytail-review, /ponytail-audit, /ponytail-debt.
11
- * Other agents: copy AGENTS.md or install skills/ponytail/SKILL.md. Optional config: ~/.config/ponytail/config.json.
12
- * Ponytail assists quality review; it is never a substitute for tests.
13
- */
14
- export const ponytail = {
15
- id: 'ponytail',
16
- name: 'Ponytail',
17
- optional: false,
18
- usage: 'Use /ponytail-review on the diff of meaningful changes (features, refactors, security work) to catch unnecessary complexity and debt; ' +
19
- 'use /ponytail-audit only when the user asks for a repository-wide quality pass. Quality review never replaces running tests.',
20
- async detect(ctx) {
21
- const details = [];
22
- const plugin = await claudeConfigMentions(ctx, 'ponytail');
23
- const skill = await skillDirExists(ctx, 'ponytail');
24
- if (plugin)
25
- details.push(`referenced in Claude Code config (${plugin})`);
26
- if (skill)
27
- details.push(`skill installed (${skill})`);
28
- let agentsMention = false;
29
- try {
30
- agentsMention = (await fs.readFile(path.join(ctx.root, 'AGENTS.md'), 'utf8')).toLowerCase().includes('ponytail');
31
- }
32
- catch {
33
- /* no AGENTS.md */
34
- }
35
- if (agentsMention)
36
- details.push('AGENTS.md references Ponytail');
37
- const userCfg = path.join(ctx.home, '.config', 'ponytail', 'config.json');
38
- if (await pathExists(userCfg))
39
- details.push('user config present (~/.config/ponytail/config.json)');
40
- const found = plugin || skill || agentsMention;
41
- return {
42
- id: 'ponytail',
43
- name: 'Ponytail',
44
- optional: false,
45
- state: found ? 'READY' : 'UNVERIFIED',
46
- details: found ? details : ['not found in Claude Code settings or project skills; plugin state is held by Claude Code so this check is best-effort'],
47
- remediation: found
48
- ? []
49
- : [
50
- 'In Claude Code run: /plugin marketplace add DietrichGebert/ponytail',
51
- 'Then: /plugin install ponytail@ponytail',
52
- 'Other agents: copy Ponytail\'s AGENTS.md into the project (see its INSTALL.md).',
53
- ],
54
- docsUrl: DOCS,
55
- };
56
- },
57
- };
58
- //# sourceMappingURL=ponytail.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ponytail.js","sourceRoot":"","sources":["../../src/integrations/ponytail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,IAAI,GAAG,4CAA4C,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB;IACnC,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,KAAK;IACf,KAAK,EACH,wIAAwI;QACxI,8HAA8H;IAChI,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACpD,IAAI,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,qCAAqC,MAAM,GAAG,CAAC,CAAC;QACzE,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,KAAK,GAAG,CAAC,CAAC;QACtD,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC;YACH,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACnH,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QACD,IAAI,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAC1E,IAAI,MAAM,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QAEpG,MAAM,KAAK,GAAG,MAAM,IAAI,KAAK,IAAI,aAAa,CAAC;QAC/C,OAAO;YACL,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;YACrC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,uHAAuH,CAAC;YACpJ,WAAW,EAAE,KAAK;gBAChB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,qEAAqE;oBACrE,yCAAyC;oBACzC,iFAAiF;iBAClF;YACL,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { Integration, IntegrationStatus } from './types.js';\nimport { claudeConfigMentions, skillDirExists } from './probe.js';\nimport { pathExists } from '../utils/fs.js';\n\nconst DOCS = 'https://github.com/DietrichGebert/ponytail';\n\n/**\n * Ponytail is a code-quality/simplification skill. Documented install for Claude Code:\n * /plugin marketplace add DietrichGebert/ponytail\n * /plugin install ponytail@ponytail\n * Commands: /ponytail [lite|full|ultra|off], /ponytail-review, /ponytail-audit, /ponytail-debt.\n * Other agents: copy AGENTS.md or install skills/ponytail/SKILL.md. Optional config: ~/.config/ponytail/config.json.\n * Ponytail assists quality review; it is never a substitute for tests.\n */\nexport const ponytail: Integration = {\n id: 'ponytail',\n name: 'Ponytail',\n optional: false,\n usage:\n 'Use /ponytail-review on the diff of meaningful changes (features, refactors, security work) to catch unnecessary complexity and debt; ' +\n 'use /ponytail-audit only when the user asks for a repository-wide quality pass. Quality review never replaces running tests.',\n async detect(ctx): Promise<IntegrationStatus> {\n const details: string[] = [];\n const plugin = await claudeConfigMentions(ctx, 'ponytail');\n const skill = await skillDirExists(ctx, 'ponytail');\n if (plugin) details.push(`referenced in Claude Code config (${plugin})`);\n if (skill) details.push(`skill installed (${skill})`);\n let agentsMention = false;\n try {\n agentsMention = (await fs.readFile(path.join(ctx.root, 'AGENTS.md'), 'utf8')).toLowerCase().includes('ponytail');\n } catch {\n /* no AGENTS.md */\n }\n if (agentsMention) details.push('AGENTS.md references Ponytail');\n const userCfg = path.join(ctx.home, '.config', 'ponytail', 'config.json');\n if (await pathExists(userCfg)) details.push('user config present (~/.config/ponytail/config.json)');\n\n const found = plugin || skill || agentsMention;\n return {\n id: 'ponytail',\n name: 'Ponytail',\n optional: false,\n state: found ? 'READY' : 'UNVERIFIED',\n details: found ? details : ['not found in Claude Code settings or project skills; plugin state is held by Claude Code so this check is best-effort'],\n remediation: found\n ? []\n : [\n 'In Claude Code run: /plugin marketplace add DietrichGebert/ponytail',\n 'Then: /plugin install ponytail@ponytail',\n 'Other agents: copy Ponytail\\'s AGENTS.md into the project (see its INSTALL.md).',\n ],\n docsUrl: DOCS,\n };\n },\n};\n"]}
@@ -1,6 +0,0 @@
1
- import type { IntegrationContext } from './types.js';
2
- /** Candidate Claude Code settings/plugin registries, project first then user. Read-only and best effort. */
3
- export declare function claudeConfigFiles(ctx: IntegrationContext): string[];
4
- /** True if any Claude Code config file mentions the needle (case-insensitive). Plugin install state belongs to Claude Code, so this can only suggest, never prove. */
5
- export declare function claudeConfigMentions(ctx: IntegrationContext, needle: string): Promise<string | null>;
6
- export declare function skillDirExists(ctx: IntegrationContext, name: string): Promise<string | null>;
@@ -1,41 +0,0 @@
1
- import { promises as fs } from 'node:fs';
2
- import path from 'node:path';
3
- import { pathExists } from '../utils/fs.js';
4
- /** Candidate Claude Code settings/plugin registries, project first then user. Read-only and best effort. */
5
- export function claudeConfigFiles(ctx) {
6
- return [
7
- path.join(ctx.root, '.claude', 'settings.json'),
8
- path.join(ctx.root, '.claude', 'settings.local.json'),
9
- path.join(ctx.home, '.claude', 'settings.json'),
10
- path.join(ctx.home, '.claude', 'plugins', 'installed_plugins.json'),
11
- path.join(ctx.home, '.claude', 'plugins', 'known_marketplaces.json'),
12
- ];
13
- }
14
- /** True if any Claude Code config file mentions the needle (case-insensitive). Plugin install state belongs to Claude Code, so this can only suggest, never prove. */
15
- export async function claudeConfigMentions(ctx, needle) {
16
- const n = needle.toLowerCase();
17
- for (const file of claudeConfigFiles(ctx)) {
18
- try {
19
- const st = await fs.stat(file);
20
- if (!st.isFile() || st.size > 2 * 1024 * 1024)
21
- continue;
22
- if ((await fs.readFile(file, 'utf8')).toLowerCase().includes(n)) {
23
- return file.startsWith(ctx.root) ? path.relative(ctx.root, file).replace(/\\/g, '/') : '~/' + path.relative(ctx.home, file).replace(/\\/g, '/');
24
- }
25
- }
26
- catch {
27
- /* missing or unreadable */
28
- }
29
- }
30
- return null;
31
- }
32
- export async function skillDirExists(ctx, name) {
33
- const project = path.join(ctx.root, '.claude', 'skills', name);
34
- if (await pathExists(project))
35
- return `.claude/skills/${name}`;
36
- const user = path.join(ctx.home, '.claude', 'skills', name);
37
- if (await pathExists(user))
38
- return `~/.claude/skills/${name}`;
39
- return null;
40
- }
41
- //# sourceMappingURL=probe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/integrations/probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,4GAA4G;AAC5G,MAAM,UAAU,iBAAiB,CAAC,GAAuB;IACvD,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,wBAAwB,CAAC;QACnE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,yBAAyB,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,sKAAsK;AACtK,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAuB,EAAE,MAAc;IAChF,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI;gBAAE,SAAS;YACxD,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChE,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAClJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAuB,EAAE,IAAY;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,MAAM,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,kBAAkB,IAAI,EAAE,CAAC;IAC/D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC5D,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,oBAAoB,IAAI,EAAE,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathExists } from '../utils/fs.js';\nimport type { IntegrationContext } from './types.js';\n\n/** Candidate Claude Code settings/plugin registries, project first then user. Read-only and best effort. */\nexport function claudeConfigFiles(ctx: IntegrationContext): string[] {\n return [\n path.join(ctx.root, '.claude', 'settings.json'),\n path.join(ctx.root, '.claude', 'settings.local.json'),\n path.join(ctx.home, '.claude', 'settings.json'),\n path.join(ctx.home, '.claude', 'plugins', 'installed_plugins.json'),\n path.join(ctx.home, '.claude', 'plugins', 'known_marketplaces.json'),\n ];\n}\n\n/** True if any Claude Code config file mentions the needle (case-insensitive). Plugin install state belongs to Claude Code, so this can only suggest, never prove. */\nexport async function claudeConfigMentions(ctx: IntegrationContext, needle: string): Promise<string | null> {\n const n = needle.toLowerCase();\n for (const file of claudeConfigFiles(ctx)) {\n try {\n const st = await fs.stat(file);\n if (!st.isFile() || st.size > 2 * 1024 * 1024) continue;\n if ((await fs.readFile(file, 'utf8')).toLowerCase().includes(n)) {\n return file.startsWith(ctx.root) ? path.relative(ctx.root, file).replace(/\\\\/g, '/') : '~/' + path.relative(ctx.home, file).replace(/\\\\/g, '/');\n }\n } catch {\n /* missing or unreadable */\n }\n }\n return null;\n}\n\nexport async function skillDirExists(ctx: IntegrationContext, name: string): Promise<string | null> {\n const project = path.join(ctx.root, '.claude', 'skills', name);\n if (await pathExists(project)) return `.claude/skills/${name}`;\n const user = path.join(ctx.home, '.claude', 'skills', name);\n if (await pathExists(user)) return `~/.claude/skills/${name}`;\n return null;\n}\n"]}