opencode-swarm 6.55.0 → 6.57.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/README.md CHANGED
@@ -689,8 +689,11 @@ Override default rules in `.opencode/opencode-swarm.json`:
689
689
  |-------|------|-------------|
690
690
  | `readOnly` | boolean | If `true`, agent cannot write anywhere |
691
691
  | `blockedExact` | string[] | Exact file paths that are blocked |
692
+ | `allowedExact` | string[] | Exact file paths that are allowed (overrides prefix/glob restrictions) |
692
693
  | `blockedPrefix` | string[] | Path prefixes that are blocked (e.g., `.swarm/`) |
693
694
  | `allowedPrefix` | string[] | Only these path prefixes are allowed. Omit to remove restriction; set `[]` to deny all |
695
+ | `blockedGlobs` | string[] | Glob patterns that are blocked (uses picomatch: `**`, `*`, `?`) |
696
+ | `allowedGlobs` | string[] | Glob patterns that are allowed (uses picomatch: `**`, `*`, `?`) |
694
697
  | `blockedZones` | string[] | File zones to block: `production`, `test`, `config`, `generated`, `docs`, `build` |
695
698
 
696
699
  ### Merge Behavior
@@ -726,6 +729,46 @@ To safely restrict a custom agent, always set `allowedPrefix` explicitly:
726
729
  }
727
730
  ```
728
731
 
732
+ ### Advanced Examples
733
+
734
+ #### Glob Pattern Support
735
+
736
+ Use glob patterns for complex path matching:
737
+
738
+ ```json
739
+ {
740
+ "authority": {
741
+ "rules": {
742
+ "coder": {
743
+ "allowedGlobs": ["src/**/*.ts", "tests/**/*.test.ts"],
744
+ "blockedGlobs": ["src/**/*.generated.ts", "**/*.d.ts"],
745
+ "allowedExact": ["src/index.ts", "package.json"]
746
+ },
747
+ "docs_agent": {
748
+ "allowedGlobs": ["docs/**/*.md", "*.md"],
749
+ "blockedExact": [".swarm/plan.md"]
750
+ }
751
+ }
752
+ }
753
+ }
754
+ ```
755
+
756
+ **Glob Pattern Features:**
757
+ - `**` — Match any number of directories: `src/**/*.ts` matches all TypeScript files in src/ and subdirectories
758
+ - `*` — Match any characters except path separators: `*.md` matches all Markdown files in current directory
759
+ - `?` — Match single character: `test?.js` matches `test1.js`, `testa.js`
760
+ - Uses [picomatch](https://github.com/micromatch/picomatch) for cross-platform compatibility
761
+
762
+ **Evaluation Order:**
763
+ 1. `readOnly` check (if true, deny all writes)
764
+ 2. `blockedExact` (exact path matches, highest priority)
765
+ 3. `blockedGlobs` (glob pattern matches)
766
+ 4. `allowedExact` (exact path matches, overrides prefix/glob restrictions)
767
+ 5. `allowedGlobs` (glob pattern matches)
768
+ 6. `allowedPrefix` (prefix matches)
769
+ 7. `blockedPrefix` (prefix matches)
770
+ 8. `blockedZones` (zone classification)
771
+
729
772
  </details>
730
773
 
731
774
  <details>
@@ -33,7 +33,7 @@ export declare function createAgents(config?: PluginConfig): AgentDefinition[];
33
33
  /**
34
34
  * Get agent configurations formatted for the OpenCode SDK.
35
35
  */
36
- export declare function getAgentConfigs(config?: PluginConfig): Record<string, SDKAgentConfig>;
36
+ export declare function getAgentConfigs(config?: PluginConfig, directory?: string, sessionId?: string): Record<string, SDKAgentConfig>;
37
37
  export { createArchitectAgent } from './architect';
38
38
  export { createCoderAgent } from './coder';
39
39
  export { createCriticAgent } from './critic';
package/dist/cli/index.js CHANGED
@@ -14587,6 +14587,9 @@ var init_plan_schema = __esm(() => {
14587
14587
  });
14588
14588
  });
14589
14589
 
14590
+ // src/telemetry.ts
14591
+ var init_telemetry = () => {};
14592
+
14590
14593
  // node_modules/graceful-fs/polyfills.js
14591
14594
  var require_polyfills = __commonJS((exports, module) => {
14592
14595
  var constants = __require("constants");
@@ -18114,9 +18117,9 @@ var TOOL_NAMES = [
18114
18117
  "doc_scan",
18115
18118
  "doc_extract",
18116
18119
  "curator_analyze",
18117
- "knowledgeAdd",
18118
- "knowledgeRecall",
18119
- "knowledgeRemove",
18120
+ "knowledge_add",
18121
+ "knowledge_recall",
18122
+ "knowledge_remove",
18120
18123
  "co_change_analyzer",
18121
18124
  "search",
18122
18125
  "batch_symbols",
@@ -18182,9 +18185,9 @@ var AGENT_TOOL_MAP = {
18182
18185
  "doc_scan",
18183
18186
  "doc_extract",
18184
18187
  "curator_analyze",
18185
- "knowledgeAdd",
18186
- "knowledgeRecall",
18187
- "knowledgeRemove",
18188
+ "knowledge_add",
18189
+ "knowledge_recall",
18190
+ "knowledge_remove",
18188
18191
  "co_change_analyzer",
18189
18192
  "suggest_patch"
18190
18193
  ],
@@ -18201,7 +18204,7 @@ var AGENT_TOOL_MAP = {
18201
18204
  "symbols",
18202
18205
  "todo_extract",
18203
18206
  "doc_scan",
18204
- "knowledgeRecall"
18207
+ "knowledge_recall"
18205
18208
  ],
18206
18209
  coder: [
18207
18210
  "diff",
@@ -18213,8 +18216,8 @@ var AGENT_TOOL_MAP = {
18213
18216
  "search",
18214
18217
  "build_check",
18215
18218
  "syntax_check",
18216
- "knowledgeAdd",
18217
- "knowledgeRecall"
18219
+ "knowledge_add",
18220
+ "knowledge_recall"
18218
18221
  ],
18219
18222
  test_engineer: [
18220
18223
  "test_runner",
@@ -18237,7 +18240,7 @@ var AGENT_TOOL_MAP = {
18237
18240
  "retrieve_summary",
18238
18241
  "schema_drift",
18239
18242
  "symbols",
18240
- "knowledgeRecall"
18243
+ "knowledge_recall"
18241
18244
  ],
18242
18245
  reviewer: [
18243
18246
  "diff",
@@ -18253,7 +18256,7 @@ var AGENT_TOOL_MAP = {
18253
18256
  "test_runner",
18254
18257
  "sast_scan",
18255
18258
  "placeholder_scan",
18256
- "knowledgeRecall",
18259
+ "knowledge_recall",
18257
18260
  "search",
18258
18261
  "batch_symbols",
18259
18262
  "suggest_patch"
@@ -18264,7 +18267,7 @@ var AGENT_TOOL_MAP = {
18264
18267
  "imports",
18265
18268
  "retrieve_summary",
18266
18269
  "symbols",
18267
- "knowledgeRecall"
18270
+ "knowledge_recall"
18268
18271
  ],
18269
18272
  critic_sounding_board: [
18270
18273
  "complexity_hotspots",
@@ -18272,7 +18275,7 @@ var AGENT_TOOL_MAP = {
18272
18275
  "imports",
18273
18276
  "retrieve_summary",
18274
18277
  "symbols",
18275
- "knowledgeRecall"
18278
+ "knowledge_recall"
18276
18279
  ],
18277
18280
  critic_drift_verifier: [
18278
18281
  "complexity_hotspots",
@@ -18280,7 +18283,7 @@ var AGENT_TOOL_MAP = {
18280
18283
  "imports",
18281
18284
  "retrieve_summary",
18282
18285
  "symbols",
18283
- "knowledgeRecall"
18286
+ "knowledge_recall"
18284
18287
  ],
18285
18288
  critic_oversight: [
18286
18289
  "complexity_hotspots",
@@ -18288,7 +18291,7 @@ var AGENT_TOOL_MAP = {
18288
18291
  "imports",
18289
18292
  "retrieve_summary",
18290
18293
  "symbols",
18291
- "knowledgeRecall"
18294
+ "knowledge_recall"
18292
18295
  ],
18293
18296
  docs: [
18294
18297
  "detect_domains",
@@ -18299,16 +18302,16 @@ var AGENT_TOOL_MAP = {
18299
18302
  "schema_drift",
18300
18303
  "symbols",
18301
18304
  "todo_extract",
18302
- "knowledgeRecall"
18305
+ "knowledge_recall"
18303
18306
  ],
18304
18307
  designer: [
18305
18308
  "extract_code_blocks",
18306
18309
  "retrieve_summary",
18307
18310
  "symbols",
18308
- "knowledgeRecall"
18311
+ "knowledge_recall"
18309
18312
  ],
18310
- curator_init: ["knowledgeRecall"],
18311
- curator_phase: ["knowledgeRecall"]
18313
+ curator_init: ["knowledge_recall"],
18314
+ curator_phase: ["knowledge_recall"]
18312
18315
  };
18313
18316
  for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
18314
18317
  const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
@@ -18727,6 +18730,7 @@ var KnowledgeConfigSchema = exports_external.object({
18727
18730
  auto_promote_days: exports_external.number().min(1).max(3650).default(90),
18728
18731
  max_inject_count: exports_external.number().min(0).max(50).default(5),
18729
18732
  inject_char_budget: exports_external.number().min(200).max(1e4).default(2000),
18733
+ context_budget_threshold: exports_external.number().int().positive().optional(),
18730
18734
  max_lesson_display_chars: exports_external.number().min(40).max(280).default(120),
18731
18735
  dedup_threshold: exports_external.number().min(0).max(1).default(0.6),
18732
18736
  scope_filter: exports_external.array(exports_external.string()).default(["global"]),
@@ -18779,9 +18783,12 @@ var CompactionConfigSchema = exports_external.object({
18779
18783
  var AgentAuthorityRuleSchema = exports_external.object({
18780
18784
  readOnly: exports_external.boolean().optional(),
18781
18785
  blockedExact: exports_external.array(exports_external.string()).optional(),
18786
+ allowedExact: exports_external.array(exports_external.string()).optional(),
18782
18787
  blockedPrefix: exports_external.array(exports_external.string()).optional(),
18783
18788
  allowedPrefix: exports_external.array(exports_external.string()).optional(),
18784
- blockedZones: exports_external.array(exports_external.enum(["production", "test", "config", "generated", "docs", "build"])).optional()
18789
+ blockedZones: exports_external.array(exports_external.enum(["production", "test", "config", "generated", "docs", "build"])).optional(),
18790
+ blockedGlobs: exports_external.array(exports_external.string()).optional(),
18791
+ allowedGlobs: exports_external.array(exports_external.string()).optional()
18785
18792
  });
18786
18793
  var AuthorityConfigSchema = exports_external.object({
18787
18794
  enabled: exports_external.boolean().default(true),
@@ -19035,6 +19042,7 @@ init_manager();
19035
19042
 
19036
19043
  // src/state.ts
19037
19044
  init_plan_schema();
19045
+ init_telemetry();
19038
19046
  var swarmState = {
19039
19047
  activeToolCalls: new Map,
19040
19048
  toolAggregates: new Map,
@@ -19047,7 +19055,8 @@ var swarmState = {
19047
19055
  lastBudgetPct: 0,
19048
19056
  agentSessions: new Map,
19049
19057
  pendingRehydrations: new Set,
19050
- fullAutoEnabledInConfig: false
19058
+ fullAutoEnabledInConfig: false,
19059
+ environmentProfiles: new Map
19051
19060
  };
19052
19061
  function getAgentSession(sessionId) {
19053
19062
  return swarmState.agentSessions.get(sessionId);
@@ -31717,6 +31726,16 @@ tool.schema = exports_external2;
31717
31726
  init_evidence_schema();
31718
31727
  init_plan_schema();
31719
31728
  // src/tools/create-tool.ts
31729
+ function classifyToolError(error93) {
31730
+ const msg = (error93 instanceof Error ? error93.message : String(error93)).toLowerCase();
31731
+ if (msg.includes("not registered") || msg.includes("unknown tool"))
31732
+ return "not_registered";
31733
+ if (msg.includes("not whitelisted") || msg.includes("not allowed"))
31734
+ return "not_whitelisted";
31735
+ if (msg.includes("enoent") || msg.includes("command not found") || msg.includes("binary not found") || msg.includes("no such file or directory"))
31736
+ return "binary_missing";
31737
+ return "execution_error";
31738
+ }
31720
31739
  function createSwarmTool(opts) {
31721
31740
  return tool({
31722
31741
  description: opts.description,
@@ -31729,6 +31748,7 @@ function createSwarmTool(opts) {
31729
31748
  const message = error93 instanceof Error ? error93.message : String(error93);
31730
31749
  return JSON.stringify({
31731
31750
  success: false,
31751
+ failure_class: classifyToolError(error93),
31732
31752
  message: "Tool execution failed",
31733
31753
  errors: [message]
31734
31754
  }, null, 2);
@@ -35028,6 +35048,30 @@ async function getDiagnoseData(directory) {
35028
35048
  checks5.push(await checkEventStreamIntegrity(directory));
35029
35049
  checks5.push(await checkSteeringDirectives(directory));
35030
35050
  checks5.push(await checkCurator(directory));
35051
+ try {
35052
+ const evidenceDir = path15.join(directory, ".swarm", "evidence");
35053
+ const snapshotFiles = existsSync6(evidenceDir) ? readdirSync2(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
35054
+ if (snapshotFiles.length > 0) {
35055
+ const latest = snapshotFiles.sort().pop();
35056
+ checks5.push({
35057
+ name: "Agent Tool Snapshots",
35058
+ status: "\u2705",
35059
+ detail: `${snapshotFiles.length} snapshot(s) found \u2014 latest: ${latest}`
35060
+ });
35061
+ } else {
35062
+ checks5.push({
35063
+ name: "Agent Tool Snapshots",
35064
+ status: "\u2705",
35065
+ detail: "No snapshots yet (snapshots written on next session start)"
35066
+ });
35067
+ }
35068
+ } catch {
35069
+ checks5.push({
35070
+ name: "Agent Tool Snapshots",
35071
+ status: "\u2705",
35072
+ detail: "No snapshots yet (snapshots written on next session start)"
35073
+ });
35074
+ }
35031
35075
  const passCount = checks5.filter((c) => c.status === "\u2705").length;
35032
35076
  const totalCount = checks5.length;
35033
35077
  const allPassed = passCount === totalCount;
@@ -416,6 +416,7 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
416
416
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
417
417
  max_inject_count: z.ZodDefault<z.ZodNumber>;
418
418
  inject_char_budget: z.ZodDefault<z.ZodNumber>;
419
+ context_budget_threshold: z.ZodOptional<z.ZodNumber>;
419
420
  max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
420
421
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
421
422
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -473,6 +474,7 @@ export type CompactionConfig = z.infer<typeof CompactionConfigSchema>;
473
474
  export declare const AgentAuthorityRuleSchema: z.ZodObject<{
474
475
  readOnly: z.ZodOptional<z.ZodBoolean>;
475
476
  blockedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
477
+ allowedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
476
478
  blockedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
477
479
  allowedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
478
480
  blockedZones: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -483,6 +485,8 @@ export declare const AgentAuthorityRuleSchema: z.ZodObject<{
483
485
  generated: "generated";
484
486
  build: "build";
485
487
  }>>>;
488
+ blockedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
489
+ allowedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
486
490
  }, z.core.$strip>;
487
491
  export type AgentAuthorityRule = z.infer<typeof AgentAuthorityRuleSchema>;
488
492
  export declare const AuthorityConfigSchema: z.ZodObject<{
@@ -490,6 +494,7 @@ export declare const AuthorityConfigSchema: z.ZodObject<{
490
494
  rules: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
491
495
  readOnly: z.ZodOptional<z.ZodBoolean>;
492
496
  blockedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
497
+ allowedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
493
498
  blockedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
494
499
  allowedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
495
500
  blockedZones: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -500,6 +505,8 @@ export declare const AuthorityConfigSchema: z.ZodObject<{
500
505
  generated: "generated";
501
506
  build: "build";
502
507
  }>>>;
508
+ blockedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
509
+ allowedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
503
510
  }, z.core.$strip>>>;
504
511
  }, z.core.$strip>;
505
512
  export type AuthorityConfig = z.infer<typeof AuthorityConfigSchema>;
@@ -667,6 +674,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
667
674
  rules: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
668
675
  readOnly: z.ZodOptional<z.ZodBoolean>;
669
676
  blockedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
677
+ allowedExact: z.ZodOptional<z.ZodArray<z.ZodString>>;
670
678
  blockedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
671
679
  allowedPrefix: z.ZodOptional<z.ZodArray<z.ZodString>>;
672
680
  blockedZones: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -677,6 +685,8 @@ export declare const PluginConfigSchema: z.ZodObject<{
677
685
  generated: "generated";
678
686
  build: "build";
679
687
  }>>>;
688
+ blockedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
689
+ allowedGlobs: z.ZodOptional<z.ZodArray<z.ZodString>>;
680
690
  }, z.core.$strip>>>;
681
691
  }, z.core.$strip>>;
682
692
  plan_cursor: z.ZodOptional<z.ZodObject<{
@@ -781,6 +791,7 @@ export declare const PluginConfigSchema: z.ZodObject<{
781
791
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
782
792
  max_inject_count: z.ZodDefault<z.ZodNumber>;
783
793
  inject_char_budget: z.ZodDefault<z.ZodNumber>;
794
+ context_budget_threshold: z.ZodOptional<z.ZodNumber>;
784
795
  max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
785
796
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
786
797
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -0,0 +1,3 @@
1
+ export type { CommandPolicy, EnvironmentProfile, ExecutionMode, HostOS, OperatingMode, ShellFamily, } from './profile.js';
2
+ export { deriveCommandPolicy, detectEnvironmentProfile } from './profile.js';
3
+ export { renderEnvironmentPrompt } from './prompt-renderer.js';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Session-level execution environment profiling for opencode-swarm.
3
+ * Computed once per session; never re-detected within a session.
4
+ */
5
+ export type HostOS = 'windows' | 'linux' | 'macos' | 'unknown';
6
+ export type ShellFamily = 'powershell' | 'cmd' | 'bash' | 'zsh' | 'sh' | 'unknown';
7
+ export type ExecutionMode = 'native' | 'docker' | 'wsl' | 'unknown';
8
+ export type OperatingMode = 'linux' | 'macos-native' | 'windows-native' | 'unknown';
9
+ export interface EnvironmentProfile {
10
+ hostOS: HostOS;
11
+ shellFamily: ShellFamily;
12
+ executionMode: ExecutionMode;
13
+ operatingMode: OperatingMode;
14
+ isWindowsNative: boolean;
15
+ isWindowsDocker: boolean;
16
+ isWSL: boolean;
17
+ pathStyle: 'windows' | 'posix';
18
+ shellCommandPreference: 'powershell-native' | 'posix-native';
19
+ evidence: {
20
+ processPlatform: string;
21
+ comspec?: string;
22
+ psModulePath?: string;
23
+ termProgram?: string;
24
+ shell?: string;
25
+ wslDistroName?: string;
26
+ containerMarkers: string[];
27
+ };
28
+ }
29
+ export interface CommandPolicy {
30
+ preferredShell: ShellFamily;
31
+ avoidPosixExamples: boolean;
32
+ preferNodeApis: boolean;
33
+ preferToolingOverShell: boolean;
34
+ pathExampleStyle: 'windows' | 'posix';
35
+ examples: {
36
+ listDir: string;
37
+ removeFile: string;
38
+ setEnv: string;
39
+ printEnv: string;
40
+ searchText: string;
41
+ };
42
+ }
43
+ /**
44
+ * Detect the current execution environment. Call once per session.
45
+ */
46
+ export declare function detectEnvironmentProfile(): EnvironmentProfile;
47
+ /**
48
+ * Derive a CommandPolicy from a detected EnvironmentProfile.
49
+ */
50
+ export declare function deriveCommandPolicy(profile: EnvironmentProfile): CommandPolicy;
@@ -0,0 +1,6 @@
1
+ import type { EnvironmentProfile } from './profile.js';
2
+ /**
3
+ * Renders a concise runtime environment block for agent prompts.
4
+ * Audience: 'coder' or 'testengineer'
5
+ */
6
+ export declare function renderEnvironmentPrompt(profile: EnvironmentProfile, audience: 'coder' | 'testengineer'): string;
@@ -106,9 +106,12 @@ export declare function validateAndRecordAttestation(dir: string, findingId: str
106
106
  type AgentRule = {
107
107
  readOnly?: boolean;
108
108
  blockedExact?: string[];
109
+ allowedExact?: string[];
109
110
  blockedPrefix?: string[];
110
111
  allowedPrefix?: string[];
111
112
  blockedZones?: FileZone[];
113
+ blockedGlobs?: string[];
114
+ allowedGlobs?: string[];
112
115
  };
113
116
  export declare const DEFAULT_AGENT_AUTHORITY_RULES: Record<string, AgentRule>;
114
117
  /**
@@ -67,6 +67,8 @@ export interface KnowledgeConfig {
67
67
  max_inject_count: number;
68
68
  /** Maximum total chars for the entire injection block. Default: 2000 */
69
69
  inject_char_budget?: number;
70
+ /** Minimum headroom chars required before knowledge injection activates. Default: 300 */
71
+ context_budget_threshold?: number;
70
72
  /** Maximum display chars per lesson at injection time. Default: 120 */
71
73
  max_lesson_display_chars?: number;
72
74
  /** Jaccard bigram similarity threshold for deduplication. Default: 0.6 */