opencode-swarm 7.63.0 → 7.65.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.
- package/.opencode/skills/swarm-pr-review/SKILL.md +124 -0
- package/README.md +57 -0
- package/dist/agents/architect.d.ts +1 -1
- package/dist/cli/index.js +192 -23
- package/dist/config/constants.d.ts +2 -0
- package/dist/config/evidence-schema.d.ts +44 -44
- package/dist/config/schema.d.ts +187 -0
- package/dist/hooks/knowledge-store.d.ts +2 -1
- package/dist/hooks/knowledge-validator.d.ts +5 -0
- package/dist/index.js +2561 -613
- package/dist/memory/schema.d.ts +2 -2
- package/dist/services/external-skill-store.d.ts +96 -0
- package/dist/services/external-skill-validator.d.ts +160 -0
- package/dist/summaries/schema.d.ts +15 -0
- package/dist/summaries/store.d.ts +5 -0
- package/dist/tools/external-skill-delete.d.ts +16 -0
- package/dist/tools/external-skill-discover.d.ts +21 -0
- package/dist/tools/external-skill-inspect.d.ts +15 -0
- package/dist/tools/external-skill-list.d.ts +15 -0
- package/dist/tools/external-skill-promote.d.ts +20 -0
- package/dist/tools/external-skill-reject.d.ts +15 -0
- package/dist/tools/external-skill-revoke.d.ts +17 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/manifest.d.ts +7 -0
- package/dist/tools/plugin-registration.d.ts +4 -1
- package/dist/tools/submit-phase-council-verdicts.d.ts +2 -0
- package/dist/tools/tool-metadata.d.ts +28 -0
- package/dist/tools/write-drift-evidence.d.ts +4 -0
- package/package.json +1 -1
package/dist/memory/schema.d.ts
CHANGED
|
@@ -213,9 +213,9 @@ export declare const MemoryProposalSchema: z.ZodObject<{
|
|
|
213
213
|
rationale: z.ZodString;
|
|
214
214
|
evidenceRefs: z.ZodArray<z.ZodString>;
|
|
215
215
|
status: z.ZodEnum<{
|
|
216
|
-
approved: "approved";
|
|
217
|
-
rejected: "rejected";
|
|
218
216
|
pending: "pending";
|
|
217
|
+
rejected: "rejected";
|
|
218
|
+
approved: "approved";
|
|
219
219
|
applied: "applied";
|
|
220
220
|
superseded: "superseded";
|
|
221
221
|
}>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External skill candidate quarantine store.
|
|
3
|
+
*
|
|
4
|
+
* Manages external skill candidates persisted as individual JSON files under
|
|
5
|
+
* `.swarm/skills/candidates/<uuid>.json`. Each candidate goes through a
|
|
6
|
+
* quarantine lifecycle (pending → in_review → quarantined → passed/rejected →
|
|
7
|
+
* promoted/revoked) before it can be activated as a generated skill.
|
|
8
|
+
*
|
|
9
|
+
* All writes are atomic (temp-file + rename) via `atomicWriteFile` from the
|
|
10
|
+
* evidence subsystem. File-system I/O is funnelled through `_internals` so
|
|
11
|
+
* that tests can replace individual operations without cross-module mock
|
|
12
|
+
* leakage (Bun's `mock.module` is intentionally avoided for I/O seams).
|
|
13
|
+
*
|
|
14
|
+
* Invariants:
|
|
15
|
+
* - Candidate IDs are UUID v4 (cryptographically random), never derived from
|
|
16
|
+
* user input, to prevent path-traversal attacks.
|
|
17
|
+
* - `passed`, `promoted`, and `revoked` candidates are NEVER evicted.
|
|
18
|
+
* - The store directory is derived from the injected `directory` parameter
|
|
19
|
+
* (typically `ctx.directory`); no `process.cwd()` calls.
|
|
20
|
+
*/
|
|
21
|
+
import * as crypto from 'node:crypto';
|
|
22
|
+
import * as fs from 'node:fs/promises';
|
|
23
|
+
import type { ExternalSkillCandidate, ExternalSkillCandidateEvaluationVerdict } from '../config/schema';
|
|
24
|
+
import { atomicWriteFile } from '../evidence/task-file';
|
|
25
|
+
/** Configuration for the store. */
|
|
26
|
+
export interface ExternalSkillStoreConfig {
|
|
27
|
+
/** Maximum number of candidates before FIFO eviction kicks in. */
|
|
28
|
+
max_candidates: number;
|
|
29
|
+
}
|
|
30
|
+
/** Optional filters for listing candidates. */
|
|
31
|
+
export interface ExternalSkillListFilter {
|
|
32
|
+
/** Restrict to candidates with this evaluation verdict. */
|
|
33
|
+
verdict?: ExternalSkillCandidateEvaluationVerdict;
|
|
34
|
+
/** Restrict to candidates from this source type (e.g. 'github'). */
|
|
35
|
+
source_type?: string;
|
|
36
|
+
/** Restrict to candidates with this exact source URL. */
|
|
37
|
+
source_url?: string;
|
|
38
|
+
/** ISO datetime — only return candidates fetched at or after this time. */
|
|
39
|
+
since?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Patch fields accepted by `update`. */
|
|
42
|
+
export type ExternalSkillCandidatePatch = Partial<Pick<ExternalSkillCandidate, 'evaluation_verdict' | 'risk_flags' | 'evaluation_history' | 'skill_name' | 'skill_description'>>;
|
|
43
|
+
/**
|
|
44
|
+
* Public interface returned by the factory function.
|
|
45
|
+
*
|
|
46
|
+
* Every method is scoped to the store directory derived at creation time.
|
|
47
|
+
*/
|
|
48
|
+
export interface ExternalSkillStore {
|
|
49
|
+
/** Create a new candidate and persist it atomically. */
|
|
50
|
+
add(candidate: Omit<ExternalSkillCandidate, 'id'>): Promise<ExternalSkillCandidate>;
|
|
51
|
+
/** Read a single candidate by UUID. Returns `null` if not found. */
|
|
52
|
+
get(id: string): Promise<ExternalSkillCandidate | null>;
|
|
53
|
+
/** List candidates with optional filters, sorted by `fetched_at` descending. */
|
|
54
|
+
list(filter?: ExternalSkillListFilter): Promise<ExternalSkillCandidate[]>;
|
|
55
|
+
/** Patch an existing candidate (read-modify-write). Appends to `evaluation_history`. */
|
|
56
|
+
update(id: string, patch: ExternalSkillCandidatePatch): Promise<ExternalSkillCandidate | null>;
|
|
57
|
+
/** Remove a candidate file. Returns `true` if the file existed and was deleted. */
|
|
58
|
+
delete(id: string): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Evict the oldest `pending` or `rejected` candidates when the store
|
|
61
|
+
* exceeds `max_candidates`. Never evicts `passed`, `promoted`, or
|
|
62
|
+
* `revoked` candidates. Returns the number of evicted files.
|
|
63
|
+
*/
|
|
64
|
+
evictIfNeeded(): Promise<number>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Dependency-injection seam for testing.
|
|
68
|
+
*
|
|
69
|
+
* Tests can temporarily replace individual entries to exercise failure paths
|
|
70
|
+
* (e.g. file-not-found, permission errors) without `mock.module` leakage.
|
|
71
|
+
* Restore each entry in `afterEach` via the saved original reference.
|
|
72
|
+
*/
|
|
73
|
+
export declare const _internals: {
|
|
74
|
+
/** UUID generator — default is `crypto.randomUUID()`. */
|
|
75
|
+
randomUUID: typeof crypto.randomUUID;
|
|
76
|
+
/** Async filesystem operations. */
|
|
77
|
+
fs: {
|
|
78
|
+
mkdir: typeof fs.mkdir;
|
|
79
|
+
readFile: typeof fs.readFile;
|
|
80
|
+
readdir: typeof fs.readdir;
|
|
81
|
+
unlink: typeof fs.unlink;
|
|
82
|
+
};
|
|
83
|
+
/** Atomic write primitive (temp-file + rename). */
|
|
84
|
+
atomicWriteFile: typeof atomicWriteFile;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Create an `ExternalSkillStore` scoped to the given project root directory.
|
|
88
|
+
*
|
|
89
|
+
* The store persists candidate files under
|
|
90
|
+
* `<directory>/.swarm/skills/candidates/<uuid>.json`.
|
|
91
|
+
*
|
|
92
|
+
* @param directory — Project root (typically `ctx.directory`). Must NOT contain
|
|
93
|
+
* user-controlled path components.
|
|
94
|
+
* @param config — Store configuration including capacity limits.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createExternalSkillStore(directory: string, config: ExternalSkillStoreConfig): ExternalSkillStore;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation gates for external skill candidates.
|
|
3
|
+
*
|
|
4
|
+
* Provides shared types and individual gate functions that scan candidate
|
|
5
|
+
* fields for security threats (prompt injection, unsafe instructions,
|
|
6
|
+
* provenance integrity). Each gate returns a structured `ValidationGateResult`
|
|
7
|
+
* that the curation pipeline can use to block, warn, or pass a candidate.
|
|
8
|
+
*
|
|
9
|
+
* Gate 1 — `scanPromptInjection`: static regex-based detection of prompt-
|
|
10
|
+
* injection patterns, prototype pollution, script injection, and obfuscated
|
|
11
|
+
* content in candidate fields. Severity is modulated by the candidate's trust
|
|
12
|
+
* level (FR-004).
|
|
13
|
+
*
|
|
14
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
15
|
+
*/
|
|
16
|
+
import type { ExternalSkillCandidate } from '../config/schema';
|
|
17
|
+
/** Result from a single validation gate scan. */
|
|
18
|
+
export interface ValidationGateResult {
|
|
19
|
+
/** Which gate produced this result. */
|
|
20
|
+
gate: 'prompt_injection' | 'unsafe_instructions' | 'provenance_integrity';
|
|
21
|
+
/** Overall pass/fail/warn verdict. */
|
|
22
|
+
verdict: 'pass' | 'fail' | 'warn';
|
|
23
|
+
/** Individual findings from the scan. */
|
|
24
|
+
findings: ValidationFinding[];
|
|
25
|
+
/** The candidate fields that were scanned. */
|
|
26
|
+
fields_scanned: string[];
|
|
27
|
+
}
|
|
28
|
+
/** A single finding from a validation gate. */
|
|
29
|
+
export interface ValidationFinding {
|
|
30
|
+
/** What was detected. */
|
|
31
|
+
pattern: string;
|
|
32
|
+
/** Which candidate field triggered the finding. */
|
|
33
|
+
field: string;
|
|
34
|
+
/** Human-readable description. */
|
|
35
|
+
description: string;
|
|
36
|
+
/**
|
|
37
|
+
* Severity: 'error' blocks promotion, 'warning' is advisory
|
|
38
|
+
* (unless trust_level=low).
|
|
39
|
+
*/
|
|
40
|
+
severity: 'error' | 'warning';
|
|
41
|
+
/** The matched text snippet (truncated to 100 chars for safety). */
|
|
42
|
+
match: string;
|
|
43
|
+
}
|
|
44
|
+
/** Result of running all validation gates against a candidate. */
|
|
45
|
+
export interface CandidateEvaluationResult {
|
|
46
|
+
/** Individual gate results. */
|
|
47
|
+
gate_results: ValidationGateResult[];
|
|
48
|
+
/** Aggregated verdict across all gates. */
|
|
49
|
+
overall_verdict: 'passed' | 'quarantined';
|
|
50
|
+
/** All findings from all gates combined. */
|
|
51
|
+
all_findings: ValidationFinding[];
|
|
52
|
+
/** Risk flags derived from findings (unique pattern names). */
|
|
53
|
+
risk_flags: string[];
|
|
54
|
+
}
|
|
55
|
+
/** Describes a single detection pattern used by the prompt-injection gate. */
|
|
56
|
+
export interface PromptInjectionPattern {
|
|
57
|
+
/** Regex to test against field text. */
|
|
58
|
+
pattern: RegExp;
|
|
59
|
+
/** Human-readable name for the pattern. */
|
|
60
|
+
name: string;
|
|
61
|
+
/** Description shown in findings. */
|
|
62
|
+
description: string;
|
|
63
|
+
/** Base severity before trust-level modulation. */
|
|
64
|
+
severity: 'error' | 'warning';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Static regex patterns for the prompt-injection gate (FR-004).
|
|
68
|
+
*
|
|
69
|
+
* ERROR-severity patterns always block promotion. WARNING-severity patterns
|
|
70
|
+
* are modulated by the candidate's trust level:
|
|
71
|
+
* - trust_level='low' → warnings promoted to errors
|
|
72
|
+
* - trust_level='medium'/'high' → warnings stay warnings
|
|
73
|
+
*/
|
|
74
|
+
export declare const PROMPT_INJECTION_PATTERNS: PromptInjectionPattern[];
|
|
75
|
+
/** Describes a single detection pattern used by the unsafe-instruction gate. */
|
|
76
|
+
export interface UnsafeInstructionPattern {
|
|
77
|
+
/** Regex to test against field text. */
|
|
78
|
+
pattern: RegExp;
|
|
79
|
+
/** Human-readable name for the pattern. */
|
|
80
|
+
name: string;
|
|
81
|
+
/** Description shown in findings. */
|
|
82
|
+
description: string;
|
|
83
|
+
/** Base severity before trust-level modulation. */
|
|
84
|
+
severity: 'error' | 'warning';
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Static regex patterns for the unsafe-instruction gate.
|
|
88
|
+
*
|
|
89
|
+
* Extends the DANGEROUS_COMMAND_PATTERNS and SECURITY_DEGRADING_PATTERNS from
|
|
90
|
+
* knowledge-validator.ts with additional destructive command, privilege
|
|
91
|
+
* escalation, shell execution, security bypass, and data exfiltration patterns.
|
|
92
|
+
*
|
|
93
|
+
* ERROR-severity patterns always block promotion. WARNING-severity patterns
|
|
94
|
+
* are modulated by the candidate's trust level:
|
|
95
|
+
* - trust_level='low' → warnings promoted to errors
|
|
96
|
+
* - trust_level='medium'/'high' → warnings stay warnings
|
|
97
|
+
*/
|
|
98
|
+
export declare const UNSAFE_INSTRUCTION_PATTERNS: UnsafeInstructionPattern[];
|
|
99
|
+
/** Rate limit defaults for validation operations (FR-007). */
|
|
100
|
+
export declare const VALIDATION_RATE_LIMITS: {
|
|
101
|
+
/** Maximum candidates per discovery invocation. */
|
|
102
|
+
readonly max_candidates_per_discovery: 50;
|
|
103
|
+
/** Maximum concurrent fetch operations. */
|
|
104
|
+
readonly max_concurrent_fetches: 5;
|
|
105
|
+
/** Timeout for individual fetch operations in milliseconds. */
|
|
106
|
+
readonly fetch_timeout_ms: 30000;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Scan an external skill candidate for prompt-injection patterns.
|
|
110
|
+
*
|
|
111
|
+
* Returns a `ValidationGateResult` with gate=`'prompt_injection'`.
|
|
112
|
+
* The verdict is modulated by `trustLevel`:
|
|
113
|
+
* - `'low'`: warnings promoted to errors → verdict is `'fail'` if any finding.
|
|
114
|
+
* - `'medium'`/`'high'`: warnings stay warnings → verdict is `'warn'` if only
|
|
115
|
+
* warnings, `'fail'` if any error-severity finding.
|
|
116
|
+
*/
|
|
117
|
+
export declare function scanPromptInjection(candidate: ExternalSkillCandidate, trustLevel?: 'low' | 'medium' | 'high'): ValidationGateResult;
|
|
118
|
+
/**
|
|
119
|
+
* Scan an external skill candidate for unsafe instruction patterns.
|
|
120
|
+
*
|
|
121
|
+
* Covers destructive commands, privilege escalation, shell execution
|
|
122
|
+
* vectors, security bypass instructions, and data exfiltration indicators.
|
|
123
|
+
*
|
|
124
|
+
* Returns a `ValidationGateResult` with gate=`'unsafe_instructions'`.
|
|
125
|
+
* The verdict is modulated by `trustLevel`:
|
|
126
|
+
* - `'low'`: warnings promoted to errors → verdict is `'fail'` if any finding.
|
|
127
|
+
* - `'medium'`/`'high'`: warnings stay warnings → verdict is `'warn'` if only
|
|
128
|
+
* warnings, `'fail'` if any error-severity finding.
|
|
129
|
+
*/
|
|
130
|
+
export declare function scanUnsafeInstructions(candidate: ExternalSkillCandidate, trustLevel?: 'low' | 'medium' | 'high'): ValidationGateResult;
|
|
131
|
+
/**
|
|
132
|
+
* Scan an external skill candidate for provenance field integrity.
|
|
133
|
+
*
|
|
134
|
+
* Validates SHA-256 hash format, fetched_at timing (not in future, not stale),
|
|
135
|
+
* source_url validity, publisher presence, and content-hash verification.
|
|
136
|
+
*
|
|
137
|
+
* Returns a `ValidationGateResult` with gate=`'provenance_integrity'`.
|
|
138
|
+
* The verdict is modulated by `trustLevel`:
|
|
139
|
+
* - `'low'`: warnings promoted to errors → verdict is `'fail'` if any finding.
|
|
140
|
+
* - `'medium'`/`'high'`: warnings stay warnings → verdict is `'warn'` if only
|
|
141
|
+
* warnings, `'fail'` if any error-severity finding.
|
|
142
|
+
*/
|
|
143
|
+
export declare function scanProvenanceIntegrity(candidate: ExternalSkillCandidate, trustLevel?: 'low' | 'medium' | 'high', ttlDays?: number): ValidationGateResult;
|
|
144
|
+
/**
|
|
145
|
+
* Run all three validation gates against a candidate and produce an
|
|
146
|
+
* aggregated evaluation result (FR-004, FR-007).
|
|
147
|
+
*
|
|
148
|
+
* Gates are run sequentially: prompt-injection → unsafe-instructions →
|
|
149
|
+
* provenance-integrity. Any gate that returns `'fail'` causes the overall
|
|
150
|
+
* verdict to be `'quarantined'`. Warnings are advisory unless trust_level
|
|
151
|
+
* is `'low'` (which promotes them to errors inside each gate).
|
|
152
|
+
*/
|
|
153
|
+
export declare function evaluateCandidate(candidate: ExternalSkillCandidate, options?: {
|
|
154
|
+
trust_level?: 'low' | 'medium' | 'high';
|
|
155
|
+
ttl_days?: number;
|
|
156
|
+
}): CandidateEvaluationResult;
|
|
157
|
+
export declare const _internals: {
|
|
158
|
+
getTimestamp: () => string;
|
|
159
|
+
computeSha256: (content: string) => string;
|
|
160
|
+
};
|
|
@@ -115,6 +115,16 @@ export declare const KnowledgeRecommendationSchema: z.ZodObject<{
|
|
|
115
115
|
evidence_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
116
116
|
}, z.core.$strip>;
|
|
117
117
|
export type KnowledgeRecommendation = z.infer<typeof KnowledgeRecommendationSchema>;
|
|
118
|
+
/**
|
|
119
|
+
* Provenance metadata for evidence: agent identity, session binding, and capture timestamp.
|
|
120
|
+
* Optional for backwards compatibility; when present and in gate mode, gates verify these fields.
|
|
121
|
+
*/
|
|
122
|
+
export declare const EvidenceProvenanceSchema: z.ZodObject<{
|
|
123
|
+
agent_name: z.ZodOptional<z.ZodString>;
|
|
124
|
+
session_id: z.ZodOptional<z.ZodString>;
|
|
125
|
+
captured_at: z.ZodOptional<z.ZodString>;
|
|
126
|
+
}, z.core.$strip>;
|
|
127
|
+
export type EvidenceProvenance = z.infer<typeof EvidenceProvenanceSchema>;
|
|
118
128
|
export declare const ArchitectureSupervisorReportSchema: z.ZodObject<{
|
|
119
129
|
schema_version: z.ZodLiteral<"1.0.0">;
|
|
120
130
|
phase: z.ZodNumber;
|
|
@@ -144,5 +154,10 @@ export declare const ArchitectureSupervisorReportSchema: z.ZodObject<{
|
|
|
144
154
|
evidence_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
145
155
|
}, z.core.$strip>>>;
|
|
146
156
|
created_at: z.ZodString;
|
|
157
|
+
provenance: z.ZodOptional<z.ZodObject<{
|
|
158
|
+
agent_name: z.ZodOptional<z.ZodString>;
|
|
159
|
+
session_id: z.ZodOptional<z.ZodString>;
|
|
160
|
+
captured_at: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strip>>;
|
|
147
162
|
}, z.core.$strip>;
|
|
148
163
|
export type ArchitectureSupervisorReport = z.infer<typeof ArchitectureSupervisorReportSchema>;
|
|
@@ -43,6 +43,11 @@ export interface RawSupervisorEntry {
|
|
|
43
43
|
verdict?: string;
|
|
44
44
|
findings?: unknown[];
|
|
45
45
|
knowledge_recommendations?: unknown[];
|
|
46
|
+
provenance?: {
|
|
47
|
+
agent_name?: string;
|
|
48
|
+
session_id?: string;
|
|
49
|
+
captured_at?: string;
|
|
50
|
+
};
|
|
46
51
|
}
|
|
47
52
|
/**
|
|
48
53
|
* Read the supervisor report sidecar raw (no zod), returning the supervisor entry or
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_delete — Delete an external skill candidate from the quarantine store.
|
|
3
|
+
*
|
|
4
|
+
* Removes a candidate by ID. If the candidate was previously promoted, the
|
|
5
|
+
* promoted skill in `.opencode/skills/generated/` is NOT affected — it must be
|
|
6
|
+
* separately retired or revoked. Returns a disabled message when
|
|
7
|
+
* external_skills.curation_enabled is false.
|
|
8
|
+
*
|
|
9
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
10
|
+
*/
|
|
11
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
12
|
+
import { createSwarmTool } from './create-tool.js';
|
|
13
|
+
export declare const _internals: {
|
|
14
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
15
|
+
};
|
|
16
|
+
export declare const external_skill_delete: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_discover — Discover external skill candidates from configured sources.
|
|
3
|
+
*
|
|
4
|
+
* Fetches skill content from URLs or accepts manual imports, validates them
|
|
5
|
+
* through the security gates (prompt-injection, unsafe-instructions,
|
|
6
|
+
* provenance-integrity), and stores them as quarantined candidates in the
|
|
7
|
+
* external skill store.
|
|
8
|
+
*
|
|
9
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
10
|
+
*/
|
|
11
|
+
import { createSwarmTool } from './create-tool.js';
|
|
12
|
+
export declare const _internals: {
|
|
13
|
+
fetchContent: (_url: string, _timeoutMs: number) => Promise<{
|
|
14
|
+
content: string;
|
|
15
|
+
finalUrl: string;
|
|
16
|
+
}>;
|
|
17
|
+
getTimestamp: () => string;
|
|
18
|
+
computeSha256: (content: string) => string;
|
|
19
|
+
uuid: () => string;
|
|
20
|
+
};
|
|
21
|
+
export declare const external_skill_discover: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_inspect — Inspect a specific external skill candidate by ID.
|
|
3
|
+
*
|
|
4
|
+
* Read-only tool that returns the full candidate record including provenance,
|
|
5
|
+
* skill_body, and evaluation_history. Returns a disabled message when
|
|
6
|
+
* external_skills.curation_enabled is false.
|
|
7
|
+
*
|
|
8
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
11
|
+
import { createSwarmTool } from './create-tool.js';
|
|
12
|
+
export declare const _internals: {
|
|
13
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
14
|
+
};
|
|
15
|
+
export declare const external_skill_inspect: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_list — List external skill candidates in the quarantine store.
|
|
3
|
+
*
|
|
4
|
+
* Read-only tool that returns candidate summaries filtered by evaluation verdict,
|
|
5
|
+
* source type, or date range. Returns a disabled message when
|
|
6
|
+
* external_skills.curation_enabled is false.
|
|
7
|
+
*
|
|
8
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
11
|
+
import { createSwarmTool } from './create-tool.js';
|
|
12
|
+
export declare const _internals: {
|
|
13
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
14
|
+
};
|
|
15
|
+
export declare const external_skill_list: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_promote — Promote a validated external skill candidate to an
|
|
3
|
+
* active generated skill.
|
|
4
|
+
*
|
|
5
|
+
* Re-runs all three validation gates (TOCTOU re-validation). Requires explicit
|
|
6
|
+
* user approval (`approver='user'`). Writes SKILL.md to
|
|
7
|
+
* `.opencode/skills/generated/<slug>/` with provenance frontmatter. Stamps the
|
|
8
|
+
* candidate as promoted and creates an audit record.
|
|
9
|
+
*
|
|
10
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
11
|
+
*/
|
|
12
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
13
|
+
import { createSwarmTool } from './create-tool.js';
|
|
14
|
+
export declare const _internals: {
|
|
15
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
16
|
+
getTimestamp: () => string;
|
|
17
|
+
fileExists: (filePath: string) => Promise<boolean>;
|
|
18
|
+
writeSkillFile: (filePath: string, content: string) => Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
export declare const external_skill_promote: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_reject — Reject an external skill candidate after evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Marks a candidate as rejected with a user-provided reason. Records the
|
|
5
|
+
* state transition in evaluation_history with timestamp, actor, and reason.
|
|
6
|
+
* Returns a disabled message when external_skills.curation_enabled is false.
|
|
7
|
+
*
|
|
8
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
11
|
+
import { createSwarmTool } from './create-tool.js';
|
|
12
|
+
export declare const _internals: {
|
|
13
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
14
|
+
};
|
|
15
|
+
export declare const external_skill_reject: ReturnType<typeof createSwarmTool>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* external_skill_revoke — Revoke a previously promoted external skill.
|
|
3
|
+
*
|
|
4
|
+
* Atomically retires the SKILL.md from `.opencode/skills/generated/<slug>/`
|
|
5
|
+
* and stamps the candidate with evaluation_verdict: 'revoked'. The candidate
|
|
6
|
+
* stays in quarantine for forensic audit.
|
|
7
|
+
*
|
|
8
|
+
* Uses an `_internals` DI seam for testability — no `mock.module` leakage.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExternalSkillsConfig } from '../config/schema.js';
|
|
11
|
+
import { createSwarmTool } from './create-tool.js';
|
|
12
|
+
export declare const _internals: {
|
|
13
|
+
loadConfig: (directory: string) => ExternalSkillsConfig | undefined;
|
|
14
|
+
getTimestamp: () => string;
|
|
15
|
+
retireSkillFile: (filePath: string) => Promise<boolean>;
|
|
16
|
+
};
|
|
17
|
+
export declare const external_skill_revoke: ReturnType<typeof createSwarmTool>;
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -18,6 +18,13 @@ export { diff_summary } from './diff-summary';
|
|
|
18
18
|
export { doc_extract, doc_scan } from './doc-scan';
|
|
19
19
|
export { detect_domains } from './domain-detector';
|
|
20
20
|
export { evidence_check } from './evidence-check';
|
|
21
|
+
export { external_skill_delete } from './external-skill-delete';
|
|
22
|
+
export { external_skill_discover } from './external-skill-discover';
|
|
23
|
+
export { external_skill_inspect } from './external-skill-inspect';
|
|
24
|
+
export { external_skill_list } from './external-skill-list';
|
|
25
|
+
export { external_skill_promote } from './external-skill-promote';
|
|
26
|
+
export { external_skill_reject } from './external-skill-reject';
|
|
27
|
+
export { external_skill_revoke } from './external-skill-revoke';
|
|
21
28
|
export { extract_code_blocks } from './file-extractor';
|
|
22
29
|
export { get_approved_plan } from './get-approved-plan';
|
|
23
30
|
export { get_qa_gate_profile } from './get-qa-gate-profile';
|
package/dist/tools/manifest.d.ts
CHANGED
|
@@ -108,4 +108,11 @@ export declare const TOOL_MANIFEST: {
|
|
|
108
108
|
lean_turbo_run_phase: () => ToolDefinition;
|
|
109
109
|
lean_turbo_status: () => ToolDefinition;
|
|
110
110
|
apply_patch: () => ToolDefinition;
|
|
111
|
+
external_skill_discover: () => ToolDefinition;
|
|
112
|
+
external_skill_list: () => ToolDefinition;
|
|
113
|
+
external_skill_inspect: () => ToolDefinition;
|
|
114
|
+
external_skill_promote: () => ToolDefinition;
|
|
115
|
+
external_skill_reject: () => ToolDefinition;
|
|
116
|
+
external_skill_delete: () => ToolDefinition;
|
|
117
|
+
external_skill_revoke: () => ToolDefinition;
|
|
111
118
|
};
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { ToolDefinition } from '@opencode-ai/plugin/tool';
|
|
12
12
|
import type { AgentDefinition } from '../agents/index.js';
|
|
13
|
+
import type { PluginConfig } from '../config/index.js';
|
|
13
14
|
/**
|
|
14
15
|
* Construct the plugin tool object: one handler per manifest entry, with
|
|
15
16
|
* `swarm_command` overridden by its dependency-injected instance.
|
|
@@ -17,5 +18,7 @@ import type { AgentDefinition } from '../agents/index.js';
|
|
|
17
18
|
* The manifest's `swarm_command` handler is the static (no-DI) form used only
|
|
18
19
|
* for derivation; the real instance needs the agent definition map, which is
|
|
19
20
|
* only available at plugin-init time.
|
|
21
|
+
*
|
|
22
|
+
* Knowledge tools are conditionally excluded when config.knowledge.enabled = false.
|
|
20
23
|
*/
|
|
21
|
-
export declare function buildPluginToolObject(agents: Record<string, AgentDefinition
|
|
24
|
+
export declare function buildPluginToolObject(agents: Record<string, AgentDefinition>, config?: PluginConfig): Record<string, ToolDefinition>;
|
|
@@ -37,5 +37,7 @@ export declare const ArgsSchema: z.ZodObject<{
|
|
|
37
37
|
durationMs: z.ZodNumber;
|
|
38
38
|
}, z.core.$strip>>;
|
|
39
39
|
working_directory: z.ZodOptional<z.ZodString>;
|
|
40
|
+
provenanceAgentName: z.ZodOptional<z.ZodString>;
|
|
41
|
+
provenanceSessionId: z.ZodOptional<z.ZodString>;
|
|
40
42
|
}, z.core.$strip>;
|
|
41
43
|
export declare const submit_phase_council_verdicts: ReturnType<typeof tool>;
|
|
@@ -363,6 +363,34 @@ export declare const TOOL_METADATA: {
|
|
|
363
363
|
description: string;
|
|
364
364
|
agents: "coder"[];
|
|
365
365
|
};
|
|
366
|
+
external_skill_discover: {
|
|
367
|
+
description: string;
|
|
368
|
+
agents: never[];
|
|
369
|
+
};
|
|
370
|
+
external_skill_list: {
|
|
371
|
+
description: string;
|
|
372
|
+
agents: never[];
|
|
373
|
+
};
|
|
374
|
+
external_skill_inspect: {
|
|
375
|
+
description: string;
|
|
376
|
+
agents: never[];
|
|
377
|
+
};
|
|
378
|
+
external_skill_promote: {
|
|
379
|
+
description: string;
|
|
380
|
+
agents: never[];
|
|
381
|
+
};
|
|
382
|
+
external_skill_reject: {
|
|
383
|
+
description: string;
|
|
384
|
+
agents: never[];
|
|
385
|
+
};
|
|
386
|
+
external_skill_delete: {
|
|
387
|
+
description: string;
|
|
388
|
+
agents: never[];
|
|
389
|
+
};
|
|
390
|
+
external_skill_revoke: {
|
|
391
|
+
description: string;
|
|
392
|
+
agents: never[];
|
|
393
|
+
};
|
|
366
394
|
};
|
|
367
395
|
/** Union type of all valid tool names (the metadata keys). */
|
|
368
396
|
export type ToolName = keyof typeof TOOL_METADATA;
|
|
@@ -16,6 +16,10 @@ export interface WriteDriftEvidenceArgs {
|
|
|
16
16
|
summary: string;
|
|
17
17
|
/** Requirement coverage report from req_coverage tool */
|
|
18
18
|
requirementCoverage?: string;
|
|
19
|
+
/** Agent name that produced this evidence (optional provenance) */
|
|
20
|
+
provenanceAgentName?: string;
|
|
21
|
+
/** Session ID of the agent that produced this evidence (optional provenance) */
|
|
22
|
+
provenanceSessionId?: string;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Execute the write_drift_evidence tool.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.65.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",
|