opencode-swarm 7.74.0 → 7.74.2

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,67 @@
1
+ /**
2
+ * External content scanner — shared ingress point for arbitrary external text.
3
+ *
4
+ * Reuses the prompt-injection and unsafe-instruction patterns from
5
+ * external-skill-validator.ts to scan network-fetched content (gitingest,
6
+ * web_search, future network tools) before it enters the LLM context.
7
+ *
8
+ * Provides a single shared interface: `scanExternalContent(text, options?)`.
9
+ * This ensures consistent threat detection across all external sources
10
+ * and closes the asymmetry documented in issue #1278.
11
+ *
12
+ * Uses an `_internals` DI seam for testability — no `mock.module` leakage.
13
+ */
14
+ import { type ValidationFinding } from './external-skill-validator';
15
+ /** Result from scanning external content for injection and unsafe instructions. */
16
+ export interface ExternalContentScanResult {
17
+ /** Whether threats were detected. */
18
+ clean: boolean;
19
+ /** Individual findings from the scan. */
20
+ findings: ValidationFinding[];
21
+ /** Threats found: 'none', 'warning', or 'error'. */
22
+ threatLevel: 'none' | 'warning' | 'error';
23
+ /** The original text (for comparison). */
24
+ originalLength: number;
25
+ /** The neutralized text with threat markers wrapped. */
26
+ neutralized: string;
27
+ }
28
+ /**
29
+ * Apply invisible-format-character detection to raw text.
30
+ *
31
+ * Unlike the other patterns, invisible format chars are detected by counting
32
+ * occurrences in the raw string (not via regex .test), because we need the
33
+ * match string and they are multi-codepoint.
34
+ *
35
+ * Returns an array of findings (empty if none found).
36
+ * Each finding includes the individual match string (not concatenated),
37
+ * so callers can neutralize each occurrence at its original position.
38
+ */
39
+ declare function scanInvisibleFormatChars(text: string): ValidationFinding[];
40
+ /**
41
+ * Neutralize threat patterns in text by wrapping them with delimiters.
42
+ * This makes them visible to the LLM as data, not instructions.
43
+ */
44
+ declare function neutralizeThreatPatterns(text: string, findings: ValidationFinding[]): string;
45
+ /**
46
+ * Scan arbitrary external content for prompt-injection and unsafe-instruction threats.
47
+ *
48
+ * Returns a structured result with:
49
+ * - `clean`: boolean indicating no error-severity findings
50
+ * - `findings`: all detected findings
51
+ * - `threatLevel`: aggregated threat assessment
52
+ * - `neutralized`: the text with threat patterns wrapped for safety
53
+ *
54
+ * @param text - The external content to scan (arbitrary length, typically from API)
55
+ * @param options - Optional: { trustLevel = 'low' }
56
+ * - 'low': warnings are treated as errors
57
+ * - 'medium'/'high': warnings stay warnings
58
+ */
59
+ export declare function scanExternalContent(text: string, options?: {
60
+ trustLevel?: 'low' | 'medium' | 'high';
61
+ maxLength?: number;
62
+ }): ExternalContentScanResult;
63
+ export declare const _internals: {
64
+ scanInvisibleFormatChars: typeof scanInvisibleFormatChars;
65
+ neutralizeThreatPatterns: typeof neutralizeThreatPatterns;
66
+ };
67
+ export {};
@@ -105,6 +105,7 @@ export declare const VALIDATION_RATE_LIMITS: {
105
105
  /** Timeout for individual fetch operations in milliseconds. */
106
106
  readonly fetch_timeout_ms: 30000;
107
107
  };
108
+ declare function stripMarkdownCodeForUnsafeScan(text: string): string;
108
109
  /**
109
110
  * Scan an external skill candidate for prompt-injection patterns.
110
111
  *
@@ -157,4 +158,6 @@ export declare function evaluateCandidate(candidate: ExternalSkillCandidate, opt
157
158
  export declare const _internals: {
158
159
  getTimestamp: () => string;
159
160
  computeSha256: (content: string) => string;
161
+ stripMarkdownCodeForUnsafeScan: typeof stripMarkdownCodeForUnsafeScan;
160
162
  };
163
+ export {};
@@ -24,6 +24,9 @@ export interface CandidateSelectionOptions {
24
24
  minConfidence: number;
25
25
  minConfirmations: number;
26
26
  }
27
+ export declare const DEFAULT_SKILL_MIN_CONFIDENCE = 0.7;
28
+ export declare const DEFAULT_SKILL_MIN_CONFIRMATIONS = 2;
29
+ export declare const STRONG_SKILL_OUTCOME_COUNT = 3;
27
30
  export interface KnowledgeCluster {
28
31
  slug: string;
29
32
  title: string;
@@ -36,6 +39,7 @@ export interface KnowledgeCluster {
36
39
  avgConfidence: number;
37
40
  }
38
41
  export declare function selectCandidateEntries(directory: string, opts: CandidateSelectionOptions): Promise<KnowledgeEntryBase[]>;
42
+ export declare function isSkillMaturityEligible(entry: KnowledgeEntryBase, opts: CandidateSelectionOptions, outcomes?: KnowledgeEntryBase['retrieval_outcomes'] | undefined): boolean;
39
43
  /**
40
44
  * Compute Jaccard similarity between two tag sets.
41
45
  * Returns 0 when both sets are empty (avoids division by zero).
@@ -147,6 +151,7 @@ export declare const _internals: {
147
151
  sanitizeSlug: typeof sanitizeSlug;
148
152
  isValidSlug: typeof isValidSlug;
149
153
  selectCandidateEntries: typeof selectCandidateEntries;
154
+ isSkillMaturityEligible: typeof isSkillMaturityEligible;
150
155
  clusterEntries: typeof clusterEntries;
151
156
  jaccardSimilarity: typeof jaccardSimilarity;
152
157
  renderSkillMarkdown: typeof renderSkillMarkdown;
@@ -1,12 +1,13 @@
1
1
  /**
2
- * Skill-improver daily-quota tracker.
2
+ * Named daily-quota tracker for low-frequency LLM work.
3
3
  *
4
- * State file: .swarm/skill-improver-quota.json
5
- * Counts every LLM-credentialed call by the skill_improver agent.
4
+ * Default state file: .swarm/skill-improver-quota.json
5
+ * Dedicated enrichment state file: .swarm/knowledge-enrichment-quota.json
6
6
  * The window is configurable: 'utc' (default) resets at 00:00 UTC; 'local'
7
7
  * resets at the host's local midnight.
8
8
  */
9
9
  export type QuotaWindow = 'utc' | 'local';
10
+ export type QuotaScope = 'skill-improver' | 'knowledge-enrichment';
10
11
  export interface QuotaState {
11
12
  /** YYYY-MM-DD in the chosen window */
12
13
  date: string;
@@ -15,12 +16,13 @@ export interface QuotaState {
15
16
  last_run_at?: string;
16
17
  window: QuotaWindow;
17
18
  }
18
- export declare function resolveQuotaPath(directory: string): string;
19
+ export declare function resolveQuotaPath(directory: string, scope?: QuotaScope): string;
19
20
  export declare function todayKey(window: QuotaWindow, now?: Date): string;
20
21
  export interface QuotaCheckOptions {
21
22
  maxCalls: number;
22
23
  window: QuotaWindow;
23
24
  now?: Date;
25
+ scope?: QuotaScope;
24
26
  }
25
27
  export interface QuotaCheckResult {
26
28
  allowed: boolean;
@@ -16,7 +16,8 @@
16
16
  * on failure: a flaky model must not burn unbounded retries within a
17
17
  * window.
18
18
  */
19
- import type { SwarmKnowledgeEntry } from '../hooks/knowledge-types.js';
19
+ import type { EnrichmentQuotaOptions } from '../hooks/knowledge-curator.js';
20
+ import type { KnowledgeEntryBase } from '../hooks/knowledge-types.js';
20
21
  import { type SkillImproverLLMDelegate } from '../hooks/skill-improver-llm-factory.js';
21
22
  import { type AutoApplyResult } from './skill-generator.js';
22
23
  import { type QuotaWindow } from './skill-improver-quota.js';
@@ -46,6 +47,9 @@ export interface SkillImproveRequest {
46
47
  * createSkillImproverLLMDelegate(directory, sessionId) which returns
47
48
  * undefined unless swarmState.opencodeClient is wired. */
48
49
  delegate?: SkillImproverLLMDelegate;
50
+ /** Dedicated quota for hardening quarantined knowledge entries. This is
51
+ * separate from the skill_improver proposal quota above. */
52
+ enrichmentQuota?: EnrichmentQuotaOptions;
49
53
  }
50
54
  export interface SkillImproveResult {
51
55
  ran: boolean;
@@ -95,7 +99,7 @@ interface InventorySnapshot {
95
99
  metadataReadable: number;
96
100
  };
97
101
  highConfidenceClusters: number;
98
- matureCandidates: SwarmKnowledgeEntry[];
102
+ matureCandidates: KnowledgeEntryBase[];
99
103
  staleActiveSkills: Array<{
100
104
  slug: string;
101
105
  reasons: string[];
@@ -12,8 +12,8 @@
12
12
  * retirement). Already-marked retire candidates are never re-processed.
13
13
  *
14
14
  * Quota: every LLM attempt goes through `enrichLessonToV3`, which reserves one
15
- * skill-improver quota slot per call the loop can never exceed the shared
16
- * daily budget. A per-run batch cap bounds worst-case cost further.
15
+ * dedicated knowledge-enrichment quota slot per call. A per-run batch cap
16
+ * bounds worst-case cost further.
17
17
  */
18
18
  import type { CuratorLLMDelegate } from '../hooks/curator.js';
19
19
  import { type EnrichmentQuotaOptions } from '../hooks/knowledge-curator.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.74.0",
3
+ "version": "7.74.2",
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",
@@ -1,30 +0,0 @@
1
- /**
2
- * Skill definition with versioning and per-agent overlays
3
- */
4
- export interface AgentOverlay {
5
- agent: string;
6
- prompt?: string;
7
- model?: string;
8
- }
9
- export interface SkillDefinition {
10
- id: string;
11
- name: string;
12
- description: string;
13
- SKILL_VERSION: number;
14
- basePrompt?: string;
15
- agents?: AgentOverlay[];
16
- }
17
- export declare const skills: SkillDefinition[];
18
- export declare const AGENT_OVERLAYS: Record<string, AgentOverlay[]>;
19
- /**
20
- * Get skill by ID
21
- */
22
- export declare function getSkill(id: string): SkillDefinition | undefined;
23
- /**
24
- * Get agent overlay for a skill
25
- */
26
- export declare function getAgentOverlay(skillId: string, agent: string): AgentOverlay | undefined;
27
- /**
28
- * Resolve effective prompt for an agent on a skill
29
- */
30
- export declare function resolveAgentPrompt(skillId: string, agent: string, defaultPrompt: string): string;