opencode-swarm 7.68.0 → 7.68.1

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/dist/cli/index.js CHANGED
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.68.0",
55
+ version: "7.68.1",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -49948,6 +49948,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
49948
49948
  import { randomUUID as randomUUID3 } from "crypto";
49949
49949
  import { existsSync as existsSync25, readFileSync as readFileSync15 } from "fs";
49950
49950
  import { mkdir as mkdir12, readFile as readFile12, writeFile as writeFile10 } from "fs/promises";
49951
+ import * as os8 from "os";
49951
49952
  import * as path37 from "path";
49952
49953
  async function migrateKnowledgeToExternal(_directory, _config) {
49953
49954
  return {
@@ -50059,6 +50060,123 @@ async function migrateContextToKnowledge(directory, config3) {
50059
50060
  entriesTotal: rawEntries.length
50060
50061
  };
50061
50062
  }
50063
+ async function migrateHiveKnowledgeLegacy(config3) {
50064
+ const legacyHivePath = _internals23.resolveLegacyHiveKnowledgePath();
50065
+ const canonicalHivePath = resolveHiveKnowledgePath();
50066
+ const sentinelPath = path37.join(path37.dirname(canonicalHivePath), ".hive-knowledge-migrated");
50067
+ if (existsSync25(sentinelPath)) {
50068
+ return {
50069
+ migrated: false,
50070
+ entriesMigrated: 0,
50071
+ entriesDropped: 0,
50072
+ entriesTotal: 0,
50073
+ skippedReason: "sentinel-exists"
50074
+ };
50075
+ }
50076
+ if (!existsSync25(legacyHivePath)) {
50077
+ return {
50078
+ migrated: false,
50079
+ entriesMigrated: 0,
50080
+ entriesDropped: 0,
50081
+ entriesTotal: 0,
50082
+ skippedReason: "no-context-file"
50083
+ };
50084
+ }
50085
+ const legacyEntries = await readKnowledge(legacyHivePath);
50086
+ if (legacyEntries.length === 0) {
50087
+ await _internals23.writeSentinel(sentinelPath, 0, 0);
50088
+ return {
50089
+ migrated: true,
50090
+ entriesMigrated: 0,
50091
+ entriesDropped: 0,
50092
+ entriesTotal: 0
50093
+ };
50094
+ }
50095
+ const existingHiveEntries = await readKnowledge(canonicalHivePath);
50096
+ let migrated = 0;
50097
+ let dropped = 0;
50098
+ const entryErrors = [];
50099
+ for (const legacyEntry of legacyEntries) {
50100
+ try {
50101
+ const lesson = legacyEntry.lesson;
50102
+ if (!lesson || typeof lesson !== "string" || lesson.length < 15) {
50103
+ dropped++;
50104
+ continue;
50105
+ }
50106
+ const dup = findNearDuplicate(lesson, existingHiveEntries, config3.dedup_threshold ?? 0.6);
50107
+ if (dup) {
50108
+ dropped++;
50109
+ continue;
50110
+ }
50111
+ const category = legacyEntry.category || "process";
50112
+ const validationResult = validateLesson(lesson, existingHiveEntries.map((e) => e.lesson), {
50113
+ category,
50114
+ scope: "global",
50115
+ confidence: 0.3
50116
+ });
50117
+ if (!validationResult.valid) {
50118
+ const errorMsg = `Validation failed for legacy entry: ${validationResult.reason}`;
50119
+ entryErrors.push(errorMsg);
50120
+ warn(`[knowledge-migrator] ${errorMsg}`);
50121
+ dropped++;
50122
+ continue;
50123
+ }
50124
+ const confidence = legacyEntry.confidence ?? 0.8;
50125
+ const scopeTag = legacyEntry.scope_tag || "global";
50126
+ const legacyId = legacyEntry.id;
50127
+ const existingIds = new Set(existingHiveEntries.map((e) => e.id));
50128
+ const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID3() : legacyId || randomUUID3();
50129
+ if (legacyId && existingIds.has(legacyId)) {
50130
+ warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);
50131
+ }
50132
+ const newHiveEntry = {
50133
+ id: resolvedId,
50134
+ tier: "hive",
50135
+ lesson: _internals23.truncateLesson(lesson),
50136
+ category,
50137
+ tags: ["migration:legacy-hive"],
50138
+ scope: scopeTag,
50139
+ confidence: Math.min(Math.max(confidence, 0), 1),
50140
+ status: "established",
50141
+ confirmed_by: [],
50142
+ retrieval_outcomes: {
50143
+ applied_count: 0,
50144
+ succeeded_after_count: 0,
50145
+ failed_after_count: 0
50146
+ },
50147
+ schema_version: KNOWLEDGE_SCHEMA_VERSION,
50148
+ created_at: legacyEntry.created_at || new Date().toISOString(),
50149
+ updated_at: legacyEntry.updated_at || new Date().toISOString(),
50150
+ source_project: "legacy-promotion",
50151
+ encounter_score: 1
50152
+ };
50153
+ try {
50154
+ await _internals23.appendKnowledge(canonicalHivePath, newHiveEntry);
50155
+ existingHiveEntries.push(newHiveEntry);
50156
+ migrated++;
50157
+ } catch (appendError) {
50158
+ const errorMsg = `Failed to append entry: ${appendError instanceof Error ? appendError.message : String(appendError)}`;
50159
+ entryErrors.push(errorMsg);
50160
+ warn(`[knowledge-migrator] ${errorMsg}`);
50161
+ dropped++;
50162
+ }
50163
+ } catch (entryError) {
50164
+ const errorMsg = `Unexpected error processing legacy entry: ${entryError instanceof Error ? entryError.message : String(entryError)}`;
50165
+ entryErrors.push(errorMsg);
50166
+ warn(`[knowledge-migrator] ${errorMsg}`);
50167
+ dropped++;
50168
+ }
50169
+ }
50170
+ await _internals23.writeSentinel(sentinelPath, migrated, dropped);
50171
+ log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`);
50172
+ return {
50173
+ migrated: true,
50174
+ entriesMigrated: migrated,
50175
+ entriesDropped: dropped,
50176
+ entriesTotal: legacyEntries.length,
50177
+ ...entryErrors.length > 0 && { entryErrors }
50178
+ };
50179
+ }
50062
50180
  function parseContextMd(content) {
50063
50181
  const sections = _internals23.splitIntoSections(content);
50064
50182
  const entries = [];
@@ -50180,21 +50298,37 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
50180
50298
  await mkdir12(path37.dirname(sentinelPath), { recursive: true });
50181
50299
  await writeFile10(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
50182
50300
  }
50301
+ function resolveLegacyHiveKnowledgePath() {
50302
+ const platform = process.platform;
50303
+ const home = process.env.HOME || os8.homedir();
50304
+ let dataDir;
50305
+ if (platform === "win32") {
50306
+ dataDir = path37.join(process.env.LOCALAPPDATA || path37.join(home, "AppData", "Local"), "opencode-swarm", "Data");
50307
+ } else if (platform === "darwin") {
50308
+ dataDir = path37.join(home, "Library", "Application Support", "opencode-swarm");
50309
+ } else {
50310
+ dataDir = path37.join(process.env.XDG_DATA_HOME || path37.join(home, ".local", "share"), "opencode-swarm");
50311
+ }
50312
+ return path37.join(dataDir, "hive-knowledge.jsonl");
50313
+ }
50183
50314
  var _internals23;
50184
50315
  var init_knowledge_migrator = __esm(() => {
50185
50316
  init_logger();
50186
50317
  init_knowledge_store();
50187
50318
  init_knowledge_validator();
50188
50319
  _internals23 = {
50320
+ appendKnowledge,
50189
50321
  migrateContextToKnowledge,
50190
50322
  migrateKnowledgeToExternal,
50323
+ migrateHiveKnowledgeLegacy,
50191
50324
  parseContextMd,
50192
50325
  splitIntoSections,
50193
50326
  extractBullets,
50194
50327
  inferCategoryFromText,
50195
50328
  truncateLesson: truncateLesson2,
50196
50329
  inferProjectName,
50197
- writeSentinel
50330
+ writeSentinel,
50331
+ resolveLegacyHiveKnowledgePath
50198
50332
  };
50199
50333
  });
50200
50334
 
@@ -50266,24 +50400,43 @@ async function handleKnowledgeRestoreCommand(directory, args) {
50266
50400
  }
50267
50401
  async function handleKnowledgeMigrateCommand(directory, args) {
50268
50402
  const targetDir = args[0] || directory;
50403
+ const config3 = KnowledgeConfigSchema.parse({});
50269
50404
  try {
50270
- const result = await migrateContextToKnowledge(targetDir, KnowledgeConfigSchema.parse({}));
50271
- if (result.skippedReason) {
50272
- switch (result.skippedReason) {
50405
+ const contextResult = await migrateContextToKnowledge(targetDir, config3);
50406
+ const hiveResult = await migrateHiveKnowledgeLegacy(config3);
50407
+ const messages = [];
50408
+ if (contextResult.skippedReason) {
50409
+ switch (contextResult.skippedReason) {
50273
50410
  case "sentinel-exists":
50274
- return "\u23ED Migration already completed for this project. Delete .swarm/.knowledge-migrated to re-run.";
50411
+ messages.push("\u23ED Context migration already completed. Delete .swarm/.knowledge-migrated to re-run.");
50412
+ break;
50275
50413
  case "no-context-file":
50276
- return "\u2139\uFE0F No .swarm/context.md found \u2014 nothing to migrate.";
50414
+ messages.push("\u2139\uFE0F No .swarm/context.md found \u2014 nothing to migrate.");
50415
+ break;
50277
50416
  case "empty-context":
50278
- return "\u2139\uFE0F .swarm/context.md is empty \u2014 nothing to migrate.";
50279
- default:
50280
- return "\u26A0\uFE0F Migration skipped for an unknown reason.";
50417
+ messages.push("\u2139\uFE0F .swarm/context.md is empty \u2014 nothing to migrate.");
50418
+ break;
50419
+ }
50420
+ } else {
50421
+ messages.push(`\u2705 Context migration: ${contextResult.entriesMigrated} entries added, ${contextResult.entriesDropped} dropped`);
50422
+ }
50423
+ if (hiveResult.skippedReason) {
50424
+ switch (hiveResult.skippedReason) {
50425
+ case "sentinel-exists":
50426
+ messages.push("\u23ED Hive legacy migration already completed. Delete the sentinel in the hive data dir to re-run.");
50427
+ break;
50428
+ case "no-context-file":
50429
+ messages.push("\u2139\uFE0F No legacy hive-knowledge.jsonl found \u2014 nothing to migrate.");
50430
+ break;
50281
50431
  }
50432
+ } else if (hiveResult.migrated) {
50433
+ messages.push(`\u2705 Hive legacy migration: ${hiveResult.entriesMigrated} entries added, ${hiveResult.entriesDropped} dropped`);
50282
50434
  }
50283
- return `\u2705 Migration complete: ${result.entriesMigrated} entries added, ${result.entriesDropped} dropped (validation/dedup), ${result.entriesTotal} total processed.`;
50435
+ return messages.join(`
50436
+ `);
50284
50437
  } catch (error93) {
50285
- console.warn("[knowledge-command] migrateContextToKnowledge error:", error93 instanceof Error ? error93.message : String(error93));
50286
- return "\u274C Migration failed. Check .swarm/context.md is readable.";
50438
+ console.warn("[knowledge-command] migration error:", error93 instanceof Error ? error93.message : String(error93));
50439
+ return "\u274C Migration failed. Check that knowledge source files are readable.";
50287
50440
  }
50288
50441
  }
50289
50442
  async function handleKnowledgeListCommand(directory, _args) {
@@ -52836,7 +52989,7 @@ var init_gateway = __esm(() => {
52836
52989
 
52837
52990
  // src/memory/evaluation.ts
52838
52991
  import * as fs16 from "fs/promises";
52839
- import * as os8 from "os";
52992
+ import * as os9 from "os";
52840
52993
  import * as path41 from "path";
52841
52994
  async function evaluateMemoryRecallFixtures(options) {
52842
52995
  const fixtureDirectory = path41.resolve(options.fixtureDirectory);
@@ -52848,7 +53001,7 @@ async function evaluateMemoryRecallFixtures(options) {
52848
53001
  for (const fixture of fixtures) {
52849
53002
  const materialized = materializeFixture(fixture);
52850
53003
  for (const providerName of providers) {
52851
- const tempRoot = await fs16.realpath(await fs16.mkdtemp(path41.join(os8.tmpdir(), "swarm-memory-eval-")));
53004
+ const tempRoot = await fs16.realpath(await fs16.mkdtemp(path41.join(os9.tmpdir(), "swarm-memory-eval-")));
52852
53005
  const provider = createEvaluationProvider(providerName, tempRoot);
52853
53006
  try {
52854
53007
  await provider.initialize?.();
@@ -63980,7 +64133,7 @@ init_registry();
63980
64133
  init_cache_paths();
63981
64134
  init_constants();
63982
64135
  import * as fs36 from "fs";
63983
- import * as os9 from "os";
64136
+ import * as os10 from "os";
63984
64137
  import * as path64 from "path";
63985
64138
  var { version: version5 } = package_default;
63986
64139
  var CONFIG_DIR = getPluginConfigDir();
@@ -63991,7 +64144,7 @@ var OPENCODE_PLUGIN_CACHE_PATHS = getPluginCachePaths();
63991
64144
  var OPENCODE_PLUGIN_LOCK_FILE_PATHS = getPluginLockFilePaths();
63992
64145
  function isSafeCachePath(p) {
63993
64146
  const resolved = path64.resolve(p);
63994
- const home = path64.resolve(os9.homedir());
64147
+ const home = path64.resolve(os10.homedir());
63995
64148
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
63996
64149
  return false;
63997
64150
  }
@@ -64015,7 +64168,7 @@ function isSafeCachePath(p) {
64015
64168
  }
64016
64169
  function isSafeLockFilePath(p) {
64017
64170
  const resolved = path64.resolve(p);
64018
- const home = path64.resolve(os9.homedir());
64171
+ const home = path64.resolve(os10.homedir());
64019
64172
  if (resolved === "/" || resolved === home || resolved.length <= home.length) {
64020
64173
  return false;
64021
64174
  }
@@ -1,10 +1,12 @@
1
1
  /** One-time migration from .swarm/context.md → .swarm/knowledge.jsonl for existing projects. */
2
+ import { appendKnowledge } from './knowledge-store.js';
2
3
  import type { KnowledgeCategory, KnowledgeConfig } from './knowledge-types.js';
3
4
  export interface MigrationResult {
4
5
  migrated: boolean;
5
6
  entriesMigrated: number;
6
7
  entriesDropped: number;
7
8
  entriesTotal: number;
9
+ entryErrors?: string[];
8
10
  skippedReason?: 'sentinel-exists' | 'no-context-file' | 'empty-context' | 'external-sentinel-exists';
9
11
  }
10
12
  export declare function migrateKnowledgeToExternal(_directory: string, _config: KnowledgeConfig): Promise<MigrationResult>;
@@ -18,8 +20,10 @@ interface Section {
18
20
  body: string;
19
21
  }
20
22
  export declare const _internals: {
23
+ appendKnowledge: typeof appendKnowledge;
21
24
  migrateContextToKnowledge: typeof migrateContextToKnowledge;
22
25
  migrateKnowledgeToExternal: typeof migrateKnowledgeToExternal;
26
+ migrateHiveKnowledgeLegacy: typeof migrateHiveKnowledgeLegacy;
23
27
  parseContextMd: typeof parseContextMd;
24
28
  splitIntoSections: typeof splitIntoSections;
25
29
  extractBullets: typeof extractBullets;
@@ -27,8 +31,21 @@ export declare const _internals: {
27
31
  truncateLesson: typeof truncateLesson;
28
32
  inferProjectName: typeof inferProjectName;
29
33
  writeSentinel: typeof writeSentinel;
34
+ resolveLegacyHiveKnowledgePath: typeof resolveLegacyHiveKnowledgePath;
30
35
  };
31
36
  export declare function migrateContextToKnowledge(directory: string, config: KnowledgeConfig): Promise<MigrationResult>;
37
+ /**
38
+ * Migrate legacy hive knowledge from {platform-data-dir}/hive-knowledge.jsonl
39
+ * to {platform-data-dir}/shared-learnings.jsonl with HiveKnowledgeEntry schema.
40
+ *
41
+ * This handles data that was created before the dual-hive-promoter consolidation (v7.63.0).
42
+ * Legacy entries were in a flat schema; this converts them to the current HiveKnowledgeEntry format
43
+ * and deduplicates against existing hive entries.
44
+ *
45
+ * @param config - Knowledge configuration
46
+ * @returns Migration result with counts and status
47
+ */
48
+ export declare function migrateHiveKnowledgeLegacy(config: KnowledgeConfig): Promise<MigrationResult>;
32
49
  /**
33
50
  * Parse context.md content into raw migration entries.
34
51
  * Extracts bullets from sections matching: lessons-learned, patterns, sme-cache, decisions.
@@ -59,4 +76,10 @@ declare function inferProjectName(directory: string): string;
59
76
  * Write sentinel file to track migration status.
60
77
  */
61
78
  declare function writeSentinel(sentinelPath: string, migrated: number, dropped: number): Promise<void>;
79
+ /**
80
+ * Resolve the legacy hive knowledge file path.
81
+ * Legacy data was stored in {platform-data-dir}/hive-knowledge.jsonl before consolidation.
82
+ * This matches the resolveHiveKnowledgePath() pattern but returns the old path.
83
+ */
84
+ declare function resolveLegacyHiveKnowledgePath(): string;
62
85
  export {};
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.68.0",
72
+ version: "7.68.1",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -73929,6 +73929,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
73929
73929
  import { randomUUID as randomUUID6 } from "node:crypto";
73930
73930
  import { existsSync as existsSync32, readFileSync as readFileSync17 } from "node:fs";
73931
73931
  import { mkdir as mkdir14, readFile as readFile16, writeFile as writeFile12 } from "node:fs/promises";
73932
+ import * as os13 from "node:os";
73932
73933
  import * as path53 from "node:path";
73933
73934
  async function migrateKnowledgeToExternal(_directory, _config) {
73934
73935
  return {
@@ -74040,6 +74041,123 @@ async function migrateContextToKnowledge(directory, config3) {
74040
74041
  entriesTotal: rawEntries.length
74041
74042
  };
74042
74043
  }
74044
+ async function migrateHiveKnowledgeLegacy(config3) {
74045
+ const legacyHivePath = _internals35.resolveLegacyHiveKnowledgePath();
74046
+ const canonicalHivePath = resolveHiveKnowledgePath();
74047
+ const sentinelPath = path53.join(path53.dirname(canonicalHivePath), ".hive-knowledge-migrated");
74048
+ if (existsSync32(sentinelPath)) {
74049
+ return {
74050
+ migrated: false,
74051
+ entriesMigrated: 0,
74052
+ entriesDropped: 0,
74053
+ entriesTotal: 0,
74054
+ skippedReason: "sentinel-exists"
74055
+ };
74056
+ }
74057
+ if (!existsSync32(legacyHivePath)) {
74058
+ return {
74059
+ migrated: false,
74060
+ entriesMigrated: 0,
74061
+ entriesDropped: 0,
74062
+ entriesTotal: 0,
74063
+ skippedReason: "no-context-file"
74064
+ };
74065
+ }
74066
+ const legacyEntries = await readKnowledge(legacyHivePath);
74067
+ if (legacyEntries.length === 0) {
74068
+ await _internals35.writeSentinel(sentinelPath, 0, 0);
74069
+ return {
74070
+ migrated: true,
74071
+ entriesMigrated: 0,
74072
+ entriesDropped: 0,
74073
+ entriesTotal: 0
74074
+ };
74075
+ }
74076
+ const existingHiveEntries = await readKnowledge(canonicalHivePath);
74077
+ let migrated = 0;
74078
+ let dropped = 0;
74079
+ const entryErrors = [];
74080
+ for (const legacyEntry of legacyEntries) {
74081
+ try {
74082
+ const lesson = legacyEntry.lesson;
74083
+ if (!lesson || typeof lesson !== "string" || lesson.length < 15) {
74084
+ dropped++;
74085
+ continue;
74086
+ }
74087
+ const dup = findNearDuplicate(lesson, existingHiveEntries, config3.dedup_threshold ?? 0.6);
74088
+ if (dup) {
74089
+ dropped++;
74090
+ continue;
74091
+ }
74092
+ const category = legacyEntry.category || "process";
74093
+ const validationResult = validateLesson(lesson, existingHiveEntries.map((e) => e.lesson), {
74094
+ category,
74095
+ scope: "global",
74096
+ confidence: 0.3
74097
+ });
74098
+ if (!validationResult.valid) {
74099
+ const errorMsg = `Validation failed for legacy entry: ${validationResult.reason}`;
74100
+ entryErrors.push(errorMsg);
74101
+ warn(`[knowledge-migrator] ${errorMsg}`);
74102
+ dropped++;
74103
+ continue;
74104
+ }
74105
+ const confidence = legacyEntry.confidence ?? 0.8;
74106
+ const scopeTag = legacyEntry.scope_tag || "global";
74107
+ const legacyId = legacyEntry.id;
74108
+ const existingIds = new Set(existingHiveEntries.map((e) => e.id));
74109
+ const resolvedId = legacyId && existingIds.has(legacyId) ? randomUUID6() : legacyId || randomUUID6();
74110
+ if (legacyId && existingIds.has(legacyId)) {
74111
+ warn(`[knowledge-migrator] Legacy entry ID collision for "${legacyId}", generating new UUID`);
74112
+ }
74113
+ const newHiveEntry = {
74114
+ id: resolvedId,
74115
+ tier: "hive",
74116
+ lesson: _internals35.truncateLesson(lesson),
74117
+ category,
74118
+ tags: ["migration:legacy-hive"],
74119
+ scope: scopeTag,
74120
+ confidence: Math.min(Math.max(confidence, 0), 1),
74121
+ status: "established",
74122
+ confirmed_by: [],
74123
+ retrieval_outcomes: {
74124
+ applied_count: 0,
74125
+ succeeded_after_count: 0,
74126
+ failed_after_count: 0
74127
+ },
74128
+ schema_version: KNOWLEDGE_SCHEMA_VERSION,
74129
+ created_at: legacyEntry.created_at || new Date().toISOString(),
74130
+ updated_at: legacyEntry.updated_at || new Date().toISOString(),
74131
+ source_project: "legacy-promotion",
74132
+ encounter_score: 1
74133
+ };
74134
+ try {
74135
+ await _internals35.appendKnowledge(canonicalHivePath, newHiveEntry);
74136
+ existingHiveEntries.push(newHiveEntry);
74137
+ migrated++;
74138
+ } catch (appendError) {
74139
+ const errorMsg = `Failed to append entry: ${appendError instanceof Error ? appendError.message : String(appendError)}`;
74140
+ entryErrors.push(errorMsg);
74141
+ warn(`[knowledge-migrator] ${errorMsg}`);
74142
+ dropped++;
74143
+ }
74144
+ } catch (entryError) {
74145
+ const errorMsg = `Unexpected error processing legacy entry: ${entryError instanceof Error ? entryError.message : String(entryError)}`;
74146
+ entryErrors.push(errorMsg);
74147
+ warn(`[knowledge-migrator] ${errorMsg}`);
74148
+ dropped++;
74149
+ }
74150
+ }
74151
+ await _internals35.writeSentinel(sentinelPath, migrated, dropped);
74152
+ log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`);
74153
+ return {
74154
+ migrated: true,
74155
+ entriesMigrated: migrated,
74156
+ entriesDropped: dropped,
74157
+ entriesTotal: legacyEntries.length,
74158
+ ...entryErrors.length > 0 && { entryErrors }
74159
+ };
74160
+ }
74043
74161
  function parseContextMd(content) {
74044
74162
  const sections = _internals35.splitIntoSections(content);
74045
74163
  const entries = [];
@@ -74161,21 +74279,37 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
74161
74279
  await mkdir14(path53.dirname(sentinelPath), { recursive: true });
74162
74280
  await writeFile12(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
74163
74281
  }
74282
+ function resolveLegacyHiveKnowledgePath() {
74283
+ const platform = process.platform;
74284
+ const home = process.env.HOME || os13.homedir();
74285
+ let dataDir;
74286
+ if (platform === "win32") {
74287
+ dataDir = path53.join(process.env.LOCALAPPDATA || path53.join(home, "AppData", "Local"), "opencode-swarm", "Data");
74288
+ } else if (platform === "darwin") {
74289
+ dataDir = path53.join(home, "Library", "Application Support", "opencode-swarm");
74290
+ } else {
74291
+ dataDir = path53.join(process.env.XDG_DATA_HOME || path53.join(home, ".local", "share"), "opencode-swarm");
74292
+ }
74293
+ return path53.join(dataDir, "hive-knowledge.jsonl");
74294
+ }
74164
74295
  var _internals35;
74165
74296
  var init_knowledge_migrator = __esm(() => {
74166
74297
  init_logger();
74167
74298
  init_knowledge_store();
74168
74299
  init_knowledge_validator();
74169
74300
  _internals35 = {
74301
+ appendKnowledge,
74170
74302
  migrateContextToKnowledge,
74171
74303
  migrateKnowledgeToExternal,
74304
+ migrateHiveKnowledgeLegacy,
74172
74305
  parseContextMd,
74173
74306
  splitIntoSections,
74174
74307
  extractBullets,
74175
74308
  inferCategoryFromText,
74176
74309
  truncateLesson: truncateLesson2,
74177
74310
  inferProjectName,
74178
- writeSentinel
74311
+ writeSentinel,
74312
+ resolveLegacyHiveKnowledgePath
74179
74313
  };
74180
74314
  });
74181
74315
 
@@ -74247,24 +74381,43 @@ async function handleKnowledgeRestoreCommand(directory, args2) {
74247
74381
  }
74248
74382
  async function handleKnowledgeMigrateCommand(directory, args2) {
74249
74383
  const targetDir = args2[0] || directory;
74384
+ const config3 = KnowledgeConfigSchema.parse({});
74250
74385
  try {
74251
- const result = await migrateContextToKnowledge(targetDir, KnowledgeConfigSchema.parse({}));
74252
- if (result.skippedReason) {
74253
- switch (result.skippedReason) {
74386
+ const contextResult = await migrateContextToKnowledge(targetDir, config3);
74387
+ const hiveResult = await migrateHiveKnowledgeLegacy(config3);
74388
+ const messages = [];
74389
+ if (contextResult.skippedReason) {
74390
+ switch (contextResult.skippedReason) {
74254
74391
  case "sentinel-exists":
74255
- return "⏭ Migration already completed for this project. Delete .swarm/.knowledge-migrated to re-run.";
74392
+ messages.push("⏭ Context migration already completed. Delete .swarm/.knowledge-migrated to re-run.");
74393
+ break;
74256
74394
  case "no-context-file":
74257
- return "ℹ️ No .swarm/context.md found — nothing to migrate.";
74395
+ messages.push("ℹ️ No .swarm/context.md found — nothing to migrate.");
74396
+ break;
74258
74397
  case "empty-context":
74259
- return "ℹ️ .swarm/context.md is empty — nothing to migrate.";
74260
- default:
74261
- return "⚠️ Migration skipped for an unknown reason.";
74398
+ messages.push("ℹ️ .swarm/context.md is empty — nothing to migrate.");
74399
+ break;
74400
+ }
74401
+ } else {
74402
+ messages.push(`✅ Context migration: ${contextResult.entriesMigrated} entries added, ${contextResult.entriesDropped} dropped`);
74403
+ }
74404
+ if (hiveResult.skippedReason) {
74405
+ switch (hiveResult.skippedReason) {
74406
+ case "sentinel-exists":
74407
+ messages.push("⏭ Hive legacy migration already completed. Delete the sentinel in the hive data dir to re-run.");
74408
+ break;
74409
+ case "no-context-file":
74410
+ messages.push("ℹ️ No legacy hive-knowledge.jsonl found — nothing to migrate.");
74411
+ break;
74262
74412
  }
74413
+ } else if (hiveResult.migrated) {
74414
+ messages.push(`✅ Hive legacy migration: ${hiveResult.entriesMigrated} entries added, ${hiveResult.entriesDropped} dropped`);
74263
74415
  }
74264
- return `✅ Migration complete: ${result.entriesMigrated} entries added, ${result.entriesDropped} dropped (validation/dedup), ${result.entriesTotal} total processed.`;
74416
+ return messages.join(`
74417
+ `);
74265
74418
  } catch (error93) {
74266
- console.warn("[knowledge-command] migrateContextToKnowledge error:", error93 instanceof Error ? error93.message : String(error93));
74267
- return "❌ Migration failed. Check .swarm/context.md is readable.";
74419
+ console.warn("[knowledge-command] migration error:", error93 instanceof Error ? error93.message : String(error93));
74420
+ return "❌ Migration failed. Check that knowledge source files are readable.";
74268
74421
  }
74269
74422
  }
74270
74423
  async function handleKnowledgeListCommand(directory, _args) {
@@ -77324,7 +77477,7 @@ var init_gateway = __esm(() => {
77324
77477
 
77325
77478
  // src/memory/evaluation.ts
77326
77479
  import * as fs27 from "node:fs/promises";
77327
- import * as os13 from "node:os";
77480
+ import * as os14 from "node:os";
77328
77481
  import * as path58 from "node:path";
77329
77482
  async function evaluateMemoryRecallFixtures(options) {
77330
77483
  const fixtureDirectory = path58.resolve(options.fixtureDirectory);
@@ -77336,7 +77489,7 @@ async function evaluateMemoryRecallFixtures(options) {
77336
77489
  for (const fixture of fixtures) {
77337
77490
  const materialized = materializeFixture(fixture);
77338
77491
  for (const providerName of providers) {
77339
- const tempRoot = await fs27.realpath(await fs27.mkdtemp(path58.join(os13.tmpdir(), "swarm-memory-eval-")));
77492
+ const tempRoot = await fs27.realpath(await fs27.mkdtemp(path58.join(os14.tmpdir(), "swarm-memory-eval-")));
77340
77493
  const provider = createEvaluationProvider(providerName, tempRoot);
77341
77494
  try {
77342
77495
  await provider.initialize?.();
@@ -104023,7 +104176,7 @@ init_path_security();
104023
104176
  import * as fsSync5 from "node:fs";
104024
104177
  import { existsSync as existsSync61, realpathSync as realpathSync13 } from "node:fs";
104025
104178
  import * as fsPromises5 from "node:fs/promises";
104026
- import * as os14 from "node:os";
104179
+ import * as os15 from "node:os";
104027
104180
  import * as path101 from "node:path";
104028
104181
 
104029
104182
  // src/tools/symbols.ts
@@ -104777,8 +104930,8 @@ function isRefusedWorkspaceRoot(target) {
104777
104930
  refused.add(path101.resolve(p));
104778
104931
  }
104779
104932
  };
104780
- add2(os14.homedir());
104781
- add2(os14.tmpdir());
104933
+ add2(os15.homedir());
104934
+ add2(os15.tmpdir());
104782
104935
  add2("/");
104783
104936
  add2("/Users");
104784
104937
  add2("/home");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.68.0",
3
+ "version": "7.68.1",
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",