@planu/cli 5.7.4 → 5.7.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 (208) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +3 -3
  3. package/dist/.planu-build.json +1 -1
  4. package/dist/cli/commands/package-handoff.js +30 -5
  5. package/dist/config/compliance-profiles.json +36 -3
  6. package/dist/config/environment-schema.json +21 -0
  7. package/dist/config/hook-templates/planu-session-safeguard.sh +22 -15
  8. package/dist/config/official-sdd-tools.d.ts +1 -1
  9. package/dist/config/official-sdd-tools.js +11 -24
  10. package/dist/config/registries/hosts/codex.json +14 -30
  11. package/dist/config/registries/hosts/opencode.json +1 -6
  12. package/dist/config/registries/legacy-guidance.json +26 -0
  13. package/dist/config/server-instructions.js +0 -21
  14. package/dist/config/skill-templates/planu-context-assets.md +3 -6
  15. package/dist/config/skill-templates/planu-implement.md +2 -2
  16. package/dist/config/skill-templates/planu-multi-teammate-review.md +1 -1
  17. package/dist/config/skill-templates/planu-release.md +2 -7
  18. package/dist/config/skill-templates/planu-validate.md +3 -3
  19. package/dist/config/spec-templates/crud-rest-api/template.json +5 -1
  20. package/dist/config/spec-templates/file-upload-s3/template.json +5 -1
  21. package/dist/config/spec-templates/stripe-payments/template.json +5 -1
  22. package/dist/config/spec-templates/webhook-system/template.json +5 -1
  23. package/dist/config/subagent-templates/planu-challenger.md +4 -9
  24. package/dist/config/subagent-templates/planu-spec-implementer.md +2 -4
  25. package/dist/config/subagent-templates/planu-validator.md +5 -8
  26. package/dist/config/tool-groups.json +6 -144
  27. package/dist/engine/ambiguity-scorer.js +40 -1
  28. package/dist/engine/autopilot/bootstrap.js +1 -1
  29. package/dist/engine/code-impact-analyzer.js +2 -6
  30. package/dist/engine/context-orchestrator/index.js +2 -2
  31. package/dist/engine/convention-scanner/codebase-scanner.js +2 -2
  32. package/dist/engine/dogfooding/runtime-gap-detector.js +2 -2
  33. package/dist/engine/evidence-gates/artifact-reader.d.ts +1 -0
  34. package/dist/engine/evidence-gates/artifact-reader.js +1 -1
  35. package/dist/engine/evidence-gates/evidence-autofill.d.ts +13 -5
  36. package/dist/engine/evidence-gates/evidence-autofill.js +106 -43
  37. package/dist/engine/evidence-gates/lifecycle-gate.js +7 -4
  38. package/dist/engine/evidence-index/index-builder.js +21 -4
  39. package/dist/engine/execution/job-runtime.js +1 -1
  40. package/dist/engine/execution/package-handoff-job-executor.d.ts +22 -0
  41. package/dist/engine/execution/package-handoff-job-executor.js +490 -0
  42. package/dist/engine/execution/validate-job-executor.js +20 -8
  43. package/dist/engine/git/exec-git.d.ts +4 -0
  44. package/dist/engine/git/exec-git.js +14 -0
  45. package/dist/engine/handoff-artifacts/implementation-review-reader.js +15 -2
  46. package/dist/engine/handoff-artifacts/schemas.d.ts +2 -0
  47. package/dist/engine/handoff-artifacts/schemas.js +1 -0
  48. package/dist/engine/handoff-format.d.ts +36 -0
  49. package/dist/engine/handoff-format.js +314 -0
  50. package/dist/engine/handoff-packager.d.ts +5 -3
  51. package/dist/engine/handoff-packager.js +89 -32
  52. package/dist/engine/host-tool-filter.js +20 -49
  53. package/dist/engine/human-summary.js +14 -3
  54. package/dist/engine/implementation-contract/common.d.ts +8 -3
  55. package/dist/engine/implementation-contract/common.js +9 -6
  56. package/dist/engine/implementation-contract/evaluator.js +4 -6
  57. package/dist/engine/implementation-contract/renderer.js +18 -23
  58. package/dist/engine/project-health-checker.js +2 -2
  59. package/dist/engine/readiness-checker.js +27 -0
  60. package/dist/engine/reconcile/apply-changes.js +4 -0
  61. package/dist/engine/reconcile/propagate-mirrors.d.ts +3 -0
  62. package/dist/engine/reconcile/propagate-mirrors.js +311 -0
  63. package/dist/engine/self-healing/healer.js +12 -5
  64. package/dist/engine/self-healing/strategies/lint-fix.d.ts +1 -1
  65. package/dist/engine/self-healing/strategies/lint-fix.js +4 -1
  66. package/dist/engine/self-healing/strategies/test-fix.d.ts +4 -3
  67. package/dist/engine/self-healing/strategies/test-fix.js +32 -14
  68. package/dist/engine/self-healing/strategies/typescript-fix.d.ts +1 -1
  69. package/dist/engine/self-healing/strategies/typescript-fix.js +28 -10
  70. package/dist/engine/session/checkpoint-writer.js +8 -4
  71. package/dist/engine/session/session-tracker.d.ts +5 -16
  72. package/dist/engine/session/session-tracker.js +29 -26
  73. package/dist/engine/session-state/writer.js +3 -11
  74. package/dist/engine/skill-generator/workflow-skill-generator.d.ts +4 -2
  75. package/dist/engine/skill-generator/workflow-skill-generator.js +113 -38
  76. package/dist/engine/spec-format/bdd-parser.d.ts +1 -11
  77. package/dist/engine/spec-format/bdd-parser.js +40 -11
  78. package/dist/engine/spec-format/lean-spec-generator.js +30 -10
  79. package/dist/engine/spec-format/retired-scaffold.d.ts +3 -0
  80. package/dist/engine/spec-format/retired-scaffold.js +5 -0
  81. package/dist/engine/spec-format/technical-md-populator.d.ts +1 -0
  82. package/dist/engine/spec-format/technical-md-populator.js +27 -0
  83. package/dist/engine/spec-format/unified-spec-builder.d.ts +1 -0
  84. package/dist/engine/spec-format/unified-spec-builder.js +30 -20
  85. package/dist/engine/spec-grounding/contract.js +115 -1
  86. package/dist/engine/spec-migrator/fold-technical.js +60 -19
  87. package/dist/engine/spec-migrator/placeholder-technical.d.ts +2 -0
  88. package/dist/engine/spec-migrator/placeholder-technical.js +18 -0
  89. package/dist/engine/spec-quality/generic-output-gate.js +37 -3
  90. package/dist/engine/technical-enricher/index.js +4 -1
  91. package/dist/engine/type-safety-gate.js +3 -11
  92. package/dist/engine/universal-rules/catalog.js +0 -2
  93. package/dist/engine/universal-rules/rules/planu-workflow.js +1 -1
  94. package/dist/engine/validation/durable-validation.d.ts +3 -2
  95. package/dist/engine/validation/durable-validation.js +106 -40
  96. package/dist/engine/validation/validation-freshness.d.ts +3 -2
  97. package/dist/engine/validation/validation-freshness.js +22 -16
  98. package/dist/engine/validation/validation-worktree.js +34 -0
  99. package/dist/hosts/claude-code/ux/mcp-prompts.js +8 -8
  100. package/dist/index.js +3 -17
  101. package/dist/resources/process.js +38 -65
  102. package/dist/storage/session-state-store.js +2 -0
  103. package/dist/tools/challenge-spec/scenarios-utils.js +2 -2
  104. package/dist/tools/configure-checkpoint-policy.js +3 -3
  105. package/dist/tools/create-spec-helpers.js +2 -5
  106. package/dist/tools/create-spec.js +21 -4
  107. package/dist/tools/facilitate.js +3 -6
  108. package/dist/tools/git/branch-ops.js +16 -4
  109. package/dist/tools/github-release-handler.js +1 -20
  110. package/dist/tools/heal-spec-docs.js +1 -13
  111. package/dist/tools/init-project/agents-md-writer.js +6 -6
  112. package/dist/tools/init-project/claude-md-generator.d.ts +0 -1
  113. package/dist/tools/init-project/claude-md-generator.js +0 -35
  114. package/dist/tools/init-project/handler.js +24 -49
  115. package/dist/tools/init-project/legacy-guidance-scanner.d.ts +12 -0
  116. package/dist/tools/init-project/legacy-guidance-scanner.js +176 -0
  117. package/dist/tools/init-project/per-client-files-writer.js +5 -5
  118. package/dist/tools/init-project/planu-workflow-generator.js +2 -13
  119. package/dist/tools/init-project/portable-index-reconciler.d.ts +21 -1
  120. package/dist/tools/init-project/portable-index-reconciler.js +66 -0
  121. package/dist/tools/init-project/rules-generator.d.ts +0 -11
  122. package/dist/tools/init-project/rules-generator.js +4 -85
  123. package/dist/tools/init-project/scaffold-writer.d.ts +0 -1
  124. package/dist/tools/init-project/scaffold-writer.js +1 -12
  125. package/dist/tools/jobs/handlers.d.ts +0 -6
  126. package/dist/tools/jobs/handlers.js +13 -40
  127. package/dist/tools/list-specs.js +6 -21
  128. package/dist/tools/package-handoff.d.ts +3 -2
  129. package/dist/tools/package-handoff.js +153 -427
  130. package/dist/tools/reconcile-session-safeguard-hook.js +22 -15
  131. package/dist/tools/register-sdd-tools.js +0 -23
  132. package/dist/tools/register-spec-tools/core-spec-tools.js +18 -27
  133. package/dist/tools/schemas/index.d.ts +1 -1
  134. package/dist/tools/schemas/index.js +1 -1
  135. package/dist/tools/schemas/output-schemas.d.ts +1 -18
  136. package/dist/tools/schemas/output-schemas.js +1 -11
  137. package/dist/tools/schemas/package-handoff-output-schema.d.ts +40 -0
  138. package/dist/tools/schemas/package-handoff-output-schema.js +68 -0
  139. package/dist/tools/schemas/validate-output-schema.d.ts +1 -2
  140. package/dist/tools/schemas/validate-output-schema.js +3 -2
  141. package/dist/tools/session-checkpoint.js +2 -2
  142. package/dist/tools/skill-registry/index.d.ts +0 -1
  143. package/dist/tools/skill-registry/index.js +0 -1
  144. package/dist/tools/sync-spec-state-handler.d.ts +2 -2
  145. package/dist/tools/sync-spec-state-handler.js +23 -3
  146. package/dist/tools/tool-registry/core-tools.js +1 -140
  147. package/dist/tools/tool-registry/group-infra.js +2 -39
  148. package/dist/tools/tool-registry/group-quality-compliance.js +9 -1
  149. package/dist/tools/update-status/batch.js +17 -0
  150. package/dist/tools/update-status/dod-gates.js +14 -1
  151. package/dist/tools/update-status/done-receipt-verifier.d.ts +22 -0
  152. package/dist/tools/update-status/done-receipt-verifier.js +56 -26
  153. package/dist/tools/update-status/evidence-gate.js +10 -21
  154. package/dist/tools/update-status/file-sync.d.ts +1 -0
  155. package/dist/tools/update-status/file-sync.js +6 -0
  156. package/dist/tools/update-status/index.d.ts +6 -0
  157. package/dist/tools/update-status/index.js +39 -44
  158. package/dist/tools/update-status-actions.js +2 -7
  159. package/dist/tools/validate.js +34 -28
  160. package/dist/transports/oauth-validator.js +12 -1
  161. package/dist/transports/transport-factory.d.ts +2 -1
  162. package/dist/transports/transport-factory.js +19 -0
  163. package/dist/types/common/primitives.d.ts +2 -0
  164. package/dist/types/durable-job.d.ts +45 -0
  165. package/dist/types/durable-validation.d.ts +1 -1
  166. package/dist/types/evidence-autofill.d.ts +13 -1
  167. package/dist/types/handoff-artifacts.d.ts +2 -1
  168. package/dist/types/index.d.ts +1 -0
  169. package/dist/types/index.js +1 -0
  170. package/dist/types/legacy-guidance.d.ts +20 -0
  171. package/dist/types/legacy-guidance.js +3 -0
  172. package/dist/types/readiness.d.ts +8 -1
  173. package/dist/types/reconcile.d.ts +6 -0
  174. package/dist/types/skill-registry.d.ts +26 -1
  175. package/dist/types/spec/core.d.ts +5 -0
  176. package/dist/types/spec/inputs.d.ts +2 -2
  177. package/dist/types/spec-format.d.ts +11 -1
  178. package/dist/types/spec-grounding.d.ts +12 -0
  179. package/dist/types/ssr-migration.d.ts +1 -1
  180. package/dist/types/transport.d.ts +1 -0
  181. package/dist/types/validation-receipt.d.ts +27 -0
  182. package/package.json +3 -2
  183. package/planu-plugin.json +13 -26
  184. package/src/i18n/messages/en.json +1 -1
  185. package/src/i18n/messages/es.json +1 -1
  186. package/src/i18n/messages/pt.json +1 -1
  187. package/dist/engine/skill-generator/conventions-hasher.d.ts +0 -7
  188. package/dist/engine/skill-generator/conventions-hasher.js +0 -24
  189. package/dist/engine/universal-rules/rules/agent-teams.d.ts +0 -3
  190. package/dist/engine/universal-rules/rules/agent-teams.js +0 -63
  191. package/dist/tools/clarify-requirements/multiple-choice.d.ts +0 -30
  192. package/dist/tools/clarify-requirements/multiple-choice.js +0 -306
  193. package/dist/tools/clarify-requirements/questions-context.d.ts +0 -9
  194. package/dist/tools/clarify-requirements/questions-context.js +0 -74
  195. package/dist/tools/clarify-requirements/questions.d.ts +0 -16
  196. package/dist/tools/clarify-requirements/questions.js +0 -96
  197. package/dist/tools/clarify-requirements.d.ts +0 -4
  198. package/dist/tools/clarify-requirements.js +0 -314
  199. package/dist/tools/code-graph-handler.d.ts +0 -6
  200. package/dist/tools/code-graph-handler.js +0 -72
  201. package/dist/tools/create-rule.d.ts +0 -4
  202. package/dist/tools/create-rule.js +0 -107
  203. package/dist/tools/feedback-handler.d.ts +0 -7
  204. package/dist/tools/feedback-handler.js +0 -150
  205. package/dist/tools/semantic-search-handler.d.ts +0 -7
  206. package/dist/tools/semantic-search-handler.js +0 -71
  207. package/dist/tools/skill-registry/search.d.ts +0 -11
  208. package/dist/tools/skill-registry/search.js +0 -159
@@ -1,150 +0,0 @@
1
- import { submitFeedback, getFeedback, resolveFeedback, findSimilar, getSummary, getFeedbackRemoteHealth, syncFeedbackRemote, } from '../storage/feedback-store.js';
2
- import { triageFeedback, formatTriageReport } from '../engine/feedback/triage.js';
3
- import { globalDataDir, hashProjectPath, projectDataDir } from '../storage/base-store.js';
4
- // ---------------------------------------------------------------------------
5
- // Default data directory
6
- // ---------------------------------------------------------------------------
7
- function getDataDir(projectPath) {
8
- return projectPath ? projectDataDir(hashProjectPath(projectPath)) : globalDataDir();
9
- }
10
- // ---------------------------------------------------------------------------
11
- // Type emoji mapping
12
- // ---------------------------------------------------------------------------
13
- const TYPE_EMOJI = {
14
- bug: 'Bug',
15
- feature: 'Feature',
16
- suggestion: 'Suggestion',
17
- dx: 'DX',
18
- };
19
- // ---------------------------------------------------------------------------
20
- // submit_feedback handler
21
- // ---------------------------------------------------------------------------
22
- export async function handleSubmitFeedback(input) {
23
- const feedbackType = input.type;
24
- const dataDir = getDataDir(input.context?.projectPath);
25
- const entry = await submitFeedback(dataDir, {
26
- type: feedbackType,
27
- title: input.title,
28
- description: input.description,
29
- context: input.context,
30
- status: 'pending',
31
- votes: 1,
32
- });
33
- // Check for similar feedback to warn about duplicates
34
- const similar = findSimilar(dataDir, input.title, 0.4).filter((e) => e.id !== entry.id);
35
- const topSimilar = similar.sort((a, b) => (b.votes ?? 0) - (a.votes ?? 0))[0];
36
- const lines = [
37
- `Feedback submitted: **${entry.id}**`,
38
- '',
39
- '| Field | Value |',
40
- '|-------|-------|',
41
- `| Type | ${TYPE_EMOJI[feedbackType]} |`,
42
- `| Title | ${entry.title} |`,
43
- `| Status | Pending |`,
44
- `| Remote Delivery | ${entry.remoteDelivery?.status ?? 'pending'} |`,
45
- ];
46
- if (topSimilar !== undefined) {
47
- lines.push('');
48
- lines.push(`Similar feedback found: ${topSimilar.id} (${topSimilar.votes ?? 1} votes) — consider voting instead of duplicating.`);
49
- }
50
- return { content: [{ type: 'text', text: lines.join('\n') }] };
51
- }
52
- // ---------------------------------------------------------------------------
53
- // triage_feedback handler
54
- // ---------------------------------------------------------------------------
55
- export function handleTriageFeedback(input) {
56
- const dataDir = getDataDir();
57
- const filterType = input.filter;
58
- const entries = getFeedback(dataDir, filterType !== undefined ? { type: filterType } : undefined);
59
- const groups = triageFeedback(entries);
60
- const report = formatTriageReport(groups);
61
- const summary = getSummaryLine(entries.length, groups.length);
62
- const text = [summary, '', report].join('\n');
63
- return { content: [{ type: 'text', text }] };
64
- }
65
- function getSummaryLine(total, groups) {
66
- return `${total} feedback item(s) → ${groups} triage group(s)`;
67
- }
68
- // ---------------------------------------------------------------------------
69
- // resolve_feedback handler
70
- // ---------------------------------------------------------------------------
71
- export async function handleResolveFeedback(input) {
72
- const dataDir = getDataDir();
73
- const resolved = await resolveFeedback(dataDir, input.feedbackId, input.specId, input.prUrl, input.notes);
74
- if (resolved === null) {
75
- return {
76
- content: [
77
- {
78
- type: 'text',
79
- text: `Error: Feedback ${input.feedbackId} not found. Check the ID and try again.`,
80
- },
81
- ],
82
- isError: true,
83
- };
84
- }
85
- const lines = [
86
- `Feedback resolved: **${resolved.id}**`,
87
- '',
88
- '| Field | Value |',
89
- '|-------|-------|',
90
- `| Title | ${resolved.title} |`,
91
- `| Status | Resolved |`,
92
- `| Resolved At | ${resolved.resolvedAt ?? 'now'} |`,
93
- ];
94
- if (resolved.specId) {
95
- lines.push(`| Linked Spec | ${resolved.specId} |`);
96
- }
97
- if (resolved.prUrl) {
98
- lines.push(`| PR URL | ${resolved.prUrl} |`);
99
- }
100
- if (resolved.resolvedNotes) {
101
- lines.push('', `**Notes:** ${resolved.resolvedNotes}`);
102
- }
103
- return { content: [{ type: 'text', text: lines.join('\n') }] };
104
- }
105
- // ---------------------------------------------------------------------------
106
- // sync_feedback handler
107
- // ---------------------------------------------------------------------------
108
- export async function handleSyncFeedback(input) {
109
- const dataDir = getDataDir(input.projectPath);
110
- const summary = await syncFeedbackRemote(dataDir, input);
111
- const lines = [
112
- 'Feedback remote sync complete.',
113
- '',
114
- '| Field | Value |',
115
- '|-------|-------|',
116
- `| Processed | ${summary.total} |`,
117
- `| Synced | ${summary.synced} |`,
118
- `| Failed | ${summary.failed} |`,
119
- `| Skipped | ${summary.skipped} |`,
120
- `| Already Synced | ${summary.alreadySynced} |`,
121
- ];
122
- if (summary.processedIds.length > 0) {
123
- lines.push(`| Processed IDs | ${summary.processedIds.join(', ')} |`);
124
- }
125
- return { content: [{ type: 'text', text: lines.join('\n') }] };
126
- }
127
- // ---------------------------------------------------------------------------
128
- // feedback_status handler
129
- // ---------------------------------------------------------------------------
130
- export function handleFeedbackStatus(input) {
131
- const dataDir = getDataDir(input.projectPath);
132
- const summary = getSummary(dataDir);
133
- const remote = getFeedbackRemoteHealth(dataDir);
134
- const lines = [
135
- 'Feedback status',
136
- '',
137
- '| Field | Value |',
138
- '|-------|-------|',
139
- `| Total | ${summary.total} |`,
140
- `| Pending Local | ${summary.pending} |`,
141
- `| Resolved Local | ${summary.resolved} |`,
142
- `| Remote Pending | ${remote.byRemoteStatus.pending} |`,
143
- `| Remote Synced | ${remote.byRemoteStatus.synced} |`,
144
- `| Remote Failed | ${remote.byRemoteStatus.failed} |`,
145
- `| Remote Skipped | ${remote.byRemoteStatus.skipped} |`,
146
- `| Retryable | ${remote.retryable} |`,
147
- ];
148
- return { content: [{ type: 'text', text: lines.join('\n') }] };
149
- }
150
- //# sourceMappingURL=feedback-handler.js.map
@@ -1,7 +0,0 @@
1
- import type { ToolResult, SemanticSearchArgs } from '../types/index.js';
2
- /**
3
- * Handle a semantic_search request.
4
- * Embeds the query with TF-IDF, then searches the vector backend.
5
- */
6
- export declare function handleSemanticSearch(args: SemanticSearchArgs): Promise<ToolResult>;
7
- //# sourceMappingURL=semantic-search-handler.d.ts.map
@@ -1,71 +0,0 @@
1
- // tools/semantic-search-handler.ts — Handler for semantic_search tool.
2
- // SPEC-075 AC-07: Generates TF-IDF embedding of query, searches backend.
3
- import { getOrCreateBackend } from '../storage/vector-store/backend-factory.js';
4
- import { SemanticIndexStore } from '../storage/semantic-index-store.js';
5
- /**
6
- * Handle a semantic_search request.
7
- * Embeds the query with TF-IDF, then searches the vector backend.
8
- */
9
- export async function handleSemanticSearch(args) {
10
- const { projectId, query, scope = 'all', topK = 5, threshold = 0.3 } = args;
11
- if (!projectId) {
12
- return {
13
- content: [
14
- {
15
- type: 'text',
16
- text: 'Error: No project ID provided. Run init_project first.',
17
- },
18
- ],
19
- isError: true,
20
- };
21
- }
22
- const backend = await getOrCreateBackend(projectId);
23
- // Build a TF-IDF engine from existing documents so IDF is accurate
24
- const type = scope === 'all' ? undefined : scope;
25
- const allDocs = await backend.getAll(type);
26
- if (allDocs.length === 0) {
27
- return {
28
- content: [
29
- {
30
- type: 'text',
31
- text: `No documents found in scope "${scope}". Add specs, patterns, or knowledge first.`,
32
- },
33
- ],
34
- };
35
- }
36
- // SPEC-1345: load the persisted TF-IDF index for this scope, incrementally
37
- // reconciled against the current corpus (no full rebuild for unchanged docs).
38
- const indexStore = new SemanticIndexStore(projectId, scope);
39
- const tfidf = await indexStore.loadOrBuild(allDocs.map((doc) => ({ id: doc.id, content: doc.content })));
40
- // Embed the query
41
- const queryEmbedding = tfidf.embed(query);
42
- // Search
43
- const results = await backend.searchSimilar(queryEmbedding, topK, threshold, type);
44
- if (results.length === 0) {
45
- return {
46
- content: [
47
- {
48
- type: 'text',
49
- text: `No results found for "${query}" in scope "${scope}" with threshold ${String(threshold)}. Try a lower threshold or broader scope.`,
50
- },
51
- ],
52
- };
53
- }
54
- const formatted = results.map((r, i) => {
55
- const truncated = r.entry.content.length > 200 ? `${r.entry.content.slice(0, 200)}...` : r.entry.content;
56
- return [
57
- `${String(i + 1)}. [${r.entry.type}] ${r.entry.id}`,
58
- ` Similarity: ${r.similarity.toFixed(3)}`,
59
- ` ${truncated}`,
60
- ].join('\n');
61
- });
62
- return {
63
- content: [
64
- {
65
- type: 'text',
66
- text: `Found ${String(results.length)} results for "${query}":\n\n${formatted.join('\n\n')}`,
67
- },
68
- ],
69
- };
70
- }
71
- //# sourceMappingURL=semantic-search-handler.js.map
@@ -1,11 +0,0 @@
1
- import type { ToolResult, SkillRegistrySource } from '../../types/index.js';
2
- export declare function loadRegistries(): SkillRegistrySource[];
3
- export declare function handleSkillSearch(params: {
4
- query: string;
5
- registry?: string;
6
- stack?: string;
7
- limit?: number;
8
- /** SPEC-606: Specific sources to search (universal engine). */
9
- sources?: string[];
10
- }): Promise<ToolResult>;
11
- //# sourceMappingURL=search.d.ts.map
@@ -1,159 +0,0 @@
1
- // @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
2
- // tools/skill-registry/search.ts — Handler for skill_search tool (SPEC-150, updated SPEC-606)
3
- import { searchAllRegistries } from '../../engine/skill-registry/index.js';
4
- import { searchSkillsUniversal } from '../../engine/skill-discovery/index.js';
5
- import { formatSuccess, toolResult } from '../response-helpers.js';
6
- import { ti } from '../../i18n/index.js';
7
- import { readFileSync } from 'node:fs';
8
- import { join, dirname } from 'node:path';
9
- import { fileURLToPath } from 'node:url';
10
- const __dirname = dirname(fileURLToPath(import.meta.url));
11
- const DEFAULT_REGISTRIES = [
12
- {
13
- id: 'builtin',
14
- name: 'Planu Built-in Skills',
15
- url: 'local://skill-catalog',
16
- type: 'api',
17
- priority: 0,
18
- enabled: true,
19
- },
20
- {
21
- id: 'anthropic',
22
- name: 'Anthropic Official Skills',
23
- url: 'https://github.com/anthropics/skills',
24
- type: 'github',
25
- priority: 1,
26
- enabled: true,
27
- },
28
- {
29
- id: 'agentskill',
30
- name: 'AgentSkill.sh',
31
- url: 'https://agentskill.sh',
32
- type: 'api',
33
- priority: 2,
34
- enabled: true,
35
- },
36
- {
37
- id: 'skillssh',
38
- name: 'Skills.sh',
39
- url: 'https://skills.sh',
40
- type: 'npm',
41
- priority: 3,
42
- enabled: true,
43
- },
44
- ];
45
- export function loadRegistries() {
46
- // Try compiled path first (dist/config/), then source path (src/config/)
47
- const compiledPath = join(__dirname, '../../config/skill-registries.json');
48
- const sourcePath = join(__dirname, '../../../src/config/skill-registries.json');
49
- for (const configPath of [compiledPath, sourcePath]) {
50
- let raw;
51
- try {
52
- raw = readFileSync(configPath, 'utf-8');
53
- }
54
- catch {
55
- // File not found at this path — try next
56
- continue;
57
- }
58
- if (!raw.trim()) {
59
- // Empty file — skip, try next path
60
- continue;
61
- }
62
- try {
63
- return JSON.parse(raw);
64
- }
65
- catch {
66
- console.warn('[skill_search] skill-registries.json is corrupted, using defaults');
67
- return DEFAULT_REGISTRIES;
68
- }
69
- }
70
- return DEFAULT_REGISTRIES;
71
- }
72
- export async function handleSkillSearch(params) {
73
- try {
74
- const registries = loadRegistries();
75
- // Guard: query must be a non-empty string to avoid returning unfiltered catalog dumps
76
- const query = typeof params.query === 'string' ? params.query.trim() : '';
77
- if (query.length === 0) {
78
- return toolResult(formatSuccess('No query provided', 'Provide a search term to find skills. Example: `skill_search({ query: "testing", projectPath: "..." })`'), { results: [], count: 0 });
79
- }
80
- const limit = Math.max(1, Math.min(params.limit ?? 10, 50));
81
- // SPEC-606: When sources are specified, delegate to the universal discovery engine.
82
- // Otherwise, use the existing registry-based search for backward compatibility.
83
- if (params.sources && params.sources.length > 0) {
84
- const universalResults = await searchSkillsUniversal(query, {
85
- stack: params.stack,
86
- limit,
87
- sources: params.sources,
88
- });
89
- const lines = [];
90
- if (universalResults.length === 0) {
91
- lines.push(`No skills found matching **"${query}"** in sources: ${params.sources.join(', ')}.`);
92
- lines.push('');
93
- lines.push('Try a broader query or remove the sources filter.');
94
- }
95
- else {
96
- lines.push('| # | Skill | Source | Description |');
97
- lines.push('|---|-------|--------|-------------|');
98
- universalResults.forEach((r, i) => {
99
- const desc = r.description.length > 80 ? r.description.slice(0, 77) + '...' : r.description;
100
- lines.push(`| ${String(i + 1)} | **${r.name}** | ${r.source} | ${desc} |`);
101
- });
102
- lines.push('');
103
- lines.push('Install with: `skill_install({ name: "skill-name", projectPath: "..." })`');
104
- }
105
- const markdown = formatSuccess(`Found ${String(universalResults.length)} skill${universalResults.length !== 1 ? 's' : ''} (universal search)`, lines.join('\n'));
106
- return toolResult(markdown, { results: universalResults, count: universalResults.length });
107
- }
108
- const searchParams = {
109
- query,
110
- registry: params.registry,
111
- stack: params.stack,
112
- limit,
113
- };
114
- const enabledCount = registries.filter((r) => {
115
- if (!r.enabled) {
116
- return false;
117
- }
118
- if (searchParams.registry &&
119
- searchParams.registry !== 'all' &&
120
- r.id !== searchParams.registry) {
121
- return false;
122
- }
123
- return true;
124
- }).length;
125
- const results = await searchAllRegistries(searchParams, registries);
126
- const lines = [];
127
- if (results.length === 0) {
128
- if (enabledCount === 0) {
129
- lines.push('No skill registries are enabled. Check your `skill-registries.json` configuration.');
130
- }
131
- else {
132
- lines.push(`No skills found matching **"${query}"**.`);
133
- lines.push('');
134
- lines.push('Suggestions:');
135
- lines.push('- Try a broader search term (e.g., "test" instead of "unit-testing")');
136
- lines.push('- Omit the `registry` filter to search all registries');
137
- lines.push('- Check network connectivity to skill registries');
138
- lines.push('- Use `sources: ["github"]` for broader universal search (SPEC-606)');
139
- }
140
- }
141
- else {
142
- lines.push('| # | Skill | Source | Description |');
143
- lines.push('|---|-------|--------|-------------|');
144
- results.forEach((r, i) => {
145
- const desc = r.description.length > 80 ? r.description.slice(0, 77) + '...' : r.description;
146
- lines.push(`| ${String(i + 1)} | **${r.name}** | ${r.source} | ${desc} |`);
147
- });
148
- lines.push('');
149
- lines.push('Install with: `skill_install({ name: "skill-name", projectPath: "..." })`');
150
- }
151
- const markdown = formatSuccess(`Found ${String(results.length)} skill${results.length !== 1 ? 's' : ''}`, lines.join('\n'));
152
- return toolResult(markdown, { results, count: results.length });
153
- }
154
- catch (error) {
155
- const msg = error instanceof Error ? error.message : String(error);
156
- return toolResult(ti('errors.internalError', { message: msg }) + (msg ? ` ${msg}` : ''), undefined, true);
157
- }
158
- }
159
- //# sourceMappingURL=search.js.map