opencode-swarm 6.49.0 → 6.50.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.
@@ -1,5 +1,5 @@
1
1
  import type { AgentDefinition } from './architect';
2
- export declare const CURATOR_INIT_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_INIT\nPRIOR_SUMMARY: [JSON or \"none\"]\nKNOWLEDGE_ENTRIES: [JSON array of high-confidence entries]\nPROJECT_CONTEXT: [context.md excerpt]\n\nACTIONS:\n- Read the prior summary to understand session history\n- Cross-reference knowledge entries against project context\n- Identify contradictions (knowledge says X, project state shows Y)\n- Produce a concise briefing for the architect\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Flag contradictions explicitly with CONTRADICTION: prefix\n- If no prior summary exists, state \"First session \u2014 no prior context\"\n\nOUTPUT FORMAT:\nBRIEFING:\n[concise summary of prior session state, key decisions, active blockers]\n\nCONTRADICTIONS:\n- [entry_id]: [description] (or \"None detected\")\n\nKNOWLEDGE_STATS:\n- Entries reviewed: [N]\n- Prior phases covered: [N]\n";
3
- export declare const CURATOR_PHASE_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_PHASE [phase_number]\nPRIOR_DIGEST: [running summary or \"none\"]\nPHASE_EVENTS: [JSON array from events.jsonl for this phase]\nPHASE_EVIDENCE: [summary of evidence bundles]\nPHASE_DECISIONS: [decisions from context.md]\nAGENTS_DISPATCHED: [list]\nAGENTS_EXPECTED: [list from config]\n\nACTIONS:\n- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)\n- Identify workflow deviations: missing reviewer, missing retro, skipped test_engineer\n- Recommend knowledge updates: entries to promote, archive, or flag as contradicted\n- Summarize key decisions and blockers resolved\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Compliance observations are READ-ONLY \u2014 report, do not enforce\n- Extend the digest, never replace it\n\nOUTPUT FORMAT:\nPHASE_DIGEST:\nphase: [N]\nsummary: [what was accomplished]\nagents_used: [list]\ntasks_completed: [N]/[total]\nkey_decisions: [list]\nblockers_resolved: [list]\n\nCOMPLIANCE:\n- [type]: [description] (or \"No deviations observed\")\n\nKNOWLEDGE_UPDATES:\n- [action] new: [reason] (or \"No recommendations\")\nNOTE: Always use \"new\" as the token \u2014 existing entry IDs (UUID v4) are not available in this context. Any non-UUID token is treated as \"new\" by the parser. Only \"promote new:\" creates a new entry; \"archive new:\" and \"flag_contradiction new:\" are silently skipped because those actions require an existing entry to operate on.\n\nEXTENDED_DIGEST:\n[the full running digest with this phase appended]\n";
2
+ export declare const CURATOR_INIT_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_INIT\nPRIOR_SUMMARY: [JSON or \"none\"]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\nPROJECT_CONTEXT: [context.md excerpt]\n\nACTIONS:\n- Read the prior summary to understand session history\n- Cross-reference knowledge entries against project context\n- Identify contradictions (knowledge says X, project state shows Y)\n- Recommend rewrites for verbose or stale lessons\n- Produce a concise briefing for the architect\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Flag contradictions explicitly with CONTRADICTION: prefix\n- If no prior summary exists, state \"First session \u2014 no prior context\"\n\nOUTPUT FORMAT:\nBRIEFING:\n[concise summary of prior session state, key decisions, active blockers]\n\nCONTRADICTIONS:\n- [entry_id]: [description] (or \"None detected\")\n\nKNOWLEDGE_UPDATES:\n- promote <uuid>: <reason> (boost confidence, mark hive_eligible)\n- archive <uuid>: <reason> (mark as archived \u2014 no longer injected)\n- rewrite <uuid>: <new lesson text> (replace verbose/stale lesson with tighter version, max 280 chars)\n- flag_contradiction <uuid>: <reason> (tag as contradicted)\n- promote new: <new lesson text> (add a brand-new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when archiving, rewriting, or flagging an existing entry. Use \"new\" only when recommending a brand-new entry.\n\nKNOWLEDGE_STATS:\n- Entries reviewed: [N]\n- Prior phases covered: [N]\n";
3
+ export declare const CURATOR_PHASE_PROMPT = "## IDENTITY\nYou are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.\nDO NOT use the Task tool to delegate. You ARE the agent that does the work.\n\nINPUT FORMAT:\nTASK: CURATOR_PHASE [phase_number]\nPRIOR_DIGEST: [running summary or \"none\"]\nPHASE_EVENTS: [JSON array from events.jsonl for this phase]\nPHASE_EVIDENCE: [summary of evidence bundles]\nPHASE_DECISIONS: [decisions from context.md]\nAGENTS_DISPATCHED: [list]\nAGENTS_EXPECTED: [list from config]\nKNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]\n\nACTIONS:\n- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)\n- Identify workflow deviations: missing reviewer, missing retro, skipped test_engineer\n- Recommend knowledge updates: entries to promote, archive, rewrite, or flag as contradicted\n- Summarize key decisions and blockers resolved\n\nRULES:\n- Output under 2000 chars\n- No code modifications\n- Compliance observations are READ-ONLY \u2014 report, do not enforce\n- Extend the digest, never replace it\n\nOUTPUT FORMAT:\nPHASE_DIGEST:\nphase: [N]\nsummary: [what was accomplished]\nagents_used: [list]\ntasks_completed: [N]/[total]\nkey_decisions: [list]\nblockers_resolved: [list]\n\nCOMPLIANCE:\n- [type]: [description] (or \"No deviations observed\")\n\nKNOWLEDGE_UPDATES:\n- promote <uuid>: <reason> (boost confidence, mark hive_eligible)\n- archive <uuid>: <reason> (mark as archived \u2014 no longer injected)\n- rewrite <uuid>: <new lesson text> (replace verbose/stale lesson with tighter version, max 280 chars)\n- flag_contradiction <uuid>: <reason> (tag as contradicted)\n- promote new: <new lesson text> (add a brand-new entry)\nUse the UUID from KNOWLEDGE_ENTRIES when archiving, rewriting, or flagging an existing entry. Use \"new\" only when recommending a brand-new entry.\n\nEXTENDED_DIGEST:\n[the full running digest with this phase appended]\n";
4
4
  export declare function createExplorerAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
5
5
  export declare function createExplorerCuratorAgent(model: string, mode: 'CURATOR_INIT' | 'CURATOR_PHASE', customAppendPrompt?: string): AgentDefinition;
@@ -8,7 +8,7 @@
8
8
  export interface PlanSyncWorkerOptions {
9
9
  /** Directory containing .swarm folder (defaults to cwd) */
10
10
  directory?: string;
11
- /** Debounce delay in ms (default: 300ms) */
11
+ /** Debounce delay in ms (default: 500ms) */
12
12
  debounceMs?: number;
13
13
  /** Polling interval in ms when fs.watch fails (default: 2000ms) */
14
14
  pollIntervalMs?: number;
package/dist/cli/index.js CHANGED
@@ -16517,25 +16517,33 @@ async function loadPlan(directory) {
16517
16517
  if (await ledgerExists(directory)) {
16518
16518
  const planHash = computePlanHash(validated);
16519
16519
  const ledgerHash = await getLatestLedgerHash(directory);
16520
- if (ledgerHash !== "" && planHash !== ledgerHash) {
16521
- const currentPlanId = `${validated.swarm}-${validated.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
16522
- const ledgerEvents = await readLedgerEvents(directory);
16523
- const firstEvent = ledgerEvents.length > 0 ? ledgerEvents[0] : null;
16524
- if (firstEvent && firstEvent.plan_id !== currentPlanId) {
16525
- warn(`[loadPlan] Ledger identity mismatch (ledger: ${firstEvent.plan_id}, plan: ${currentPlanId}) \u2014 skipping ledger rebuild (migration detected). Use /swarm reset-session to reinitialize the ledger.`);
16526
- } else {
16527
- warn("[loadPlan] plan.json is stale (hash mismatch with ledger) \u2014 rebuilding from ledger. If this recurs, run /swarm reset-session to clear stale session state.");
16528
- try {
16529
- const rebuilt = await replayFromLedger(directory);
16530
- if (rebuilt) {
16531
- await rebuildPlan(directory, rebuilt);
16532
- warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
16533
- return rebuilt;
16520
+ const resolvedWorkspace = path8.resolve(directory);
16521
+ if (!startupLedgerCheckedWorkspaces.has(resolvedWorkspace)) {
16522
+ startupLedgerCheckedWorkspaces.add(resolvedWorkspace);
16523
+ if (ledgerHash !== "" && planHash !== ledgerHash) {
16524
+ const currentPlanId = `${validated.swarm}-${validated.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
16525
+ const ledgerEvents = await readLedgerEvents(directory);
16526
+ const firstEvent = ledgerEvents.length > 0 ? ledgerEvents[0] : null;
16527
+ if (firstEvent && firstEvent.plan_id !== currentPlanId) {
16528
+ warn(`[loadPlan] Ledger identity mismatch (ledger: ${firstEvent.plan_id}, plan: ${currentPlanId}) \u2014 skipping ledger rebuild (migration detected). Use /swarm reset-session to reinitialize the ledger.`);
16529
+ } else {
16530
+ warn("[loadPlan] plan.json is stale (hash mismatch with ledger) \u2014 rebuilding from ledger. If this recurs, run /swarm reset-session to clear stale session state.");
16531
+ try {
16532
+ const rebuilt = await replayFromLedger(directory);
16533
+ if (rebuilt) {
16534
+ await rebuildPlan(directory, rebuilt);
16535
+ warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
16536
+ return rebuilt;
16537
+ }
16538
+ } catch (replayError) {
16539
+ warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16534
16540
  }
16535
- } catch (replayError) {
16536
- warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16537
16541
  }
16538
16542
  }
16543
+ } else if (ledgerHash !== "" && planHash !== ledgerHash) {
16544
+ if (process.env.DEBUG_SWARM) {
16545
+ console.warn(`[loadPlan] Ledger hash mismatch during active session for ${resolvedWorkspace} \u2014 skipping rebuild (startup check already performed).`);
16546
+ }
16539
16547
  }
16540
16548
  }
16541
16549
  return validated;
@@ -17028,11 +17036,13 @@ function migrateLegacyPlan(planContent, swarmId) {
17028
17036
  };
17029
17037
  return plan;
17030
17038
  }
17039
+ var startupLedgerCheckedWorkspaces;
17031
17040
  var init_manager2 = __esm(() => {
17032
17041
  init_plan_schema();
17033
17042
  init_utils2();
17034
17043
  init_utils();
17035
17044
  init_ledger();
17045
+ startupLedgerCheckedWorkspaces = new Set;
17036
17046
  });
17037
17047
 
17038
17048
  // src/services/config-doctor.ts
@@ -18665,6 +18675,8 @@ var KnowledgeConfigSchema = exports_external.object({
18665
18675
  hive_max_entries: exports_external.number().min(1).max(1e5).default(200),
18666
18676
  auto_promote_days: exports_external.number().min(1).max(3650).default(90),
18667
18677
  max_inject_count: exports_external.number().min(0).max(50).default(5),
18678
+ inject_char_budget: exports_external.number().min(200).max(1e4).default(2000),
18679
+ max_lesson_display_chars: exports_external.number().min(40).max(280).default(120),
18668
18680
  dedup_threshold: exports_external.number().min(0).max(1).default(0.6),
18669
18681
  scope_filter: exports_external.array(exports_external.string()).default(["global"]),
18670
18682
  hive_enabled: exports_external.boolean().default(true),
@@ -415,6 +415,8 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
415
415
  hive_max_entries: z.ZodDefault<z.ZodNumber>;
416
416
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
417
417
  max_inject_count: z.ZodDefault<z.ZodNumber>;
418
+ inject_char_budget: z.ZodDefault<z.ZodNumber>;
419
+ max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
418
420
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
419
421
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
420
422
  hive_enabled: z.ZodDefault<z.ZodBoolean>;
@@ -778,6 +780,8 @@ export declare const PluginConfigSchema: z.ZodObject<{
778
780
  hive_max_entries: z.ZodDefault<z.ZodNumber>;
779
781
  auto_promote_days: z.ZodDefault<z.ZodNumber>;
780
782
  max_inject_count: z.ZodDefault<z.ZodNumber>;
783
+ inject_char_budget: z.ZodDefault<z.ZodNumber>;
784
+ max_lesson_display_chars: z.ZodDefault<z.ZodNumber>;
781
785
  dedup_threshold: z.ZodDefault<z.ZodNumber>;
782
786
  scope_filter: z.ZodDefault<z.ZodArray<z.ZodString>>;
783
787
  hive_enabled: z.ZodDefault<z.ZodBoolean>;
@@ -36,7 +36,7 @@ export interface ComplianceObservation {
36
36
  severity: 'info' | 'warning';
37
37
  }
38
38
  export interface KnowledgeRecommendation {
39
- action: 'promote' | 'archive' | 'flag_contradiction';
39
+ action: 'promote' | 'archive' | 'flag_contradiction' | 'rewrite';
40
40
  entry_id?: string;
41
41
  lesson: string;
42
42
  reason: string;
@@ -65,6 +65,10 @@ export interface KnowledgeConfig {
65
65
  auto_promote_days: number;
66
66
  /** Maximum knowledge entries to inject per architect message. Default: 5 */
67
67
  max_inject_count: number;
68
+ /** Maximum total chars for the entire injection block. Default: 2000 */
69
+ inject_char_budget?: number;
70
+ /** Maximum display chars per lesson at injection time. Default: 120 */
71
+ max_lesson_display_chars?: number;
68
72
  /** Jaccard bigram similarity threshold for deduplication. Default: 0.6 */
69
73
  dedup_threshold: number;
70
74
  /** Scope filters to apply when reading knowledge. Default: ['global'] */