opencode-swarm 7.76.2 → 7.77.0

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.
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Scheduled skill-improver consolidation.
3
+ *
4
+ * This module owns cadence state only. The actual queue draining, proposal
5
+ * writing, and draft-skill generation stays in `runSkillImprover`.
6
+ */
7
+ import type { EnrichmentQuotaOptions } from '../hooks/knowledge-curator.js';
8
+ import type { SkillImproveResult, SkillImproverConfigInput } from './skill-improver.js';
9
+ export interface SkillConsolidationState {
10
+ last_consolidation_at?: string;
11
+ last_source?: SkillConsolidationSource;
12
+ last_ran?: boolean;
13
+ last_reason?: string;
14
+ }
15
+ export type SkillConsolidationSource = 'startup' | 'phase_complete' | 'manual';
16
+ export interface SkillConsolidationRequest {
17
+ directory: string;
18
+ config: SkillImproverConfigInput;
19
+ source: SkillConsolidationSource;
20
+ sessionId?: string;
21
+ force?: boolean;
22
+ now?: Date;
23
+ enrichmentQuota?: EnrichmentQuotaOptions;
24
+ evaluateDrafts?: boolean;
25
+ }
26
+ export interface SkillConsolidationResult {
27
+ started: boolean;
28
+ reason?: string;
29
+ statePath: string;
30
+ result?: SkillImproveResult;
31
+ }
32
+ export declare function consolidationStatePath(directory: string): string;
33
+ declare function readState(directory: string): Promise<SkillConsolidationState>;
34
+ declare function writeState(directory: string, state: SkillConsolidationState): Promise<void>;
35
+ declare function intervalElapsed(state: SkillConsolidationState, intervalHours: number, now: Date): boolean;
36
+ export declare function shouldRunSkillConsolidation(req: SkillConsolidationRequest): Promise<{
37
+ shouldRun: boolean;
38
+ reason?: string;
39
+ state: SkillConsolidationState;
40
+ }>;
41
+ export declare function runSkillConsolidation(req: SkillConsolidationRequest): Promise<SkillConsolidationResult>;
42
+ export declare function runSkillConsolidationFireAndForget(req: SkillConsolidationRequest, onComplete?: (result: SkillConsolidationResult) => void, onError?: (error: unknown) => void): void;
43
+ export declare const _internals: {
44
+ readState: typeof readState;
45
+ writeState: typeof writeState;
46
+ intervalElapsed: typeof intervalElapsed;
47
+ runningByDirectory: Map<string, Promise<SkillConsolidationResult>>;
48
+ };
49
+ export {};
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Generated-skill validation gate.
3
+ *
4
+ * Eval fixtures live under `.swarm/skills/evals/<slug>/*.json`. Each fixture can
5
+ * be either a single case, an array of cases, or `{ "cases": [...] }`.
6
+ *
7
+ * This service is deterministic and fail-open only when no eval set exists.
8
+ * Malformed eval files fail closed so a broken gate cannot silently approve a
9
+ * promotion.
10
+ */
11
+ export interface SkillEvalCase {
12
+ id?: string;
13
+ task?: string;
14
+ required_phrases?: string[];
15
+ forbidden_phrases?: string[];
16
+ }
17
+ export interface SkillCaseEvaluation {
18
+ id: string;
19
+ candidateScore: number;
20
+ incumbentScore: number;
21
+ candidateFailures: string[];
22
+ incumbentFailures: string[];
23
+ }
24
+ export type SkillEvaluationStatus = 'unevaluated' | 'passed' | 'rejected' | 'invalid_eval_set';
25
+ export interface SkillEvaluationResult {
26
+ status: SkillEvaluationStatus;
27
+ passed: boolean;
28
+ reason: string;
29
+ evalFiles: string[];
30
+ caseCount: number;
31
+ candidateScore: number;
32
+ incumbentScore: number;
33
+ caseResults: SkillCaseEvaluation[];
34
+ }
35
+ export interface EvaluateSkillChangeRequest {
36
+ directory: string;
37
+ slug: string;
38
+ candidateContent: string;
39
+ incumbentContent?: string;
40
+ operation: string;
41
+ }
42
+ export interface RejectedSkillEditRecord {
43
+ timestamp: string;
44
+ slug: string;
45
+ operation: string;
46
+ reason: string;
47
+ candidateHash: string;
48
+ candidateNormalizedHash?: string;
49
+ incumbentHash?: string;
50
+ candidateScore: number;
51
+ incumbentScore: number;
52
+ evalFiles: string[];
53
+ caseCount: number;
54
+ candidatePreview: string;
55
+ }
56
+ export declare function rejectedEditsPath(directory: string): string;
57
+ declare function loadEvalSet(directory: string, slug: string): Promise<{
58
+ status: 'missing' | 'loaded' | 'invalid';
59
+ files: string[];
60
+ cases: SkillEvalCase[];
61
+ reason?: string;
62
+ }>;
63
+ declare function evaluateContent(content: string, testCase: SkillEvalCase): {
64
+ score: number;
65
+ failures: string[];
66
+ };
67
+ declare function hashNormalizedContent(content: string | undefined): string | undefined;
68
+ export declare function evaluateSkillChange(req: EvaluateSkillChangeRequest): Promise<SkillEvaluationResult>;
69
+ export declare function appendRejectedSkillEdit(req: EvaluateSkillChangeRequest, evaluation: SkillEvaluationResult): Promise<void>;
70
+ export declare function isRejectedSkillContent(directory: string, slug: string, content: string): Promise<boolean>;
71
+ export declare const _internals: {
72
+ loadEvalSet: typeof loadEvalSet;
73
+ evaluateContent: typeof evaluateContent;
74
+ rejectedEditsPath: typeof rejectedEditsPath;
75
+ hashNormalizedContent: typeof hashNormalizedContent;
76
+ };
77
+ export {};
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { unlinkSync } from 'node:fs';
16
16
  import type { KnowledgeEntryBase } from '../hooks/knowledge-types.js';
17
+ import { type SkillEvaluationResult } from './skill-evaluator.js';
17
18
  export declare function sanitizeSlug(input: string): string;
18
19
  export declare function isValidSlug(slug: string): boolean;
19
20
  export declare function proposalPath(directory: string, slug: string): string;
@@ -59,6 +60,7 @@ export interface GenerateRequest {
59
60
  slug?: string;
60
61
  sourceKnowledgeIds?: string[];
61
62
  force?: boolean;
63
+ evaluate?: boolean;
62
64
  minConfidence?: number;
63
65
  minConfirmations?: number;
64
66
  }
@@ -69,10 +71,12 @@ export interface GenerateResult {
69
71
  mode: GenerateMode;
70
72
  sourceKnowledgeIds: string[];
71
73
  preserved: boolean;
74
+ evaluation?: SkillEvaluationResult;
72
75
  }>;
73
76
  skipped: Array<{
74
77
  slug: string;
75
78
  reason: string;
79
+ evaluation?: SkillEvaluationResult;
76
80
  }>;
77
81
  }
78
82
  export declare function generateSkills(req: GenerateRequest): Promise<GenerateResult>;
@@ -95,17 +99,22 @@ export declare function parseDraftFrontmatter(content: string): {
95
99
  status?: string;
96
100
  generatedAt?: string;
97
101
  sourceKnowledgeIds: string[];
102
+ triggers: string[];
98
103
  version?: number;
99
104
  skillOrigin?: string;
100
105
  skillType?: 'directive' | 'workflow';
101
106
  } | null;
102
- export declare function activateProposal(directory: string, slug: string, force?: boolean): Promise<{
107
+ export declare function activateProposal(directory: string, slug: string, force?: boolean, options?: {
108
+ evaluate?: boolean;
109
+ operation?: string;
110
+ }): Promise<{
103
111
  activated: boolean;
104
112
  from: string;
105
113
  to: string;
106
114
  reason?: string;
107
115
  stamped?: boolean;
108
116
  stampedIds?: string[];
117
+ evaluation?: SkillEvaluationResult;
109
118
  }>;
110
119
  export declare function listSkills(directory: string): Promise<{
111
120
  proposals: Array<{
@@ -140,12 +149,15 @@ export declare function retireSkill(directory: string, slug: string, reason?: st
140
149
  markerPath: string;
141
150
  reason?: string;
142
151
  }>;
143
- export declare function regenerateSkill(directory: string, slug: string): Promise<{
152
+ export declare function regenerateSkill(directory: string, slug: string, options?: {
153
+ evaluate?: boolean;
154
+ }): Promise<{
144
155
  regenerated: boolean;
145
156
  path: string;
146
157
  entryCount: number;
147
158
  reason?: string;
148
159
  retired?: boolean;
160
+ evaluation?: SkillEvaluationResult;
149
161
  }>;
150
162
  export declare const _internals: {
151
163
  sanitizeSlug: typeof sanitizeSlug;
@@ -27,6 +27,8 @@ export interface SkillImproverConfigInput {
27
27
  fallback_models: string[];
28
28
  max_calls_per_day: number;
29
29
  trigger: 'manual' | 'scheduled';
30
+ consolidation_interval_hours?: number;
31
+ consolidation_max_calls_per_run?: number;
30
32
  targets: Array<'skills' | 'spec' | 'architect_prompt' | 'knowledge'>;
31
33
  write_mode: 'proposal' | 'draft_skills';
32
34
  require_user_approval: boolean;
@@ -50,6 +52,10 @@ export interface SkillImproveRequest {
50
52
  /** Dedicated quota for hardening quarantined knowledge entries. This is
51
53
  * separate from the skill_improver proposal quota above. */
52
54
  enrichmentQuota?: EnrichmentQuotaOptions;
55
+ /** Validate generated draft skills when write_mode is draft_skills. */
56
+ evaluateDrafts?: boolean;
57
+ /** Consolidation callers stage proposals only and must never auto-apply. */
58
+ allowAutoApply?: boolean;
53
59
  }
54
60
  export interface SkillImproveResult {
55
61
  ran: boolean;
@@ -46,6 +46,12 @@ declare function buildLLMPrompt(currentContent: string, currentVersion: number,
46
46
  userPrompt: string;
47
47
  };
48
48
  declare function validateLLMOutput(output: string): boolean;
49
+ declare function validateRevisionCandidate(params: ReviseSkillParams, candidateContent: string, operation: string): Promise<{
50
+ passed: true;
51
+ } | {
52
+ passed: false;
53
+ reason: string;
54
+ }>;
49
55
  export declare function reviseSkill(params: ReviseSkillParams): Promise<SkillRevisionResult>;
50
56
  export declare const _internals: {
51
57
  reviseSkill: typeof reviseSkill;
@@ -53,6 +59,7 @@ export declare const _internals: {
53
59
  buildDeterministicRevision: typeof buildDeterministicRevision;
54
60
  buildLLMPrompt: typeof buildLLMPrompt;
55
61
  validateLLMOutput: typeof validateLLMOutput;
62
+ validateRevisionCandidate: typeof validateRevisionCandidate;
56
63
  REVISION_VIOLATION_THRESHOLD: number;
57
64
  MAX_REVISION_CALLS_PER_PHASE: number;
58
65
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.76.2",
3
+ "version": "7.77.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",