opencode-swarm 7.9.0 → 7.11.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/dist/agents/architect.d.ts +1 -0
- package/dist/agents/skill-improver.d.ts +12 -0
- package/dist/agents/spec-writer.d.ts +8 -0
- package/dist/cli/index.js +1115 -709
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/schema.d.ts +103 -0
- package/dist/git/branch.d.ts +19 -0
- package/dist/hooks/curator-types.d.ts +25 -0
- package/dist/hooks/curator.d.ts +33 -1
- package/dist/hooks/knowledge-application-gate.d.ts +61 -0
- package/dist/hooks/knowledge-application.d.ts +103 -0
- package/dist/hooks/knowledge-reader.d.ts +18 -1
- package/dist/hooks/knowledge-store.d.ts +1 -0
- package/dist/hooks/knowledge-types.d.ts +96 -1
- package/dist/hooks/knowledge-validator.d.ts +16 -1
- package/dist/hooks/skill-improver-llm-factory.d.ts +30 -0
- package/dist/index.js +5973 -3534
- package/dist/plan/manager.d.ts +13 -0
- package/dist/services/skill-generator.d.ts +120 -0
- package/dist/services/skill-improver-quota.d.ts +57 -0
- package/dist/services/skill-improver.d.ts +102 -0
- package/dist/state.d.ts +40 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/knowledge-ack.d.ts +15 -0
- package/dist/tools/skill-apply.d.ts +11 -0
- package/dist/tools/skill-generate.d.ts +16 -0
- package/dist/tools/skill-improve.d.ts +16 -0
- package/dist/tools/skill-inspect.d.ts +9 -0
- package/dist/tools/skill-list.d.ts +8 -0
- package/dist/tools/spec-write.d.ts +13 -0
- package/dist/tools/tool-names.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -34,7 +34,7 @@ var package_default;
|
|
|
34
34
|
var init_package = __esm(() => {
|
|
35
35
|
package_default = {
|
|
36
36
|
name: "opencode-swarm",
|
|
37
|
-
version: "7.
|
|
37
|
+
version: "7.11.0",
|
|
38
38
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
39
39
|
main: "dist/index.js",
|
|
40
40
|
types: "dist/index.d.ts",
|
|
@@ -16054,7 +16054,14 @@ var init_tool_names = __esm(() => {
|
|
|
16054
16054
|
"set_qa_gates",
|
|
16055
16055
|
"web_search",
|
|
16056
16056
|
"convene_general_council",
|
|
16057
|
-
"write_final_council_evidence"
|
|
16057
|
+
"write_final_council_evidence",
|
|
16058
|
+
"skill_generate",
|
|
16059
|
+
"skill_list",
|
|
16060
|
+
"skill_apply",
|
|
16061
|
+
"skill_inspect",
|
|
16062
|
+
"skill_improve",
|
|
16063
|
+
"spec_write",
|
|
16064
|
+
"knowledge_ack"
|
|
16058
16065
|
];
|
|
16059
16066
|
TOOL_NAME_SET = new Set(TOOL_NAMES);
|
|
16060
16067
|
});
|
|
@@ -16110,6 +16117,8 @@ var init_constants = __esm(() => {
|
|
|
16110
16117
|
"council_generalist",
|
|
16111
16118
|
"council_skeptic",
|
|
16112
16119
|
"council_domain_expert",
|
|
16120
|
+
"skill_improver",
|
|
16121
|
+
"spec_writer",
|
|
16113
16122
|
...QA_AGENTS,
|
|
16114
16123
|
...PIPELINE_AGENTS
|
|
16115
16124
|
];
|
|
@@ -16292,7 +16301,13 @@ var init_constants = __esm(() => {
|
|
|
16292
16301
|
"set_qa_gates",
|
|
16293
16302
|
"convene_general_council",
|
|
16294
16303
|
"web_search",
|
|
16295
|
-
"write_final_council_evidence"
|
|
16304
|
+
"write_final_council_evidence",
|
|
16305
|
+
"skill_generate",
|
|
16306
|
+
"skill_list",
|
|
16307
|
+
"skill_apply",
|
|
16308
|
+
"skill_inspect",
|
|
16309
|
+
"skill_improve",
|
|
16310
|
+
"knowledge_ack"
|
|
16296
16311
|
],
|
|
16297
16312
|
explorer: [
|
|
16298
16313
|
"complexity_hotspots",
|
|
@@ -16462,7 +16477,32 @@ var init_constants = __esm(() => {
|
|
|
16462
16477
|
curator_phase: ["knowledge_recall"],
|
|
16463
16478
|
council_generalist: [],
|
|
16464
16479
|
council_skeptic: [],
|
|
16465
|
-
council_domain_expert: []
|
|
16480
|
+
council_domain_expert: [],
|
|
16481
|
+
skill_improver: [
|
|
16482
|
+
"knowledge_recall",
|
|
16483
|
+
"knowledge_query",
|
|
16484
|
+
"skill_list",
|
|
16485
|
+
"skill_inspect",
|
|
16486
|
+
"skill_generate",
|
|
16487
|
+
"skill_improve",
|
|
16488
|
+
"search",
|
|
16489
|
+
"doc_scan",
|
|
16490
|
+
"doc_extract",
|
|
16491
|
+
"web_search"
|
|
16492
|
+
],
|
|
16493
|
+
spec_writer: [
|
|
16494
|
+
"search",
|
|
16495
|
+
"knowledge_recall",
|
|
16496
|
+
"knowledge_query",
|
|
16497
|
+
"doc_scan",
|
|
16498
|
+
"doc_extract",
|
|
16499
|
+
"req_coverage",
|
|
16500
|
+
"lint_spec",
|
|
16501
|
+
"retrieve_summary",
|
|
16502
|
+
"symbols",
|
|
16503
|
+
"extract_code_blocks",
|
|
16504
|
+
"spec_write"
|
|
16505
|
+
]
|
|
16466
16506
|
};
|
|
16467
16507
|
for (const [agentName, tools] of Object.entries(AGENT_TOOL_MAP)) {
|
|
16468
16508
|
const invalidTools = tools.filter((tool) => !TOOL_NAME_SET.has(tool));
|
|
@@ -16526,6 +16566,14 @@ var init_constants = __esm(() => {
|
|
|
16526
16566
|
curator_phase: {
|
|
16527
16567
|
model: "opencode/gpt-5-nano",
|
|
16528
16568
|
fallback_models: ["opencode/big-pickle"]
|
|
16569
|
+
},
|
|
16570
|
+
skill_improver: {
|
|
16571
|
+
model: "opencode/big-pickle",
|
|
16572
|
+
fallback_models: ["opencode/gpt-5-nano"]
|
|
16573
|
+
},
|
|
16574
|
+
spec_writer: {
|
|
16575
|
+
model: "opencode/big-pickle",
|
|
16576
|
+
fallback_models: ["opencode/gpt-5-nano"]
|
|
16529
16577
|
}
|
|
16530
16578
|
};
|
|
16531
16579
|
});
|
|
@@ -16559,7 +16607,7 @@ function getCanonicalAgentRole(agentName, generatedAgentNames) {
|
|
|
16559
16607
|
function stripKnownSwarmPrefix(agentName) {
|
|
16560
16608
|
return getCanonicalAgentRole(agentName);
|
|
16561
16609
|
}
|
|
16562
|
-
var SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, CuratorConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, ParallelizationConfigSchema, PluginConfigSchema;
|
|
16610
|
+
var SEPARATORS, CANONICAL_ROLES_LONGEST_FIRST, CANONICAL_ROLES_SET, AgentOverrideConfigSchema, SwarmConfigSchema, HooksConfigSchema, ScoringWeightsSchema, DecisionDecaySchema, TokenRatiosSchema, ScoringConfigSchema, ContextBudgetConfigSchema, EvidenceConfigSchema, GateFeatureSchema, PlaceholderScanConfigSchema, QualityBudgetConfigSchema, GateConfigSchema, PipelineConfigSchema, PhaseCompleteConfigSchema, SummaryConfigSchema, ReviewPassesConfigSchema, AdversarialDetectionConfigSchema, AdversarialTestingConfigSchemaBase, AdversarialTestingConfigSchema, IntegrationAnalysisConfigSchema, DocsConfigSchema, UIReviewConfigSchema, CompactionAdvisoryConfigSchema, LintConfigSchema, SecretscanConfigSchema, GuardrailsProfileSchema, DEFAULT_AGENT_PROFILES, DEFAULT_ARCHITECT_PROFILE, GuardrailsConfigSchema, WatchdogConfigSchema, SelfReviewConfigSchema, ToolFilterConfigSchema, PlanCursorConfigSchema, CheckpointConfigSchema, AutomationModeSchema, AutomationCapabilitiesSchema, AutomationConfigSchemaBase, AutomationConfigSchema, KnowledgeConfigSchema, CuratorConfigSchema, KnowledgeApplicationConfigSchema, SkillImproverConfigSchema, SpecWriterConfigSchema, SlopDetectorConfigSchema, IncrementalVerifyConfigSchema, CompactionConfigSchema, PrmConfigSchema, AgentAuthorityRuleSchema, AuthorityConfigSchema, GeneralCouncilMemberConfigSchema, GeneralCouncilConfigSchema, CouncilConfigSchema, ParallelizationConfigSchema, PluginConfigSchema;
|
|
16563
16611
|
var init_schema = __esm(() => {
|
|
16564
16612
|
init_zod();
|
|
16565
16613
|
init_constants();
|
|
@@ -17000,6 +17048,7 @@ var init_schema = __esm(() => {
|
|
|
17000
17048
|
low_utility_threshold: exports_external.number().min(0).max(1).default(0.3),
|
|
17001
17049
|
min_retrievals_for_utility: exports_external.number().min(1).max(100).default(3),
|
|
17002
17050
|
schema_version: exports_external.number().int().min(1).default(1),
|
|
17051
|
+
directive_min_confidence: exports_external.number().min(0).max(1).default(0.75),
|
|
17003
17052
|
same_project_weight: exports_external.number().min(0).max(5).default(1),
|
|
17004
17053
|
cross_project_weight: exports_external.number().min(0).max(5).default(0.5),
|
|
17005
17054
|
min_encounter_score: exports_external.number().min(0).max(1).default(0.1),
|
|
@@ -17019,7 +17068,36 @@ var init_schema = __esm(() => {
|
|
|
17019
17068
|
compliance_report: exports_external.boolean().default(true),
|
|
17020
17069
|
suppress_warnings: exports_external.boolean().default(true),
|
|
17021
17070
|
drift_inject_max_chars: exports_external.number().min(100).max(2000).default(500),
|
|
17022
|
-
llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000)
|
|
17071
|
+
llm_timeout_ms: exports_external.number().int().min(5000).max(600000).default(300000),
|
|
17072
|
+
skill_generation_enabled: exports_external.boolean().default(true),
|
|
17073
|
+
skill_generation_mode: exports_external.enum(["draft", "active"]).default("draft"),
|
|
17074
|
+
min_skill_confidence: exports_external.number().min(0).max(1).default(0.85),
|
|
17075
|
+
min_skill_confirmations: exports_external.number().int().min(1).max(50).default(2)
|
|
17076
|
+
});
|
|
17077
|
+
KnowledgeApplicationConfigSchema = exports_external.object({
|
|
17078
|
+
enabled: exports_external.boolean().default(true),
|
|
17079
|
+
mode: exports_external.enum(["warn", "enforce"]).default("warn"),
|
|
17080
|
+
min_confidence: exports_external.number().min(0).max(1).default(0.85),
|
|
17081
|
+
critical_requires_ack: exports_external.boolean().default(true),
|
|
17082
|
+
require_skill_refs: exports_external.boolean().default(true)
|
|
17083
|
+
});
|
|
17084
|
+
SkillImproverConfigSchema = exports_external.object({
|
|
17085
|
+
enabled: exports_external.boolean().default(false),
|
|
17086
|
+
model: exports_external.string().nullable().default(null),
|
|
17087
|
+
fallback_models: exports_external.array(exports_external.string()).default([]),
|
|
17088
|
+
max_calls_per_day: exports_external.number().int().min(1).max(1000).default(10),
|
|
17089
|
+
trigger: exports_external.enum(["manual", "scheduled"]).default("manual"),
|
|
17090
|
+
targets: exports_external.array(exports_external.enum(["skills", "spec", "architect_prompt", "knowledge"])).default(["skills", "spec", "architect_prompt", "knowledge"]),
|
|
17091
|
+
write_mode: exports_external.enum(["proposal", "draft_skills"]).default("proposal"),
|
|
17092
|
+
require_user_approval: exports_external.boolean().default(true),
|
|
17093
|
+
quota_window: exports_external.enum(["utc", "local"]).default("utc"),
|
|
17094
|
+
allow_deterministic_fallback: exports_external.boolean().default(true)
|
|
17095
|
+
});
|
|
17096
|
+
SpecWriterConfigSchema = exports_external.object({
|
|
17097
|
+
enabled: exports_external.boolean().default(true),
|
|
17098
|
+
model: exports_external.string().nullable().default(null),
|
|
17099
|
+
fallback_models: exports_external.array(exports_external.string()).default([]),
|
|
17100
|
+
allow_spec_write: exports_external.boolean().default(true)
|
|
17023
17101
|
});
|
|
17024
17102
|
SlopDetectorConfigSchema = exports_external.object({
|
|
17025
17103
|
enabled: exports_external.boolean().default(true),
|
|
@@ -17155,6 +17233,9 @@ var init_schema = __esm(() => {
|
|
|
17155
17233
|
automation: AutomationConfigSchema.optional(),
|
|
17156
17234
|
knowledge: KnowledgeConfigSchema.optional(),
|
|
17157
17235
|
curator: CuratorConfigSchema.optional(),
|
|
17236
|
+
knowledge_application: KnowledgeApplicationConfigSchema.optional(),
|
|
17237
|
+
skill_improver: SkillImproverConfigSchema.optional(),
|
|
17238
|
+
spec_writer: SpecWriterConfigSchema.optional(),
|
|
17158
17239
|
tool_output: exports_external.object({
|
|
17159
17240
|
truncation_enabled: exports_external.boolean().default(true),
|
|
17160
17241
|
max_lines: exports_external.number().min(10).max(500).default(150),
|
|
@@ -20705,6 +20786,10 @@ function resetSwarmState() {
|
|
|
20705
20786
|
swarmState.opencodeClient = null;
|
|
20706
20787
|
swarmState.curatorInitAgentNames = [];
|
|
20707
20788
|
swarmState.curatorPhaseAgentNames = [];
|
|
20789
|
+
swarmState.skillImproverAgentNames = [];
|
|
20790
|
+
swarmState.specWriterAgentNames = [];
|
|
20791
|
+
swarmState.currentCriticalShownIds.clear();
|
|
20792
|
+
swarmState.knowledgeAckDedup.clear();
|
|
20708
20793
|
swarmState.generatedAgentNames = [];
|
|
20709
20794
|
_rehydrationCache = null;
|
|
20710
20795
|
swarmState.fullAutoEnabledInConfig = false;
|
|
@@ -20750,6 +20835,10 @@ var init_state = __esm(() => {
|
|
|
20750
20835
|
opencodeClient: null,
|
|
20751
20836
|
curatorInitAgentNames: [],
|
|
20752
20837
|
curatorPhaseAgentNames: [],
|
|
20838
|
+
skillImproverAgentNames: [],
|
|
20839
|
+
specWriterAgentNames: [],
|
|
20840
|
+
currentCriticalShownIds: new Map,
|
|
20841
|
+
knowledgeAckDedup: new Set,
|
|
20753
20842
|
generatedAgentNames: [],
|
|
20754
20843
|
lastBudgetPct: 0,
|
|
20755
20844
|
agentSessions: defaultRunContext.agentSessions,
|
|
@@ -34490,6 +34579,205 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
34490
34579
|
};
|
|
34491
34580
|
}
|
|
34492
34581
|
}
|
|
34582
|
+
function resetToMainAfterMerge(cwd, options) {
|
|
34583
|
+
const warnings = [];
|
|
34584
|
+
try {
|
|
34585
|
+
const defaultBranch = _internals6.detectDefaultRemoteBranch(cwd);
|
|
34586
|
+
if (!defaultBranch) {
|
|
34587
|
+
return {
|
|
34588
|
+
success: false,
|
|
34589
|
+
targetBranch: "",
|
|
34590
|
+
previousBranch: "",
|
|
34591
|
+
message: "Could not detect default remote branch",
|
|
34592
|
+
branchDeleted: false,
|
|
34593
|
+
changesDiscarded: false,
|
|
34594
|
+
warnings
|
|
34595
|
+
};
|
|
34596
|
+
}
|
|
34597
|
+
const currentBranch = getCurrentBranch(cwd);
|
|
34598
|
+
const targetBranch = `origin/${defaultBranch}`;
|
|
34599
|
+
if (currentBranch === "HEAD") {
|
|
34600
|
+
return {
|
|
34601
|
+
success: false,
|
|
34602
|
+
targetBranch,
|
|
34603
|
+
previousBranch: "HEAD",
|
|
34604
|
+
message: "Cannot reset: detached HEAD state",
|
|
34605
|
+
branchDeleted: false,
|
|
34606
|
+
changesDiscarded: false,
|
|
34607
|
+
warnings
|
|
34608
|
+
};
|
|
34609
|
+
}
|
|
34610
|
+
if (currentBranch === defaultBranch) {
|
|
34611
|
+
try {
|
|
34612
|
+
const logOutput = _internals6.gitExec(["log", `${targetBranch}..HEAD`, "--oneline"], cwd);
|
|
34613
|
+
if (logOutput.trim().length > 0) {
|
|
34614
|
+
return {
|
|
34615
|
+
success: false,
|
|
34616
|
+
targetBranch,
|
|
34617
|
+
previousBranch: currentBranch,
|
|
34618
|
+
message: `Cannot reset: ${defaultBranch} has unpushed commits. Push them first.`,
|
|
34619
|
+
branchDeleted: false,
|
|
34620
|
+
changesDiscarded: false,
|
|
34621
|
+
warnings
|
|
34622
|
+
};
|
|
34623
|
+
}
|
|
34624
|
+
} catch {}
|
|
34625
|
+
} else {
|
|
34626
|
+
try {
|
|
34627
|
+
_internals6.gitExec(["rev-parse", "--abbrev-ref", `${currentBranch}@{upstream}`], cwd);
|
|
34628
|
+
} catch {
|
|
34629
|
+
try {
|
|
34630
|
+
const localSha = _internals6.gitExec(["rev-parse", "HEAD"], cwd).trim();
|
|
34631
|
+
const remoteSha = _internals6.gitExec(["rev-parse", targetBranch], cwd).trim();
|
|
34632
|
+
if (localSha !== remoteSha) {
|
|
34633
|
+
return {
|
|
34634
|
+
success: false,
|
|
34635
|
+
targetBranch,
|
|
34636
|
+
previousBranch: currentBranch,
|
|
34637
|
+
message: `Cannot reset: branch ${currentBranch} is local-only and diverges from ${defaultBranch}. Push or check manually.`,
|
|
34638
|
+
branchDeleted: false,
|
|
34639
|
+
changesDiscarded: false,
|
|
34640
|
+
warnings
|
|
34641
|
+
};
|
|
34642
|
+
}
|
|
34643
|
+
} catch {
|
|
34644
|
+
return {
|
|
34645
|
+
success: false,
|
|
34646
|
+
targetBranch,
|
|
34647
|
+
previousBranch: currentBranch,
|
|
34648
|
+
message: `Cannot reset: unable to compare ${currentBranch} with ${defaultBranch}`,
|
|
34649
|
+
branchDeleted: false,
|
|
34650
|
+
changesDiscarded: false,
|
|
34651
|
+
warnings
|
|
34652
|
+
};
|
|
34653
|
+
}
|
|
34654
|
+
}
|
|
34655
|
+
}
|
|
34656
|
+
try {
|
|
34657
|
+
_internals6.gitExec(["fetch", "--prune", "origin"], cwd);
|
|
34658
|
+
} catch (err) {
|
|
34659
|
+
return {
|
|
34660
|
+
success: false,
|
|
34661
|
+
targetBranch,
|
|
34662
|
+
previousBranch: currentBranch,
|
|
34663
|
+
message: `Cannot reset: fetch failed \u2014 ${err instanceof Error ? err.message : String(err)}`,
|
|
34664
|
+
branchDeleted: false,
|
|
34665
|
+
changesDiscarded: false,
|
|
34666
|
+
warnings
|
|
34667
|
+
};
|
|
34668
|
+
}
|
|
34669
|
+
const previousBranch = currentBranch;
|
|
34670
|
+
let switchedBranch = false;
|
|
34671
|
+
if (currentBranch !== defaultBranch) {
|
|
34672
|
+
try {
|
|
34673
|
+
_internals6.gitExec(["checkout", defaultBranch], cwd);
|
|
34674
|
+
switchedBranch = true;
|
|
34675
|
+
} catch (err) {
|
|
34676
|
+
return {
|
|
34677
|
+
success: false,
|
|
34678
|
+
targetBranch,
|
|
34679
|
+
previousBranch,
|
|
34680
|
+
message: `Checkout to ${defaultBranch} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
34681
|
+
branchDeleted: false,
|
|
34682
|
+
changesDiscarded: false,
|
|
34683
|
+
warnings
|
|
34684
|
+
};
|
|
34685
|
+
}
|
|
34686
|
+
}
|
|
34687
|
+
try {
|
|
34688
|
+
_internals6.gitExec(["reset", "--hard", targetBranch], cwd);
|
|
34689
|
+
} catch (err) {
|
|
34690
|
+
return {
|
|
34691
|
+
success: false,
|
|
34692
|
+
targetBranch,
|
|
34693
|
+
previousBranch,
|
|
34694
|
+
message: `Reset to ${targetBranch} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
34695
|
+
branchDeleted: false,
|
|
34696
|
+
changesDiscarded: false,
|
|
34697
|
+
warnings
|
|
34698
|
+
};
|
|
34699
|
+
}
|
|
34700
|
+
let changesDiscarded = false;
|
|
34701
|
+
if (hasUncommittedChanges(cwd)) {
|
|
34702
|
+
let discardSucceeded = false;
|
|
34703
|
+
for (let retry = 0;retry < 4; retry++) {
|
|
34704
|
+
if (retry > 0 && process.platform === "win32") {
|
|
34705
|
+
const endTime = Date.now() + 500;
|
|
34706
|
+
while (Date.now() < endTime) {}
|
|
34707
|
+
}
|
|
34708
|
+
try {
|
|
34709
|
+
_internals6.gitExec(["checkout", "--", "."], cwd);
|
|
34710
|
+
discardSucceeded = true;
|
|
34711
|
+
break;
|
|
34712
|
+
} catch {}
|
|
34713
|
+
}
|
|
34714
|
+
if (!discardSucceeded) {
|
|
34715
|
+
warnings.push("Could not discard all uncommitted changes after reset");
|
|
34716
|
+
}
|
|
34717
|
+
changesDiscarded = discardSucceeded;
|
|
34718
|
+
}
|
|
34719
|
+
try {
|
|
34720
|
+
_internals6.gitExec(["clean", "-fd"], cwd);
|
|
34721
|
+
} catch {
|
|
34722
|
+
warnings.push("Could not clean untracked files");
|
|
34723
|
+
}
|
|
34724
|
+
let branchDeleted = false;
|
|
34725
|
+
if (switchedBranch && previousBranch !== defaultBranch) {
|
|
34726
|
+
try {
|
|
34727
|
+
const mergedOutput = _internals6.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
34728
|
+
const isMerged = mergedOutput.split(`
|
|
34729
|
+
`).some((line) => line.trim() === previousBranch || line.trim() === `* ${previousBranch}`);
|
|
34730
|
+
if (isMerged) {
|
|
34731
|
+
_internals6.gitExec(["branch", "-d", previousBranch], cwd);
|
|
34732
|
+
branchDeleted = true;
|
|
34733
|
+
} else {
|
|
34734
|
+
warnings.push(`Branch ${previousBranch} is not merged into ${defaultBranch} \u2014 keeping it`);
|
|
34735
|
+
}
|
|
34736
|
+
} catch {
|
|
34737
|
+
warnings.push(`Could not delete branch ${previousBranch}`);
|
|
34738
|
+
}
|
|
34739
|
+
}
|
|
34740
|
+
if (options?.pruneBranches) {
|
|
34741
|
+
try {
|
|
34742
|
+
const mergedOutput = _internals6.gitExec(["branch", "--merged", defaultBranch], cwd);
|
|
34743
|
+
const mergedLines = mergedOutput.split(`
|
|
34744
|
+
`);
|
|
34745
|
+
for (const line of mergedLines) {
|
|
34746
|
+
const trimmedLine = line.trim();
|
|
34747
|
+
if (!trimmedLine || trimmedLine.startsWith("*") || trimmedLine === defaultBranch) {
|
|
34748
|
+
continue;
|
|
34749
|
+
}
|
|
34750
|
+
try {
|
|
34751
|
+
_internals6.gitExec(["branch", "-d", trimmedLine], cwd);
|
|
34752
|
+
} catch {
|
|
34753
|
+
warnings.push(`Could not prune branch: ${trimmedLine}`);
|
|
34754
|
+
}
|
|
34755
|
+
}
|
|
34756
|
+
} catch (err) {
|
|
34757
|
+
warnings.push(`Prune failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
34758
|
+
}
|
|
34759
|
+
}
|
|
34760
|
+
return {
|
|
34761
|
+
success: true,
|
|
34762
|
+
targetBranch,
|
|
34763
|
+
previousBranch,
|
|
34764
|
+
message: branchDeleted ? `Reset to ${defaultBranch} and deleted branch ${previousBranch}` : `Reset to ${defaultBranch}`,
|
|
34765
|
+
branchDeleted,
|
|
34766
|
+
changesDiscarded,
|
|
34767
|
+
warnings
|
|
34768
|
+
};
|
|
34769
|
+
} catch (err) {
|
|
34770
|
+
return {
|
|
34771
|
+
success: false,
|
|
34772
|
+
targetBranch: "",
|
|
34773
|
+
previousBranch: "",
|
|
34774
|
+
message: `Unexpected error: ${err instanceof Error ? err.message : String(err)}`,
|
|
34775
|
+
branchDeleted: false,
|
|
34776
|
+
changesDiscarded: false,
|
|
34777
|
+
warnings
|
|
34778
|
+
};
|
|
34779
|
+
}
|
|
34780
|
+
}
|
|
34493
34781
|
var GIT_TIMEOUT_MS2 = 30000, _internals6;
|
|
34494
34782
|
var init_branch = __esm(() => {
|
|
34495
34783
|
init_logger();
|
|
@@ -34497,10 +34785,81 @@ var init_branch = __esm(() => {
|
|
|
34497
34785
|
gitExec: gitExec2,
|
|
34498
34786
|
detectDefaultRemoteBranch,
|
|
34499
34787
|
getDefaultBaseBranch,
|
|
34500
|
-
resetToRemoteBranch
|
|
34788
|
+
resetToRemoteBranch,
|
|
34789
|
+
resetToMainAfterMerge
|
|
34501
34790
|
};
|
|
34502
34791
|
});
|
|
34503
34792
|
|
|
34793
|
+
// src/background/event-bus.ts
|
|
34794
|
+
class AutomationEventBus {
|
|
34795
|
+
listeners = new Map;
|
|
34796
|
+
eventHistory = [];
|
|
34797
|
+
maxHistorySize;
|
|
34798
|
+
constructor(options) {
|
|
34799
|
+
this.maxHistorySize = options?.maxHistorySize ?? 100;
|
|
34800
|
+
}
|
|
34801
|
+
subscribe(type, listener) {
|
|
34802
|
+
if (!this.listeners.has(type)) {
|
|
34803
|
+
this.listeners.set(type, new Set);
|
|
34804
|
+
}
|
|
34805
|
+
this.listeners.get(type).add(listener);
|
|
34806
|
+
return () => {
|
|
34807
|
+
this.listeners.get(type)?.delete(listener);
|
|
34808
|
+
};
|
|
34809
|
+
}
|
|
34810
|
+
async publish(type, payload, source) {
|
|
34811
|
+
const event = {
|
|
34812
|
+
type,
|
|
34813
|
+
timestamp: Date.now(),
|
|
34814
|
+
payload,
|
|
34815
|
+
source
|
|
34816
|
+
};
|
|
34817
|
+
this.eventHistory.push(event);
|
|
34818
|
+
if (this.eventHistory.length > this.maxHistorySize) {
|
|
34819
|
+
this.eventHistory.shift();
|
|
34820
|
+
}
|
|
34821
|
+
log(`[EventBus] ${type}`, {
|
|
34822
|
+
source,
|
|
34823
|
+
payload: typeof payload === "object" ? "..." : payload
|
|
34824
|
+
});
|
|
34825
|
+
const listeners = this.listeners.get(type);
|
|
34826
|
+
if (listeners) {
|
|
34827
|
+
await Promise.all(Array.from(listeners).map(async (listener) => {
|
|
34828
|
+
try {
|
|
34829
|
+
await listener(event);
|
|
34830
|
+
} catch (error93) {
|
|
34831
|
+
log(`[EventBus] Listener error for ${type}`, { error: error93 });
|
|
34832
|
+
}
|
|
34833
|
+
}));
|
|
34834
|
+
}
|
|
34835
|
+
}
|
|
34836
|
+
getHistory(types) {
|
|
34837
|
+
if (!types || types.length === 0) {
|
|
34838
|
+
return [...this.eventHistory];
|
|
34839
|
+
}
|
|
34840
|
+
return this.eventHistory.filter((e) => types.includes(e.type));
|
|
34841
|
+
}
|
|
34842
|
+
clearHistory() {
|
|
34843
|
+
this.eventHistory = [];
|
|
34844
|
+
}
|
|
34845
|
+
getListenerCount(type) {
|
|
34846
|
+
return this.listeners.get(type)?.size ?? 0;
|
|
34847
|
+
}
|
|
34848
|
+
hasListeners(type) {
|
|
34849
|
+
return this.getListenerCount(type) > 0;
|
|
34850
|
+
}
|
|
34851
|
+
}
|
|
34852
|
+
function getGlobalEventBus() {
|
|
34853
|
+
if (!globalEventBus) {
|
|
34854
|
+
globalEventBus = new AutomationEventBus;
|
|
34855
|
+
}
|
|
34856
|
+
return globalEventBus;
|
|
34857
|
+
}
|
|
34858
|
+
var globalEventBus = null;
|
|
34859
|
+
var init_event_bus = __esm(() => {
|
|
34860
|
+
init_utils();
|
|
34861
|
+
});
|
|
34862
|
+
|
|
34504
34863
|
// src/hooks/knowledge-store.ts
|
|
34505
34864
|
import { existsSync as existsSync7 } from "fs";
|
|
34506
34865
|
import { appendFile as appendFile2, mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
@@ -34540,13 +34899,59 @@ async function readKnowledge(filePath) {
|
|
|
34540
34899
|
if (!trimmed)
|
|
34541
34900
|
continue;
|
|
34542
34901
|
try {
|
|
34543
|
-
|
|
34902
|
+
const raw = JSON.parse(trimmed);
|
|
34903
|
+
results.push(normalizeEntry(raw));
|
|
34544
34904
|
} catch {
|
|
34545
34905
|
console.warn(`[knowledge-store] Skipping corrupted JSONL line in ${filePath}: ${trimmed.slice(0, 80)}`);
|
|
34546
34906
|
}
|
|
34547
34907
|
}
|
|
34548
34908
|
return results;
|
|
34549
34909
|
}
|
|
34910
|
+
function normalizeEntry(raw) {
|
|
34911
|
+
if (!raw || typeof raw !== "object")
|
|
34912
|
+
return raw;
|
|
34913
|
+
const obj = raw;
|
|
34914
|
+
if (!("retrieval_outcomes" in obj))
|
|
34915
|
+
return raw;
|
|
34916
|
+
const ro = obj.retrieval_outcomes;
|
|
34917
|
+
if (ro && typeof ro === "object") {
|
|
34918
|
+
if (typeof ro.shown_count !== "number") {
|
|
34919
|
+
ro.shown_count = typeof ro.applied_count === "number" ? ro.applied_count : 0;
|
|
34920
|
+
}
|
|
34921
|
+
if (typeof ro.acknowledged_count !== "number")
|
|
34922
|
+
ro.acknowledged_count = 0;
|
|
34923
|
+
if (typeof ro.applied_explicit_count !== "number") {
|
|
34924
|
+
ro.applied_explicit_count = 0;
|
|
34925
|
+
}
|
|
34926
|
+
if (typeof ro.ignored_count !== "number")
|
|
34927
|
+
ro.ignored_count = 0;
|
|
34928
|
+
if (typeof ro.violated_count !== "number")
|
|
34929
|
+
ro.violated_count = 0;
|
|
34930
|
+
if (typeof ro.succeeded_after_shown_count !== "number") {
|
|
34931
|
+
ro.succeeded_after_shown_count = typeof ro.succeeded_after_count === "number" ? ro.succeeded_after_count : 0;
|
|
34932
|
+
}
|
|
34933
|
+
if (typeof ro.failed_after_shown_count !== "number") {
|
|
34934
|
+
ro.failed_after_shown_count = typeof ro.failed_after_count === "number" ? ro.failed_after_count : 0;
|
|
34935
|
+
}
|
|
34936
|
+
}
|
|
34937
|
+
const arrayFields = [
|
|
34938
|
+
"triggers",
|
|
34939
|
+
"required_actions",
|
|
34940
|
+
"forbidden_actions",
|
|
34941
|
+
"applies_to_agents",
|
|
34942
|
+
"applies_to_tools",
|
|
34943
|
+
"verification_checks",
|
|
34944
|
+
"source_refs",
|
|
34945
|
+
"source_knowledge_ids"
|
|
34946
|
+
];
|
|
34947
|
+
for (const f of arrayFields) {
|
|
34948
|
+
const v = obj[f];
|
|
34949
|
+
if (v !== undefined && !Array.isArray(v)) {
|
|
34950
|
+
delete obj[f];
|
|
34951
|
+
}
|
|
34952
|
+
}
|
|
34953
|
+
return raw;
|
|
34954
|
+
}
|
|
34550
34955
|
async function readRejectedLessons(directory) {
|
|
34551
34956
|
return readKnowledge(resolveSwarmRejectedPath(directory));
|
|
34552
34957
|
}
|
|
@@ -34668,78 +35073,9 @@ var init_knowledge_store = __esm(() => {
|
|
|
34668
35073
|
import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
34669
35074
|
});
|
|
34670
35075
|
|
|
34671
|
-
// src/hooks/knowledge-reader.ts
|
|
34672
|
-
import { existsSync as existsSync8 } from "fs";
|
|
34673
|
-
import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
34674
|
-
import * as path11 from "path";
|
|
34675
|
-
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
34676
|
-
const shownFile = path11.join(directory, ".swarm", ".knowledge-shown.json");
|
|
34677
|
-
try {
|
|
34678
|
-
if (!existsSync8(shownFile)) {
|
|
34679
|
-
return;
|
|
34680
|
-
}
|
|
34681
|
-
const content = await readFile4(shownFile, "utf-8");
|
|
34682
|
-
const shownData = JSON.parse(content);
|
|
34683
|
-
const shownIds = shownData[phaseInfo];
|
|
34684
|
-
if (!shownIds || shownIds.length === 0) {
|
|
34685
|
-
return;
|
|
34686
|
-
}
|
|
34687
|
-
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
34688
|
-
const entries = await readKnowledge(swarmPath);
|
|
34689
|
-
let updated = false;
|
|
34690
|
-
const foundInSwarm = new Set;
|
|
34691
|
-
for (const entry of entries) {
|
|
34692
|
-
if (shownIds.includes(entry.id)) {
|
|
34693
|
-
entry.retrieval_outcomes.applied_count++;
|
|
34694
|
-
if (phaseSucceeded) {
|
|
34695
|
-
entry.retrieval_outcomes.succeeded_after_count++;
|
|
34696
|
-
} else {
|
|
34697
|
-
entry.retrieval_outcomes.failed_after_count++;
|
|
34698
|
-
}
|
|
34699
|
-
updated = true;
|
|
34700
|
-
foundInSwarm.add(entry.id);
|
|
34701
|
-
}
|
|
34702
|
-
}
|
|
34703
|
-
if (updated) {
|
|
34704
|
-
await rewriteKnowledge(swarmPath, entries);
|
|
34705
|
-
}
|
|
34706
|
-
const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
|
|
34707
|
-
if (remainingIds.length === 0) {
|
|
34708
|
-
delete shownData[phaseInfo];
|
|
34709
|
-
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
34710
|
-
return;
|
|
34711
|
-
}
|
|
34712
|
-
const hivePath = resolveHiveKnowledgePath();
|
|
34713
|
-
const hiveEntries = await readKnowledge(hivePath);
|
|
34714
|
-
let hiveUpdated = false;
|
|
34715
|
-
for (const entry of hiveEntries) {
|
|
34716
|
-
if (remainingIds.includes(entry.id)) {
|
|
34717
|
-
entry.retrieval_outcomes.applied_count++;
|
|
34718
|
-
if (phaseSucceeded) {
|
|
34719
|
-
entry.retrieval_outcomes.succeeded_after_count++;
|
|
34720
|
-
} else {
|
|
34721
|
-
entry.retrieval_outcomes.failed_after_count++;
|
|
34722
|
-
}
|
|
34723
|
-
hiveUpdated = true;
|
|
34724
|
-
}
|
|
34725
|
-
}
|
|
34726
|
-
if (hiveUpdated) {
|
|
34727
|
-
await rewriteKnowledge(hivePath, hiveEntries);
|
|
34728
|
-
}
|
|
34729
|
-
delete shownData[phaseInfo];
|
|
34730
|
-
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
34731
|
-
} catch {
|
|
34732
|
-
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
34733
|
-
}
|
|
34734
|
-
}
|
|
34735
|
-
var init_knowledge_reader = __esm(() => {
|
|
34736
|
-
init_logger();
|
|
34737
|
-
init_knowledge_store();
|
|
34738
|
-
});
|
|
34739
|
-
|
|
34740
35076
|
// src/hooks/knowledge-validator.ts
|
|
34741
|
-
import { appendFile as appendFile3, mkdir as
|
|
34742
|
-
import * as
|
|
35077
|
+
import { appendFile as appendFile3, mkdir as mkdir3, writeFile as writeFile4 } from "fs/promises";
|
|
35078
|
+
import * as path11 from "path";
|
|
34743
35079
|
function normalizeText(text) {
|
|
34744
35080
|
return text.normalize("NFKC").toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
34745
35081
|
}
|
|
@@ -34893,11 +35229,11 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34893
35229
|
return;
|
|
34894
35230
|
}
|
|
34895
35231
|
const sanitizedReason = reason.slice(0, 500).replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\x0d]/g, "");
|
|
34896
|
-
const knowledgePath =
|
|
34897
|
-
const quarantinePath =
|
|
34898
|
-
const rejectedPath =
|
|
34899
|
-
const swarmDir =
|
|
34900
|
-
await
|
|
35232
|
+
const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
|
|
35233
|
+
const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
35234
|
+
const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
35235
|
+
const swarmDir = path11.join(directory, ".swarm");
|
|
35236
|
+
await mkdir3(swarmDir, { recursive: true });
|
|
34901
35237
|
let release;
|
|
34902
35238
|
try {
|
|
34903
35239
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
@@ -34918,7 +35254,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34918
35254
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
34919
35255
|
`)}
|
|
34920
35256
|
` : "";
|
|
34921
|
-
await
|
|
35257
|
+
await writeFile4(knowledgePath, jsonlContent, "utf-8");
|
|
34922
35258
|
await appendFile3(quarantinePath, `${JSON.stringify(quarantined)}
|
|
34923
35259
|
`, "utf-8");
|
|
34924
35260
|
const quarantinedEntries = await readKnowledge(quarantinePath);
|
|
@@ -34927,7 +35263,7 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34927
35263
|
const capContent = trimmed.length > 0 ? `${trimmed.map((e) => JSON.stringify(e)).join(`
|
|
34928
35264
|
`)}
|
|
34929
35265
|
` : "";
|
|
34930
|
-
await
|
|
35266
|
+
await writeFile4(quarantinePath, capContent, "utf-8");
|
|
34931
35267
|
}
|
|
34932
35268
|
const rejectedRecord = {
|
|
34933
35269
|
id: entryId,
|
|
@@ -34953,11 +35289,11 @@ async function restoreEntry(directory, entryId) {
|
|
|
34953
35289
|
warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
|
|
34954
35290
|
return;
|
|
34955
35291
|
}
|
|
34956
|
-
const knowledgePath =
|
|
34957
|
-
const quarantinePath =
|
|
34958
|
-
const rejectedPath =
|
|
34959
|
-
const swarmDir =
|
|
34960
|
-
await
|
|
35292
|
+
const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
|
|
35293
|
+
const quarantinePath = path11.join(directory, ".swarm", "knowledge-quarantined.jsonl");
|
|
35294
|
+
const rejectedPath = path11.join(directory, ".swarm", "knowledge-rejected.jsonl");
|
|
35295
|
+
const swarmDir = path11.join(directory, ".swarm");
|
|
35296
|
+
await mkdir3(swarmDir, { recursive: true });
|
|
34961
35297
|
let release;
|
|
34962
35298
|
try {
|
|
34963
35299
|
release = await import_proper_lockfile4.default.lock(swarmDir, {
|
|
@@ -34973,7 +35309,7 @@ async function restoreEntry(directory, entryId) {
|
|
|
34973
35309
|
const jsonlContent = remaining.length > 0 ? `${remaining.map((e) => JSON.stringify(e)).join(`
|
|
34974
35310
|
`)}
|
|
34975
35311
|
` : "";
|
|
34976
|
-
await
|
|
35312
|
+
await writeFile4(quarantinePath, jsonlContent, "utf-8");
|
|
34977
35313
|
await appendFile3(knowledgePath, `${JSON.stringify(original)}
|
|
34978
35314
|
`, "utf-8");
|
|
34979
35315
|
const rejectedEntries = await readKnowledge(rejectedPath);
|
|
@@ -34981,14 +35317,14 @@ async function restoreEntry(directory, entryId) {
|
|
|
34981
35317
|
const rejectedContent = filtered.length > 0 ? `${filtered.map((e) => JSON.stringify(e)).join(`
|
|
34982
35318
|
`)}
|
|
34983
35319
|
` : "";
|
|
34984
|
-
await
|
|
35320
|
+
await writeFile4(rejectedPath, rejectedContent, "utf-8");
|
|
34985
35321
|
} finally {
|
|
34986
35322
|
if (release) {
|
|
34987
35323
|
await release();
|
|
34988
35324
|
}
|
|
34989
35325
|
}
|
|
34990
35326
|
}
|
|
34991
|
-
var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS;
|
|
35327
|
+
var import_proper_lockfile4, DANGEROUS_COMMAND_PATTERNS, SECURITY_DEGRADING_PATTERNS, INVISIBLE_FORMAT_CHARS, INJECTION_PATTERNS, VALID_CATEGORIES, TECH_REFERENCE_WORDS, ACTION_VERB_WORDS, NEGATION_PAIRS, VALID_DIRECTIVE_PRIORITIES;
|
|
34992
35328
|
var init_knowledge_validator = __esm(() => {
|
|
34993
35329
|
init_logger();
|
|
34994
35330
|
init_knowledge_store();
|
|
@@ -35094,6 +35430,329 @@ var init_knowledge_validator = __esm(() => {
|
|
|
35094
35430
|
["use", "don't use"],
|
|
35095
35431
|
["recommended", "not recommended"]
|
|
35096
35432
|
];
|
|
35433
|
+
VALID_DIRECTIVE_PRIORITIES = new Set([
|
|
35434
|
+
"low",
|
|
35435
|
+
"medium",
|
|
35436
|
+
"high",
|
|
35437
|
+
"critical"
|
|
35438
|
+
]);
|
|
35439
|
+
});
|
|
35440
|
+
|
|
35441
|
+
// src/hooks/curator.ts
|
|
35442
|
+
var init_curator = __esm(() => {
|
|
35443
|
+
init_event_bus();
|
|
35444
|
+
init_schema();
|
|
35445
|
+
init_manager();
|
|
35446
|
+
init_state();
|
|
35447
|
+
init_bun_compat();
|
|
35448
|
+
init_logger();
|
|
35449
|
+
init_knowledge_store();
|
|
35450
|
+
init_knowledge_validator();
|
|
35451
|
+
init_utils2();
|
|
35452
|
+
});
|
|
35453
|
+
|
|
35454
|
+
// src/hooks/hive-promoter.ts
|
|
35455
|
+
import path12 from "path";
|
|
35456
|
+
function isAlreadyInHive(entry, hiveEntries, threshold) {
|
|
35457
|
+
return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
|
|
35458
|
+
}
|
|
35459
|
+
function countDistinctPhases(confirmedBy) {
|
|
35460
|
+
const phaseNumbers = new Set;
|
|
35461
|
+
for (const record3 of confirmedBy) {
|
|
35462
|
+
phaseNumbers.add(record3.phase_number);
|
|
35463
|
+
}
|
|
35464
|
+
return phaseNumbers.size;
|
|
35465
|
+
}
|
|
35466
|
+
function countDistinctProjects(confirmedBy) {
|
|
35467
|
+
const projectNames = new Set;
|
|
35468
|
+
for (const record3 of confirmedBy) {
|
|
35469
|
+
projectNames.add(record3.project_name);
|
|
35470
|
+
}
|
|
35471
|
+
return projectNames.size;
|
|
35472
|
+
}
|
|
35473
|
+
function hasProjectConfirmation(hiveEntry, projectName) {
|
|
35474
|
+
return hiveEntry.confirmed_by.some((record3) => record3.project_name === projectName);
|
|
35475
|
+
}
|
|
35476
|
+
function calculateEncounterScore(currentScore, isSameProject, config3) {
|
|
35477
|
+
const weight = isSameProject ? config3.same_project_weight : config3.cross_project_weight;
|
|
35478
|
+
const increment = config3.encounter_increment * weight;
|
|
35479
|
+
const newScore = currentScore + increment;
|
|
35480
|
+
return Math.min(Math.max(newScore, config3.min_encounter_score), config3.max_encounter_score);
|
|
35481
|
+
}
|
|
35482
|
+
function getEntryAgeMs(createdAt) {
|
|
35483
|
+
const createdTime = new Date(createdAt).getTime();
|
|
35484
|
+
if (Number.isNaN(createdTime))
|
|
35485
|
+
return 0;
|
|
35486
|
+
return Date.now() - createdTime;
|
|
35487
|
+
}
|
|
35488
|
+
async function checkHivePromotions(swarmEntries, config3) {
|
|
35489
|
+
let newPromotions = 0;
|
|
35490
|
+
let encountersIncremented = 0;
|
|
35491
|
+
let advancements = 0;
|
|
35492
|
+
if (config3.hive_enabled === false) {
|
|
35493
|
+
return {
|
|
35494
|
+
timestamp: new Date().toISOString(),
|
|
35495
|
+
new_promotions: 0,
|
|
35496
|
+
encounters_incremented: 0,
|
|
35497
|
+
advancements: 0,
|
|
35498
|
+
total_hive_entries: 0
|
|
35499
|
+
};
|
|
35500
|
+
}
|
|
35501
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35502
|
+
for (const swarmEntry of swarmEntries) {
|
|
35503
|
+
if (isAlreadyInHive(swarmEntry, hiveEntries, config3.dedup_threshold)) {
|
|
35504
|
+
continue;
|
|
35505
|
+
}
|
|
35506
|
+
let shouldPromote = false;
|
|
35507
|
+
if (swarmEntry.hive_eligible === true && countDistinctPhases(swarmEntry.confirmed_by) >= 3) {
|
|
35508
|
+
shouldPromote = true;
|
|
35509
|
+
}
|
|
35510
|
+
if (swarmEntry.tags.includes("hive-fast-track")) {
|
|
35511
|
+
shouldPromote = true;
|
|
35512
|
+
}
|
|
35513
|
+
const ageMs = getEntryAgeMs(swarmEntry.created_at);
|
|
35514
|
+
const ageThresholdMs = config3.auto_promote_days * 86400000;
|
|
35515
|
+
if (ageMs >= ageThresholdMs) {
|
|
35516
|
+
shouldPromote = true;
|
|
35517
|
+
}
|
|
35518
|
+
if (!shouldPromote) {
|
|
35519
|
+
continue;
|
|
35520
|
+
}
|
|
35521
|
+
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
35522
|
+
category: swarmEntry.category,
|
|
35523
|
+
scope: swarmEntry.scope,
|
|
35524
|
+
confidence: swarmEntry.confidence
|
|
35525
|
+
});
|
|
35526
|
+
if (validationResult.severity === "error") {
|
|
35527
|
+
const rejectedLesson = {
|
|
35528
|
+
id: crypto.randomUUID(),
|
|
35529
|
+
lesson: swarmEntry.lesson,
|
|
35530
|
+
rejection_reason: validationResult.reason || "validation failed for hive promotion",
|
|
35531
|
+
rejected_at: new Date().toISOString(),
|
|
35532
|
+
rejection_layer: validationResult.layer || 2
|
|
35533
|
+
};
|
|
35534
|
+
const hiveRejectedPath = resolveHiveRejectedPath();
|
|
35535
|
+
await appendKnowledge(hiveRejectedPath, rejectedLesson);
|
|
35536
|
+
continue;
|
|
35537
|
+
}
|
|
35538
|
+
const newHiveEntry = {
|
|
35539
|
+
id: crypto.randomUUID(),
|
|
35540
|
+
tier: "hive",
|
|
35541
|
+
lesson: swarmEntry.lesson,
|
|
35542
|
+
category: swarmEntry.category,
|
|
35543
|
+
tags: swarmEntry.tags,
|
|
35544
|
+
scope: swarmEntry.scope,
|
|
35545
|
+
confidence: 0.5,
|
|
35546
|
+
status: "candidate",
|
|
35547
|
+
confirmed_by: [],
|
|
35548
|
+
retrieval_outcomes: {
|
|
35549
|
+
applied_count: 0,
|
|
35550
|
+
succeeded_after_count: 0,
|
|
35551
|
+
failed_after_count: 0
|
|
35552
|
+
},
|
|
35553
|
+
schema_version: config3.schema_version,
|
|
35554
|
+
created_at: new Date().toISOString(),
|
|
35555
|
+
updated_at: new Date().toISOString(),
|
|
35556
|
+
source_project: swarmEntry.project_name,
|
|
35557
|
+
encounter_score: config3.initial_encounter_score
|
|
35558
|
+
};
|
|
35559
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35560
|
+
newPromotions++;
|
|
35561
|
+
hiveEntries.push(newHiveEntry);
|
|
35562
|
+
}
|
|
35563
|
+
let hiveModified = false;
|
|
35564
|
+
for (const hiveEntry of hiveEntries) {
|
|
35565
|
+
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
|
|
35566
|
+
if (!nearDuplicate) {
|
|
35567
|
+
continue;
|
|
35568
|
+
}
|
|
35569
|
+
const isSameProject = nearDuplicate.project_name === hiveEntry.source_project;
|
|
35570
|
+
if (hasProjectConfirmation(hiveEntry, nearDuplicate.project_name)) {
|
|
35571
|
+
continue;
|
|
35572
|
+
}
|
|
35573
|
+
const newConfirmation = {
|
|
35574
|
+
project_name: nearDuplicate.project_name,
|
|
35575
|
+
confirmed_at: new Date().toISOString()
|
|
35576
|
+
};
|
|
35577
|
+
hiveEntry.confirmed_by.push(newConfirmation);
|
|
35578
|
+
const currentScore = hiveEntry.encounter_score ?? 1;
|
|
35579
|
+
hiveEntry.encounter_score = calculateEncounterScore(currentScore, isSameProject, config3);
|
|
35580
|
+
encountersIncremented++;
|
|
35581
|
+
hiveEntry.updated_at = new Date().toISOString();
|
|
35582
|
+
if (hiveEntry.status === "candidate" && countDistinctProjects(hiveEntry.confirmed_by) >= 3) {
|
|
35583
|
+
hiveEntry.status = "established";
|
|
35584
|
+
advancements++;
|
|
35585
|
+
}
|
|
35586
|
+
hiveModified = true;
|
|
35587
|
+
}
|
|
35588
|
+
if (hiveModified) {
|
|
35589
|
+
await rewriteKnowledge(resolveHiveKnowledgePath(), hiveEntries);
|
|
35590
|
+
}
|
|
35591
|
+
if (newPromotions > 0 || hiveModified) {
|
|
35592
|
+
await enforceKnowledgeCap(resolveHiveKnowledgePath(), config3.hive_max_entries);
|
|
35593
|
+
}
|
|
35594
|
+
return {
|
|
35595
|
+
timestamp: new Date().toISOString(),
|
|
35596
|
+
new_promotions: newPromotions,
|
|
35597
|
+
encounters_incremented: encountersIncremented,
|
|
35598
|
+
advancements,
|
|
35599
|
+
total_hive_entries: hiveEntries.length
|
|
35600
|
+
};
|
|
35601
|
+
}
|
|
35602
|
+
async function promoteToHive(directory, lesson, category) {
|
|
35603
|
+
const trimmedLesson = lesson.trim();
|
|
35604
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35605
|
+
const validationResult = validateLesson(trimmedLesson, hiveEntries.map((e) => e.lesson), {
|
|
35606
|
+
category: category || "process",
|
|
35607
|
+
scope: "global",
|
|
35608
|
+
confidence: 1
|
|
35609
|
+
});
|
|
35610
|
+
if (validationResult.severity === "error") {
|
|
35611
|
+
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
35612
|
+
}
|
|
35613
|
+
if (findNearDuplicate(trimmedLesson, hiveEntries, 0.6)) {
|
|
35614
|
+
return `Lesson already exists in hive (near-duplicate).`;
|
|
35615
|
+
}
|
|
35616
|
+
const newHiveEntry = {
|
|
35617
|
+
id: crypto.randomUUID(),
|
|
35618
|
+
tier: "hive",
|
|
35619
|
+
lesson: trimmedLesson,
|
|
35620
|
+
category: category || "process",
|
|
35621
|
+
tags: [],
|
|
35622
|
+
scope: "global",
|
|
35623
|
+
confidence: 1,
|
|
35624
|
+
status: "promoted",
|
|
35625
|
+
confirmed_by: [],
|
|
35626
|
+
retrieval_outcomes: {
|
|
35627
|
+
applied_count: 0,
|
|
35628
|
+
succeeded_after_count: 0,
|
|
35629
|
+
failed_after_count: 0
|
|
35630
|
+
},
|
|
35631
|
+
schema_version: 1,
|
|
35632
|
+
created_at: new Date().toISOString(),
|
|
35633
|
+
updated_at: new Date().toISOString(),
|
|
35634
|
+
source_project: path12.basename(directory) || "unknown",
|
|
35635
|
+
encounter_score: 1
|
|
35636
|
+
};
|
|
35637
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35638
|
+
return `Promoted to hive: "${trimmedLesson.slice(0, 50)}${trimmedLesson.length > 50 ? "..." : ""}" (confidence: 1.0, source: manual)`;
|
|
35639
|
+
}
|
|
35640
|
+
async function promoteFromSwarm(directory, lessonId) {
|
|
35641
|
+
const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
35642
|
+
const swarmEntry = swarmEntries.find((e) => e.id === lessonId);
|
|
35643
|
+
if (!swarmEntry) {
|
|
35644
|
+
throw new Error(`Lesson ${lessonId} not found in .swarm/knowledge.jsonl`);
|
|
35645
|
+
}
|
|
35646
|
+
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
35647
|
+
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
35648
|
+
category: swarmEntry.category,
|
|
35649
|
+
scope: swarmEntry.scope,
|
|
35650
|
+
confidence: swarmEntry.confidence
|
|
35651
|
+
});
|
|
35652
|
+
if (validationResult.severity === "error") {
|
|
35653
|
+
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
35654
|
+
}
|
|
35655
|
+
if (findNearDuplicate(swarmEntry.lesson, hiveEntries, 0.6)) {
|
|
35656
|
+
return `Lesson already exists in hive (near-duplicate).`;
|
|
35657
|
+
}
|
|
35658
|
+
const newHiveEntry = {
|
|
35659
|
+
id: crypto.randomUUID(),
|
|
35660
|
+
tier: "hive",
|
|
35661
|
+
lesson: swarmEntry.lesson,
|
|
35662
|
+
category: swarmEntry.category,
|
|
35663
|
+
tags: swarmEntry.tags,
|
|
35664
|
+
scope: swarmEntry.scope,
|
|
35665
|
+
confidence: 1,
|
|
35666
|
+
status: "promoted",
|
|
35667
|
+
confirmed_by: [],
|
|
35668
|
+
retrieval_outcomes: {
|
|
35669
|
+
applied_count: 0,
|
|
35670
|
+
succeeded_after_count: 0,
|
|
35671
|
+
failed_after_count: 0
|
|
35672
|
+
},
|
|
35673
|
+
schema_version: 1,
|
|
35674
|
+
created_at: new Date().toISOString(),
|
|
35675
|
+
updated_at: new Date().toISOString(),
|
|
35676
|
+
source_project: swarmEntry.project_name,
|
|
35677
|
+
encounter_score: 1
|
|
35678
|
+
};
|
|
35679
|
+
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
35680
|
+
return `Promoted lesson ${lessonId} from swarm to hive: "${swarmEntry.lesson.slice(0, 50)}${swarmEntry.lesson.length > 50 ? "..." : ""}"`;
|
|
35681
|
+
}
|
|
35682
|
+
var init_hive_promoter = __esm(() => {
|
|
35683
|
+
init_curator();
|
|
35684
|
+
init_knowledge_store();
|
|
35685
|
+
init_knowledge_validator();
|
|
35686
|
+
init_utils2();
|
|
35687
|
+
});
|
|
35688
|
+
|
|
35689
|
+
// src/hooks/knowledge-reader.ts
|
|
35690
|
+
import { existsSync as existsSync8 } from "fs";
|
|
35691
|
+
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
35692
|
+
import * as path13 from "path";
|
|
35693
|
+
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
35694
|
+
const shownFile = path13.join(directory, ".swarm", ".knowledge-shown.json");
|
|
35695
|
+
try {
|
|
35696
|
+
if (!existsSync8(shownFile)) {
|
|
35697
|
+
return;
|
|
35698
|
+
}
|
|
35699
|
+
const content = await readFile4(shownFile, "utf-8");
|
|
35700
|
+
const shownData = JSON.parse(content);
|
|
35701
|
+
const shownIds = shownData[phaseInfo];
|
|
35702
|
+
if (!shownIds || shownIds.length === 0) {
|
|
35703
|
+
return;
|
|
35704
|
+
}
|
|
35705
|
+
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
35706
|
+
const entries = await readKnowledge(swarmPath);
|
|
35707
|
+
let updated = false;
|
|
35708
|
+
const foundInSwarm = new Set;
|
|
35709
|
+
for (const entry of entries) {
|
|
35710
|
+
if (shownIds.includes(entry.id)) {
|
|
35711
|
+
const ro = entry.retrieval_outcomes;
|
|
35712
|
+
if (phaseSucceeded) {
|
|
35713
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
35714
|
+
} else {
|
|
35715
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
35716
|
+
}
|
|
35717
|
+
updated = true;
|
|
35718
|
+
foundInSwarm.add(entry.id);
|
|
35719
|
+
}
|
|
35720
|
+
}
|
|
35721
|
+
if (updated) {
|
|
35722
|
+
await rewriteKnowledge(swarmPath, entries);
|
|
35723
|
+
}
|
|
35724
|
+
const remainingIds = shownIds.filter((id) => !foundInSwarm.has(id));
|
|
35725
|
+
if (remainingIds.length === 0) {
|
|
35726
|
+
delete shownData[phaseInfo];
|
|
35727
|
+
await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
35728
|
+
return;
|
|
35729
|
+
}
|
|
35730
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
35731
|
+
const hiveEntries = await readKnowledge(hivePath);
|
|
35732
|
+
let hiveUpdated = false;
|
|
35733
|
+
for (const entry of hiveEntries) {
|
|
35734
|
+
if (remainingIds.includes(entry.id)) {
|
|
35735
|
+
const ro = entry.retrieval_outcomes;
|
|
35736
|
+
if (phaseSucceeded) {
|
|
35737
|
+
ro.succeeded_after_shown_count = (ro.succeeded_after_shown_count ?? 0) + 1;
|
|
35738
|
+
} else {
|
|
35739
|
+
ro.failed_after_shown_count = (ro.failed_after_shown_count ?? 0) + 1;
|
|
35740
|
+
}
|
|
35741
|
+
hiveUpdated = true;
|
|
35742
|
+
}
|
|
35743
|
+
}
|
|
35744
|
+
if (hiveUpdated) {
|
|
35745
|
+
await rewriteKnowledge(hivePath, hiveEntries);
|
|
35746
|
+
}
|
|
35747
|
+
delete shownData[phaseInfo];
|
|
35748
|
+
await writeFile5(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
35749
|
+
} catch {
|
|
35750
|
+
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
35751
|
+
}
|
|
35752
|
+
}
|
|
35753
|
+
var init_knowledge_reader = __esm(() => {
|
|
35754
|
+
init_logger();
|
|
35755
|
+
init_knowledge_store();
|
|
35097
35756
|
});
|
|
35098
35757
|
|
|
35099
35758
|
// src/hooks/knowledge-curator.ts
|
|
@@ -35431,133 +36090,6 @@ var init_knowledge_curator = __esm(() => {
|
|
|
35431
36090
|
};
|
|
35432
36091
|
});
|
|
35433
36092
|
|
|
35434
|
-
// src/session/snapshot-writer.ts
|
|
35435
|
-
import { mkdirSync as mkdirSync7, renameSync as renameSync5 } from "fs";
|
|
35436
|
-
import * as path13 from "path";
|
|
35437
|
-
function serializeAgentSession(s) {
|
|
35438
|
-
const gateLog = {};
|
|
35439
|
-
const rawGateLog = s.gateLog ?? new Map;
|
|
35440
|
-
for (const [taskId, gates] of rawGateLog) {
|
|
35441
|
-
gateLog[taskId] = Array.from(gates ?? []);
|
|
35442
|
-
}
|
|
35443
|
-
const reviewerCallCount = {};
|
|
35444
|
-
const rawReviewerCallCount = s.reviewerCallCount ?? new Map;
|
|
35445
|
-
for (const [phase, count] of rawReviewerCallCount) {
|
|
35446
|
-
reviewerCallCount[String(phase)] = count;
|
|
35447
|
-
}
|
|
35448
|
-
const partialGateWarningsIssuedForTask = Array.from(s.partialGateWarningsIssuedForTask ?? new Set);
|
|
35449
|
-
const catastrophicPhaseWarnings = Array.from(s.catastrophicPhaseWarnings ?? new Set);
|
|
35450
|
-
const phaseAgentsDispatched = Array.from(s.phaseAgentsDispatched ?? new Set);
|
|
35451
|
-
const lastCompletedPhaseAgentsDispatched = Array.from(s.lastCompletedPhaseAgentsDispatched ?? new Set);
|
|
35452
|
-
const windows = {};
|
|
35453
|
-
const rawWindows = s.windows ?? {};
|
|
35454
|
-
for (const [key, win] of Object.entries(rawWindows)) {
|
|
35455
|
-
windows[key] = {
|
|
35456
|
-
id: win.id,
|
|
35457
|
-
agentName: win.agentName,
|
|
35458
|
-
startedAtMs: win.startedAtMs,
|
|
35459
|
-
toolCalls: win.toolCalls,
|
|
35460
|
-
consecutiveErrors: win.consecutiveErrors,
|
|
35461
|
-
hardLimitHit: win.hardLimitHit,
|
|
35462
|
-
lastSuccessTimeMs: win.lastSuccessTimeMs,
|
|
35463
|
-
recentToolCalls: win.recentToolCalls,
|
|
35464
|
-
warningIssued: win.warningIssued,
|
|
35465
|
-
warningReason: win.warningReason,
|
|
35466
|
-
transientRetryCount: win.transientRetryCount ?? 0
|
|
35467
|
-
};
|
|
35468
|
-
}
|
|
35469
|
-
return {
|
|
35470
|
-
agentName: s.agentName,
|
|
35471
|
-
lastToolCallTime: s.lastToolCallTime,
|
|
35472
|
-
lastAgentEventTime: s.lastAgentEventTime,
|
|
35473
|
-
delegationActive: s.delegationActive,
|
|
35474
|
-
activeInvocationId: s.activeInvocationId,
|
|
35475
|
-
lastInvocationIdByAgent: s.lastInvocationIdByAgent ?? {},
|
|
35476
|
-
windows,
|
|
35477
|
-
lastCompactionHint: s.lastCompactionHint ?? 0,
|
|
35478
|
-
architectWriteCount: s.architectWriteCount ?? 0,
|
|
35479
|
-
lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
|
|
35480
|
-
currentTaskId: s.currentTaskId ?? null,
|
|
35481
|
-
turboMode: s.turboMode ?? false,
|
|
35482
|
-
gateLog,
|
|
35483
|
-
reviewerCallCount,
|
|
35484
|
-
lastGateFailure: s.lastGateFailure ?? null,
|
|
35485
|
-
partialGateWarningsIssuedForTask,
|
|
35486
|
-
selfFixAttempted: s.selfFixAttempted ?? false,
|
|
35487
|
-
selfCodingWarnedAtCount: s.selfCodingWarnedAtCount ?? 0,
|
|
35488
|
-
catastrophicPhaseWarnings,
|
|
35489
|
-
lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
|
|
35490
|
-
lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
|
|
35491
|
-
phaseAgentsDispatched,
|
|
35492
|
-
lastCompletedPhaseAgentsDispatched,
|
|
35493
|
-
qaSkipCount: s.qaSkipCount ?? 0,
|
|
35494
|
-
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
35495
|
-
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
|
|
35496
|
-
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
35497
|
-
...s.scopeViolationDetected !== undefined && {
|
|
35498
|
-
scopeViolationDetected: s.scopeViolationDetected
|
|
35499
|
-
},
|
|
35500
|
-
model_fallback_index: s.model_fallback_index ?? 0,
|
|
35501
|
-
modelFallbackExhausted: s.modelFallbackExhausted ?? false,
|
|
35502
|
-
coderRevisions: s.coderRevisions ?? 0,
|
|
35503
|
-
revisionLimitHit: s.revisionLimitHit ?? false,
|
|
35504
|
-
fullAutoMode: s.fullAutoMode ?? false,
|
|
35505
|
-
fullAutoInteractionCount: s.fullAutoInteractionCount ?? 0,
|
|
35506
|
-
fullAutoDeadlockCount: s.fullAutoDeadlockCount ?? 0,
|
|
35507
|
-
fullAutoLastQuestionHash: s.fullAutoLastQuestionHash ?? null,
|
|
35508
|
-
sessionRehydratedAt: s.sessionRehydratedAt ?? 0
|
|
35509
|
-
};
|
|
35510
|
-
}
|
|
35511
|
-
async function writeSnapshot(directory, state) {
|
|
35512
|
-
try {
|
|
35513
|
-
const snapshot = {
|
|
35514
|
-
version: 2,
|
|
35515
|
-
writtenAt: Date.now(),
|
|
35516
|
-
toolAggregates: Object.fromEntries(state.toolAggregates),
|
|
35517
|
-
activeAgent: Object.fromEntries(state.activeAgent),
|
|
35518
|
-
delegationChains: Object.fromEntries(state.delegationChains),
|
|
35519
|
-
agentSessions: {}
|
|
35520
|
-
};
|
|
35521
|
-
for (const [sessionId, sessionState] of state.agentSessions) {
|
|
35522
|
-
snapshot.agentSessions[sessionId] = serializeAgentSession(sessionState);
|
|
35523
|
-
}
|
|
35524
|
-
const content = JSON.stringify(snapshot, null, 2);
|
|
35525
|
-
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
35526
|
-
const dir = path13.dirname(resolvedPath);
|
|
35527
|
-
mkdirSync7(dir, { recursive: true });
|
|
35528
|
-
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
35529
|
-
await bunWrite(tempPath, content);
|
|
35530
|
-
renameSync5(tempPath, resolvedPath);
|
|
35531
|
-
} catch (error93) {
|
|
35532
|
-
log("[snapshot-writer] write failed", {
|
|
35533
|
-
error: error93 instanceof Error ? error93.message : String(error93)
|
|
35534
|
-
});
|
|
35535
|
-
}
|
|
35536
|
-
}
|
|
35537
|
-
function createSnapshotWriterHook(directory) {
|
|
35538
|
-
return (_input, _output) => {
|
|
35539
|
-
_writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
|
|
35540
|
-
return _writeInFlight;
|
|
35541
|
-
};
|
|
35542
|
-
}
|
|
35543
|
-
async function flushPendingSnapshot(directory) {
|
|
35544
|
-
_writeInFlight = _writeInFlight.then(() => _internals8.writeSnapshot(directory, swarmState), () => _internals8.writeSnapshot(directory, swarmState));
|
|
35545
|
-
await _writeInFlight;
|
|
35546
|
-
}
|
|
35547
|
-
var _writeInFlight, _internals8;
|
|
35548
|
-
var init_snapshot_writer = __esm(() => {
|
|
35549
|
-
init_utils2();
|
|
35550
|
-
init_state();
|
|
35551
|
-
init_utils();
|
|
35552
|
-
init_bun_compat();
|
|
35553
|
-
_writeInFlight = Promise.resolve();
|
|
35554
|
-
_internals8 = {
|
|
35555
|
-
writeSnapshot,
|
|
35556
|
-
createSnapshotWriterHook,
|
|
35557
|
-
flushPendingSnapshot
|
|
35558
|
-
};
|
|
35559
|
-
});
|
|
35560
|
-
|
|
35561
36093
|
// src/tools/write-retro.ts
|
|
35562
36094
|
async function executeWriteRetro(args, directory) {
|
|
35563
36095
|
if (/^(CON|PRN|AUX|NUL|COM[0-9]|LPT[0-9])(:|$)/i.test(directory)) {
|
|
@@ -35859,7 +36391,7 @@ async function executeWriteRetro(args, directory) {
|
|
|
35859
36391
|
}, null, 2);
|
|
35860
36392
|
}
|
|
35861
36393
|
}
|
|
35862
|
-
var write_retro,
|
|
36394
|
+
var write_retro, _internals8;
|
|
35863
36395
|
var init_write_retro = __esm(() => {
|
|
35864
36396
|
init_zod();
|
|
35865
36397
|
init_evidence_schema();
|
|
@@ -35906,13 +36438,13 @@ var init_write_retro = __esm(() => {
|
|
|
35906
36438
|
task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
|
|
35907
36439
|
metadata: args.metadata
|
|
35908
36440
|
};
|
|
35909
|
-
return await
|
|
36441
|
+
return await _internals8.executeWriteRetro(writeRetroArgs, directory);
|
|
35910
36442
|
} catch {
|
|
35911
36443
|
return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
|
|
35912
36444
|
}
|
|
35913
36445
|
}
|
|
35914
36446
|
});
|
|
35915
|
-
|
|
36447
|
+
_internals8 = {
|
|
35916
36448
|
executeWriteRetro,
|
|
35917
36449
|
write_retro
|
|
35918
36450
|
};
|
|
@@ -35974,6 +36506,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
35974
36506
|
const closedPhases = [];
|
|
35975
36507
|
const closedTasks = [];
|
|
35976
36508
|
const warnings = [];
|
|
36509
|
+
let hivePromoted = 0;
|
|
35977
36510
|
if (!planAlreadyDone) {
|
|
35978
36511
|
for (const phase of inProgressPhases) {
|
|
35979
36512
|
closedPhases.push(phase.id);
|
|
@@ -36094,6 +36627,26 @@ async function handleCloseCommand(directory, args) {
|
|
|
36094
36627
|
if (curationSucceeded && allLessons.length > 0) {
|
|
36095
36628
|
await fs7.unlink(lessonsFilePath).catch(() => {});
|
|
36096
36629
|
}
|
|
36630
|
+
if (curationSucceeded) {
|
|
36631
|
+
try {
|
|
36632
|
+
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
36633
|
+
const entries = await readKnowledge(knowledgePath);
|
|
36634
|
+
if (entries.length > 0) {
|
|
36635
|
+
for (const entry of entries) {
|
|
36636
|
+
try {
|
|
36637
|
+
await promoteToHive(directory, entry.lesson, entry.category);
|
|
36638
|
+
hivePromoted++;
|
|
36639
|
+
} catch (promotionErr) {
|
|
36640
|
+
const msg = promotionErr instanceof Error ? promotionErr.message : String(promotionErr);
|
|
36641
|
+
warnings.push(`Hive promotion skipped for lesson: ${msg}`);
|
|
36642
|
+
}
|
|
36643
|
+
}
|
|
36644
|
+
}
|
|
36645
|
+
} catch (hiveErr) {
|
|
36646
|
+
const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
|
|
36647
|
+
warnings.push(`Hive promotion failed: ${msg}`);
|
|
36648
|
+
}
|
|
36649
|
+
}
|
|
36097
36650
|
if (planExists) {
|
|
36098
36651
|
const guaranteeResult = guaranteeAllPlansComplete(planData);
|
|
36099
36652
|
for (const phaseId of guaranteeResult.closedPhaseIds) {
|
|
@@ -36122,6 +36675,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
36122
36675
|
let archiveResult = "";
|
|
36123
36676
|
let archivedFileCount = 0;
|
|
36124
36677
|
const archivedActiveStateFiles = new Set;
|
|
36678
|
+
const archivedActiveStateDirs = new Set;
|
|
36125
36679
|
try {
|
|
36126
36680
|
await fs7.mkdir(archiveDir, { recursive: true });
|
|
36127
36681
|
for (const artifact of ARCHIVE_ARTIFACTS) {
|
|
@@ -36135,38 +36689,34 @@ async function handleCloseCommand(directory, args) {
|
|
|
36135
36689
|
}
|
|
36136
36690
|
} catch {}
|
|
36137
36691
|
}
|
|
36138
|
-
const
|
|
36139
|
-
|
|
36140
|
-
|
|
36141
|
-
|
|
36142
|
-
|
|
36143
|
-
|
|
36144
|
-
|
|
36145
|
-
const
|
|
36146
|
-
|
|
36147
|
-
|
|
36148
|
-
|
|
36149
|
-
|
|
36150
|
-
|
|
36151
|
-
|
|
36152
|
-
|
|
36153
|
-
|
|
36692
|
+
for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
|
|
36693
|
+
const srcDir = path14.join(swarmDir, dirName);
|
|
36694
|
+
const destDir = path14.join(archiveDir, dirName);
|
|
36695
|
+
try {
|
|
36696
|
+
const entries = await fs7.readdir(srcDir);
|
|
36697
|
+
if (entries.length > 0) {
|
|
36698
|
+
await fs7.mkdir(destDir, { recursive: true });
|
|
36699
|
+
for (const entry of entries) {
|
|
36700
|
+
const srcEntry = path14.join(srcDir, entry);
|
|
36701
|
+
const destEntry = path14.join(destDir, entry);
|
|
36702
|
+
try {
|
|
36703
|
+
const stat2 = await fs7.stat(srcEntry);
|
|
36704
|
+
if (stat2.isDirectory()) {
|
|
36705
|
+
await fs7.mkdir(destEntry, { recursive: true });
|
|
36706
|
+
const subEntries = await fs7.readdir(srcEntry);
|
|
36707
|
+
for (const sub of subEntries) {
|
|
36708
|
+
await fs7.copyFile(path14.join(srcEntry, sub), path14.join(destEntry, sub)).catch(() => {});
|
|
36709
|
+
}
|
|
36710
|
+
} else {
|
|
36711
|
+
await fs7.copyFile(srcEntry, destEntry);
|
|
36154
36712
|
}
|
|
36155
|
-
|
|
36156
|
-
|
|
36157
|
-
|
|
36158
|
-
archivedFileCount++;
|
|
36159
|
-
} catch {}
|
|
36713
|
+
archivedFileCount++;
|
|
36714
|
+
} catch {}
|
|
36715
|
+
}
|
|
36160
36716
|
}
|
|
36161
|
-
|
|
36162
|
-
|
|
36163
|
-
|
|
36164
|
-
try {
|
|
36165
|
-
const archiveSessionDir = path14.join(archiveDir, "session");
|
|
36166
|
-
await fs7.mkdir(archiveSessionDir, { recursive: true });
|
|
36167
|
-
await fs7.copyFile(sessionStatePath, path14.join(archiveSessionDir, "state.json"));
|
|
36168
|
-
archivedFileCount++;
|
|
36169
|
-
} catch {}
|
|
36717
|
+
archivedActiveStateDirs.add(dirName);
|
|
36718
|
+
} catch {}
|
|
36719
|
+
}
|
|
36170
36720
|
archiveResult = `Archived ${archivedFileCount} artifact(s) to .swarm/archive/swarm-${timestamp}/`;
|
|
36171
36721
|
} catch (archiveError) {
|
|
36172
36722
|
warnings.push(`Archive creation failed: ${archiveError instanceof Error ? archiveError.message : String(archiveError)}`);
|
|
@@ -36196,6 +36746,16 @@ async function handleCloseCommand(directory, args) {
|
|
|
36196
36746
|
} else {
|
|
36197
36747
|
warnings.push("Skipped active-state cleanup because no active-state files were archived. Files preserved to prevent data loss.");
|
|
36198
36748
|
}
|
|
36749
|
+
for (const dirName of ACTIVE_STATE_DIRS_TO_CLEAN) {
|
|
36750
|
+
if (!archivedActiveStateDirs.has(dirName)) {
|
|
36751
|
+
continue;
|
|
36752
|
+
}
|
|
36753
|
+
const dirPath = path14.join(swarmDir, dirName);
|
|
36754
|
+
try {
|
|
36755
|
+
await fs7.rm(dirPath, { recursive: true, force: true });
|
|
36756
|
+
cleanedFiles.push(`${dirName}/`);
|
|
36757
|
+
} catch {}
|
|
36758
|
+
}
|
|
36199
36759
|
try {
|
|
36200
36760
|
const swarmFiles = await fs7.readdir(swarmDir);
|
|
36201
36761
|
const configBackups = swarmFiles.filter((f) => f.startsWith("config-backup-") && f.endsWith(".json"));
|
|
@@ -36254,17 +36814,30 @@ async function handleCloseCommand(directory, args) {
|
|
|
36254
36814
|
const prunedBranches = [];
|
|
36255
36815
|
const isGit = isGitRepo2(directory);
|
|
36256
36816
|
if (isGit) {
|
|
36257
|
-
const
|
|
36258
|
-
|
|
36259
|
-
|
|
36260
|
-
if (
|
|
36261
|
-
|
|
36262
|
-
|
|
36263
|
-
|
|
36264
|
-
|
|
36265
|
-
|
|
36266
|
-
|
|
36267
|
-
|
|
36817
|
+
const aggressiveResult = resetToMainAfterMerge(directory, {
|
|
36818
|
+
pruneBranches
|
|
36819
|
+
});
|
|
36820
|
+
if (aggressiveResult.success) {
|
|
36821
|
+
gitAlignResult = aggressiveResult.message;
|
|
36822
|
+
for (const w of aggressiveResult.warnings) {
|
|
36823
|
+
warnings.push(w);
|
|
36824
|
+
}
|
|
36825
|
+
if (aggressiveResult.changesDiscarded) {
|
|
36826
|
+
warnings.push("Uncommitted changes were discarded during git alignment");
|
|
36827
|
+
}
|
|
36828
|
+
} else {
|
|
36829
|
+
const alignResult = resetToRemoteBranch(directory, { pruneBranches });
|
|
36830
|
+
gitAlignResult = alignResult.message;
|
|
36831
|
+
prunedBranches.push(...alignResult.prunedBranches);
|
|
36832
|
+
if (!alignResult.success) {
|
|
36833
|
+
warnings.push(`Git alignment: ${alignResult.message}`);
|
|
36834
|
+
}
|
|
36835
|
+
if (alignResult.alreadyAligned) {
|
|
36836
|
+
gitAlignResult = `Already aligned with ${alignResult.targetBranch}`;
|
|
36837
|
+
}
|
|
36838
|
+
for (const w of alignResult.warnings) {
|
|
36839
|
+
warnings.push(w);
|
|
36840
|
+
}
|
|
36268
36841
|
}
|
|
36269
36842
|
} else {
|
|
36270
36843
|
gitAlignResult = "Not a git repository \u2014 skipped git alignment";
|
|
@@ -36304,6 +36877,7 @@ async function handleCloseCommand(directory, args) {
|
|
|
36304
36877
|
...swarmPlanFilesRemoved > 0 ? [`- Removed ${swarmPlanFilesRemoved} SWARM_PLAN checkpoint artifact(s)`] : [],
|
|
36305
36878
|
...planExists && !planAlreadyDone ? ["- Set non-completed phases/tasks to closed status"] : [],
|
|
36306
36879
|
...curationSucceeded && allLessons.length > 0 ? [`- Committed ${allLessons.length} lesson(s) to knowledge store`] : [],
|
|
36880
|
+
...hivePromoted > 0 ? [`- Promoted ${hivePromoted} lesson(s) to hive knowledge`] : [],
|
|
36307
36881
|
"",
|
|
36308
36882
|
...warnings.length > 0 ? ["## Warnings", ...warnings.map((w) => `- ${w}`), ""] : []
|
|
36309
36883
|
].join(`
|
|
@@ -36315,13 +36889,6 @@ async function handleCloseCommand(directory, args) {
|
|
|
36315
36889
|
warnings.push(`Failed to write close-summary.md: ${msg}`);
|
|
36316
36890
|
console.warn("[close-command] Failed to write close-summary.md:", error93);
|
|
36317
36891
|
}
|
|
36318
|
-
try {
|
|
36319
|
-
await flushPendingSnapshot(directory);
|
|
36320
|
-
} catch (error93) {
|
|
36321
|
-
const msg = error93 instanceof Error ? error93.message : String(error93);
|
|
36322
|
-
warnings.push(`flushPendingSnapshot failed: ${msg}`);
|
|
36323
|
-
console.warn("[close-command] flushPendingSnapshot error:", error93);
|
|
36324
|
-
}
|
|
36325
36892
|
const preservedClient = swarmState.opencodeClient;
|
|
36326
36893
|
const preservedFullAutoFlag = swarmState.fullAutoEnabledInConfig;
|
|
36327
36894
|
const preservedCuratorInitNames = swarmState.curatorInitAgentNames;
|
|
@@ -36362,15 +36929,16 @@ ${otherWarnings.map((w) => `- ${w}`).join(`
|
|
|
36362
36929
|
**Archive:** ${archiveResult}
|
|
36363
36930
|
**Git:** ${gitAlignResult}${lessonSummary}${warningMsg}`;
|
|
36364
36931
|
}
|
|
36365
|
-
var ARCHIVE_ARTIFACTS, ACTIVE_STATE_TO_CLEAN;
|
|
36932
|
+
var ARCHIVE_ARTIFACTS, ACTIVE_STATE_TO_CLEAN, ACTIVE_STATE_DIRS_TO_CLEAN;
|
|
36366
36933
|
var init_close = __esm(() => {
|
|
36367
36934
|
init_schema();
|
|
36368
36935
|
init_manager2();
|
|
36369
36936
|
init_branch();
|
|
36937
|
+
init_hive_promoter();
|
|
36370
36938
|
init_knowledge_curator();
|
|
36939
|
+
init_knowledge_store();
|
|
36371
36940
|
init_utils2();
|
|
36372
36941
|
init_scope_persistence();
|
|
36373
|
-
init_snapshot_writer();
|
|
36374
36942
|
init_state();
|
|
36375
36943
|
init_write_retro();
|
|
36376
36944
|
ARCHIVE_ARTIFACTS = [
|
|
@@ -36383,7 +36951,18 @@ var init_close = __esm(() => {
|
|
|
36383
36951
|
"handoff-prompt.md",
|
|
36384
36952
|
"handoff-consumed.md",
|
|
36385
36953
|
"escalation-report.md",
|
|
36386
|
-
"close-lessons.md"
|
|
36954
|
+
"close-lessons.md",
|
|
36955
|
+
"knowledge.jsonl",
|
|
36956
|
+
"knowledge-rejected.jsonl",
|
|
36957
|
+
"repo-graph.json",
|
|
36958
|
+
"doc-manifest.json",
|
|
36959
|
+
"dark-matter.md",
|
|
36960
|
+
"telemetry.jsonl",
|
|
36961
|
+
"swarm.db",
|
|
36962
|
+
"swarm.db-shm",
|
|
36963
|
+
"swarm.db-wal",
|
|
36964
|
+
"close-summary.md",
|
|
36965
|
+
"spec.md"
|
|
36387
36966
|
];
|
|
36388
36967
|
ACTIVE_STATE_TO_CLEAN = [
|
|
36389
36968
|
"plan.json",
|
|
@@ -36393,7 +36972,23 @@ var init_close = __esm(() => {
|
|
|
36393
36972
|
"handoff.md",
|
|
36394
36973
|
"handoff-prompt.md",
|
|
36395
36974
|
"handoff-consumed.md",
|
|
36396
|
-
"escalation-report.md"
|
|
36975
|
+
"escalation-report.md",
|
|
36976
|
+
"knowledge.jsonl",
|
|
36977
|
+
"knowledge-rejected.jsonl",
|
|
36978
|
+
"repo-graph.json",
|
|
36979
|
+
"doc-manifest.json",
|
|
36980
|
+
"dark-matter.md",
|
|
36981
|
+
"telemetry.jsonl",
|
|
36982
|
+
"swarm.db",
|
|
36983
|
+
"swarm.db-shm",
|
|
36984
|
+
"swarm.db-wal"
|
|
36985
|
+
];
|
|
36986
|
+
ACTIVE_STATE_DIRS_TO_CLEAN = [
|
|
36987
|
+
"evidence",
|
|
36988
|
+
"session",
|
|
36989
|
+
"scopes",
|
|
36990
|
+
"locks",
|
|
36991
|
+
"spec-archive"
|
|
36397
36992
|
];
|
|
36398
36993
|
});
|
|
36399
36994
|
|
|
@@ -36496,322 +37091,6 @@ var init_council = __esm(() => {
|
|
|
36496
37091
|
`);
|
|
36497
37092
|
});
|
|
36498
37093
|
|
|
36499
|
-
// src/background/event-bus.ts
|
|
36500
|
-
class AutomationEventBus {
|
|
36501
|
-
listeners = new Map;
|
|
36502
|
-
eventHistory = [];
|
|
36503
|
-
maxHistorySize;
|
|
36504
|
-
constructor(options) {
|
|
36505
|
-
this.maxHistorySize = options?.maxHistorySize ?? 100;
|
|
36506
|
-
}
|
|
36507
|
-
subscribe(type, listener) {
|
|
36508
|
-
if (!this.listeners.has(type)) {
|
|
36509
|
-
this.listeners.set(type, new Set);
|
|
36510
|
-
}
|
|
36511
|
-
this.listeners.get(type).add(listener);
|
|
36512
|
-
return () => {
|
|
36513
|
-
this.listeners.get(type)?.delete(listener);
|
|
36514
|
-
};
|
|
36515
|
-
}
|
|
36516
|
-
async publish(type, payload, source) {
|
|
36517
|
-
const event = {
|
|
36518
|
-
type,
|
|
36519
|
-
timestamp: Date.now(),
|
|
36520
|
-
payload,
|
|
36521
|
-
source
|
|
36522
|
-
};
|
|
36523
|
-
this.eventHistory.push(event);
|
|
36524
|
-
if (this.eventHistory.length > this.maxHistorySize) {
|
|
36525
|
-
this.eventHistory.shift();
|
|
36526
|
-
}
|
|
36527
|
-
log(`[EventBus] ${type}`, {
|
|
36528
|
-
source,
|
|
36529
|
-
payload: typeof payload === "object" ? "..." : payload
|
|
36530
|
-
});
|
|
36531
|
-
const listeners = this.listeners.get(type);
|
|
36532
|
-
if (listeners) {
|
|
36533
|
-
await Promise.all(Array.from(listeners).map(async (listener) => {
|
|
36534
|
-
try {
|
|
36535
|
-
await listener(event);
|
|
36536
|
-
} catch (error93) {
|
|
36537
|
-
log(`[EventBus] Listener error for ${type}`, { error: error93 });
|
|
36538
|
-
}
|
|
36539
|
-
}));
|
|
36540
|
-
}
|
|
36541
|
-
}
|
|
36542
|
-
getHistory(types) {
|
|
36543
|
-
if (!types || types.length === 0) {
|
|
36544
|
-
return [...this.eventHistory];
|
|
36545
|
-
}
|
|
36546
|
-
return this.eventHistory.filter((e) => types.includes(e.type));
|
|
36547
|
-
}
|
|
36548
|
-
clearHistory() {
|
|
36549
|
-
this.eventHistory = [];
|
|
36550
|
-
}
|
|
36551
|
-
getListenerCount(type) {
|
|
36552
|
-
return this.listeners.get(type)?.size ?? 0;
|
|
36553
|
-
}
|
|
36554
|
-
hasListeners(type) {
|
|
36555
|
-
return this.getListenerCount(type) > 0;
|
|
36556
|
-
}
|
|
36557
|
-
}
|
|
36558
|
-
function getGlobalEventBus() {
|
|
36559
|
-
if (!globalEventBus) {
|
|
36560
|
-
globalEventBus = new AutomationEventBus;
|
|
36561
|
-
}
|
|
36562
|
-
return globalEventBus;
|
|
36563
|
-
}
|
|
36564
|
-
var globalEventBus = null;
|
|
36565
|
-
var init_event_bus = __esm(() => {
|
|
36566
|
-
init_utils();
|
|
36567
|
-
});
|
|
36568
|
-
|
|
36569
|
-
// src/hooks/curator.ts
|
|
36570
|
-
var init_curator = __esm(() => {
|
|
36571
|
-
init_event_bus();
|
|
36572
|
-
init_manager();
|
|
36573
|
-
init_bun_compat();
|
|
36574
|
-
init_logger();
|
|
36575
|
-
init_knowledge_store();
|
|
36576
|
-
init_knowledge_validator();
|
|
36577
|
-
init_utils2();
|
|
36578
|
-
});
|
|
36579
|
-
|
|
36580
|
-
// src/hooks/hive-promoter.ts
|
|
36581
|
-
import path16 from "path";
|
|
36582
|
-
function isAlreadyInHive(entry, hiveEntries, threshold) {
|
|
36583
|
-
return findNearDuplicate(entry.lesson, hiveEntries, threshold) !== undefined;
|
|
36584
|
-
}
|
|
36585
|
-
function countDistinctPhases(confirmedBy) {
|
|
36586
|
-
const phaseNumbers = new Set;
|
|
36587
|
-
for (const record3 of confirmedBy) {
|
|
36588
|
-
phaseNumbers.add(record3.phase_number);
|
|
36589
|
-
}
|
|
36590
|
-
return phaseNumbers.size;
|
|
36591
|
-
}
|
|
36592
|
-
function countDistinctProjects(confirmedBy) {
|
|
36593
|
-
const projectNames = new Set;
|
|
36594
|
-
for (const record3 of confirmedBy) {
|
|
36595
|
-
projectNames.add(record3.project_name);
|
|
36596
|
-
}
|
|
36597
|
-
return projectNames.size;
|
|
36598
|
-
}
|
|
36599
|
-
function hasProjectConfirmation(hiveEntry, projectName) {
|
|
36600
|
-
return hiveEntry.confirmed_by.some((record3) => record3.project_name === projectName);
|
|
36601
|
-
}
|
|
36602
|
-
function calculateEncounterScore(currentScore, isSameProject, config3) {
|
|
36603
|
-
const weight = isSameProject ? config3.same_project_weight : config3.cross_project_weight;
|
|
36604
|
-
const increment = config3.encounter_increment * weight;
|
|
36605
|
-
const newScore = currentScore + increment;
|
|
36606
|
-
return Math.min(Math.max(newScore, config3.min_encounter_score), config3.max_encounter_score);
|
|
36607
|
-
}
|
|
36608
|
-
function getEntryAgeMs(createdAt) {
|
|
36609
|
-
const createdTime = new Date(createdAt).getTime();
|
|
36610
|
-
if (Number.isNaN(createdTime))
|
|
36611
|
-
return 0;
|
|
36612
|
-
return Date.now() - createdTime;
|
|
36613
|
-
}
|
|
36614
|
-
async function checkHivePromotions(swarmEntries, config3) {
|
|
36615
|
-
let newPromotions = 0;
|
|
36616
|
-
let encountersIncremented = 0;
|
|
36617
|
-
let advancements = 0;
|
|
36618
|
-
if (config3.hive_enabled === false) {
|
|
36619
|
-
return {
|
|
36620
|
-
timestamp: new Date().toISOString(),
|
|
36621
|
-
new_promotions: 0,
|
|
36622
|
-
encounters_incremented: 0,
|
|
36623
|
-
advancements: 0,
|
|
36624
|
-
total_hive_entries: 0
|
|
36625
|
-
};
|
|
36626
|
-
}
|
|
36627
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36628
|
-
for (const swarmEntry of swarmEntries) {
|
|
36629
|
-
if (isAlreadyInHive(swarmEntry, hiveEntries, config3.dedup_threshold)) {
|
|
36630
|
-
continue;
|
|
36631
|
-
}
|
|
36632
|
-
let shouldPromote = false;
|
|
36633
|
-
if (swarmEntry.hive_eligible === true && countDistinctPhases(swarmEntry.confirmed_by) >= 3) {
|
|
36634
|
-
shouldPromote = true;
|
|
36635
|
-
}
|
|
36636
|
-
if (swarmEntry.tags.includes("hive-fast-track")) {
|
|
36637
|
-
shouldPromote = true;
|
|
36638
|
-
}
|
|
36639
|
-
const ageMs = getEntryAgeMs(swarmEntry.created_at);
|
|
36640
|
-
const ageThresholdMs = config3.auto_promote_days * 86400000;
|
|
36641
|
-
if (ageMs >= ageThresholdMs) {
|
|
36642
|
-
shouldPromote = true;
|
|
36643
|
-
}
|
|
36644
|
-
if (!shouldPromote) {
|
|
36645
|
-
continue;
|
|
36646
|
-
}
|
|
36647
|
-
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
36648
|
-
category: swarmEntry.category,
|
|
36649
|
-
scope: swarmEntry.scope,
|
|
36650
|
-
confidence: swarmEntry.confidence
|
|
36651
|
-
});
|
|
36652
|
-
if (validationResult.severity === "error") {
|
|
36653
|
-
const rejectedLesson = {
|
|
36654
|
-
id: crypto.randomUUID(),
|
|
36655
|
-
lesson: swarmEntry.lesson,
|
|
36656
|
-
rejection_reason: validationResult.reason || "validation failed for hive promotion",
|
|
36657
|
-
rejected_at: new Date().toISOString(),
|
|
36658
|
-
rejection_layer: validationResult.layer || 2
|
|
36659
|
-
};
|
|
36660
|
-
const hiveRejectedPath = resolveHiveRejectedPath();
|
|
36661
|
-
await appendKnowledge(hiveRejectedPath, rejectedLesson);
|
|
36662
|
-
continue;
|
|
36663
|
-
}
|
|
36664
|
-
const newHiveEntry = {
|
|
36665
|
-
id: crypto.randomUUID(),
|
|
36666
|
-
tier: "hive",
|
|
36667
|
-
lesson: swarmEntry.lesson,
|
|
36668
|
-
category: swarmEntry.category,
|
|
36669
|
-
tags: swarmEntry.tags,
|
|
36670
|
-
scope: swarmEntry.scope,
|
|
36671
|
-
confidence: 0.5,
|
|
36672
|
-
status: "candidate",
|
|
36673
|
-
confirmed_by: [],
|
|
36674
|
-
retrieval_outcomes: {
|
|
36675
|
-
applied_count: 0,
|
|
36676
|
-
succeeded_after_count: 0,
|
|
36677
|
-
failed_after_count: 0
|
|
36678
|
-
},
|
|
36679
|
-
schema_version: config3.schema_version,
|
|
36680
|
-
created_at: new Date().toISOString(),
|
|
36681
|
-
updated_at: new Date().toISOString(),
|
|
36682
|
-
source_project: swarmEntry.project_name,
|
|
36683
|
-
encounter_score: config3.initial_encounter_score
|
|
36684
|
-
};
|
|
36685
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36686
|
-
newPromotions++;
|
|
36687
|
-
hiveEntries.push(newHiveEntry);
|
|
36688
|
-
}
|
|
36689
|
-
let hiveModified = false;
|
|
36690
|
-
for (const hiveEntry of hiveEntries) {
|
|
36691
|
-
const nearDuplicate = findNearDuplicate(hiveEntry.lesson, swarmEntries, config3.dedup_threshold);
|
|
36692
|
-
if (!nearDuplicate) {
|
|
36693
|
-
continue;
|
|
36694
|
-
}
|
|
36695
|
-
const isSameProject = nearDuplicate.project_name === hiveEntry.source_project;
|
|
36696
|
-
if (hasProjectConfirmation(hiveEntry, nearDuplicate.project_name)) {
|
|
36697
|
-
continue;
|
|
36698
|
-
}
|
|
36699
|
-
const newConfirmation = {
|
|
36700
|
-
project_name: nearDuplicate.project_name,
|
|
36701
|
-
confirmed_at: new Date().toISOString()
|
|
36702
|
-
};
|
|
36703
|
-
hiveEntry.confirmed_by.push(newConfirmation);
|
|
36704
|
-
const currentScore = hiveEntry.encounter_score ?? 1;
|
|
36705
|
-
hiveEntry.encounter_score = calculateEncounterScore(currentScore, isSameProject, config3);
|
|
36706
|
-
encountersIncremented++;
|
|
36707
|
-
hiveEntry.updated_at = new Date().toISOString();
|
|
36708
|
-
if (hiveEntry.status === "candidate" && countDistinctProjects(hiveEntry.confirmed_by) >= 3) {
|
|
36709
|
-
hiveEntry.status = "established";
|
|
36710
|
-
advancements++;
|
|
36711
|
-
}
|
|
36712
|
-
hiveModified = true;
|
|
36713
|
-
}
|
|
36714
|
-
if (hiveModified) {
|
|
36715
|
-
await rewriteKnowledge(resolveHiveKnowledgePath(), hiveEntries);
|
|
36716
|
-
}
|
|
36717
|
-
if (newPromotions > 0 || hiveModified) {
|
|
36718
|
-
await enforceKnowledgeCap(resolveHiveKnowledgePath(), config3.hive_max_entries);
|
|
36719
|
-
}
|
|
36720
|
-
return {
|
|
36721
|
-
timestamp: new Date().toISOString(),
|
|
36722
|
-
new_promotions: newPromotions,
|
|
36723
|
-
encounters_incremented: encountersIncremented,
|
|
36724
|
-
advancements,
|
|
36725
|
-
total_hive_entries: hiveEntries.length
|
|
36726
|
-
};
|
|
36727
|
-
}
|
|
36728
|
-
async function promoteToHive(directory, lesson, category) {
|
|
36729
|
-
const trimmedLesson = lesson.trim();
|
|
36730
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36731
|
-
const validationResult = validateLesson(trimmedLesson, hiveEntries.map((e) => e.lesson), {
|
|
36732
|
-
category: category || "process",
|
|
36733
|
-
scope: "global",
|
|
36734
|
-
confidence: 1
|
|
36735
|
-
});
|
|
36736
|
-
if (validationResult.severity === "error") {
|
|
36737
|
-
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
36738
|
-
}
|
|
36739
|
-
if (findNearDuplicate(trimmedLesson, hiveEntries, 0.6)) {
|
|
36740
|
-
return `Lesson already exists in hive (near-duplicate).`;
|
|
36741
|
-
}
|
|
36742
|
-
const newHiveEntry = {
|
|
36743
|
-
id: crypto.randomUUID(),
|
|
36744
|
-
tier: "hive",
|
|
36745
|
-
lesson: trimmedLesson,
|
|
36746
|
-
category: category || "process",
|
|
36747
|
-
tags: [],
|
|
36748
|
-
scope: "global",
|
|
36749
|
-
confidence: 1,
|
|
36750
|
-
status: "promoted",
|
|
36751
|
-
confirmed_by: [],
|
|
36752
|
-
retrieval_outcomes: {
|
|
36753
|
-
applied_count: 0,
|
|
36754
|
-
succeeded_after_count: 0,
|
|
36755
|
-
failed_after_count: 0
|
|
36756
|
-
},
|
|
36757
|
-
schema_version: 1,
|
|
36758
|
-
created_at: new Date().toISOString(),
|
|
36759
|
-
updated_at: new Date().toISOString(),
|
|
36760
|
-
source_project: path16.basename(directory) || "unknown",
|
|
36761
|
-
encounter_score: 1
|
|
36762
|
-
};
|
|
36763
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36764
|
-
return `Promoted to hive: "${trimmedLesson.slice(0, 50)}${trimmedLesson.length > 50 ? "..." : ""}" (confidence: 1.0, source: manual)`;
|
|
36765
|
-
}
|
|
36766
|
-
async function promoteFromSwarm(directory, lessonId) {
|
|
36767
|
-
const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
36768
|
-
const swarmEntry = swarmEntries.find((e) => e.id === lessonId);
|
|
36769
|
-
if (!swarmEntry) {
|
|
36770
|
-
throw new Error(`Lesson ${lessonId} not found in .swarm/knowledge.jsonl`);
|
|
36771
|
-
}
|
|
36772
|
-
const hiveEntries = await readKnowledge(resolveHiveKnowledgePath());
|
|
36773
|
-
const validationResult = validateLesson(swarmEntry.lesson, hiveEntries.map((e) => e.lesson), {
|
|
36774
|
-
category: swarmEntry.category,
|
|
36775
|
-
scope: swarmEntry.scope,
|
|
36776
|
-
confidence: swarmEntry.confidence
|
|
36777
|
-
});
|
|
36778
|
-
if (validationResult.severity === "error") {
|
|
36779
|
-
throw new Error(`Lesson rejected by validator: ${validationResult.reason}`);
|
|
36780
|
-
}
|
|
36781
|
-
if (findNearDuplicate(swarmEntry.lesson, hiveEntries, 0.6)) {
|
|
36782
|
-
return `Lesson already exists in hive (near-duplicate).`;
|
|
36783
|
-
}
|
|
36784
|
-
const newHiveEntry = {
|
|
36785
|
-
id: crypto.randomUUID(),
|
|
36786
|
-
tier: "hive",
|
|
36787
|
-
lesson: swarmEntry.lesson,
|
|
36788
|
-
category: swarmEntry.category,
|
|
36789
|
-
tags: swarmEntry.tags,
|
|
36790
|
-
scope: swarmEntry.scope,
|
|
36791
|
-
confidence: 1,
|
|
36792
|
-
status: "promoted",
|
|
36793
|
-
confirmed_by: [],
|
|
36794
|
-
retrieval_outcomes: {
|
|
36795
|
-
applied_count: 0,
|
|
36796
|
-
succeeded_after_count: 0,
|
|
36797
|
-
failed_after_count: 0
|
|
36798
|
-
},
|
|
36799
|
-
schema_version: 1,
|
|
36800
|
-
created_at: new Date().toISOString(),
|
|
36801
|
-
updated_at: new Date().toISOString(),
|
|
36802
|
-
source_project: swarmEntry.project_name,
|
|
36803
|
-
encounter_score: 1
|
|
36804
|
-
};
|
|
36805
|
-
await appendKnowledge(resolveHiveKnowledgePath(), newHiveEntry);
|
|
36806
|
-
return `Promoted lesson ${lessonId} from swarm to hive: "${swarmEntry.lesson.slice(0, 50)}${swarmEntry.lesson.length > 50 ? "..." : ""}"`;
|
|
36807
|
-
}
|
|
36808
|
-
var init_hive_promoter = __esm(() => {
|
|
36809
|
-
init_curator();
|
|
36810
|
-
init_knowledge_store();
|
|
36811
|
-
init_knowledge_validator();
|
|
36812
|
-
init_utils2();
|
|
36813
|
-
});
|
|
36814
|
-
|
|
36815
37094
|
// src/commands/curate.ts
|
|
36816
37095
|
async function handleCurateCommand(directory, _args) {
|
|
36817
37096
|
try {
|
|
@@ -36849,7 +37128,7 @@ var init_curate = __esm(() => {
|
|
|
36849
37128
|
import * as child_process3 from "child_process";
|
|
36850
37129
|
import { randomUUID } from "crypto";
|
|
36851
37130
|
import { readdir, readFile as readFile5, stat as stat2 } from "fs/promises";
|
|
36852
|
-
import * as
|
|
37131
|
+
import * as path16 from "path";
|
|
36853
37132
|
import { promisify } from "util";
|
|
36854
37133
|
function getExecFileAsync() {
|
|
36855
37134
|
return promisify(child_process3.execFile);
|
|
@@ -36951,7 +37230,7 @@ async function scanSourceFiles(dir) {
|
|
|
36951
37230
|
try {
|
|
36952
37231
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
36953
37232
|
for (const entry of entries) {
|
|
36954
|
-
const fullPath =
|
|
37233
|
+
const fullPath = path16.join(dir, entry.name);
|
|
36955
37234
|
if (entry.isDirectory()) {
|
|
36956
37235
|
if (skipDirs.has(entry.name)) {
|
|
36957
37236
|
continue;
|
|
@@ -36959,7 +37238,7 @@ async function scanSourceFiles(dir) {
|
|
|
36959
37238
|
const subFiles = await scanSourceFiles(fullPath);
|
|
36960
37239
|
results.push(...subFiles);
|
|
36961
37240
|
} else if (entry.isFile()) {
|
|
36962
|
-
const ext =
|
|
37241
|
+
const ext = path16.extname(entry.name);
|
|
36963
37242
|
if ([".ts", ".tsx", ".js", ".jsx", ".mjs"].includes(ext)) {
|
|
36964
37243
|
results.push(fullPath);
|
|
36965
37244
|
}
|
|
@@ -36981,8 +37260,8 @@ async function getStaticEdges(directory) {
|
|
|
36981
37260
|
continue;
|
|
36982
37261
|
}
|
|
36983
37262
|
try {
|
|
36984
|
-
const sourceDir =
|
|
36985
|
-
const resolvedPath =
|
|
37263
|
+
const sourceDir = path16.dirname(sourceFile);
|
|
37264
|
+
const resolvedPath = path16.resolve(sourceDir, importPath);
|
|
36986
37265
|
const extensions = [
|
|
36987
37266
|
"",
|
|
36988
37267
|
".ts",
|
|
@@ -37007,8 +37286,8 @@ async function getStaticEdges(directory) {
|
|
|
37007
37286
|
if (!targetFile) {
|
|
37008
37287
|
continue;
|
|
37009
37288
|
}
|
|
37010
|
-
const relSource =
|
|
37011
|
-
const relTarget =
|
|
37289
|
+
const relSource = path16.relative(directory, sourceFile).replace(/\\/g, "/");
|
|
37290
|
+
const relTarget = path16.relative(directory, targetFile).replace(/\\/g, "/");
|
|
37012
37291
|
const [key] = relSource < relTarget ? [`${relSource}::${relTarget}`, relSource, relTarget] : [`${relTarget}::${relSource}`, relTarget, relSource];
|
|
37013
37292
|
edges.add(key);
|
|
37014
37293
|
} catch {}
|
|
@@ -37020,7 +37299,7 @@ async function getStaticEdges(directory) {
|
|
|
37020
37299
|
function isTestImplementationPair(fileA, fileB) {
|
|
37021
37300
|
const testPatterns = [".test.ts", ".test.js", ".spec.ts", ".spec.js"];
|
|
37022
37301
|
const getBaseName = (filePath) => {
|
|
37023
|
-
const base =
|
|
37302
|
+
const base = path16.basename(filePath);
|
|
37024
37303
|
for (const pattern of testPatterns) {
|
|
37025
37304
|
if (base.endsWith(pattern)) {
|
|
37026
37305
|
return base.slice(0, -pattern.length);
|
|
@@ -37030,16 +37309,16 @@ function isTestImplementationPair(fileA, fileB) {
|
|
|
37030
37309
|
};
|
|
37031
37310
|
const baseA = getBaseName(fileA);
|
|
37032
37311
|
const baseB = getBaseName(fileB);
|
|
37033
|
-
return baseA === baseB && baseA !==
|
|
37312
|
+
return baseA === baseB && baseA !== path16.basename(fileA) && baseA !== path16.basename(fileB);
|
|
37034
37313
|
}
|
|
37035
37314
|
function hasSharedPrefix(fileA, fileB) {
|
|
37036
|
-
const dirA =
|
|
37037
|
-
const dirB =
|
|
37315
|
+
const dirA = path16.dirname(fileA);
|
|
37316
|
+
const dirB = path16.dirname(fileB);
|
|
37038
37317
|
if (dirA !== dirB) {
|
|
37039
37318
|
return false;
|
|
37040
37319
|
}
|
|
37041
|
-
const baseA =
|
|
37042
|
-
const baseB =
|
|
37320
|
+
const baseA = path16.basename(fileA).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
37321
|
+
const baseB = path16.basename(fileB).replace(/\.(ts|js|tsx|jsx|mjs)$/, "");
|
|
37043
37322
|
if (baseA.startsWith(baseB) || baseB.startsWith(baseA)) {
|
|
37044
37323
|
return true;
|
|
37045
37324
|
}
|
|
@@ -37067,9 +37346,9 @@ async function detectDarkMatter(directory, options) {
|
|
|
37067
37346
|
} catch {
|
|
37068
37347
|
return [];
|
|
37069
37348
|
}
|
|
37070
|
-
const commitMap = await
|
|
37071
|
-
const matrix =
|
|
37072
|
-
const staticEdges = await
|
|
37349
|
+
const commitMap = await _internals9.parseGitLog(directory, maxCommitsToAnalyze);
|
|
37350
|
+
const matrix = _internals9.buildCoChangeMatrix(commitMap);
|
|
37351
|
+
const staticEdges = await _internals9.getStaticEdges(directory);
|
|
37073
37352
|
const results = [];
|
|
37074
37353
|
for (const entry of matrix.values()) {
|
|
37075
37354
|
const key = `${entry.fileA}::${entry.fileB}`;
|
|
@@ -37093,8 +37372,8 @@ function darkMatterToKnowledgeEntries(pairs, projectName) {
|
|
|
37093
37372
|
const entries = [];
|
|
37094
37373
|
const now = new Date().toISOString();
|
|
37095
37374
|
for (const pair of pairs.slice(0, 10)) {
|
|
37096
|
-
const baseA =
|
|
37097
|
-
const baseB =
|
|
37375
|
+
const baseA = path16.basename(pair.fileA);
|
|
37376
|
+
const baseB = path16.basename(pair.fileB);
|
|
37098
37377
|
let lesson = `Files ${pair.fileA} and ${pair.fileB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
37099
37378
|
if (lesson.length > 280) {
|
|
37100
37379
|
lesson = `Files ${baseA} and ${baseB} co-change with NPMI=${pair.npmi.toFixed(3)} but have no import relationship. This hidden coupling suggests a shared architectural concern \u2014 changes to one likely require changes to the other.`;
|
|
@@ -37149,7 +37428,7 @@ ${rows}
|
|
|
37149
37428
|
These pairs likely share an architectural concern invisible to static analysis.
|
|
37150
37429
|
Consider adding explicit documentation or extracting the shared concern.`;
|
|
37151
37430
|
}
|
|
37152
|
-
var co_change_analyzer,
|
|
37431
|
+
var co_change_analyzer, _internals9;
|
|
37153
37432
|
var init_co_change_analyzer = __esm(() => {
|
|
37154
37433
|
init_zod();
|
|
37155
37434
|
init_create_tool();
|
|
@@ -37181,11 +37460,11 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
37181
37460
|
npmiThreshold,
|
|
37182
37461
|
maxCommitsToAnalyze
|
|
37183
37462
|
};
|
|
37184
|
-
const pairs = await
|
|
37185
|
-
return
|
|
37463
|
+
const pairs = await _internals9.detectDarkMatter(directory, options);
|
|
37464
|
+
return _internals9.formatDarkMatterOutput(pairs);
|
|
37186
37465
|
}
|
|
37187
37466
|
});
|
|
37188
|
-
|
|
37467
|
+
_internals9 = {
|
|
37189
37468
|
parseGitLog,
|
|
37190
37469
|
buildCoChangeMatrix,
|
|
37191
37470
|
getStaticEdges,
|
|
@@ -37196,7 +37475,7 @@ var init_co_change_analyzer = __esm(() => {
|
|
|
37196
37475
|
});
|
|
37197
37476
|
|
|
37198
37477
|
// src/commands/dark-matter.ts
|
|
37199
|
-
import
|
|
37478
|
+
import path17 from "path";
|
|
37200
37479
|
async function handleDarkMatterCommand(directory, args) {
|
|
37201
37480
|
const options = {};
|
|
37202
37481
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -37216,7 +37495,7 @@ async function handleDarkMatterCommand(directory, args) {
|
|
|
37216
37495
|
}
|
|
37217
37496
|
let pairs;
|
|
37218
37497
|
try {
|
|
37219
|
-
pairs = await
|
|
37498
|
+
pairs = await _internals9.detectDarkMatter(directory, options);
|
|
37220
37499
|
} catch (err) {
|
|
37221
37500
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
37222
37501
|
return `## Dark Matter Analysis Failed
|
|
@@ -37228,7 +37507,7 @@ Ensure this is a git repository with commit history.`;
|
|
|
37228
37507
|
const output = formatDarkMatterOutput(pairs);
|
|
37229
37508
|
if (pairs.length > 0) {
|
|
37230
37509
|
try {
|
|
37231
|
-
const projectName =
|
|
37510
|
+
const projectName = path17.basename(path17.resolve(directory));
|
|
37232
37511
|
const entries = darkMatterToKnowledgeEntries(pairs, projectName);
|
|
37233
37512
|
if (entries.length > 0) {
|
|
37234
37513
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
@@ -37253,51 +37532,51 @@ var init_dark_matter = __esm(() => {
|
|
|
37253
37532
|
|
|
37254
37533
|
// src/config/cache-paths.ts
|
|
37255
37534
|
import * as os5 from "os";
|
|
37256
|
-
import * as
|
|
37535
|
+
import * as path18 from "path";
|
|
37257
37536
|
function getPluginConfigDir() {
|
|
37258
|
-
return
|
|
37537
|
+
return path18.join(process.env.XDG_CONFIG_HOME || path18.join(os5.homedir(), ".config"), "opencode");
|
|
37259
37538
|
}
|
|
37260
37539
|
function getPluginCachePaths() {
|
|
37261
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
37540
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
|
|
37262
37541
|
const configDir = getPluginConfigDir();
|
|
37263
37542
|
const paths = [
|
|
37264
|
-
|
|
37265
|
-
|
|
37266
|
-
|
|
37543
|
+
path18.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
|
|
37544
|
+
path18.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
|
|
37545
|
+
path18.join(configDir, "node_modules", "opencode-swarm")
|
|
37267
37546
|
];
|
|
37268
37547
|
if (process.platform === "darwin") {
|
|
37269
|
-
const libCaches =
|
|
37270
|
-
paths.push(
|
|
37548
|
+
const libCaches = path18.join(os5.homedir(), "Library", "Caches");
|
|
37549
|
+
paths.push(path18.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path18.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
|
|
37271
37550
|
}
|
|
37272
37551
|
if (process.platform === "win32") {
|
|
37273
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
37274
|
-
const appData = process.env.APPDATA ||
|
|
37275
|
-
paths.push(
|
|
37552
|
+
const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
|
|
37553
|
+
const appData = process.env.APPDATA || path18.join(os5.homedir(), "AppData", "Roaming");
|
|
37554
|
+
paths.push(path18.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path18.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path18.join(appData, "opencode", "node_modules", "opencode-swarm"));
|
|
37276
37555
|
}
|
|
37277
37556
|
return paths;
|
|
37278
37557
|
}
|
|
37279
37558
|
function getPluginLockFilePaths() {
|
|
37280
|
-
const cacheBase = process.env.XDG_CACHE_HOME ||
|
|
37559
|
+
const cacheBase = process.env.XDG_CACHE_HOME || path18.join(os5.homedir(), ".cache");
|
|
37281
37560
|
const configDir = getPluginConfigDir();
|
|
37282
37561
|
const paths = [
|
|
37283
|
-
|
|
37284
|
-
|
|
37285
|
-
|
|
37562
|
+
path18.join(cacheBase, "opencode", "bun.lock"),
|
|
37563
|
+
path18.join(cacheBase, "opencode", "bun.lockb"),
|
|
37564
|
+
path18.join(configDir, "package-lock.json")
|
|
37286
37565
|
];
|
|
37287
37566
|
if (process.platform === "darwin") {
|
|
37288
|
-
const libCaches =
|
|
37289
|
-
paths.push(
|
|
37567
|
+
const libCaches = path18.join(os5.homedir(), "Library", "Caches");
|
|
37568
|
+
paths.push(path18.join(libCaches, "opencode", "bun.lock"), path18.join(libCaches, "opencode", "bun.lockb"));
|
|
37290
37569
|
}
|
|
37291
37570
|
if (process.platform === "win32") {
|
|
37292
|
-
const localAppData = process.env.LOCALAPPDATA ||
|
|
37293
|
-
paths.push(
|
|
37571
|
+
const localAppData = process.env.LOCALAPPDATA || path18.join(os5.homedir(), "AppData", "Local");
|
|
37572
|
+
paths.push(path18.join(localAppData, "opencode", "bun.lock"), path18.join(localAppData, "opencode", "bun.lockb"));
|
|
37294
37573
|
}
|
|
37295
37574
|
return paths;
|
|
37296
37575
|
}
|
|
37297
37576
|
var init_cache_paths = () => {};
|
|
37298
37577
|
|
|
37299
37578
|
// src/services/version-check.ts
|
|
37300
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
37579
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
37301
37580
|
import { homedir as homedir5 } from "os";
|
|
37302
37581
|
import { join as join17 } from "path";
|
|
37303
37582
|
function cacheDir() {
|
|
@@ -37310,10 +37589,10 @@ function cacheFile() {
|
|
|
37310
37589
|
}
|
|
37311
37590
|
function readVersionCache() {
|
|
37312
37591
|
try {
|
|
37313
|
-
const
|
|
37314
|
-
if (!existsSync9(
|
|
37592
|
+
const path19 = cacheFile();
|
|
37593
|
+
if (!existsSync9(path19))
|
|
37315
37594
|
return null;
|
|
37316
|
-
const raw = readFileSync5(
|
|
37595
|
+
const raw = readFileSync5(path19, "utf-8");
|
|
37317
37596
|
const parsed = JSON.parse(raw);
|
|
37318
37597
|
if (typeof parsed?.checkedAt !== "number")
|
|
37319
37598
|
return null;
|
|
@@ -37353,7 +37632,7 @@ var init_version_check = __esm(() => {
|
|
|
37353
37632
|
// src/services/diagnose-service.ts
|
|
37354
37633
|
import * as child_process4 from "child_process";
|
|
37355
37634
|
import { existsSync as existsSync10, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync6 } from "fs";
|
|
37356
|
-
import
|
|
37635
|
+
import path19 from "path";
|
|
37357
37636
|
import { fileURLToPath } from "url";
|
|
37358
37637
|
function validateTaskDag(plan) {
|
|
37359
37638
|
const allTaskIds = new Set;
|
|
@@ -37650,7 +37929,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
37650
37929
|
};
|
|
37651
37930
|
}
|
|
37652
37931
|
async function checkConfigParseability(directory) {
|
|
37653
|
-
const configPath =
|
|
37932
|
+
const configPath = path19.join(directory, ".opencode/opencode-swarm.json");
|
|
37654
37933
|
if (!existsSync10(configPath)) {
|
|
37655
37934
|
return {
|
|
37656
37935
|
name: "Config Parseability",
|
|
@@ -37679,7 +37958,7 @@ function resolveGrammarDir(thisDir) {
|
|
|
37679
37958
|
const normalized = thisDir.replace(/\\/g, "/");
|
|
37680
37959
|
const isSource = normalized.endsWith("/src/services");
|
|
37681
37960
|
const isCliBundle = normalized.endsWith("/cli");
|
|
37682
|
-
return isSource || isCliBundle ?
|
|
37961
|
+
return isSource || isCliBundle ? path19.join(thisDir, "..", "lang", "grammars") : path19.join(thisDir, "lang", "grammars");
|
|
37683
37962
|
}
|
|
37684
37963
|
async function checkGrammarWasmFiles() {
|
|
37685
37964
|
const grammarFiles = [
|
|
@@ -37703,14 +37982,14 @@ async function checkGrammarWasmFiles() {
|
|
|
37703
37982
|
"tree-sitter-ini.wasm",
|
|
37704
37983
|
"tree-sitter-regex.wasm"
|
|
37705
37984
|
];
|
|
37706
|
-
const thisDir =
|
|
37985
|
+
const thisDir = path19.dirname(fileURLToPath(import.meta.url));
|
|
37707
37986
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
37708
37987
|
const missing = [];
|
|
37709
|
-
if (!existsSync10(
|
|
37988
|
+
if (!existsSync10(path19.join(grammarDir, "tree-sitter.wasm"))) {
|
|
37710
37989
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
37711
37990
|
}
|
|
37712
37991
|
for (const file3 of grammarFiles) {
|
|
37713
|
-
if (!existsSync10(
|
|
37992
|
+
if (!existsSync10(path19.join(grammarDir, file3))) {
|
|
37714
37993
|
missing.push(file3);
|
|
37715
37994
|
}
|
|
37716
37995
|
}
|
|
@@ -37728,7 +38007,7 @@ async function checkGrammarWasmFiles() {
|
|
|
37728
38007
|
};
|
|
37729
38008
|
}
|
|
37730
38009
|
async function checkCheckpointManifest(directory) {
|
|
37731
|
-
const manifestPath =
|
|
38010
|
+
const manifestPath = path19.join(directory, ".swarm/checkpoints.json");
|
|
37732
38011
|
if (!existsSync10(manifestPath)) {
|
|
37733
38012
|
return {
|
|
37734
38013
|
name: "Checkpoint Manifest",
|
|
@@ -37780,7 +38059,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
37780
38059
|
}
|
|
37781
38060
|
}
|
|
37782
38061
|
async function checkEventStreamIntegrity(directory) {
|
|
37783
|
-
const eventsPath =
|
|
38062
|
+
const eventsPath = path19.join(directory, ".swarm/events.jsonl");
|
|
37784
38063
|
if (!existsSync10(eventsPath)) {
|
|
37785
38064
|
return {
|
|
37786
38065
|
name: "Event Stream",
|
|
@@ -37821,7 +38100,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
37821
38100
|
}
|
|
37822
38101
|
}
|
|
37823
38102
|
async function checkSteeringDirectives(directory) {
|
|
37824
|
-
const eventsPath =
|
|
38103
|
+
const eventsPath = path19.join(directory, ".swarm/events.jsonl");
|
|
37825
38104
|
if (!existsSync10(eventsPath)) {
|
|
37826
38105
|
return {
|
|
37827
38106
|
name: "Steering Directives",
|
|
@@ -37877,7 +38156,7 @@ async function checkCurator(directory) {
|
|
|
37877
38156
|
detail: "Disabled (enable via curator.enabled)"
|
|
37878
38157
|
};
|
|
37879
38158
|
}
|
|
37880
|
-
const summaryPath =
|
|
38159
|
+
const summaryPath = path19.join(directory, ".swarm/curator-summary.json");
|
|
37881
38160
|
if (!existsSync10(summaryPath)) {
|
|
37882
38161
|
return {
|
|
37883
38162
|
name: "Curator",
|
|
@@ -38043,7 +38322,7 @@ async function getDiagnoseData(directory) {
|
|
|
38043
38322
|
checks5.push(await checkSteeringDirectives(directory));
|
|
38044
38323
|
checks5.push(await checkCurator(directory));
|
|
38045
38324
|
try {
|
|
38046
|
-
const evidenceDir =
|
|
38325
|
+
const evidenceDir = path19.join(directory, ".swarm", "evidence");
|
|
38047
38326
|
const snapshotFiles = existsSync10(evidenceDir) ? readdirSync4(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
38048
38327
|
if (snapshotFiles.length > 0) {
|
|
38049
38328
|
const latest = snapshotFiles.sort().pop();
|
|
@@ -38081,7 +38360,7 @@ async function getDiagnoseData(directory) {
|
|
|
38081
38360
|
cacheRows.push(`\u2B1C ${cachePath} \u2014 absent`);
|
|
38082
38361
|
continue;
|
|
38083
38362
|
}
|
|
38084
|
-
const pkgJsonPath =
|
|
38363
|
+
const pkgJsonPath = path19.join(cachePath, "package.json");
|
|
38085
38364
|
try {
|
|
38086
38365
|
const raw = readFileSync6(pkgJsonPath, "utf-8");
|
|
38087
38366
|
const parsed = JSON.parse(raw);
|
|
@@ -38169,13 +38448,13 @@ __export(exports_config_doctor, {
|
|
|
38169
38448
|
import * as crypto3 from "crypto";
|
|
38170
38449
|
import * as fs8 from "fs";
|
|
38171
38450
|
import * as os6 from "os";
|
|
38172
|
-
import * as
|
|
38451
|
+
import * as path20 from "path";
|
|
38173
38452
|
function getUserConfigDir3() {
|
|
38174
|
-
return process.env.XDG_CONFIG_HOME ||
|
|
38453
|
+
return process.env.XDG_CONFIG_HOME || path20.join(os6.homedir(), ".config");
|
|
38175
38454
|
}
|
|
38176
38455
|
function getConfigPaths(directory) {
|
|
38177
|
-
const userConfigPath =
|
|
38178
|
-
const projectConfigPath =
|
|
38456
|
+
const userConfigPath = path20.join(getUserConfigDir3(), "opencode", "opencode-swarm.json");
|
|
38457
|
+
const projectConfigPath = path20.join(directory, ".opencode", "opencode-swarm.json");
|
|
38179
38458
|
return { userConfigPath, projectConfigPath };
|
|
38180
38459
|
}
|
|
38181
38460
|
function computeHash(content) {
|
|
@@ -38200,9 +38479,9 @@ function isValidConfigPath(configPath, directory) {
|
|
|
38200
38479
|
const normalizedUser = userConfigPath.replace(/\\/g, "/");
|
|
38201
38480
|
const normalizedProject = projectConfigPath.replace(/\\/g, "/");
|
|
38202
38481
|
try {
|
|
38203
|
-
const resolvedConfig =
|
|
38204
|
-
const resolvedUser =
|
|
38205
|
-
const resolvedProject =
|
|
38482
|
+
const resolvedConfig = path20.resolve(configPath);
|
|
38483
|
+
const resolvedUser = path20.resolve(normalizedUser);
|
|
38484
|
+
const resolvedProject = path20.resolve(normalizedProject);
|
|
38206
38485
|
return resolvedConfig === resolvedUser || resolvedConfig === resolvedProject;
|
|
38207
38486
|
} catch {
|
|
38208
38487
|
return false;
|
|
@@ -38242,12 +38521,12 @@ function createConfigBackup(directory) {
|
|
|
38242
38521
|
};
|
|
38243
38522
|
}
|
|
38244
38523
|
function writeBackupArtifact(directory, backup) {
|
|
38245
|
-
const swarmDir =
|
|
38524
|
+
const swarmDir = path20.join(directory, ".swarm");
|
|
38246
38525
|
if (!fs8.existsSync(swarmDir)) {
|
|
38247
38526
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
38248
38527
|
}
|
|
38249
38528
|
const backupFilename = `config-backup-${backup.createdAt}.json`;
|
|
38250
|
-
const backupPath =
|
|
38529
|
+
const backupPath = path20.join(swarmDir, backupFilename);
|
|
38251
38530
|
const artifact = {
|
|
38252
38531
|
createdAt: backup.createdAt,
|
|
38253
38532
|
configPath: backup.configPath,
|
|
@@ -38277,7 +38556,7 @@ function restoreFromBackup(backupPath, directory) {
|
|
|
38277
38556
|
return null;
|
|
38278
38557
|
}
|
|
38279
38558
|
const targetPath = artifact.configPath;
|
|
38280
|
-
const targetDir =
|
|
38559
|
+
const targetDir = path20.dirname(targetPath);
|
|
38281
38560
|
if (!fs8.existsSync(targetDir)) {
|
|
38282
38561
|
fs8.mkdirSync(targetDir, { recursive: true });
|
|
38283
38562
|
}
|
|
@@ -38308,9 +38587,9 @@ function readConfigFromFile(directory) {
|
|
|
38308
38587
|
return null;
|
|
38309
38588
|
}
|
|
38310
38589
|
}
|
|
38311
|
-
function validateConfigKey(
|
|
38590
|
+
function validateConfigKey(path21, value, _config) {
|
|
38312
38591
|
const findings = [];
|
|
38313
|
-
switch (
|
|
38592
|
+
switch (path21) {
|
|
38314
38593
|
case "agents": {
|
|
38315
38594
|
if (value !== undefined) {
|
|
38316
38595
|
findings.push({
|
|
@@ -38557,27 +38836,27 @@ function validateConfigKey(path22, value, _config) {
|
|
|
38557
38836
|
}
|
|
38558
38837
|
return findings;
|
|
38559
38838
|
}
|
|
38560
|
-
function walkConfigAndValidate(obj,
|
|
38839
|
+
function walkConfigAndValidate(obj, path21, config3, findings) {
|
|
38561
38840
|
if (obj === null || obj === undefined) {
|
|
38562
38841
|
return;
|
|
38563
38842
|
}
|
|
38564
|
-
if (
|
|
38565
|
-
const keyFindings = validateConfigKey(
|
|
38843
|
+
if (path21 && typeof obj === "object" && !Array.isArray(obj)) {
|
|
38844
|
+
const keyFindings = validateConfigKey(path21, obj, config3);
|
|
38566
38845
|
findings.push(...keyFindings);
|
|
38567
38846
|
}
|
|
38568
38847
|
if (typeof obj !== "object") {
|
|
38569
|
-
const keyFindings = validateConfigKey(
|
|
38848
|
+
const keyFindings = validateConfigKey(path21, obj, config3);
|
|
38570
38849
|
findings.push(...keyFindings);
|
|
38571
38850
|
return;
|
|
38572
38851
|
}
|
|
38573
38852
|
if (Array.isArray(obj)) {
|
|
38574
38853
|
obj.forEach((item, index) => {
|
|
38575
|
-
walkConfigAndValidate(item, `${
|
|
38854
|
+
walkConfigAndValidate(item, `${path21}[${index}]`, config3, findings);
|
|
38576
38855
|
});
|
|
38577
38856
|
return;
|
|
38578
38857
|
}
|
|
38579
38858
|
for (const [key, value] of Object.entries(obj)) {
|
|
38580
|
-
const newPath =
|
|
38859
|
+
const newPath = path21 ? `${path21}.${key}` : key;
|
|
38581
38860
|
walkConfigAndValidate(value, newPath, config3, findings);
|
|
38582
38861
|
}
|
|
38583
38862
|
}
|
|
@@ -38697,7 +38976,7 @@ function applySafeAutoFixes(directory, result) {
|
|
|
38697
38976
|
}
|
|
38698
38977
|
}
|
|
38699
38978
|
if (appliedFixes.length > 0) {
|
|
38700
|
-
const configDir =
|
|
38979
|
+
const configDir = path20.dirname(configPath);
|
|
38701
38980
|
if (!fs8.existsSync(configDir)) {
|
|
38702
38981
|
fs8.mkdirSync(configDir, { recursive: true });
|
|
38703
38982
|
}
|
|
@@ -38707,12 +38986,12 @@ function applySafeAutoFixes(directory, result) {
|
|
|
38707
38986
|
return { appliedFixes, updatedConfigPath };
|
|
38708
38987
|
}
|
|
38709
38988
|
function writeDoctorArtifact(directory, result) {
|
|
38710
|
-
const swarmDir =
|
|
38989
|
+
const swarmDir = path20.join(directory, ".swarm");
|
|
38711
38990
|
if (!fs8.existsSync(swarmDir)) {
|
|
38712
38991
|
fs8.mkdirSync(swarmDir, { recursive: true });
|
|
38713
38992
|
}
|
|
38714
38993
|
const artifactFilename = "config-doctor.json";
|
|
38715
|
-
const artifactPath =
|
|
38994
|
+
const artifactPath = path20.join(swarmDir, artifactFilename);
|
|
38716
38995
|
const guiOutput = {
|
|
38717
38996
|
timestamp: result.timestamp,
|
|
38718
38997
|
summary: result.summary,
|
|
@@ -39815,7 +40094,7 @@ var init_detector = __esm(() => {
|
|
|
39815
40094
|
|
|
39816
40095
|
// src/build/discovery.ts
|
|
39817
40096
|
import * as fs9 from "fs";
|
|
39818
|
-
import * as
|
|
40097
|
+
import * as path21 from "path";
|
|
39819
40098
|
function isCommandAvailable(command) {
|
|
39820
40099
|
if (toolchainCache.has(command)) {
|
|
39821
40100
|
return toolchainCache.get(command);
|
|
@@ -39847,11 +40126,11 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
39847
40126
|
const regex = simpleGlobToRegex(pattern);
|
|
39848
40127
|
const matches = files.filter((f) => regex.test(f));
|
|
39849
40128
|
if (matches.length > 0) {
|
|
39850
|
-
return
|
|
40129
|
+
return path21.join(dir, matches[0]);
|
|
39851
40130
|
}
|
|
39852
40131
|
} catch {}
|
|
39853
40132
|
} else {
|
|
39854
|
-
const filePath =
|
|
40133
|
+
const filePath = path21.join(workingDir, pattern);
|
|
39855
40134
|
if (fs9.existsSync(filePath)) {
|
|
39856
40135
|
return filePath;
|
|
39857
40136
|
}
|
|
@@ -39860,7 +40139,7 @@ function findBuildFiles(workingDir, patterns) {
|
|
|
39860
40139
|
return null;
|
|
39861
40140
|
}
|
|
39862
40141
|
function getRepoDefinedScripts(workingDir, scripts) {
|
|
39863
|
-
const packageJsonPath =
|
|
40142
|
+
const packageJsonPath = path21.join(workingDir, "package.json");
|
|
39864
40143
|
if (!fs9.existsSync(packageJsonPath)) {
|
|
39865
40144
|
return [];
|
|
39866
40145
|
}
|
|
@@ -39901,7 +40180,7 @@ function findAllBuildFiles(workingDir) {
|
|
|
39901
40180
|
const regex = simpleGlobToRegex(pattern);
|
|
39902
40181
|
findFilesRecursive(workingDir, regex, allBuildFiles);
|
|
39903
40182
|
} else {
|
|
39904
|
-
const filePath =
|
|
40183
|
+
const filePath = path21.join(workingDir, pattern);
|
|
39905
40184
|
if (fs9.existsSync(filePath)) {
|
|
39906
40185
|
allBuildFiles.add(filePath);
|
|
39907
40186
|
}
|
|
@@ -39914,7 +40193,7 @@ function findFilesRecursive(dir, regex, results) {
|
|
|
39914
40193
|
try {
|
|
39915
40194
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
39916
40195
|
for (const entry of entries) {
|
|
39917
|
-
const fullPath =
|
|
40196
|
+
const fullPath = path21.join(dir, entry.name);
|
|
39918
40197
|
if (entry.isDirectory() && !["node_modules", ".git", "dist", "build", "target"].includes(entry.name)) {
|
|
39919
40198
|
findFilesRecursive(fullPath, regex, results);
|
|
39920
40199
|
} else if (entry.isFile() && regex.test(entry.name)) {
|
|
@@ -39937,7 +40216,7 @@ async function discoverBuildCommandsFromProfiles(workingDir) {
|
|
|
39937
40216
|
let foundCommand = false;
|
|
39938
40217
|
for (const cmd of sortedCommands) {
|
|
39939
40218
|
if (cmd.detectFile) {
|
|
39940
|
-
const detectFilePath =
|
|
40219
|
+
const detectFilePath = path21.join(workingDir, cmd.detectFile);
|
|
39941
40220
|
if (!fs9.existsSync(detectFilePath)) {
|
|
39942
40221
|
continue;
|
|
39943
40222
|
}
|
|
@@ -39970,7 +40249,7 @@ async function discoverBuildCommands(workingDir, options) {
|
|
|
39970
40249
|
const scope = options?.scope ?? "all";
|
|
39971
40250
|
const changedFiles = options?.changedFiles ?? [];
|
|
39972
40251
|
const _filesToCheck = filterByScope(workingDir, scope, changedFiles);
|
|
39973
|
-
const profileResult = await
|
|
40252
|
+
const profileResult = await _internals10.discoverBuildCommandsFromProfiles(workingDir);
|
|
39974
40253
|
const profileCommands = profileResult.commands;
|
|
39975
40254
|
const profileSkipped = profileResult.skipped;
|
|
39976
40255
|
const coveredEcosystems = new Set;
|
|
@@ -40033,7 +40312,7 @@ function clearToolchainCache() {
|
|
|
40033
40312
|
function getEcosystems() {
|
|
40034
40313
|
return ECOSYSTEMS.map((e) => e.ecosystem);
|
|
40035
40314
|
}
|
|
40036
|
-
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache,
|
|
40315
|
+
var ECOSYSTEMS, PROFILE_TO_ECOSYSTEM_NAMES, toolchainCache, _internals10, build_discovery;
|
|
40037
40316
|
var init_discovery = __esm(() => {
|
|
40038
40317
|
init_dist();
|
|
40039
40318
|
init_detector();
|
|
@@ -40151,7 +40430,7 @@ var init_discovery = __esm(() => {
|
|
|
40151
40430
|
php: ["php-composer"]
|
|
40152
40431
|
};
|
|
40153
40432
|
toolchainCache = new Map;
|
|
40154
|
-
|
|
40433
|
+
_internals10 = {
|
|
40155
40434
|
isCommandAvailable,
|
|
40156
40435
|
discoverBuildCommandsFromProfiles,
|
|
40157
40436
|
discoverBuildCommands,
|
|
@@ -40177,7 +40456,7 @@ var init_discovery = __esm(() => {
|
|
|
40177
40456
|
|
|
40178
40457
|
// src/services/tool-doctor.ts
|
|
40179
40458
|
import * as fs10 from "fs";
|
|
40180
|
-
import * as
|
|
40459
|
+
import * as path22 from "path";
|
|
40181
40460
|
function extractRegisteredToolKeys(indexPath) {
|
|
40182
40461
|
const registeredKeys = new Set;
|
|
40183
40462
|
try {
|
|
@@ -40232,8 +40511,8 @@ function checkBinaryReadiness() {
|
|
|
40232
40511
|
}
|
|
40233
40512
|
function runToolDoctor(_directory, pluginRoot) {
|
|
40234
40513
|
const findings = [];
|
|
40235
|
-
const resolvedPluginRoot = pluginRoot ??
|
|
40236
|
-
const indexPath =
|
|
40514
|
+
const resolvedPluginRoot = pluginRoot ?? path22.resolve(import.meta.dir, "..", "..");
|
|
40515
|
+
const indexPath = path22.join(resolvedPluginRoot, "src", "index.ts");
|
|
40237
40516
|
if (!fs10.existsSync(indexPath)) {
|
|
40238
40517
|
return {
|
|
40239
40518
|
findings: [
|
|
@@ -40403,7 +40682,7 @@ var exports_evidence_summary_service = {};
|
|
|
40403
40682
|
__export(exports_evidence_summary_service, {
|
|
40404
40683
|
isAutoSummaryEnabled: () => isAutoSummaryEnabled,
|
|
40405
40684
|
buildEvidenceSummary: () => buildEvidenceSummary,
|
|
40406
|
-
_internals: () =>
|
|
40685
|
+
_internals: () => _internals11,
|
|
40407
40686
|
REQUIRED_EVIDENCE_TYPES: () => REQUIRED_EVIDENCE_TYPES,
|
|
40408
40687
|
EVIDENCE_SUMMARY_VERSION: () => EVIDENCE_SUMMARY_VERSION
|
|
40409
40688
|
});
|
|
@@ -40441,14 +40720,14 @@ function getTaskStatus(task, bundle) {
|
|
|
40441
40720
|
if (task?.status) {
|
|
40442
40721
|
return task.status;
|
|
40443
40722
|
}
|
|
40444
|
-
const entries =
|
|
40723
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40445
40724
|
if (entries.length > 0) {
|
|
40446
40725
|
return "completed";
|
|
40447
40726
|
}
|
|
40448
40727
|
return "pending";
|
|
40449
40728
|
}
|
|
40450
40729
|
function isEvidenceComplete(bundle) {
|
|
40451
|
-
const entries =
|
|
40730
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40452
40731
|
if (entries.length === 0) {
|
|
40453
40732
|
return {
|
|
40454
40733
|
isComplete: false,
|
|
@@ -40484,10 +40763,10 @@ async function buildTaskSummary(directory, task, taskId) {
|
|
|
40484
40763
|
const result = await loadEvidence(directory, taskId);
|
|
40485
40764
|
const bundle = result.status === "found" ? result.bundle : null;
|
|
40486
40765
|
const phase = task?.phase ?? 0;
|
|
40487
|
-
const status =
|
|
40488
|
-
const evidenceCheck =
|
|
40489
|
-
const blockers =
|
|
40490
|
-
const entries =
|
|
40766
|
+
const status = _internals11.getTaskStatus(task, bundle);
|
|
40767
|
+
const evidenceCheck = _internals11.isEvidenceComplete(bundle);
|
|
40768
|
+
const blockers = _internals11.getTaskBlockers(task, evidenceCheck, status);
|
|
40769
|
+
const entries = _internals11.normalizeBundleEntries(bundle);
|
|
40491
40770
|
const hasReview = entries.some((e) => e.type === "review");
|
|
40492
40771
|
const hasTest = entries.some((e) => e.type === "test");
|
|
40493
40772
|
const hasApproval = entries.some((e) => e.type === "approval");
|
|
@@ -40516,12 +40795,12 @@ async function buildPhaseSummary(directory, phase) {
|
|
|
40516
40795
|
const taskSummaries = [];
|
|
40517
40796
|
const _taskMap = new Map(phase.tasks.map((t) => [t.id, t]));
|
|
40518
40797
|
for (const task of phase.tasks) {
|
|
40519
|
-
const summary = await
|
|
40798
|
+
const summary = await _internals11.buildTaskSummary(directory, task, task.id);
|
|
40520
40799
|
taskSummaries.push(summary);
|
|
40521
40800
|
}
|
|
40522
40801
|
const extraTaskIds = taskIds.filter((id) => !phaseTaskIds.has(id));
|
|
40523
40802
|
for (const taskId of extraTaskIds) {
|
|
40524
|
-
const summary = await
|
|
40803
|
+
const summary = await _internals11.buildTaskSummary(directory, undefined, taskId);
|
|
40525
40804
|
if (summary.phase === phase.id) {
|
|
40526
40805
|
taskSummaries.push(summary);
|
|
40527
40806
|
}
|
|
@@ -40622,7 +40901,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
40622
40901
|
let totalTasks = 0;
|
|
40623
40902
|
let completedTasks = 0;
|
|
40624
40903
|
for (const phase of phasesToProcess) {
|
|
40625
|
-
const summary = await
|
|
40904
|
+
const summary = await _internals11.buildPhaseSummary(directory, phase);
|
|
40626
40905
|
phaseSummaries.push(summary);
|
|
40627
40906
|
totalTasks += summary.totalTasks;
|
|
40628
40907
|
completedTasks += summary.completedTasks;
|
|
@@ -40644,7 +40923,7 @@ async function buildEvidenceSummary(directory, currentPhase) {
|
|
|
40644
40923
|
overallBlockers,
|
|
40645
40924
|
summaryText: ""
|
|
40646
40925
|
};
|
|
40647
|
-
artifact.summaryText =
|
|
40926
|
+
artifact.summaryText = _internals11.generateSummaryText(artifact);
|
|
40648
40927
|
log("[EvidenceSummary] Summary built", {
|
|
40649
40928
|
phases: phaseSummaries.length,
|
|
40650
40929
|
totalTasks,
|
|
@@ -40663,7 +40942,7 @@ function isAutoSummaryEnabled(automationConfig) {
|
|
|
40663
40942
|
}
|
|
40664
40943
|
return automationConfig.capabilities?.evidence_auto_summaries === true;
|
|
40665
40944
|
}
|
|
40666
|
-
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0",
|
|
40945
|
+
var VALID_EVIDENCE_TYPES2, REQUIRED_EVIDENCE_TYPES, EVIDENCE_SUMMARY_VERSION = "1.0.0", _internals11;
|
|
40667
40946
|
var init_evidence_summary_service = __esm(() => {
|
|
40668
40947
|
init_manager2();
|
|
40669
40948
|
init_manager();
|
|
@@ -40677,7 +40956,7 @@ var init_evidence_summary_service = __esm(() => {
|
|
|
40677
40956
|
"retrospective"
|
|
40678
40957
|
]);
|
|
40679
40958
|
REQUIRED_EVIDENCE_TYPES = ["review", "test"];
|
|
40680
|
-
|
|
40959
|
+
_internals11 = {
|
|
40681
40960
|
buildEvidenceSummary,
|
|
40682
40961
|
isAutoSummaryEnabled,
|
|
40683
40962
|
normalizeBundleEntries,
|
|
@@ -40924,12 +41203,12 @@ var init_export = __esm(() => {
|
|
|
40924
41203
|
|
|
40925
41204
|
// src/full-auto/state.ts
|
|
40926
41205
|
import * as fs11 from "fs";
|
|
40927
|
-
import * as
|
|
41206
|
+
import * as path23 from "path";
|
|
40928
41207
|
function nowISO() {
|
|
40929
41208
|
return new Date().toISOString();
|
|
40930
41209
|
}
|
|
40931
41210
|
function ensureSwarmDir(directory) {
|
|
40932
|
-
const swarmDir =
|
|
41211
|
+
const swarmDir = path23.resolve(directory, ".swarm");
|
|
40933
41212
|
if (!fs11.existsSync(swarmDir)) {
|
|
40934
41213
|
fs11.mkdirSync(swarmDir, { recursive: true });
|
|
40935
41214
|
}
|
|
@@ -41280,7 +41559,7 @@ function extractCurrentPhaseFromPlan2(plan) {
|
|
|
41280
41559
|
if (!plan) {
|
|
41281
41560
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
41282
41561
|
}
|
|
41283
|
-
if (!
|
|
41562
|
+
if (!_internals12.validatePlanPhases(plan)) {
|
|
41284
41563
|
return { currentPhase: null, currentTask: null, incompleteTasks: [] };
|
|
41285
41564
|
}
|
|
41286
41565
|
let currentPhase = null;
|
|
@@ -41422,9 +41701,9 @@ function extractPhaseMetrics(content) {
|
|
|
41422
41701
|
async function getHandoffData(directory) {
|
|
41423
41702
|
const now = new Date().toISOString();
|
|
41424
41703
|
const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
|
|
41425
|
-
const sessionState =
|
|
41704
|
+
const sessionState = _internals12.parseSessionState(sessionContent);
|
|
41426
41705
|
const plan = await loadPlanJsonOnly(directory);
|
|
41427
|
-
const planInfo =
|
|
41706
|
+
const planInfo = _internals12.extractCurrentPhaseFromPlan(plan);
|
|
41428
41707
|
if (!plan) {
|
|
41429
41708
|
const planMdContent = await readSwarmFileAsync(directory, "plan.md");
|
|
41430
41709
|
if (planMdContent) {
|
|
@@ -41443,8 +41722,8 @@ async function getHandoffData(directory) {
|
|
|
41443
41722
|
}
|
|
41444
41723
|
}
|
|
41445
41724
|
const contextContent = await readSwarmFileAsync(directory, "context.md");
|
|
41446
|
-
const recentDecisions =
|
|
41447
|
-
const rawPhaseMetrics =
|
|
41725
|
+
const recentDecisions = _internals12.extractDecisions(contextContent);
|
|
41726
|
+
const rawPhaseMetrics = _internals12.extractPhaseMetrics(contextContent);
|
|
41448
41727
|
const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
|
|
41449
41728
|
let delegationState = null;
|
|
41450
41729
|
if (sessionState?.delegationState) {
|
|
@@ -41608,13 +41887,13 @@ ${lines.join(`
|
|
|
41608
41887
|
`)}
|
|
41609
41888
|
\`\`\``;
|
|
41610
41889
|
}
|
|
41611
|
-
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20,
|
|
41890
|
+
var RTL_OVERRIDE_PATTERN, MAX_TASK_ID_LENGTH = 100, MAX_DECISION_LENGTH = 500, MAX_INCOMPLETE_TASKS = 20, _internals12;
|
|
41612
41891
|
var init_handoff_service = __esm(() => {
|
|
41613
41892
|
init_utils2();
|
|
41614
41893
|
init_manager();
|
|
41615
41894
|
init_utils();
|
|
41616
41895
|
RTL_OVERRIDE_PATTERN = /[\u202e\u202d\u202c\u200f]/g;
|
|
41617
|
-
|
|
41896
|
+
_internals12 = {
|
|
41618
41897
|
getHandoffData,
|
|
41619
41898
|
formatHandoffMarkdown,
|
|
41620
41899
|
formatContinuationPrompt,
|
|
@@ -41628,6 +41907,133 @@ var init_handoff_service = __esm(() => {
|
|
|
41628
41907
|
};
|
|
41629
41908
|
});
|
|
41630
41909
|
|
|
41910
|
+
// src/session/snapshot-writer.ts
|
|
41911
|
+
import { mkdirSync as mkdirSync10, renameSync as renameSync6 } from "fs";
|
|
41912
|
+
import * as path24 from "path";
|
|
41913
|
+
function serializeAgentSession(s) {
|
|
41914
|
+
const gateLog = {};
|
|
41915
|
+
const rawGateLog = s.gateLog ?? new Map;
|
|
41916
|
+
for (const [taskId, gates] of rawGateLog) {
|
|
41917
|
+
gateLog[taskId] = Array.from(gates ?? []);
|
|
41918
|
+
}
|
|
41919
|
+
const reviewerCallCount = {};
|
|
41920
|
+
const rawReviewerCallCount = s.reviewerCallCount ?? new Map;
|
|
41921
|
+
for (const [phase, count] of rawReviewerCallCount) {
|
|
41922
|
+
reviewerCallCount[String(phase)] = count;
|
|
41923
|
+
}
|
|
41924
|
+
const partialGateWarningsIssuedForTask = Array.from(s.partialGateWarningsIssuedForTask ?? new Set);
|
|
41925
|
+
const catastrophicPhaseWarnings = Array.from(s.catastrophicPhaseWarnings ?? new Set);
|
|
41926
|
+
const phaseAgentsDispatched = Array.from(s.phaseAgentsDispatched ?? new Set);
|
|
41927
|
+
const lastCompletedPhaseAgentsDispatched = Array.from(s.lastCompletedPhaseAgentsDispatched ?? new Set);
|
|
41928
|
+
const windows = {};
|
|
41929
|
+
const rawWindows = s.windows ?? {};
|
|
41930
|
+
for (const [key, win] of Object.entries(rawWindows)) {
|
|
41931
|
+
windows[key] = {
|
|
41932
|
+
id: win.id,
|
|
41933
|
+
agentName: win.agentName,
|
|
41934
|
+
startedAtMs: win.startedAtMs,
|
|
41935
|
+
toolCalls: win.toolCalls,
|
|
41936
|
+
consecutiveErrors: win.consecutiveErrors,
|
|
41937
|
+
hardLimitHit: win.hardLimitHit,
|
|
41938
|
+
lastSuccessTimeMs: win.lastSuccessTimeMs,
|
|
41939
|
+
recentToolCalls: win.recentToolCalls,
|
|
41940
|
+
warningIssued: win.warningIssued,
|
|
41941
|
+
warningReason: win.warningReason,
|
|
41942
|
+
transientRetryCount: win.transientRetryCount ?? 0
|
|
41943
|
+
};
|
|
41944
|
+
}
|
|
41945
|
+
return {
|
|
41946
|
+
agentName: s.agentName,
|
|
41947
|
+
lastToolCallTime: s.lastToolCallTime,
|
|
41948
|
+
lastAgentEventTime: s.lastAgentEventTime,
|
|
41949
|
+
delegationActive: s.delegationActive,
|
|
41950
|
+
activeInvocationId: s.activeInvocationId,
|
|
41951
|
+
lastInvocationIdByAgent: s.lastInvocationIdByAgent ?? {},
|
|
41952
|
+
windows,
|
|
41953
|
+
lastCompactionHint: s.lastCompactionHint ?? 0,
|
|
41954
|
+
architectWriteCount: s.architectWriteCount ?? 0,
|
|
41955
|
+
lastCoderDelegationTaskId: s.lastCoderDelegationTaskId ?? null,
|
|
41956
|
+
currentTaskId: s.currentTaskId ?? null,
|
|
41957
|
+
turboMode: s.turboMode ?? false,
|
|
41958
|
+
gateLog,
|
|
41959
|
+
reviewerCallCount,
|
|
41960
|
+
lastGateFailure: s.lastGateFailure ?? null,
|
|
41961
|
+
partialGateWarningsIssuedForTask,
|
|
41962
|
+
selfFixAttempted: s.selfFixAttempted ?? false,
|
|
41963
|
+
selfCodingWarnedAtCount: s.selfCodingWarnedAtCount ?? 0,
|
|
41964
|
+
catastrophicPhaseWarnings,
|
|
41965
|
+
lastPhaseCompleteTimestamp: s.lastPhaseCompleteTimestamp ?? 0,
|
|
41966
|
+
lastPhaseCompletePhase: s.lastPhaseCompletePhase ?? 0,
|
|
41967
|
+
phaseAgentsDispatched,
|
|
41968
|
+
lastCompletedPhaseAgentsDispatched,
|
|
41969
|
+
qaSkipCount: s.qaSkipCount ?? 0,
|
|
41970
|
+
qaSkipTaskIds: s.qaSkipTaskIds ?? [],
|
|
41971
|
+
pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
|
|
41972
|
+
taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
|
|
41973
|
+
...s.scopeViolationDetected !== undefined && {
|
|
41974
|
+
scopeViolationDetected: s.scopeViolationDetected
|
|
41975
|
+
},
|
|
41976
|
+
model_fallback_index: s.model_fallback_index ?? 0,
|
|
41977
|
+
modelFallbackExhausted: s.modelFallbackExhausted ?? false,
|
|
41978
|
+
coderRevisions: s.coderRevisions ?? 0,
|
|
41979
|
+
revisionLimitHit: s.revisionLimitHit ?? false,
|
|
41980
|
+
fullAutoMode: s.fullAutoMode ?? false,
|
|
41981
|
+
fullAutoInteractionCount: s.fullAutoInteractionCount ?? 0,
|
|
41982
|
+
fullAutoDeadlockCount: s.fullAutoDeadlockCount ?? 0,
|
|
41983
|
+
fullAutoLastQuestionHash: s.fullAutoLastQuestionHash ?? null,
|
|
41984
|
+
sessionRehydratedAt: s.sessionRehydratedAt ?? 0
|
|
41985
|
+
};
|
|
41986
|
+
}
|
|
41987
|
+
async function writeSnapshot(directory, state) {
|
|
41988
|
+
try {
|
|
41989
|
+
const snapshot = {
|
|
41990
|
+
version: 2,
|
|
41991
|
+
writtenAt: Date.now(),
|
|
41992
|
+
toolAggregates: Object.fromEntries(state.toolAggregates),
|
|
41993
|
+
activeAgent: Object.fromEntries(state.activeAgent),
|
|
41994
|
+
delegationChains: Object.fromEntries(state.delegationChains),
|
|
41995
|
+
agentSessions: {}
|
|
41996
|
+
};
|
|
41997
|
+
for (const [sessionId, sessionState] of state.agentSessions) {
|
|
41998
|
+
snapshot.agentSessions[sessionId] = serializeAgentSession(sessionState);
|
|
41999
|
+
}
|
|
42000
|
+
const content = JSON.stringify(snapshot, null, 2);
|
|
42001
|
+
const resolvedPath = validateSwarmPath(directory, "session/state.json");
|
|
42002
|
+
const dir = path24.dirname(resolvedPath);
|
|
42003
|
+
mkdirSync10(dir, { recursive: true });
|
|
42004
|
+
const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
|
|
42005
|
+
await bunWrite(tempPath, content);
|
|
42006
|
+
renameSync6(tempPath, resolvedPath);
|
|
42007
|
+
} catch (error93) {
|
|
42008
|
+
log("[snapshot-writer] write failed", {
|
|
42009
|
+
error: error93 instanceof Error ? error93.message : String(error93)
|
|
42010
|
+
});
|
|
42011
|
+
}
|
|
42012
|
+
}
|
|
42013
|
+
function createSnapshotWriterHook(directory) {
|
|
42014
|
+
return (_input, _output) => {
|
|
42015
|
+
_writeInFlight = _writeInFlight.then(() => _internals13.writeSnapshot(directory, swarmState), () => _internals13.writeSnapshot(directory, swarmState));
|
|
42016
|
+
return _writeInFlight;
|
|
42017
|
+
};
|
|
42018
|
+
}
|
|
42019
|
+
async function flushPendingSnapshot(directory) {
|
|
42020
|
+
_writeInFlight = _writeInFlight.then(() => _internals13.writeSnapshot(directory, swarmState), () => _internals13.writeSnapshot(directory, swarmState));
|
|
42021
|
+
await _writeInFlight;
|
|
42022
|
+
}
|
|
42023
|
+
var _writeInFlight, _internals13;
|
|
42024
|
+
var init_snapshot_writer = __esm(() => {
|
|
42025
|
+
init_utils2();
|
|
42026
|
+
init_state();
|
|
42027
|
+
init_utils();
|
|
42028
|
+
init_bun_compat();
|
|
42029
|
+
_writeInFlight = Promise.resolve();
|
|
42030
|
+
_internals13 = {
|
|
42031
|
+
writeSnapshot,
|
|
42032
|
+
createSnapshotWriterHook,
|
|
42033
|
+
flushPendingSnapshot
|
|
42034
|
+
};
|
|
42035
|
+
});
|
|
42036
|
+
|
|
41631
42037
|
// src/commands/handoff.ts
|
|
41632
42038
|
import crypto4 from "crypto";
|
|
41633
42039
|
import { renameSync as renameSync7, unlinkSync as unlinkSync4 } from "fs";
|
|
@@ -47772,7 +48178,7 @@ async function handleSimulateCommand(directory, args) {
|
|
|
47772
48178
|
}
|
|
47773
48179
|
let darkMatterPairs;
|
|
47774
48180
|
try {
|
|
47775
|
-
darkMatterPairs = await
|
|
48181
|
+
darkMatterPairs = await _internals9.detectDarkMatter(directory, options);
|
|
47776
48182
|
} catch (err) {
|
|
47777
48183
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
47778
48184
|
return `## Simulate Report
|