opencode-swarm 7.164.12 → 7.164.13

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 (97) hide show
  1. package/.opencode/skills/loop/SKILL.md +1 -1
  2. package/.opencode/skills/{plan → swarm-plan}/SKILL.md +1 -1
  3. package/dist/cli/{coder-settlement-yh1q5fr3.js → coder-settlement-em2fgg4p.js} +11 -11
  4. package/dist/cli/{config-doctor-bd4yzmh7.js → config-doctor-1m4mrybp.js} +3 -3
  5. package/dist/cli/{core-y0s1vmyc.js → core-zbzdffha.js} +2 -2
  6. package/dist/cli/{curation-policy-gs1qakn7.js → curation-policy-bqpmry2n.js} +5 -5
  7. package/dist/cli/{curator-drift-1sg9yk2m.js → curator-drift-hbc3w5zj.js} +4 -4
  8. package/dist/cli/curator-llm-factory-j76c96t7.js +70 -0
  9. package/dist/cli/{curator-brqack0j.js → curator-tn3x5j02.js} +36 -36
  10. package/dist/cli/{evidence-summary-service-nqbcvp30.js → evidence-summary-service-7cn9z4sn.js} +16 -16
  11. package/dist/cli/{gate-evidence-9stdtpej.js → gate-evidence-deyzt3hz.js} +7 -7
  12. package/dist/cli/guardrail-explain-4k2pqj46.js +71 -0
  13. package/dist/cli/{guardrail-log-sf39x00b.js → guardrail-log-cnbv6vry.js} +8 -8
  14. package/dist/cli/{guardrail-reset-9wr6a60s.js → guardrail-reset-xhh61cax.js} +36 -36
  15. package/dist/cli/{hive-promoter-bqtj8261.js → hive-promoter-1m8zpz4d.js} +36 -36
  16. package/dist/cli/{index-vw66q1rw.js → index-0mwjamha.js} +1 -1
  17. package/dist/cli/{index-d7j3n5ra.js → index-3c0z1jnc.js} +41 -39
  18. package/dist/cli/{index-wasdrhev.js → index-4fhcbe14.js} +4 -4
  19. package/dist/cli/{index-r2p0pgst.js → index-5ebgzb5a.js} +3 -3
  20. package/dist/cli/{index-ebce775n.js → index-5h60rtaa.js} +2 -2
  21. package/dist/cli/{index-yvqg6kn5.js → index-6m24v15v.js} +2 -2
  22. package/dist/cli/{index-sphahrmq.js → index-6rx1rdaq.js} +1 -1
  23. package/dist/cli/{index-ad9064j9.js → index-74514zkh.js} +4 -4
  24. package/dist/cli/{index-hb7bh4r2.js → index-7f2r3ysr.js} +30 -6
  25. package/dist/cli/{index-hg09xemc.js → index-7z9zqxqt.js} +4 -4
  26. package/dist/cli/{index-xxfk62zd.js → index-8bdk7124.js} +2 -2
  27. package/dist/cli/{index-50j914b5.js → index-a0d4fp6r.js} +29 -7
  28. package/dist/cli/{index-4mjmnysc.js → index-ajknebrc.js} +1 -1
  29. package/dist/cli/{index-qqq04n70.js → index-anxs69ad.js} +1 -1
  30. package/dist/cli/{index-cgewrpw5.js → index-asey3tb3.js} +4 -3
  31. package/dist/cli/{index-03enxdaq.js → index-bvkd7at6.js} +1 -1
  32. package/dist/cli/{index-5wc5pbzc.js → index-c98rjgjq.js} +682 -349
  33. package/dist/cli/{index-qgajv9rd.js → index-d224mhr9.js} +3 -3
  34. package/dist/cli/{index-ztm0q26v.js → index-dh5th4jn.js} +1 -1
  35. package/dist/cli/{index-c45662wc.js → index-e45htt92.js} +1 -1
  36. package/dist/cli/{index-hvz4ad2t.js → index-f36hy1x4.js} +1 -1
  37. package/dist/cli/{index-m8xrbdmn.js → index-f8jdar6q.js} +2 -2
  38. package/dist/cli/{index-r69gzes2.js → index-fnyw5rzg.js} +7 -7
  39. package/dist/cli/{index-kxv193aq.js → index-g11h1qpk.js} +5 -5
  40. package/dist/cli/{index-40twgsyh.js → index-g9weyhq6.js} +2 -2
  41. package/dist/cli/{index-888pq4xx.js → index-grn6tkbt.js} +7 -7
  42. package/dist/cli/{index-ewv8qa8q.js → index-gy0nyfbw.js} +2 -2
  43. package/dist/cli/{index-8vw2pjgr.js → index-hhzzyjm3.js} +6 -6
  44. package/dist/cli/{index-eed0gkv6.js → index-j2svfhzk.js} +2 -2
  45. package/dist/cli/{index-2bhz5k91.js → index-jre6tm3v.js} +2 -2
  46. package/dist/cli/{index-k0s8n6m5.js → index-mpf1tvwf.js} +11 -11
  47. package/dist/cli/{index-4vb56w2k.js → index-ndjjvxzz.js} +4 -4
  48. package/dist/cli/{index-d3mpxsmy.js → index-ptsqnxwd.js} +7 -7
  49. package/dist/cli/{index-0byep4pe.js → index-qtxevgdx.js} +8 -8
  50. package/dist/cli/{index-wknpkfm8.js → index-s3k7xbqd.js} +7 -7
  51. package/dist/cli/{index-x39hjdf1.js → index-tqw8w2n5.js} +1 -1
  52. package/dist/cli/{index-es64amqt.js → index-w6988bbc.js} +1 -1
  53. package/dist/cli/{index-mee9maf5.js → index-xwbn7c8m.js} +2 -2
  54. package/dist/cli/{index-3fnym6ac.js → index-y5hfk7ya.js} +4 -4
  55. package/dist/cli/{index-b25t91a3.js → index-zb6gdym8.js} +2 -2
  56. package/dist/cli/index.js +146 -67
  57. package/dist/cli/{knowledge-escalator-01vva51d.js → knowledge-escalator-3fax9y3s.js} +13 -13
  58. package/dist/cli/{knowledge-events-dpfwh1hs.js → knowledge-events-9cpdyhmb.js} +11 -11
  59. package/dist/cli/{knowledge-link-2rvp966j.js → knowledge-link-dgvbqjqg.js} +4 -4
  60. package/dist/cli/{knowledge-store-aw58ae7b.js → knowledge-store-y35rka0p.js} +5 -5
  61. package/dist/cli/{knowledge-validator-yhd31ryf.js → knowledge-validator-fd761gpx.js} +7 -7
  62. package/dist/cli/{model-preflight-288nsgpw.js → model-preflight-3s1c0zpc.js} +1 -1
  63. package/dist/cli/{pending-delegations-fjetcz8e.js → pending-delegations-t3y19j3n.js} +11 -11
  64. package/dist/cli/{pr-subscriptions-cwwtfs8w.js → pr-subscriptions-00zp69mt.js} +11 -11
  65. package/dist/cli/{pr-workflow-gate-5xwtg1k2.js → pr-workflow-gate-2h0j8c92.js} +36 -36
  66. package/dist/cli/{runner-mb51twxt.js → runner-0e3bjeev.js} +5 -5
  67. package/dist/cli/{scan-cursor-j11qwf0v.js → scan-cursor-wppe2gxw.js} +6 -6
  68. package/dist/cli/{schema-0xp3bde3.js → schema-sec49ppy.js} +2 -2
  69. package/dist/cli/{scope-persistence-brrk806y.js → scope-persistence-59eyqaz4.js} +15 -15
  70. package/dist/cli/{skill-generator-j8qzmet9.js → skill-generator-56rbmpj7.js} +15 -15
  71. package/dist/cli/{snapshot-coordination-init-h0xmtftq.js → snapshot-coordination-init-dnkdc7gx.js} +36 -36
  72. package/dist/cli/{telemetry-m84ap0pp.js → telemetry-a1yvjerj.js} +1 -1
  73. package/dist/cli/{worktree-collision-ownership-j9zykj18.js → worktree-collision-ownership-fj9n4mhk.js} +12 -12
  74. package/dist/cli/{worktree-isolation-jd39xz6h.js → worktree-isolation-vd1s86ya.js} +36 -36
  75. package/dist/commands/benchmark.d.ts +5 -1
  76. package/dist/commands/registry.d.ts +34 -43
  77. package/dist/commands/turbo.d.ts +1 -1
  78. package/dist/config/bundled-skills.d.ts +4 -3
  79. package/dist/config/constants.d.ts +13 -0
  80. package/dist/hooks/extractors.d.ts +9 -0
  81. package/dist/hooks/non-architect-advisory.d.ts +18 -0
  82. package/dist/hooks/repo-graph-injection.d.ts +16 -0
  83. package/dist/index.js +73 -71
  84. package/dist/services/decision-drift-analyzer.d.ts +7 -0
  85. package/dist/services/handoff-service.d.ts +10 -0
  86. package/dist/services/status-service.d.ts +27 -0
  87. package/dist/state.d.ts +8 -0
  88. package/dist/tools/repo-graph/builder.d.ts +1 -25
  89. package/dist/tools/repo-graph/cache.d.ts +5 -1
  90. package/dist/tools/repo-graph/fallback-scanner.d.ts +71 -0
  91. package/dist/tools/repo-graph/indexed-storage.d.ts +11 -0
  92. package/dist/tools/repo-graph/storage.d.ts +7 -0
  93. package/dist/utils/context-decisions.d.ts +77 -0
  94. package/dist/utils/sanitize-display.d.ts +7 -0
  95. package/package.json +3 -2
  96. package/dist/cli/curator-llm-factory-dtsjc3zf.js +0 -70
  97. package/dist/cli/guardrail-explain-3ff1z3fm.js +0 -71
@@ -78,6 +78,13 @@ export interface DriftAnalyzerConfig {
78
78
  export declare const DEFAULT_DRIFT_CONFIG: DriftAnalyzerConfig;
79
79
  /**
80
80
  * Extract decisions from context.md content
81
+ *
82
+ * #2493 W9a: the section scan itself now lives in the shared extractor
83
+ * (`src/utils/context-decisions.ts`) so all four historical consumers of
84
+ * the `## Decisions` section agree on boundaries. This delegate preserves
85
+ * this module's public shape exactly — `ContextDecision` is a structural
86
+ * superset of `Decision` (it additionally carries the raw source line), so
87
+ * the mapping is the identity.
81
88
  */
82
89
  export declare function extractDecisionsFromContext(contextContent: string): Decision[];
83
90
  /**
@@ -98,6 +98,16 @@ declare function parseSessionState(content: string | null): {
98
98
  } | null;
99
99
  /**
100
100
  * Extract decisions from context.md content
101
+ *
102
+ * #2493 W9a: derives from the shared section extractor
103
+ * (`src/utils/context-decisions.ts`) instead of a private line-scan.
104
+ * Mapping preserves this consumer's historical output exactly:
105
+ * - cleaned text: bracket groups (timestamps, [confirmed]) and the ✅
106
+ * marker removed (the shared `text` already strips bracket groups, so
107
+ * only ✅ removal remains here);
108
+ * - empty results dropped;
109
+ * - RTL-sanitized and truncated to MAX_DECISION_LENGTH;
110
+ * - LAST 5 decisions kept.
101
111
  */
102
112
  declare function extractDecisions(content: string | null): string[];
103
113
  /**
@@ -17,6 +17,7 @@ export declare const _internals: {
17
17
  getActiveFullAutoSessionID: typeof getActiveFullAutoSessionID;
18
18
  loadFullAutoRunState: typeof loadFullAutoRunState;
19
19
  summarizeTelemetryCosts: typeof summarizeTelemetryCosts;
20
+ renderNoActivePlanStatusTail: typeof renderNoActivePlanStatusTail;
20
21
  };
21
22
  /**
22
23
  * Structured status data returned by the status service.
@@ -102,6 +103,22 @@ export interface StatusData {
102
103
  specStaleStoredHash?: string;
103
104
  /** Current spec.md hash on disk (null when spec.md is missing) */
104
105
  specStaleCurrentHash?: string | null;
106
+ /**
107
+ * #2493 W9b: decision-drift visibility. Counts derived from running the
108
+ * same analyzer the architect context injection uses
109
+ * (`analyzeDecisionDrift`) over `.swarm/context.md`. `undefined` when
110
+ * detection is disabled (`automation.capabilities.decision_drift_detection:
111
+ * false`), when there is no drift, or when the analysis fails (fail-open —
112
+ * a status command must never fail because an optional signal hiccupped).
113
+ */
114
+ decisionDrift?: {
115
+ /** Number of stale-decision signals */
116
+ staleCount: number;
117
+ /** Number of contradictory-decision signals */
118
+ contradictionCount: number;
119
+ /** Timestamp of the most recent timestamped decision, when any exist */
120
+ lastDecisionAt?: string;
121
+ };
105
122
  /** Directives auto-escalated in the last 7 days (Change 3). */
106
123
  recentEscalations?: RecentEscalation[];
107
124
  /** #1234 Part 3: pending skill/motif proposals in .swarm/skills/proposals/ */
@@ -262,6 +279,15 @@ export declare function getStatusData(directory: string, agents: Record<string,
262
279
  * This is the thin adapter that delegates to the service.
263
280
  */
264
281
  export declare function formatStatusMarkdown(status: StatusData): string;
282
+ /**
283
+ * No-active-plan status tail (#853 Layer C, #2493 W9b, #2034/#1659): spec
284
+ * drift, decision drift, and delegation-ledger health must COMPOSE — none of
285
+ * the three signals may suppress another. Extracted from
286
+ * handleStatusCommand so the composition is directly unit-testable
287
+ * (#2493 review: the old inline decision-drift early-return silently
288
+ * suppressed the ledger-health block when both signals coexisted).
289
+ */
290
+ declare function renderNoActivePlanStatusTail(statusData: StatusData): string;
265
291
  /**
266
292
  * Handle status command - delegates to service and formats output.
267
293
  * Kept for backward compatibility - thin adapter.
@@ -269,3 +295,4 @@ export declare function formatStatusMarkdown(status: StatusData): string;
269
295
  export declare function handleStatusCommand(directory: string, agents: Record<string, AgentDefinition>, sessionId?: string, options?: {
270
296
  backgroundSubagents?: boolean;
271
297
  }): Promise<string>;
298
+ export {};
package/dist/state.d.ts CHANGED
@@ -568,6 +568,14 @@ export interface AgentSessionState {
568
568
  resumeModelAdvisoryDone?: boolean;
569
569
  /** One-shot guard: the config-vs-UI model advisory has fired for this session (#1896). */
570
570
  configModelAdvisoryDone?: boolean;
571
+ /**
572
+ * One-shot guard: the first-run non-architect advisory has fired for this
573
+ * session (#2493 K3 UX-3). Keyed by sessionID only — "session starts on a
574
+ * non-architect agent" is operationalized as the first user message
575
+ * arriving on a non-architect agent (the OpenCode plugin v1 shape has no
576
+ * session-start hook).
577
+ */
578
+ nonArchitectAdvisoryDone?: boolean;
571
579
  }
572
580
  export type NonTransientErrorCategory = 'shell_parse_error' | 'command_not_found' | 'sandbox_wrapper_failure' | 'general_permanent';
573
581
  export interface NonTransientCircuitState {
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { extractFileSymbols } from '../../lang/symbol-graph';
14
14
  import { extractDartSymbols, extractGoSymbols, extractPhpSymbols, extractPythonSymbols, extractRubySymbols, extractRustSymbols, extractTSSymbols } from '../symbols';
15
+ import { type ImportBinding, type ParsedImport } from './fallback-scanner';
15
16
  import { extractFileOntology } from './ontology';
16
17
  import { safeRealpathSync } from './safe-realpath';
17
18
  import type { BuildWorkspaceGraphOptions, GraphEdge, GraphExtractorInputWitness, GraphNode, RepoGraph, RepoGraphDiagnostics, SymbolEdge } from './types';
@@ -96,31 +97,6 @@ export declare function addEdge(graph: RepoGraph, edge: GraphEdge): void;
96
97
  * @returns Resolved absolute path or null if unresolvable
97
98
  */
98
99
  export declare function resolveModuleSpecifier(workspaceRoot: string, sourceFile: string, specifier: string): string | null;
99
- /**
100
- * A parsed import with its specifier and type.
101
- */
102
- /**
103
- * A single imported binding: the symbol's *exported* name in the target file
104
- * and the *local* name it is bound to in the importing file (differs when an
105
- * `as` alias or default import is used). Used to attribute call-site usage back
106
- * to the correct exported symbol.
107
- */
108
- interface ImportBinding {
109
- imported: string;
110
- local: string;
111
- }
112
- interface ParsedImport {
113
- /** The module specifier (e.g., './foo', 'lodash') */
114
- specifier: string;
115
- /** The type of import */
116
- importType: 'default' | 'named' | 'namespace' | 'require' | 'sideeffect' | 'type';
117
- /** Named imported symbols when statically detectable */
118
- importedSymbols: string[];
119
- /** Alias-aware imported→local bindings for usage attribution */
120
- bindings: ImportBinding[];
121
- /** True for `export { x } from '...'` re-exports (symbols are re-exposed). */
122
- reExport: boolean;
123
- }
124
100
  /**
125
101
  * Strip line (`//…`) and block (`/* … *\/`) comments from JS/TS source while
126
102
  * preserving string, template-literal, and regex-literal contents (DD-C010).
@@ -13,7 +13,7 @@ export declare function getCachedGraph(workspace: string): RepoGraph | undefined
13
13
  * Cache a graph and mark it clean. Omitting mtime clears any previous mtime so
14
14
  * an old optimistic-concurrency witness cannot survive a new graph value.
15
15
  */
16
- export declare function setCachedGraph(workspace: string, graph: RepoGraph, mtime?: number): void;
16
+ export declare function setCachedGraph(workspace: string, graph: RepoGraph, mtime?: number, ino?: number | string, size?: number): void;
17
17
  /** Mark a workspace's cached state dirty, preserving its graph and mtime. */
18
18
  export declare function markDirty(workspace: string): void;
19
19
  /** Return whether the workspace's cached state is dirty. */
@@ -22,3 +22,7 @@ export declare function isDirty(workspace: string): boolean;
22
22
  export declare function clearCache(workspace: string): void;
23
23
  /** Return the graph-file mtime captured with the cached graph, if present. */
24
24
  export declare function getCachedMtime(workspace: string): number | undefined;
25
+ /** Return the graph-file inode/file-id captured with the cached graph. */
26
+ export declare function getCachedIno(workspace: string): string | undefined;
27
+ /** Return the graph-file byte size captured with the cached graph. */
28
+ export declare function getCachedSize(workspace: string): number | undefined;
@@ -0,0 +1,71 @@
1
+ import type { GraphEdge, GraphNode } from './types';
2
+ export interface ImportBinding {
3
+ imported: string;
4
+ local: string;
5
+ }
6
+ export interface ParsedImport {
7
+ specifier: string;
8
+ importType: GraphEdge['importType'];
9
+ importedSymbols: string[];
10
+ bindings: ImportBinding[];
11
+ reExport: boolean;
12
+ }
13
+ interface FileStat {
14
+ size: number;
15
+ mtime: Date;
16
+ mtimeMs: number;
17
+ }
18
+ interface OntologyInput {
19
+ moduleName: string;
20
+ filePath: string;
21
+ content: string;
22
+ language: string;
23
+ exports: string[];
24
+ imports: string[];
25
+ hasManifest?: (relDir: string) => boolean;
26
+ }
27
+ export interface FallbackScannerDependencies {
28
+ statFile: (filePath: string) => FileStat;
29
+ readFile: (filePath: string) => string;
30
+ isBinaryContent: (content: string) => boolean;
31
+ extractExports: (filePath: string, absoluteRoot: string) => {
32
+ exports: string[];
33
+ exportLines: Record<string, number>;
34
+ };
35
+ parseImports: (content: string, filePath: string, absoluteRoot: string) => ParsedImport[];
36
+ stripComments: (content: string) => string;
37
+ toModuleName: (filePath: string, absoluteRoot: string) => string;
38
+ getLanguage: (filePath: string) => string;
39
+ extractOntology: (input: OntologyInput) => GraphNode['ontology'];
40
+ resolveSpecifier: (absoluteRoot: string, filePath: string, specifier: string) => string | null;
41
+ usedSymbolsForImport: (parsedImport: ParsedImport, strippedContent: string) => string[] | undefined;
42
+ isScannableSourcePath: (filePath: string) => boolean;
43
+ }
44
+ export type FallbackScanOutcome = {
45
+ status: 'scanned';
46
+ node: GraphNode & Required<Pick<GraphNode, 'sizeBytes' | 'mtimeMs'>>;
47
+ edges: GraphEdge[];
48
+ } | {
49
+ status: 'skipped';
50
+ reason: 'oversized' | 'unreadable' | 'binary' | 'malformed';
51
+ moduleName: string;
52
+ language?: string;
53
+ sizeBytes?: number;
54
+ mtimeMs?: number;
55
+ };
56
+ export interface FallbackScanOptions {
57
+ filePath: string;
58
+ absoluteRoot: string;
59
+ maxFileSize: number;
60
+ hasManifest?: (relDir: string) => boolean;
61
+ dependencies: FallbackScannerDependencies;
62
+ }
63
+ /**
64
+ * Bounded, fail-open boundary for the legacy parser-based file scanner.
65
+ *
66
+ * All filesystem access happens before parser work, with the size cap enforced
67
+ * before content is read. Language extraction and resolution stay injectable so
68
+ * builder tests can replace them without process-wide module mocks.
69
+ */
70
+ export declare function runFallbackScan({ filePath, absoluteRoot, maxFileSize, hasManifest, dependencies, }: FallbackScanOptions): FallbackScanOutcome;
71
+ export {};
@@ -25,6 +25,8 @@
25
25
  * statement's placeholder count equals its argument count exactly and
26
26
  * no-placeholder statements are issued as `db.run(sql)` with no array.
27
27
  */
28
+ import type { Database } from 'bun:sqlite';
29
+ import { unlinkSync } from 'node:fs';
28
30
  import type { GraphNode, RepoGraph } from './types';
29
31
  /** Filename of the derived index inside `.swarm/`. */
30
32
  export declare const REPO_MEMORY_FILENAME = "repo-memory.sqlite";
@@ -34,6 +36,7 @@ export declare const REPO_MEMORY_FILENAME = "repo-memory.sqlite";
34
36
  * validateSymlinkBoundary.
35
37
  */
36
38
  export declare function getRepoMemoryPath(workspace: string): string;
39
+ declare function cacheHandle(storePath: string, db: Database): void;
37
40
  /**
38
41
  * Close the cached connection for a workspace. Called by the `/swarm close`
39
42
  * clean stage before unlinking the store (Windows holds a WAL-mode file open,
@@ -55,6 +58,7 @@ export declare function closeAllRepoMemory(): void;
55
58
  * otherwise.
56
59
  */
57
60
  export declare function deleteRepoMemory(workspace: string): void;
61
+ declare function removeRepoMemoryFiles(workspace: string): boolean;
58
62
  /** Whether a SQLite driver is resolvable in this runtime. */
59
63
  export declare function isIndexedStorageAvailable(): boolean;
60
64
  /**
@@ -74,6 +78,12 @@ export declare function resolveGraphStorageMode(workspace: string): 'json' | 'in
74
78
  */
75
79
  export declare const _internals: {
76
80
  isIndexedStorageAvailable: typeof isIndexedStorageAvailable;
81
+ removeRepoMemoryFiles: typeof removeRepoMemoryFiles;
82
+ unlinkSync: typeof unlinkSync;
83
+ cacheHandle: typeof cacheHandle;
84
+ maxOpenHandles: number;
85
+ openHandleCount: () => number;
86
+ hasOpenHandle: (workspace: string) => boolean;
77
87
  };
78
88
  /**
79
89
  * Replace the whole index from `graph` in one transaction.
@@ -134,3 +144,4 @@ export declare function queryNodeByFile(workspace: string, file: string): GraphN
134
144
  * `maxDepth = 0` blast radius early-returns, query.ts:613-621).
135
145
  */
136
146
  export declare function loadSubgraphForFiles(workspace: string, files: string[], depth: number): RepoGraph | null;
147
+ export {};
@@ -22,7 +22,13 @@ export declare const _internals: {
22
22
  fsRename: typeof fsPromises.rename;
23
23
  retryDelayMs: number;
24
24
  writeFingerprint: typeof writeFingerprint;
25
+ cacheArtifactMatches: typeof cacheArtifactMatches;
25
26
  };
27
+ declare function cacheArtifactMatches(cachedMtime: number | undefined, cachedIno: string | undefined, cachedSize: number | undefined, stats: {
28
+ mtimeMs: number;
29
+ ino: number;
30
+ size: number;
31
+ }): boolean;
26
32
  /**
27
33
  * Get the validated path for the repo-graph.json file.
28
34
  * Resolves symlinks via realpath before validation to prevent
@@ -78,3 +84,4 @@ export declare function loadOrCreateGraph(workspace: string): Promise<RepoGraph>
78
84
  * @throws Error if save fails
79
85
  */
80
86
  export declare function saveIfDirty(workspace: string, freshnessOptions?: FreshnessOptions): Promise<void>;
87
+ export {};
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared "## Decisions" section extractor for `.swarm/context.md`.
3
+ *
4
+ * Issue #1661 residual, consolidated under #2493 (W9a): four independent
5
+ * parsers of the same section had drifted apart —
6
+ *
7
+ * - `src/services/decision-drift-analyzer.ts` (line-scan, rich Decision[])
8
+ * - `src/hooks/extractors.ts` (line-scan, joined/truncated text)
9
+ * - `src/services/handoff-service.ts` (line-scan, cleaned strings)
10
+ * - `src/hooks/curator.ts` (inline regex, raw keyDecisions)
11
+ *
12
+ * The three line-scanners already agreed on boundary semantics (exact
13
+ * `## Decisions` header line; section ends at the next `## ` header; a
14
+ * repeated `## Decisions` header re-enters the section instead of ending
15
+ * it because the start check runs before the end check). Only the curator's
16
+ * inline regex diverged: it matched `## Decisions` anywhere in a line
17
+ * (so a prose mention or `### Decisions` started a bogus section) and ended
18
+ * the section at any `\n##` (so a `###` subheading truncated the list).
19
+ *
20
+ * This module is that line-scan, lifted verbatim from the drift analyzer
21
+ * (the richest consumer) and extended with a `raw` field so each consumer
22
+ * can reconstruct its historical output exactly. It imports nothing —
23
+ * keeping it dependency-free makes it safe for both `src/services` and
24
+ * `src/hooks` consumers without import cycles.
25
+ *
26
+ * Consumers map to their own output shapes in-place; per-consumer quirks
27
+ * (indentation intolerance, marker stripping, first-5 vs last-5 windows)
28
+ * live in the consumers, not here.
29
+ */
30
+ /**
31
+ * A single decision extracted from the `## Decisions` section of
32
+ * `.swarm/context.md`.
33
+ */
34
+ export interface ContextDecision {
35
+ /**
36
+ * The decision line exactly as it appears in the source file, bullet
37
+ * prefix (`- `), indentation, confirmation markers and timestamps
38
+ * preserved. Consumers that historically returned raw text
39
+ * (hooks/extractors, curator keyDecisions) reconstruct their output
40
+ * from this; consumers that never needed it ignore it.
41
+ */
42
+ raw: string;
43
+ /**
44
+ * Decision text with bracketed markers (timestamps, `[confirmed]`)
45
+ * removed. The ✅ marker is preserved — it is not bracketed. This is
46
+ * the drift analyzer's historical `text` semantics.
47
+ */
48
+ text: string;
49
+ /**
50
+ * Phase the decision belongs to: an explicit `Phase N` inside the
51
+ * decision text, else the most recent `## Phase N` heading seen before
52
+ * the decision, else null.
53
+ */
54
+ phase: number | null;
55
+ /** Whether the decision carries a confirmation marker (✅ or [confirmed]) */
56
+ confirmed: boolean;
57
+ /** Timestamp parsed from a `[YYYY-MM-DDTHH:MM:SSZ]` marker, else null */
58
+ timestamp: string | null;
59
+ /** 1-based line number of the decision bullet in the source content */
60
+ line: number;
61
+ }
62
+ /**
63
+ * Extract decisions from `## Decisions` section content.
64
+ *
65
+ * Boundary semantics (strict, shared by every consumer post-#2493):
66
+ * - The section starts at a line whose trimmed content is exactly
67
+ * `## Decisions` (trailing whitespace / CRLF tolerated).
68
+ * - The section ends at the next line starting with `## ` (a repeated
69
+ * `## Decisions` header re-enters the section rather than ending it —
70
+ * the start check precedes the end check, preserving the historical
71
+ * line-scanner behavior all three scanner consumers shared).
72
+ * - Decision items are lines whose trimmed content starts with `- `
73
+ * (indentation-tolerant). Consumers with stricter historical item
74
+ * matching (hooks/extractors required non-indented `- ` lines) filter
75
+ * on `raw` in their mapping layer.
76
+ */
77
+ export declare function extractContextDecisions(content: string): ContextDecision[];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Strip ASCII control characters (C0 range + DEL) from a string that is
3
+ * interpolated into a single-line user-facing message (#2493 review F-11).
4
+ * A char-code loop instead of a control-character regex: lint/suspicious/
5
+ * noControlCharactersInRegex rejects `[\u0000-\u001f]`-style patterns.
6
+ */
7
+ export declare function stripControlCharacters(input: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.164.12",
3
+ "version": "7.164.13",
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",
@@ -63,7 +63,7 @@
63
63
  ".opencode/skills/swarm-pr-subscribe",
64
64
  ".opencode/skills/swarm-ci-monitor",
65
65
  ".opencode/skills/issue-ingest",
66
- ".opencode/skills/plan",
66
+ ".opencode/skills/swarm-plan",
67
67
  ".opencode/skills/critic-gate",
68
68
  ".opencode/skills/execute",
69
69
  ".opencode/skills/phase-wrap",
@@ -100,6 +100,7 @@
100
100
  "drift:check": "bun run scripts/drift-check.ts",
101
101
  "check:pre-push": "bun run scripts/drift-check.ts --enforce --no-report && bun run check:registry-citations",
102
102
  "schema:generate": "bun run scripts/generate-config-schema.ts",
103
+ "generate:commands-docs": "bun run scripts/generate-commands-docs.ts",
103
104
  "check:runtime-src-refs": "bun run scripts/check-runtime-src-refs.ts",
104
105
  "drift:fix": "bun run scripts/drift-check.ts --fix --confirm",
105
106
  "skills:sync": "bun run scripts/sync-qa-gate-skills.ts",
@@ -1,70 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-5wc5pbzc.js";
5
- import"./index-8d90gzaz.js";
6
- import"./index-hvz4ad2t.js";
7
- import"./index-wasdrhev.js";
8
- import"./index-b25t91a3.js";
9
- import"./index-k0s8n6m5.js";
10
- import"./index-x39hjdf1.js";
11
- import"./index-txdagbh7.js";
12
- import"./index-cw912re7.js";
13
- import"./index-hb7bh4r2.js";
14
- import"./index-kxv193aq.js";
15
- import"./index-40twgsyh.js";
16
- import"./index-70ha9e09.js";
17
- import"./index-ztm0q26v.js";
18
- import"./index-9ss2m4rs.js";
19
- import"./index-d3mpxsmy.js";
20
- import"./index-zsrtt42s.js";
21
- import"./index-r69gzes2.js";
22
- import"./index-6chhqq2n.js";
23
- import"./index-xxfk62zd.js";
24
- import"./index-b43rt5ph.js";
25
- import"./index-q7sjgr1y.js";
26
- import"./index-ad9064j9.js";
27
- import"./index-ebce775n.js";
28
- import"./index-8vw2pjgr.js";
29
- import"./index-0byep4pe.js";
30
- import"./index-qqq04n70.js";
31
- import"./index-z6xqpmqg.js";
32
- import"./index-p612v1mv.js";
33
- import"./index-hg09xemc.js";
34
- import"./index-4mjmnysc.js";
35
- import"./index-rtry5xyf.js";
36
- import"./index-qgajv9rd.js";
37
- import"./index-3qf1vxtb.js";
38
- import"./index-n832052r.js";
39
- import"./index-wknpkfm8.js";
40
- import"./index-4vb56w2k.js";
41
- import"./index-mee9maf5.js";
42
- import"./index-556ja8an.js";
43
- import"./index-yvqg6kn5.js";
44
- import"./index-c45662wc.js";
45
- import"./index-es64amqt.js";
46
- import"./index-ry16d01s.js";
47
- import"./index-n4fzmqz8.js";
48
- import"./index-eed0gkv6.js";
49
- import"./index-888pq4xx.js";
50
- import"./index-ae75rja9.js";
51
- import"./index-sphahrmq.js";
52
- import"./index-7qefgq4j.js";
53
- import"./index-2bhz5k91.js";
54
- import"./index-ewv8qa8q.js";
55
- import"./index-r2p0pgst.js";
56
- import"./index-7g4c7s5r.js";
57
- import"./index-vw66q1rw.js";
58
- import"./index-9e6fdz2h.js";
59
- import"./index-4rhhvd1a.js";
60
- import"./index-cgewrpw5.js";
61
- import"./index-50j914b5.js";
62
- import"./index-zjygnfay.js";
63
- import"./index-bk5tah7q.js";
64
- import"./index-bpmtbmy9.js";
65
- import"./index-4fwbbad3.js";
66
- import"./index-zgwm4ryv.js";
67
- import"./index-a76rekgs.js";
68
- export {
69
- createCuratorLLMDelegate
70
- };
@@ -1,71 +0,0 @@
1
- // @bun
2
- import {
3
- handleGuardrailExplain
4
- } from "./index-m8xrbdmn.js";
5
- import"./index-5wc5pbzc.js";
6
- import"./index-8d90gzaz.js";
7
- import"./index-hvz4ad2t.js";
8
- import"./index-wasdrhev.js";
9
- import"./index-b25t91a3.js";
10
- import"./index-k0s8n6m5.js";
11
- import"./index-x39hjdf1.js";
12
- import"./index-txdagbh7.js";
13
- import"./index-cw912re7.js";
14
- import"./index-hb7bh4r2.js";
15
- import"./index-kxv193aq.js";
16
- import"./index-40twgsyh.js";
17
- import"./index-70ha9e09.js";
18
- import"./index-ztm0q26v.js";
19
- import"./index-9ss2m4rs.js";
20
- import"./index-d3mpxsmy.js";
21
- import"./index-zsrtt42s.js";
22
- import"./index-r69gzes2.js";
23
- import"./index-6chhqq2n.js";
24
- import"./index-xxfk62zd.js";
25
- import"./index-b43rt5ph.js";
26
- import"./index-q7sjgr1y.js";
27
- import"./index-ad9064j9.js";
28
- import"./index-ebce775n.js";
29
- import"./index-8vw2pjgr.js";
30
- import"./index-0byep4pe.js";
31
- import"./index-qqq04n70.js";
32
- import"./index-z6xqpmqg.js";
33
- import"./index-p612v1mv.js";
34
- import"./index-hg09xemc.js";
35
- import"./index-4mjmnysc.js";
36
- import"./index-rtry5xyf.js";
37
- import"./index-qgajv9rd.js";
38
- import"./index-3qf1vxtb.js";
39
- import"./index-n832052r.js";
40
- import"./index-wknpkfm8.js";
41
- import"./index-4vb56w2k.js";
42
- import"./index-mee9maf5.js";
43
- import"./index-556ja8an.js";
44
- import"./index-yvqg6kn5.js";
45
- import"./index-c45662wc.js";
46
- import"./index-es64amqt.js";
47
- import"./index-ry16d01s.js";
48
- import"./index-n4fzmqz8.js";
49
- import"./index-eed0gkv6.js";
50
- import"./index-888pq4xx.js";
51
- import"./index-ae75rja9.js";
52
- import"./index-sphahrmq.js";
53
- import"./index-7qefgq4j.js";
54
- import"./index-2bhz5k91.js";
55
- import"./index-ewv8qa8q.js";
56
- import"./index-r2p0pgst.js";
57
- import"./index-7g4c7s5r.js";
58
- import"./index-vw66q1rw.js";
59
- import"./index-9e6fdz2h.js";
60
- import"./index-4rhhvd1a.js";
61
- import"./index-cgewrpw5.js";
62
- import"./index-50j914b5.js";
63
- import"./index-zjygnfay.js";
64
- import"./index-bk5tah7q.js";
65
- import"./index-bpmtbmy9.js";
66
- import"./index-4fwbbad3.js";
67
- import"./index-zgwm4ryv.js";
68
- import"./index-a76rekgs.js";
69
- export {
70
- handleGuardrailExplain
71
- };