opencode-swarm 7.93.1 → 7.94.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/plan/SKILL.md +2 -2
- package/dist/agents/council-prompts.d.ts +3 -3
- package/dist/agents/critic.d.ts +6 -6
- package/dist/agents/explorer.d.ts +2 -2
- package/dist/agents/read-only-lane-guidance.d.ts +1 -0
- package/dist/cli/{config-doctor-fkwyrtpq.js → config-doctor-ecmx9scq.js} +2 -2
- package/dist/cli/{explorer-4ttwy7jd.js → explorer-jc46negv.js} +1 -1
- package/dist/cli/{guardrail-explain-bjsc2ydm.js → guardrail-explain-we8mhb6y.js} +8 -8
- package/dist/cli/{guardrail-log-x3w800x5.js → guardrail-log-0q6pvbpx.js} +3 -3
- package/dist/cli/{index-1x2608ga.js → index-2a6ppa65.js} +14 -2
- package/dist/cli/{index-xsbtbffr.js → index-79dcqsg9.js} +4 -0
- package/dist/cli/{index-mv27v975.js → index-a59fjg9v.js} +1141 -15
- package/dist/cli/{index-ne4g3mk1.js → index-dgjsa6hy.js} +1 -1
- package/dist/cli/{index-5hrexm02.js → index-fjxjb66n.js} +166 -5
- package/dist/cli/{index-w7gkpmq8.js → index-hb10a2g8.js} +35 -2
- package/dist/cli/{index-dy6zs70b.js → index-jv0bz96v.js} +9 -9
- package/dist/cli/{index-9j1xvd8m.js → index-q8qx8p47.js} +2 -2
- package/dist/cli/{index-yykcmn6m.js → index-tx5czwpd.js} +1 -1
- package/dist/cli/{index-2jpbaedv.js → index-vqg905es.js} +1 -1
- package/dist/cli/index.js +7 -7
- package/dist/cli/{knowledge-store-eqans52j.js → knowledge-store-pa58msy5.js} +3 -1
- package/dist/cli/{schema-1kndsf0c.js → schema-jy18ftky.js} +1 -1
- package/dist/cli/{skill-generator-d0jzw6n2.js → skill-generator-3tkwcg4x.js} +12 -2
- package/dist/hooks/curator.d.ts +8 -3
- package/dist/hooks/knowledge-events.d.ts +12 -1
- package/dist/hooks/knowledge-store.d.ts +2 -0
- package/dist/index.js +1114 -621
- package/dist/services/skill-generator.d.ts +46 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/manifest.d.ts +1 -0
- package/dist/tools/stale-reconciliation.d.ts +23 -0
- package/dist/tools/tool-metadata.d.ts +7 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ var package_default;
|
|
|
69
69
|
var init_package = __esm(() => {
|
|
70
70
|
package_default = {
|
|
71
71
|
name: "opencode-swarm",
|
|
72
|
-
version: "7.
|
|
72
|
+
version: "7.94.1",
|
|
73
73
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
74
74
|
main: "dist/index.js",
|
|
75
75
|
types: "dist/index.d.ts",
|
|
@@ -645,6 +645,10 @@ var init_tool_metadata = __esm(() => {
|
|
|
645
645
|
description: "inspect the content and source entries of a skill file",
|
|
646
646
|
agents: ["architect", "skill_improver"]
|
|
647
647
|
},
|
|
648
|
+
run_stale_reconciliation: {
|
|
649
|
+
description: "reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",
|
|
650
|
+
agents: ["architect"]
|
|
651
|
+
},
|
|
648
652
|
skill_regenerate: {
|
|
649
653
|
description: "regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",
|
|
650
654
|
agents: ["architect"]
|
|
@@ -61550,6 +61554,7 @@ __export(exports_knowledge_store, {
|
|
|
61550
61554
|
jaccardBigram: () => jaccardBigram,
|
|
61551
61555
|
inferTags: () => inferTags,
|
|
61552
61556
|
getPlatformConfigDir: () => getPlatformConfigDir,
|
|
61557
|
+
getArchivedKnowledgeIds: () => getArchivedKnowledgeIds,
|
|
61553
61558
|
findNearDuplicate: () => findNearDuplicate,
|
|
61554
61559
|
enforceKnowledgeCap: () => enforceKnowledgeCap,
|
|
61555
61560
|
computeOutcomeSignal: () => computeOutcomeSignal,
|
|
@@ -61790,6 +61795,38 @@ async function transactKnowledge(filePath, mutate) {
|
|
|
61790
61795
|
await atomicWriteFile(fp, content);
|
|
61791
61796
|
}, mutate);
|
|
61792
61797
|
}
|
|
61798
|
+
async function getArchivedKnowledgeIds(directory) {
|
|
61799
|
+
const archived = new Set;
|
|
61800
|
+
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
61801
|
+
try {
|
|
61802
|
+
const content = await readFile5(swarmPath, "utf-8");
|
|
61803
|
+
const lines = content.split(`
|
|
61804
|
+
`).filter((l) => l.trim());
|
|
61805
|
+
for (const line of lines) {
|
|
61806
|
+
try {
|
|
61807
|
+
const entry = JSON.parse(line);
|
|
61808
|
+
if (entry.status === "archived" || entry.status === "quarantined" || entry.status === "quarantined_unactionable") {
|
|
61809
|
+
archived.add(entry.id);
|
|
61810
|
+
}
|
|
61811
|
+
} catch {}
|
|
61812
|
+
}
|
|
61813
|
+
} catch {}
|
|
61814
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
61815
|
+
try {
|
|
61816
|
+
const content = await readFile5(hivePath, "utf-8");
|
|
61817
|
+
const lines = content.split(`
|
|
61818
|
+
`).filter((l) => l.trim());
|
|
61819
|
+
for (const line of lines) {
|
|
61820
|
+
try {
|
|
61821
|
+
const entry = JSON.parse(line);
|
|
61822
|
+
if (entry.status === "archived" || entry.status === "quarantined" || entry.status === "quarantined_unactionable") {
|
|
61823
|
+
archived.add(entry.id);
|
|
61824
|
+
}
|
|
61825
|
+
} catch {}
|
|
61826
|
+
}
|
|
61827
|
+
} catch {}
|
|
61828
|
+
return archived;
|
|
61829
|
+
}
|
|
61793
61830
|
async function appendKnowledgeWithCapEnforcement(filePath, entry, maxEntries) {
|
|
61794
61831
|
return transactKnowledge(filePath, (entries) => {
|
|
61795
61832
|
const updated = [...entries, entry];
|
|
@@ -62084,7 +62121,8 @@ var init_knowledge_store = __esm(() => {
|
|
|
62084
62121
|
computeOutcomeSignal,
|
|
62085
62122
|
selectKnowledgeCapSurvivors,
|
|
62086
62123
|
inferTags,
|
|
62087
|
-
bumpKnowledgeConfidenceBatch
|
|
62124
|
+
bumpKnowledgeConfidenceBatch,
|
|
62125
|
+
getArchivedKnowledgeIds
|
|
62088
62126
|
};
|
|
62089
62127
|
});
|
|
62090
62128
|
|
|
@@ -62687,6 +62725,16 @@ var init_knowledge_events = __esm(() => {
|
|
|
62687
62725
|
};
|
|
62688
62726
|
});
|
|
62689
62727
|
|
|
62728
|
+
// src/agents/read-only-lane-guidance.ts
|
|
62729
|
+
var READ_ONLY_LANE_GUIDANCE = `## READ-ONLY ADVISORY LANE CONTEXT
|
|
62730
|
+
|
|
62731
|
+
You may be invoked through dispatch_lanes or dispatch_lanes_async as a read-only advisory lane. In that context, your job is to inspect, reason, and report only.
|
|
62732
|
+
|
|
62733
|
+
- Do NOT write, edit, patch, save plans, update task status, declare scope, submit council verdicts, set QA gates, or complete phases.
|
|
62734
|
+
- Do NOT call artifact-producing or workflow-mutating helpers such as extract_code_blocks, knowledge_add, summarize_work, or doc_scan when lane permissions deny them.
|
|
62735
|
+
- Treat any denied or unavailable tool as intentionally unavailable in lane mode; continue with the read-only tools and context you have.
|
|
62736
|
+
- Return findings for the architect to synthesize. Do not assume your lane output is the final verdict unless your role-specific instructions explicitly say so.`;
|
|
62737
|
+
|
|
62690
62738
|
// src/agents/explorer.ts
|
|
62691
62739
|
var exports_explorer = {};
|
|
62692
62740
|
__export(exports_explorer, {
|
|
@@ -62721,7 +62769,186 @@ ${customAppendPrompt}`;
|
|
|
62721
62769
|
}
|
|
62722
62770
|
};
|
|
62723
62771
|
}
|
|
62724
|
-
var EXPLORER_PROMPT = `## IDENTITY
|
|
62772
|
+
var EXPLORER_PROMPT, CURATOR_INIT_PROMPT = `## IDENTITY
|
|
62773
|
+
You are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.
|
|
62774
|
+
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62775
|
+
|
|
62776
|
+
INPUT FORMAT:
|
|
62777
|
+
TASK: CURATOR_INIT
|
|
62778
|
+
PRIOR_SUMMARY: [JSON or "none"]
|
|
62779
|
+
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
62780
|
+
PROJECT_CONTEXT: [context.md excerpt]
|
|
62781
|
+
|
|
62782
|
+
ACTIONS:
|
|
62783
|
+
- Read the prior summary to understand session history
|
|
62784
|
+
- Cross-reference knowledge entries against project context
|
|
62785
|
+
- Note contradictions (knowledge says X, project state shows Y)
|
|
62786
|
+
- Observe where lessons could be tighter or stale
|
|
62787
|
+
- Produce a concise briefing for the architect
|
|
62788
|
+
|
|
62789
|
+
RULES:
|
|
62790
|
+
- Output under 2000 chars
|
|
62791
|
+
- No code modifications
|
|
62792
|
+
- Flag contradictions explicitly with CONTRADICTION: prefix
|
|
62793
|
+
- Memory proposals are for concise durable facts only. Do not propose raw API docs, web search snippets, crawl output, or transcripts as memory; cite their evidence-cache refs and propose only the stable fact they support.
|
|
62794
|
+
- If no prior summary exists, state "First session — no prior context"
|
|
62795
|
+
|
|
62796
|
+
OUTPUT FORMAT:
|
|
62797
|
+
BRIEFING:
|
|
62798
|
+
[concise summary of prior session state, key decisions, active blockers]
|
|
62799
|
+
|
|
62800
|
+
CONTRADICTIONS:
|
|
62801
|
+
- [entry_id]: [description] (or "None detected")
|
|
62802
|
+
|
|
62803
|
+
OBSERVATIONS:
|
|
62804
|
+
- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)
|
|
62805
|
+
- entry <uuid> appears stale: [observable evidence] (suggests archive — no longer injected)
|
|
62806
|
+
- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)
|
|
62807
|
+
- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)
|
|
62808
|
+
- new candidate: [concise lesson text from observed patterns] (suggests new entry)
|
|
62809
|
+
Use the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use "new candidate" only when observing a potential new entry.
|
|
62810
|
+
|
|
62811
|
+
KNOWLEDGE_STATS:
|
|
62812
|
+
- Entries reviewed: [N]
|
|
62813
|
+
- Prior phases covered: [N]
|
|
62814
|
+
`, CURATOR_PHASE_PROMPT = `## IDENTITY
|
|
62815
|
+
You are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.
|
|
62816
|
+
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62817
|
+
|
|
62818
|
+
INPUT FORMAT:
|
|
62819
|
+
TASK: CURATOR_PHASE [phase_number]
|
|
62820
|
+
PRIOR_DIGEST: [running summary or "none"]
|
|
62821
|
+
PHASE_EVENTS: [JSON array from events.jsonl for this phase]
|
|
62822
|
+
PHASE_EVIDENCE: [summary of evidence bundles]
|
|
62823
|
+
PHASE_DECISIONS: [decisions from context.md]
|
|
62824
|
+
AGENTS_DISPATCHED: [list]
|
|
62825
|
+
AGENTS_EXPECTED: [list from config]
|
|
62826
|
+
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
62827
|
+
|
|
62828
|
+
ACTIONS:
|
|
62829
|
+
- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)
|
|
62830
|
+
- Observe workflow deviations: missing reviewer, missing retro, skipped test_engineer
|
|
62831
|
+
- Report knowledge update candidates with observable evidence: entries that appear promoted, archived, rewritten, or contradicted
|
|
62832
|
+
- Summarize key decisions and blockers resolved
|
|
62833
|
+
|
|
62834
|
+
RULES:
|
|
62835
|
+
- Output under 2000 chars
|
|
62836
|
+
- No code modifications
|
|
62837
|
+
- Compliance observations are READ-ONLY — report, do not enforce
|
|
62838
|
+
- OBSERVATIONS should not contain directives — report what is observed, do not instruct the architect what to do
|
|
62839
|
+
- Extend the digest, never replace it
|
|
62840
|
+
- Memory proposals are for concise durable facts only. Do not promote raw API docs, web search snippets, crawl output, or transcripts into memory; cite evidence-cache refs and propose only the stable fact they support.
|
|
62841
|
+
|
|
62842
|
+
OUTPUT FORMAT:
|
|
62843
|
+
PHASE_DIGEST:
|
|
62844
|
+
phase: [N]
|
|
62845
|
+
summary: [what was accomplished]
|
|
62846
|
+
agents_used: [list]
|
|
62847
|
+
tasks_completed: [N]/[total]
|
|
62848
|
+
key_decisions: [list]
|
|
62849
|
+
blockers_resolved: [list]
|
|
62850
|
+
|
|
62851
|
+
COMPLIANCE:
|
|
62852
|
+
- [type] observed: [description] (or "No deviations observed")
|
|
62853
|
+
|
|
62854
|
+
OBSERVATIONS:
|
|
62855
|
+
- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)
|
|
62856
|
+
- entry <uuid> appears stale: [observable evidence] (suggests archive — no longer injected)
|
|
62857
|
+
- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)
|
|
62858
|
+
- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)
|
|
62859
|
+
- new candidate: [concise lesson text from observed patterns] (suggests new entry)
|
|
62860
|
+
Use the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use "new candidate" only when observing a potential new entry.
|
|
62861
|
+
|
|
62862
|
+
EXTENDED_DIGEST:
|
|
62863
|
+
[the full running digest with this phase appended]
|
|
62864
|
+
|
|
62865
|
+
## ACTIONABILITY ENRICHMENT (V3 compatibility label; overrides the format above when triggered)
|
|
62866
|
+
When the input asks you to "Convert this prose lesson into an actionable knowledge directive", ignore the PHASE_DIGEST output format entirely and output ONLY a single JSON object — no fences, no commentary, no digest.
|
|
62867
|
+
MANDATORY fields (the directive is rejected without them):
|
|
62868
|
+
- at least one non-empty scope field: "applies_to_agents" (roles: architect, coder, reviewer, test_engineer, sme, docs, designer, critic, curator) or "applies_to_tools" (edit, write, patch, bash, read, grep, glob)
|
|
62869
|
+
- at least one non-empty predicate field: "forbidden_actions", "required_actions", or "verification_checks"
|
|
62870
|
+
Optional: "triggers" (short surfacing phrases), "directive_priority" (low|medium|high|critical).
|
|
62871
|
+
Example output:
|
|
62872
|
+
{"applies_to_agents":["coder"],"forbidden_actions":["use async iterators in hot paths"],"required_actions":["use a plain for loop in hot paths"],"triggers":["hot path","async iterator"],"directive_priority":"high"}
|
|
62873
|
+
`, CURATOR_POSTMORTEM_PROMPT = `## IDENTITY
|
|
62874
|
+
You are Explorer in CURATOR_POSTMORTEM mode. You synthesize a project-end post-mortem from structured .swarm/ evidence.
|
|
62875
|
+
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62876
|
+
DO NOT scan raw source code — work only from the recorded evidence provided below.
|
|
62877
|
+
|
|
62878
|
+
INPUT FORMAT:
|
|
62879
|
+
TASK: CURATOR_POSTMORTEM [plan_id]
|
|
62880
|
+
PLAN_SUMMARY: [plan phases, task counts, completion status]
|
|
62881
|
+
CURATOR_DIGESTS: [running digest from curator_phase across all phases]
|
|
62882
|
+
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
62883
|
+
KNOWLEDGE_EVENTS_SUMMARY: [aggregated violation/applied/ignored counts per entry]
|
|
62884
|
+
PENDING_PROPOSALS: [skill/motif proposals awaiting triage]
|
|
62885
|
+
UNACTIONABLE_QUARANTINE: [entries flagged unactionable with retry status]
|
|
62886
|
+
DRIFT_REPORTS: [per-phase alignment/drift scores if available]
|
|
62887
|
+
RETROSPECTIVES: [any session retrospectives found]
|
|
62888
|
+
|
|
62889
|
+
ACTIONS:
|
|
62890
|
+
1. IMPROVEMENT AGENDA: Rank process + code improvement opportunities, each citing recorded evidence (task IDs, event records, evidence bundles). Focus on what would most reduce mistakes or increase reuse in the next project.
|
|
62891
|
+
2. FINAL CURATION PASS: Consolidate knowledge across phases — identify near-duplicate lessons that accumulated under different IDs, recommend hive promotion for project-proven entries (high confidence, multiple phases confirmed), flag never-applied entries past 3+ phases for review.
|
|
62892
|
+
3. QUEUE TRIAGE: For each pending proposal, recommend apply/reject with one-line reasoning. Surface unactionable-quarantine counts and retry candidates.
|
|
62893
|
+
4. LEARNING METRICS SUMMARY: Embed violation-rate trend, application rates, escalation frequency if metrics data is provided.
|
|
62894
|
+
|
|
62895
|
+
RULES:
|
|
62896
|
+
- Output under 4000 chars
|
|
62897
|
+
- No code modifications — read-only synthesis
|
|
62898
|
+
- Every improvement item must cite a specific evidence artifact or event record
|
|
62899
|
+
- Do not invent evidence — if an artifact is missing, note the gap
|
|
62900
|
+
- Proposals route through existing gated paths (knowledge_add, skill proposals, hive promotion) — recommend the path, do not bypass it
|
|
62901
|
+
- HIGH-severity items that should become critical directives must be flagged for critic gate validation
|
|
62902
|
+
|
|
62903
|
+
OUTPUT FORMAT:
|
|
62904
|
+
POST_MORTEM_REPORT:
|
|
62905
|
+
plan_id: [plan identifier]
|
|
62906
|
+
generated_at: [ISO timestamp]
|
|
62907
|
+
|
|
62908
|
+
IMPROVEMENT_AGENDA:
|
|
62909
|
+
1. [priority] [description] — evidence: [artifact/event ref]
|
|
62910
|
+
2. ...
|
|
62911
|
+
|
|
62912
|
+
CURATION_RECOMMENDATIONS:
|
|
62913
|
+
- merge: [entry_a UUID] + [entry_b UUID] — [reason]
|
|
62914
|
+
- promote_to_hive: [entry UUID] — [evidence of cross-phase confirmation]
|
|
62915
|
+
- flag_stale: [entry UUID] — [never applied in N phases]
|
|
62916
|
+
- rewrite: [entry UUID] — [what's verbose/outdated]
|
|
62917
|
+
|
|
62918
|
+
QUEUE_TRIAGE:
|
|
62919
|
+
- [proposal_id]: APPLY|REJECT — [one-line reasoning]
|
|
62920
|
+
|
|
62921
|
+
LEARNING_METRICS:
|
|
62922
|
+
[3-line summary of trends if data available, or "metrics data not provided"]
|
|
62923
|
+
|
|
62924
|
+
SUMMARY:
|
|
62925
|
+
[3-line executive summary for architect briefing]
|
|
62926
|
+
`, CURATOR_CONSOLIDATION_PROMPT = `## IDENTITY
|
|
62927
|
+
You are Curator in CONSOLIDATION mode. You distill clusters of raw episodic memory into a small set of durable semantic facts.
|
|
62928
|
+
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62929
|
+
DO NOT scan raw source code — work only from the episodic events and existing memories provided in the prompt.
|
|
62930
|
+
|
|
62931
|
+
INPUT FORMAT:
|
|
62932
|
+
- A cluster of verbatim episodic events.
|
|
62933
|
+
- A list of existing durable memories (each prefixed with its mem_ id) for dedup and contradiction detection.
|
|
62934
|
+
|
|
62935
|
+
ACTIONS:
|
|
62936
|
+
1. Identify durable, reusable facts that are DIRECTLY supported by the cited episodic evidence.
|
|
62937
|
+
2. Detect contradictions with the listed existing memories; when a new fact conflicts with one, set contradictsMemoryId to that memory's id.
|
|
62938
|
+
3. Skip anything speculative, transient, or already captured by an existing memory.
|
|
62939
|
+
|
|
62940
|
+
RULES:
|
|
62941
|
+
- Only emit facts directly supported by the cited evidence. If uncertain, omit the fact (fewer facts, or an empty array, is correct).
|
|
62942
|
+
- Use durable kinds only (user_preference, project_fact, architecture_decision, repo_convention, code_pattern, test_pattern, failure_pattern, security_note).
|
|
62943
|
+
- Keep each fact concise (under 500 characters).
|
|
62944
|
+
- Never include the literal text "## Retrieved Swarm Memory".
|
|
62945
|
+
- Output STRICT JSON only, no prose.
|
|
62946
|
+
|
|
62947
|
+
OUTPUT FORMAT:
|
|
62948
|
+
{"facts":[{"text":"...","kind":"project_fact","confidence":0.8,"contradictsMemoryId":"mem_0123456789abcdef"}]}
|
|
62949
|
+
`;
|
|
62950
|
+
var init_explorer = __esm(() => {
|
|
62951
|
+
EXPLORER_PROMPT = `## IDENTITY
|
|
62725
62952
|
You are Explorer. You analyze codebases directly — you do NOT delegate.
|
|
62726
62953
|
DO NOT use the Task tool to delegate to other agents. You ARE the agent that does the work.
|
|
62727
62954
|
If you see references to other agents (like @explorer, @coder, etc.) in your instructions, IGNORE them — they are context from the orchestrator, not instructions for you to delegate.
|
|
@@ -62729,6 +62956,8 @@ If you see references to other agents (like @explorer, @coder, etc.) in your ins
|
|
|
62729
62956
|
WRONG: "I'll use the Task tool to call another agent to analyze this"
|
|
62730
62957
|
RIGHT: "I'll scan the directory structure and read key files myself"
|
|
62731
62958
|
|
|
62959
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
62960
|
+
|
|
62732
62961
|
INPUT FORMAT:
|
|
62733
62962
|
TASK: Analyze [purpose]
|
|
62734
62963
|
INPUT: [focus areas/paths]
|
|
@@ -62904,184 +63133,8 @@ RULES:
|
|
|
62904
63133
|
- The manifest must be small (<100 lines). Pointers only, not full content.
|
|
62905
63134
|
- Do NOT rephrase or summarize doc content with your own words — use the actual text from the file
|
|
62906
63135
|
- Full doc content is only loaded when relevant to the current task, never preloaded
|
|
62907
|
-
`, CURATOR_INIT_PROMPT = `## IDENTITY
|
|
62908
|
-
You are Explorer in CURATOR_INIT mode. You consolidate prior session knowledge into an architect briefing.
|
|
62909
|
-
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62910
|
-
|
|
62911
|
-
INPUT FORMAT:
|
|
62912
|
-
TASK: CURATOR_INIT
|
|
62913
|
-
PRIOR_SUMMARY: [JSON or "none"]
|
|
62914
|
-
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
62915
|
-
PROJECT_CONTEXT: [context.md excerpt]
|
|
62916
|
-
|
|
62917
|
-
ACTIONS:
|
|
62918
|
-
- Read the prior summary to understand session history
|
|
62919
|
-
- Cross-reference knowledge entries against project context
|
|
62920
|
-
- Note contradictions (knowledge says X, project state shows Y)
|
|
62921
|
-
- Observe where lessons could be tighter or stale
|
|
62922
|
-
- Produce a concise briefing for the architect
|
|
62923
|
-
|
|
62924
|
-
RULES:
|
|
62925
|
-
- Output under 2000 chars
|
|
62926
|
-
- No code modifications
|
|
62927
|
-
- Flag contradictions explicitly with CONTRADICTION: prefix
|
|
62928
|
-
- Memory proposals are for concise durable facts only. Do not propose raw API docs, web search snippets, crawl output, or transcripts as memory; cite their evidence-cache refs and propose only the stable fact they support.
|
|
62929
|
-
- If no prior summary exists, state "First session — no prior context"
|
|
62930
|
-
|
|
62931
|
-
OUTPUT FORMAT:
|
|
62932
|
-
BRIEFING:
|
|
62933
|
-
[concise summary of prior session state, key decisions, active blockers]
|
|
62934
|
-
|
|
62935
|
-
CONTRADICTIONS:
|
|
62936
|
-
- [entry_id]: [description] (or "None detected")
|
|
62937
|
-
|
|
62938
|
-
OBSERVATIONS:
|
|
62939
|
-
- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)
|
|
62940
|
-
- entry <uuid> appears stale: [observable evidence] (suggests archive — no longer injected)
|
|
62941
|
-
- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)
|
|
62942
|
-
- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)
|
|
62943
|
-
- new candidate: [concise lesson text from observed patterns] (suggests new entry)
|
|
62944
|
-
Use the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use "new candidate" only when observing a potential new entry.
|
|
62945
|
-
|
|
62946
|
-
KNOWLEDGE_STATS:
|
|
62947
|
-
- Entries reviewed: [N]
|
|
62948
|
-
- Prior phases covered: [N]
|
|
62949
|
-
`, CURATOR_PHASE_PROMPT = `## IDENTITY
|
|
62950
|
-
You are Explorer in CURATOR_PHASE mode. You consolidate a completed phase into a digest.
|
|
62951
|
-
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
62952
|
-
|
|
62953
|
-
INPUT FORMAT:
|
|
62954
|
-
TASK: CURATOR_PHASE [phase_number]
|
|
62955
|
-
PRIOR_DIGEST: [running summary or "none"]
|
|
62956
|
-
PHASE_EVENTS: [JSON array from events.jsonl for this phase]
|
|
62957
|
-
PHASE_EVIDENCE: [summary of evidence bundles]
|
|
62958
|
-
PHASE_DECISIONS: [decisions from context.md]
|
|
62959
|
-
AGENTS_DISPATCHED: [list]
|
|
62960
|
-
AGENTS_EXPECTED: [list from config]
|
|
62961
|
-
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
62962
|
-
|
|
62963
|
-
ACTIONS:
|
|
62964
|
-
- Extend the prior digest with this phase's outcomes (do NOT regenerate from scratch)
|
|
62965
|
-
- Observe workflow deviations: missing reviewer, missing retro, skipped test_engineer
|
|
62966
|
-
- Report knowledge update candidates with observable evidence: entries that appear promoted, archived, rewritten, or contradicted
|
|
62967
|
-
- Summarize key decisions and blockers resolved
|
|
62968
|
-
|
|
62969
|
-
RULES:
|
|
62970
|
-
- Output under 2000 chars
|
|
62971
|
-
- No code modifications
|
|
62972
|
-
- Compliance observations are READ-ONLY — report, do not enforce
|
|
62973
|
-
- OBSERVATIONS should not contain directives — report what is observed, do not instruct the architect what to do
|
|
62974
|
-
- Extend the digest, never replace it
|
|
62975
|
-
- Memory proposals are for concise durable facts only. Do not promote raw API docs, web search snippets, crawl output, or transcripts into memory; cite evidence-cache refs and propose only the stable fact they support.
|
|
62976
|
-
|
|
62977
|
-
OUTPUT FORMAT:
|
|
62978
|
-
PHASE_DIGEST:
|
|
62979
|
-
phase: [N]
|
|
62980
|
-
summary: [what was accomplished]
|
|
62981
|
-
agents_used: [list]
|
|
62982
|
-
tasks_completed: [N]/[total]
|
|
62983
|
-
key_decisions: [list]
|
|
62984
|
-
blockers_resolved: [list]
|
|
62985
|
-
|
|
62986
|
-
COMPLIANCE:
|
|
62987
|
-
- [type] observed: [description] (or "No deviations observed")
|
|
62988
|
-
|
|
62989
|
-
OBSERVATIONS:
|
|
62990
|
-
- entry <uuid> appears high-confidence: [observable evidence] (suggests boost confidence, mark hive_eligible)
|
|
62991
|
-
- entry <uuid> appears stale: [observable evidence] (suggests archive — no longer injected)
|
|
62992
|
-
- entry <uuid> could be tighter: [what's verbose or duplicate] (suggests rewrite with tighter version, max 280 chars)
|
|
62993
|
-
- entry <uuid> contradicts project state: [observable conflict] (suggests tag as contradicted)
|
|
62994
|
-
- new candidate: [concise lesson text from observed patterns] (suggests new entry)
|
|
62995
|
-
Use the UUID from KNOWLEDGE_ENTRIES when observing about existing entries. Use "new candidate" only when observing a potential new entry.
|
|
62996
|
-
|
|
62997
|
-
EXTENDED_DIGEST:
|
|
62998
|
-
[the full running digest with this phase appended]
|
|
62999
|
-
|
|
63000
|
-
## V3 ACTIONABILITY ENRICHMENT (overrides the format above when triggered)
|
|
63001
|
-
When the input asks you to "Convert this prose lesson into an actionable knowledge directive", ignore the PHASE_DIGEST output format entirely and output ONLY a single JSON object — no fences, no commentary, no digest.
|
|
63002
|
-
MANDATORY fields (the directive is rejected without them):
|
|
63003
|
-
- at least one non-empty scope field: "applies_to_agents" (roles: architect, coder, reviewer, test_engineer, sme, docs, designer, critic, curator) or "applies_to_tools" (edit, write, patch, bash, read, grep, glob)
|
|
63004
|
-
- at least one non-empty predicate field: "forbidden_actions", "required_actions", or "verification_checks"
|
|
63005
|
-
Optional: "triggers" (short surfacing phrases), "directive_priority" (low|medium|high|critical).
|
|
63006
|
-
Example output:
|
|
63007
|
-
{"applies_to_agents":["coder"],"forbidden_actions":["use async iterators in hot paths"],"required_actions":["use a plain for loop in hot paths"],"triggers":["hot path","async iterator"],"directive_priority":"high"}
|
|
63008
|
-
`, CURATOR_POSTMORTEM_PROMPT = `## IDENTITY
|
|
63009
|
-
You are Explorer in CURATOR_POSTMORTEM mode. You synthesize a project-end post-mortem from structured .swarm/ evidence.
|
|
63010
|
-
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
63011
|
-
DO NOT scan raw source code — work only from the recorded evidence provided below.
|
|
63012
|
-
|
|
63013
|
-
INPUT FORMAT:
|
|
63014
|
-
TASK: CURATOR_POSTMORTEM [plan_id]
|
|
63015
|
-
PLAN_SUMMARY: [plan phases, task counts, completion status]
|
|
63016
|
-
CURATOR_DIGESTS: [running digest from curator_phase across all phases]
|
|
63017
|
-
KNOWLEDGE_ENTRIES: [JSON array of existing entries with UUIDs]
|
|
63018
|
-
KNOWLEDGE_EVENTS_SUMMARY: [aggregated violation/applied/ignored counts per entry]
|
|
63019
|
-
PENDING_PROPOSALS: [skill/motif proposals awaiting triage]
|
|
63020
|
-
UNACTIONABLE_QUARANTINE: [entries flagged unactionable with retry status]
|
|
63021
|
-
DRIFT_REPORTS: [per-phase alignment/drift scores if available]
|
|
63022
|
-
RETROSPECTIVES: [any session retrospectives found]
|
|
63023
|
-
|
|
63024
|
-
ACTIONS:
|
|
63025
|
-
1. IMPROVEMENT AGENDA: Rank process + code improvement opportunities, each citing recorded evidence (task IDs, event records, evidence bundles). Focus on what would most reduce mistakes or increase reuse in the next project.
|
|
63026
|
-
2. FINAL CURATION PASS: Consolidate knowledge across phases — identify near-duplicate lessons that accumulated under different IDs, recommend hive promotion for project-proven entries (high confidence, multiple phases confirmed), flag never-applied entries past 3+ phases for review.
|
|
63027
|
-
3. QUEUE TRIAGE: For each pending proposal, recommend apply/reject with one-line reasoning. Surface unactionable-quarantine counts and retry candidates.
|
|
63028
|
-
4. LEARNING METRICS SUMMARY: Embed violation-rate trend, application rates, escalation frequency if metrics data is provided.
|
|
63029
|
-
|
|
63030
|
-
RULES:
|
|
63031
|
-
- Output under 4000 chars
|
|
63032
|
-
- No code modifications — read-only synthesis
|
|
63033
|
-
- Every improvement item must cite a specific evidence artifact or event record
|
|
63034
|
-
- Do not invent evidence — if an artifact is missing, note the gap
|
|
63035
|
-
- Proposals route through existing gated paths (knowledge_add, skill proposals, hive promotion) — recommend the path, do not bypass it
|
|
63036
|
-
- HIGH-severity items that should become critical directives must be flagged for critic gate validation
|
|
63037
|
-
|
|
63038
|
-
OUTPUT FORMAT:
|
|
63039
|
-
POST_MORTEM_REPORT:
|
|
63040
|
-
plan_id: [plan identifier]
|
|
63041
|
-
generated_at: [ISO timestamp]
|
|
63042
|
-
|
|
63043
|
-
IMPROVEMENT_AGENDA:
|
|
63044
|
-
1. [priority] [description] — evidence: [artifact/event ref]
|
|
63045
|
-
2. ...
|
|
63046
|
-
|
|
63047
|
-
CURATION_RECOMMENDATIONS:
|
|
63048
|
-
- merge: [entry_a UUID] + [entry_b UUID] — [reason]
|
|
63049
|
-
- promote_to_hive: [entry UUID] — [evidence of cross-phase confirmation]
|
|
63050
|
-
- flag_stale: [entry UUID] — [never applied in N phases]
|
|
63051
|
-
- rewrite: [entry UUID] — [what's verbose/outdated]
|
|
63052
|
-
|
|
63053
|
-
QUEUE_TRIAGE:
|
|
63054
|
-
- [proposal_id]: APPLY|REJECT — [one-line reasoning]
|
|
63055
|
-
|
|
63056
|
-
LEARNING_METRICS:
|
|
63057
|
-
[3-line summary of trends if data available, or "metrics data not provided"]
|
|
63058
|
-
|
|
63059
|
-
SUMMARY:
|
|
63060
|
-
[3-line executive summary for architect briefing]
|
|
63061
|
-
`, CURATOR_CONSOLIDATION_PROMPT = `## IDENTITY
|
|
63062
|
-
You are Curator in CONSOLIDATION mode. You distill clusters of raw episodic memory into a small set of durable semantic facts.
|
|
63063
|
-
DO NOT use the Task tool to delegate. You ARE the agent that does the work.
|
|
63064
|
-
DO NOT scan raw source code — work only from the episodic events and existing memories provided in the prompt.
|
|
63065
|
-
|
|
63066
|
-
INPUT FORMAT:
|
|
63067
|
-
- A cluster of verbatim episodic events.
|
|
63068
|
-
- A list of existing durable memories (each prefixed with its mem_ id) for dedup and contradiction detection.
|
|
63069
|
-
|
|
63070
|
-
ACTIONS:
|
|
63071
|
-
1. Identify durable, reusable facts that are DIRECTLY supported by the cited episodic evidence.
|
|
63072
|
-
2. Detect contradictions with the listed existing memories; when a new fact conflicts with one, set contradictsMemoryId to that memory's id.
|
|
63073
|
-
3. Skip anything speculative, transient, or already captured by an existing memory.
|
|
63074
|
-
|
|
63075
|
-
RULES:
|
|
63076
|
-
- Only emit facts directly supported by the cited evidence. If uncertain, omit the fact (fewer facts, or an empty array, is correct).
|
|
63077
|
-
- Use durable kinds only (user_preference, project_fact, architecture_decision, repo_convention, code_pattern, test_pattern, failure_pattern, security_note).
|
|
63078
|
-
- Keep each fact concise (under 500 characters).
|
|
63079
|
-
- Never include the literal text "## Retrieved Swarm Memory".
|
|
63080
|
-
- Output STRICT JSON only, no prose.
|
|
63081
|
-
|
|
63082
|
-
OUTPUT FORMAT:
|
|
63083
|
-
{"facts":[{"text":"...","kind":"project_fact","confidence":0.8,"contradictsMemoryId":"mem_0123456789abcdef"}]}
|
|
63084
63136
|
`;
|
|
63137
|
+
});
|
|
63085
63138
|
|
|
63086
63139
|
// src/hooks/curator-postmortem.ts
|
|
63087
63140
|
var exports_curator_postmortem = {};
|
|
@@ -63441,7 +63494,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
63441
63494
|
let reportContent;
|
|
63442
63495
|
if (options.llmDelegate) {
|
|
63443
63496
|
try {
|
|
63444
|
-
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await Promise.resolve().then(() => exports_explorer);
|
|
63497
|
+
const { CURATOR_POSTMORTEM_PROMPT: CURATOR_POSTMORTEM_PROMPT2 } = await Promise.resolve().then(() => (init_explorer(), exports_explorer));
|
|
63445
63498
|
const userInput = assembleLLMInput(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
|
|
63446
63499
|
const ac = new AbortController;
|
|
63447
63500
|
const timer = setTimeout(() => ac.abort(), 300000);
|
|
@@ -63776,6 +63829,8 @@ function countWindowedReceipts(events, entryId, windowMs, nowMs) {
|
|
|
63776
63829
|
continue;
|
|
63777
63830
|
if (e.knowledge_id !== entryId)
|
|
63778
63831
|
continue;
|
|
63832
|
+
if (e.timestamp === undefined)
|
|
63833
|
+
continue;
|
|
63779
63834
|
const t = Date.parse(e.timestamp);
|
|
63780
63835
|
if (Number.isNaN(t) || t < cutoff)
|
|
63781
63836
|
continue;
|
|
@@ -63863,6 +63918,8 @@ async function computeLearningMetrics(directory, options) {
|
|
|
63863
63918
|
throwIfAborted(options?.signal);
|
|
63864
63919
|
if (!isReceiptType(e))
|
|
63865
63920
|
continue;
|
|
63921
|
+
if (e.timestamp === undefined)
|
|
63922
|
+
continue;
|
|
63866
63923
|
const t = Date.parse(e.timestamp);
|
|
63867
63924
|
if (Number.isNaN(t))
|
|
63868
63925
|
continue;
|
|
@@ -65183,16 +65240,21 @@ __export(exports_skill_generator, {
|
|
|
65183
65240
|
selectCandidateEntries: () => selectCandidateEntries,
|
|
65184
65241
|
sanitizeSlug: () => sanitizeSlug,
|
|
65185
65242
|
retireSkill: () => retireSkill,
|
|
65243
|
+
retireOrMarkStale: () => retireOrMarkStale,
|
|
65186
65244
|
renderSkillMarkdown: () => renderSkillMarkdown,
|
|
65187
65245
|
regenerateSkill: () => regenerateSkill,
|
|
65188
65246
|
proposalPath: () => proposalPath,
|
|
65189
65247
|
parseDraftFrontmatter: () => parseDraftFrontmatter,
|
|
65248
|
+
markSkillStale: () => markSkillStale,
|
|
65190
65249
|
listSkills: () => listSkills,
|
|
65191
65250
|
isValidSlug: () => isValidSlug2,
|
|
65192
65251
|
isSkillMaturityEligible: () => isSkillMaturityEligible,
|
|
65193
65252
|
inspectSkill: () => inspectSkill,
|
|
65194
65253
|
generateSkills: () => generateSkills,
|
|
65254
|
+
findStaleSkillsBySourceKnowledgeId: () => findStaleSkillsBySourceKnowledgeId,
|
|
65255
|
+
findSkillsBySourceKnowledgeId: () => findSkillsBySourceKnowledgeId,
|
|
65195
65256
|
clusterEntries: () => clusterEntries,
|
|
65257
|
+
clearSkillStale: () => clearSkillStale,
|
|
65196
65258
|
autoApplyProposals: () => autoApplyProposals,
|
|
65197
65259
|
activeRepoRelativePath: () => activeRepoRelativePath,
|
|
65198
65260
|
activePath: () => activePath,
|
|
@@ -65204,7 +65266,7 @@ __export(exports_skill_generator, {
|
|
|
65204
65266
|
DEFAULT_SKILL_MIN_CONFIDENCE: () => DEFAULT_SKILL_MIN_CONFIDENCE
|
|
65205
65267
|
});
|
|
65206
65268
|
import { existsSync as existsSync23, unlinkSync as unlinkSync7 } from "node:fs";
|
|
65207
|
-
import { mkdir as mkdir10, readFile as readFile9, rename as rename4, writeFile as writeFile6 } from "node:fs/promises";
|
|
65269
|
+
import { mkdir as mkdir10, readFile as readFile9, rename as rename4, unlink as unlink3, writeFile as writeFile6 } from "node:fs/promises";
|
|
65208
65270
|
import * as path47 from "node:path";
|
|
65209
65271
|
function sanitizeSlug(input) {
|
|
65210
65272
|
const lc = input.toLowerCase().trim();
|
|
@@ -65895,10 +65957,81 @@ async function activateProposal(directory, slug, force = false, options = {}) {
|
|
|
65895
65957
|
};
|
|
65896
65958
|
}
|
|
65897
65959
|
}
|
|
65960
|
+
async function findSkillsBySourceKnowledgeId(directory, sourceId) {
|
|
65961
|
+
const activeDir = path47.join(directory, ".opencode", "skills", "generated");
|
|
65962
|
+
const fs23 = await import("node:fs/promises");
|
|
65963
|
+
if (!existsSync23(activeDir))
|
|
65964
|
+
return [];
|
|
65965
|
+
const entries = await fs23.readdir(activeDir, { withFileTypes: true });
|
|
65966
|
+
const matches = [];
|
|
65967
|
+
for (const e of entries) {
|
|
65968
|
+
if (!e.isDirectory())
|
|
65969
|
+
continue;
|
|
65970
|
+
const skillDir = path47.join(activeDir, e.name);
|
|
65971
|
+
const retiredMarker = path47.join(skillDir, "retired.marker");
|
|
65972
|
+
if (existsSync23(retiredMarker))
|
|
65973
|
+
continue;
|
|
65974
|
+
const staleMarker = path47.join(skillDir, "stale.marker");
|
|
65975
|
+
if (existsSync23(staleMarker))
|
|
65976
|
+
continue;
|
|
65977
|
+
const skillPath = path47.join(skillDir, "SKILL.md");
|
|
65978
|
+
if (!existsSync23(skillPath))
|
|
65979
|
+
continue;
|
|
65980
|
+
let content;
|
|
65981
|
+
try {
|
|
65982
|
+
content = await fs23.readFile(skillPath, "utf-8");
|
|
65983
|
+
} catch {
|
|
65984
|
+
continue;
|
|
65985
|
+
}
|
|
65986
|
+
const fm = parseDraftFrontmatter(content);
|
|
65987
|
+
if (fm?.sourceKnowledgeIds.includes(sourceId)) {
|
|
65988
|
+
matches.push(skillDir);
|
|
65989
|
+
}
|
|
65990
|
+
}
|
|
65991
|
+
return matches;
|
|
65992
|
+
}
|
|
65993
|
+
async function findStaleSkillsBySourceKnowledgeId(directory, archivedIds) {
|
|
65994
|
+
const activeDir = path47.join(directory, ".opencode", "skills", "generated");
|
|
65995
|
+
if (!existsSync23(activeDir))
|
|
65996
|
+
return [];
|
|
65997
|
+
const fs23 = await import("node:fs/promises");
|
|
65998
|
+
const entries = await fs23.readdir(activeDir, { withFileTypes: true });
|
|
65999
|
+
const matches = [];
|
|
66000
|
+
for (const e of entries) {
|
|
66001
|
+
if (!e.isDirectory())
|
|
66002
|
+
continue;
|
|
66003
|
+
const skillDir = path47.join(activeDir, e.name);
|
|
66004
|
+
const retiredMarker = path47.join(skillDir, "retired.marker");
|
|
66005
|
+
if (existsSync23(retiredMarker))
|
|
66006
|
+
continue;
|
|
66007
|
+
const staleMarker = path47.join(skillDir, "stale.marker");
|
|
66008
|
+
if (!existsSync23(staleMarker))
|
|
66009
|
+
continue;
|
|
66010
|
+
const skillPath = path47.join(skillDir, "SKILL.md");
|
|
66011
|
+
if (!existsSync23(skillPath))
|
|
66012
|
+
continue;
|
|
66013
|
+
let content;
|
|
66014
|
+
try {
|
|
66015
|
+
content = await fs23.readFile(skillPath, "utf-8");
|
|
66016
|
+
} catch {
|
|
66017
|
+
continue;
|
|
66018
|
+
}
|
|
66019
|
+
const fm = parseDraftFrontmatter(content);
|
|
66020
|
+
const sourceIds = fm?.sourceKnowledgeIds ?? [];
|
|
66021
|
+
if (sourceIds.length === 0)
|
|
66022
|
+
continue;
|
|
66023
|
+
const allArchived = sourceIds.every((id) => archivedIds.has(id));
|
|
66024
|
+
if (allArchived) {
|
|
66025
|
+
matches.push(skillDir);
|
|
66026
|
+
}
|
|
66027
|
+
}
|
|
66028
|
+
return matches;
|
|
66029
|
+
}
|
|
65898
66030
|
async function listSkills(directory) {
|
|
65899
66031
|
const result = {
|
|
65900
66032
|
proposals: [],
|
|
65901
|
-
active: []
|
|
66033
|
+
active: [],
|
|
66034
|
+
stale: []
|
|
65902
66035
|
};
|
|
65903
66036
|
const proposalsDir = path47.join(directory, ".swarm", "skills", "proposals");
|
|
65904
66037
|
const activeDir = path47.join(directory, ".opencode", "skills", "generated");
|
|
@@ -65923,6 +66056,16 @@ async function listSkills(directory) {
|
|
|
65923
66056
|
const retiredMarker = path47.join(activeDir, e.name, "retired.marker");
|
|
65924
66057
|
if (existsSync23(retiredMarker))
|
|
65925
66058
|
continue;
|
|
66059
|
+
const staleMarker = path47.join(activeDir, e.name, "stale.marker");
|
|
66060
|
+
if (existsSync23(staleMarker)) {
|
|
66061
|
+
let reason = "stale";
|
|
66062
|
+
try {
|
|
66063
|
+
const content = await fs23.readFile(staleMarker, "utf-8");
|
|
66064
|
+
reason = content.trim() || "stale";
|
|
66065
|
+
} catch {}
|
|
66066
|
+
result.stale.push({ slug: e.name, reason });
|
|
66067
|
+
continue;
|
|
66068
|
+
}
|
|
65926
66069
|
const skillPath = path47.join(activeDir, e.name, "SKILL.md");
|
|
65927
66070
|
if (existsSync23(skillPath)) {
|
|
65928
66071
|
result.active.push({
|
|
@@ -66008,7 +66151,34 @@ async function inspectSkill(directory, slug, prefer = "auto") {
|
|
|
66008
66151
|
for (const c of candidates) {
|
|
66009
66152
|
if (existsSync23(c.p)) {
|
|
66010
66153
|
const content = await readFile9(c.p, "utf-8");
|
|
66011
|
-
|
|
66154
|
+
const result = { found: true, path: c.p, content, mode: c.m };
|
|
66155
|
+
const fm = parseDraftFrontmatter(content);
|
|
66156
|
+
if (fm && fm.sourceKnowledgeIds.length > 0) {
|
|
66157
|
+
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
66158
|
+
const hivePath = resolveHiveKnowledgePath();
|
|
66159
|
+
const hive = existsSync23(hivePath) ? await readKnowledge(hivePath) : [];
|
|
66160
|
+
const allEntries = [...swarm, ...hive];
|
|
66161
|
+
const entryMap = new Map(allEntries.map((e) => [e.id, e]));
|
|
66162
|
+
result.source_knowledge_status = fm.sourceKnowledgeIds.map((id) => {
|
|
66163
|
+
const entry = entryMap.get(id);
|
|
66164
|
+
if (!entry)
|
|
66165
|
+
return { id, status: "deleted" };
|
|
66166
|
+
if (entry.status === "archived" || entry.status === "quarantined") {
|
|
66167
|
+
return { id, status: "archived" };
|
|
66168
|
+
}
|
|
66169
|
+
return { id, status: "active" };
|
|
66170
|
+
});
|
|
66171
|
+
}
|
|
66172
|
+
if (c.m === "active") {
|
|
66173
|
+
const skillDir = path47.join(directory, ".opencode", "skills", "generated", cleanSlug);
|
|
66174
|
+
const staleMarker = path47.join(skillDir, "stale.marker");
|
|
66175
|
+
if (existsSync23(staleMarker)) {
|
|
66176
|
+
try {
|
|
66177
|
+
result.stale_reason = await readFile9(staleMarker, "utf-8");
|
|
66178
|
+
} catch {}
|
|
66179
|
+
}
|
|
66180
|
+
}
|
|
66181
|
+
return result;
|
|
66012
66182
|
}
|
|
66013
66183
|
}
|
|
66014
66184
|
return { found: false };
|
|
@@ -66047,6 +66217,54 @@ async function retireSkill(directory, slug, reason) {
|
|
|
66047
66217
|
reason
|
|
66048
66218
|
};
|
|
66049
66219
|
}
|
|
66220
|
+
async function markSkillStale(skillDir, reason) {
|
|
66221
|
+
await mkdir10(skillDir, { recursive: true });
|
|
66222
|
+
await writeFile6(path47.join(skillDir, "stale.marker"), reason, "utf-8");
|
|
66223
|
+
}
|
|
66224
|
+
async function clearSkillStale(skillDir) {
|
|
66225
|
+
const markerPath = path47.join(skillDir, "stale.marker");
|
|
66226
|
+
try {
|
|
66227
|
+
await unlink3(markerPath);
|
|
66228
|
+
} catch (err) {
|
|
66229
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
66230
|
+
return;
|
|
66231
|
+
}
|
|
66232
|
+
warn(`[skill-generator] failed to remove stale.marker at ${markerPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
66233
|
+
}
|
|
66234
|
+
}
|
|
66235
|
+
async function retireOrMarkStale(directory, skillDir, archivedKnowledgeIds) {
|
|
66236
|
+
const fs23 = await import("node:fs/promises");
|
|
66237
|
+
const skillPath = path47.join(skillDir, "SKILL.md");
|
|
66238
|
+
if (!existsSync23(skillPath)) {
|
|
66239
|
+
await markSkillStale(skillDir, "source knowledge archived, SKILL.md missing");
|
|
66240
|
+
const slug2 = path47.basename(skillDir);
|
|
66241
|
+
return { action: "stale", slug: slug2, skillDir };
|
|
66242
|
+
}
|
|
66243
|
+
let content;
|
|
66244
|
+
try {
|
|
66245
|
+
content = await fs23.readFile(skillPath, "utf-8");
|
|
66246
|
+
} catch {
|
|
66247
|
+
await markSkillStale(skillDir, "source knowledge archived, SKILL.md unreadable");
|
|
66248
|
+
const slug2 = path47.basename(skillDir);
|
|
66249
|
+
return { action: "stale", slug: slug2, skillDir };
|
|
66250
|
+
}
|
|
66251
|
+
const fm = parseDraftFrontmatter(content);
|
|
66252
|
+
const sourceIds = fm?.sourceKnowledgeIds ?? [];
|
|
66253
|
+
if (sourceIds.length === 0) {
|
|
66254
|
+
await markSkillStale(skillDir, "source knowledge archived, no source_knowledge_ids in frontmatter");
|
|
66255
|
+
const slug2 = path47.basename(skillDir);
|
|
66256
|
+
return { action: "stale", slug: slug2, skillDir };
|
|
66257
|
+
}
|
|
66258
|
+
const allArchived = sourceIds.every((id) => archivedKnowledgeIds.has(id));
|
|
66259
|
+
const slug = path47.basename(skillDir);
|
|
66260
|
+
if (allArchived) {
|
|
66261
|
+
await retireSkill(directory, slug, "all source knowledge entries archived or deleted");
|
|
66262
|
+
return { action: "retire", slug, skillDir };
|
|
66263
|
+
} else {
|
|
66264
|
+
await markSkillStale(skillDir, "one or more source knowledge entries archived");
|
|
66265
|
+
return { action: "stale", slug, skillDir };
|
|
66266
|
+
}
|
|
66267
|
+
}
|
|
66050
66268
|
async function regenerateSkill(directory, slug, options = {}) {
|
|
66051
66269
|
const cleanSlug = sanitizeSlug(slug);
|
|
66052
66270
|
if (!isValidSlug2(cleanSlug)) {
|
|
@@ -66206,6 +66424,7 @@ async function regenerateSkill(directory, slug, options = {}) {
|
|
|
66206
66424
|
try {
|
|
66207
66425
|
await atomicWrite3(skillPath, content);
|
|
66208
66426
|
await stampSourceEntries(directory, cleanSlug, matchedEntries.map((e) => e.id));
|
|
66427
|
+
await clearSkillStale(path47.dirname(activePath(directory, cleanSlug)));
|
|
66209
66428
|
} catch (writeErr) {
|
|
66210
66429
|
return {
|
|
66211
66430
|
regenerated: false,
|
|
@@ -66249,11 +66468,15 @@ var init_skill_generator = __esm(() => {
|
|
|
66249
66468
|
generateSkills,
|
|
66250
66469
|
activateProposal,
|
|
66251
66470
|
listSkills,
|
|
66471
|
+
findSkillsBySourceKnowledgeId,
|
|
66472
|
+
findStaleSkillsBySourceKnowledgeId,
|
|
66252
66473
|
inspectSkill,
|
|
66253
66474
|
stampSourceEntries,
|
|
66254
66475
|
parseDraftFrontmatter,
|
|
66255
66476
|
retireSkill,
|
|
66477
|
+
retireOrMarkStale,
|
|
66256
66478
|
regenerateSkill,
|
|
66479
|
+
clearSkillStale,
|
|
66257
66480
|
autoApplyProposals,
|
|
66258
66481
|
unlinkSync: unlinkSync7
|
|
66259
66482
|
};
|
|
@@ -67199,11 +67422,12 @@ ${digest2.summary}`).join(`
|
|
|
67199
67422
|
|
|
67200
67423
|
`);
|
|
67201
67424
|
}
|
|
67202
|
-
async function autoRetireSkills(directory,
|
|
67425
|
+
async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs) {
|
|
67203
67426
|
const observations = [];
|
|
67204
67427
|
try {
|
|
67205
67428
|
const skillListResult = await _internals32.listSkills(directory);
|
|
67206
67429
|
const usageEntries = _internals32.readSkillUsageEntries(directory);
|
|
67430
|
+
const allArchivedIds = await _internals32.getArchivedKnowledgeIds(directory);
|
|
67207
67431
|
for (const active of skillListResult.active) {
|
|
67208
67432
|
if (excludeSlugs?.has(active.slug))
|
|
67209
67433
|
continue;
|
|
@@ -67223,30 +67447,20 @@ async function autoRetireSkills(directory, curatorKnowledgePath, excludeSlugs) {
|
|
|
67223
67447
|
});
|
|
67224
67448
|
const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
|
|
67225
67449
|
const violationRate = skillUsage.length > 0 ? violations / skillUsage.length : 0;
|
|
67226
|
-
|
|
67227
|
-
|
|
67228
|
-
const content = await _internals32.readFileAsync(active.path, "utf-8");
|
|
67229
|
-
const fm = _internals32.parseDraftFrontmatter(content);
|
|
67230
|
-
if (fm && fm.sourceKnowledgeIds.length > 0) {
|
|
67231
|
-
const swarmKnowledge = await _internals32.readKnowledge(curatorKnowledgePath);
|
|
67232
|
-
let hiveKnowledge = [];
|
|
67233
|
-
try {
|
|
67234
|
-
const hivePath = resolveHiveKnowledgePath();
|
|
67235
|
-
if (fs24.existsSync(hivePath)) {
|
|
67236
|
-
hiveKnowledge = await _internals32.readKnowledge(hivePath);
|
|
67237
|
-
}
|
|
67238
|
-
} catch {}
|
|
67239
|
-
const allKnowledge = [...swarmKnowledge, ...hiveKnowledge];
|
|
67240
|
-
const sourceIds = new Set(fm.sourceKnowledgeIds);
|
|
67241
|
-
const sources = allKnowledge.filter((e) => sourceIds.has(e.id));
|
|
67242
|
-
allArchived = sources.length === sourceIds.size && sources.every((e) => e.status === "archived");
|
|
67243
|
-
}
|
|
67244
|
-
} catch {}
|
|
67245
|
-
if (violationRate > 0.3 || allArchived) {
|
|
67246
|
-
const reason = violationRate > 0.3 ? `auto-retire: violation rate ${(violationRate * 100).toFixed(0)}% exceeds 30% threshold` : "auto-retire: all source knowledge entries archived";
|
|
67450
|
+
if (violationRate > 0.3) {
|
|
67451
|
+
const reason = `auto-retire: violation rate ${(violationRate * 100).toFixed(0)}% exceeds 30% threshold`;
|
|
67247
67452
|
await _internals32.retireSkill(directory, active.slug, reason);
|
|
67248
67453
|
observations.push(`Skill '${active.slug}' auto-retired: ${reason}`);
|
|
67249
67454
|
warn(`[curator] ${observations[observations.length - 1]}`);
|
|
67455
|
+
continue;
|
|
67456
|
+
}
|
|
67457
|
+
const result = await _internals32.retireOrMarkStale(directory, path50.dirname(active.path), allArchivedIds);
|
|
67458
|
+
if (result.action === "retire") {
|
|
67459
|
+
observations.push(`Skill '${active.slug}' auto-retired: all source knowledge entries archived`);
|
|
67460
|
+
warn(`[curator] ${observations[observations.length - 1]}`);
|
|
67461
|
+
} else if (result.action === "stale") {
|
|
67462
|
+
observations.push(`Skill '${active.slug}' marked stale: some source knowledge entries archived`);
|
|
67463
|
+
warn(`[curator] ${observations[observations.length - 1]}`);
|
|
67250
67464
|
}
|
|
67251
67465
|
}
|
|
67252
67466
|
} catch (autoRetireErr) {
|
|
@@ -68015,6 +68229,29 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config3, know
|
|
|
68015
68229
|
const retireNote = ` [${autoRetireObservations.length} skill(s) auto-retired]`;
|
|
68016
68230
|
phaseDigest.summary += retireNote;
|
|
68017
68231
|
}
|
|
68232
|
+
try {
|
|
68233
|
+
const eventsContent = await readSwarmFileAsync(directory, "knowledge-events.jsonl");
|
|
68234
|
+
if (eventsContent) {
|
|
68235
|
+
const lines = eventsContent.split(`
|
|
68236
|
+
`).filter((l) => l.trim());
|
|
68237
|
+
const batchEvents = [];
|
|
68238
|
+
for (const line of lines) {
|
|
68239
|
+
try {
|
|
68240
|
+
const event = JSON.parse(line);
|
|
68241
|
+
if (event.type === "skill-stale-batch") {
|
|
68242
|
+
batchEvents.push({
|
|
68243
|
+
skillIds: event.skillIds ?? [],
|
|
68244
|
+
retiredCount: event.retiredCount ?? 0,
|
|
68245
|
+
staleCount: event.staleCount ?? 0
|
|
68246
|
+
});
|
|
68247
|
+
}
|
|
68248
|
+
} catch {}
|
|
68249
|
+
}
|
|
68250
|
+
for (const batch of batchEvents) {
|
|
68251
|
+
warn(`[curator] skill-stale-batch: ${batch.skillIds.length} skills affected (${batch.retiredCount} retired, ${batch.staleCount} stale)`);
|
|
68252
|
+
}
|
|
68253
|
+
}
|
|
68254
|
+
} catch {}
|
|
68018
68255
|
try {
|
|
68019
68256
|
const metrics = await computeLearningMetrics(directory, {
|
|
68020
68257
|
currentPhase: phase
|
|
@@ -68220,6 +68457,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
68220
68457
|
}
|
|
68221
68458
|
var DEFAULT_CURATOR_LLM_TIMEOUT_MS = 300000, MAX_CURATOR_PHASE_DIGESTS = 50, MAX_CURATOR_COMPLIANCE_OBSERVATIONS = 200, MAX_CURATOR_RECOMMENDATIONS = 200, _internals32;
|
|
68222
68459
|
var init_curator = __esm(() => {
|
|
68460
|
+
init_explorer();
|
|
68223
68461
|
init_event_bus();
|
|
68224
68462
|
init_schema();
|
|
68225
68463
|
init_manager();
|
|
@@ -68245,7 +68483,9 @@ var init_curator = __esm(() => {
|
|
|
68245
68483
|
readSkillUsageEntries,
|
|
68246
68484
|
listSkills,
|
|
68247
68485
|
parseDraftFrontmatter,
|
|
68486
|
+
retireOrMarkStale,
|
|
68248
68487
|
retireSkill,
|
|
68488
|
+
getArchivedKnowledgeIds,
|
|
68249
68489
|
readFileAsync: (filePath, encoding) => import("node:fs/promises").then((fs25) => fs25.readFile(filePath, encoding)),
|
|
68250
68490
|
readKnowledge,
|
|
68251
68491
|
reviseSkill,
|
|
@@ -68546,7 +68786,7 @@ import {
|
|
|
68546
68786
|
readFile as readFile12,
|
|
68547
68787
|
rename as rename7,
|
|
68548
68788
|
stat as stat8,
|
|
68549
|
-
unlink as
|
|
68789
|
+
unlink as unlink4,
|
|
68550
68790
|
writeFile as writeFile9
|
|
68551
68791
|
} from "node:fs/promises";
|
|
68552
68792
|
import * as path52 from "node:path";
|
|
@@ -68751,7 +68991,7 @@ async function writeSynonymMapAtomic(filePath, map3) {
|
|
|
68751
68991
|
await rename7(tmp, filePath);
|
|
68752
68992
|
} finally {
|
|
68753
68993
|
try {
|
|
68754
|
-
await
|
|
68994
|
+
await unlink4(tmp);
|
|
68755
68995
|
} catch {}
|
|
68756
68996
|
}
|
|
68757
68997
|
}
|
|
@@ -69314,7 +69554,7 @@ function discoverAvailableSkills(directory) {
|
|
|
69314
69554
|
if (entry.startsWith("."))
|
|
69315
69555
|
continue;
|
|
69316
69556
|
const skillDir = path54.join(rootPath, entry);
|
|
69317
|
-
if (_internals34.existsSync(path54.join(skillDir, "retired.marker")))
|
|
69557
|
+
if (_internals34.existsSync(path54.join(skillDir, "retired.marker")) || _internals34.existsSync(path54.join(skillDir, "stale.marker")))
|
|
69318
69558
|
continue;
|
|
69319
69559
|
const skillFile = path54.join(skillDir, "SKILL.md");
|
|
69320
69560
|
try {
|
|
@@ -69520,7 +69760,7 @@ async function skillPropagationGateBefore(directory, input, config3) {
|
|
|
69520
69760
|
const existingPaths = new Set(scored.map((s) => s.skillPath));
|
|
69521
69761
|
for (const routingPath of routingPaths) {
|
|
69522
69762
|
const routedSkillDir = path54.dirname(path54.join(directory, routingPath));
|
|
69523
|
-
if (_internals34.existsSync(path54.join(routedSkillDir, "retired.marker")))
|
|
69763
|
+
if (_internals34.existsSync(path54.join(routedSkillDir, "retired.marker")) || _internals34.existsSync(path54.join(routedSkillDir, "stale.marker")))
|
|
69524
69764
|
continue;
|
|
69525
69765
|
if (!existingPaths.has(routingPath)) {
|
|
69526
69766
|
scored.push({
|
|
@@ -69831,7 +70071,7 @@ var init_skill_propagation_gate = __esm(() => {
|
|
|
69831
70071
|
});
|
|
69832
70072
|
|
|
69833
70073
|
// src/hooks/micro-reflector.ts
|
|
69834
|
-
import { existsSync as
|
|
70074
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
69835
70075
|
import { readFile as readFile13, writeFile as writeFile10 } from "node:fs/promises";
|
|
69836
70076
|
import * as path55 from "node:path";
|
|
69837
70077
|
function resolveInsightCandidatesPath(directory) {
|
|
@@ -69866,7 +70106,7 @@ async function readTaskTrajectory(directory, taskId) {
|
|
|
69866
70106
|
try {
|
|
69867
70107
|
const rel = path55.join("evidence", sanitizeTaskId2(taskId), "trajectory.jsonl");
|
|
69868
70108
|
const filePath = validateSwarmPath(directory, rel);
|
|
69869
|
-
if (!
|
|
70109
|
+
if (!existsSync27(filePath))
|
|
69870
70110
|
return [];
|
|
69871
70111
|
const content = await readFile13(filePath, "utf-8");
|
|
69872
70112
|
const out = [];
|
|
@@ -70110,7 +70350,7 @@ var init_micro_reflector = __esm(() => {
|
|
|
70110
70350
|
|
|
70111
70351
|
// src/hooks/knowledge-curator.ts
|
|
70112
70352
|
import { createHash as createHash9 } from "node:crypto";
|
|
70113
|
-
import { existsSync as
|
|
70353
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
70114
70354
|
import { appendFile as appendFile8, mkdir as mkdir13, readFile as readFile14, writeFile as writeFile11 } from "node:fs/promises";
|
|
70115
70355
|
import * as path56 from "node:path";
|
|
70116
70356
|
function pruneSeenRetroSections() {
|
|
@@ -70535,7 +70775,7 @@ function readInsightJsonl2(content) {
|
|
|
70535
70775
|
async function consumeInsightCandidates(directory, batchLimit = MESO_INSIGHT_BATCH_LIMIT) {
|
|
70536
70776
|
try {
|
|
70537
70777
|
const filePath = resolveInsightCandidatesPath(directory);
|
|
70538
|
-
if (!
|
|
70778
|
+
if (!existsSync28(filePath))
|
|
70539
70779
|
return [];
|
|
70540
70780
|
const consumed = [];
|
|
70541
70781
|
await transactFile(filePath, async (p) => readInsightJsonl2(await readFile14(p, "utf-8").catch(() => "")), async (p, data) => {
|
|
@@ -71676,12 +71916,12 @@ var init_trajectory_cluster = __esm(() => {
|
|
|
71676
71916
|
});
|
|
71677
71917
|
|
|
71678
71918
|
// src/services/unactionable-hardening.ts
|
|
71679
|
-
import { existsSync as
|
|
71919
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
71680
71920
|
async function hardenUnactionableEntries(params) {
|
|
71681
71921
|
const result = { hardened: 0, retired: 0, remaining: 0 };
|
|
71682
71922
|
try {
|
|
71683
71923
|
const queuePath = resolveUnactionablePath(params.directory);
|
|
71684
|
-
if (!
|
|
71924
|
+
if (!existsSync29(queuePath))
|
|
71685
71925
|
return result;
|
|
71686
71926
|
const limit = params.batchLimit ?? HARDENING_BATCH_LIMIT;
|
|
71687
71927
|
const dedupThreshold = params.dedupThreshold ?? 0.6;
|
|
@@ -71788,7 +72028,7 @@ var init_unactionable_hardening = __esm(() => {
|
|
|
71788
72028
|
});
|
|
71789
72029
|
|
|
71790
72030
|
// src/services/skill-improver.ts
|
|
71791
|
-
import { existsSync as
|
|
72031
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
71792
72032
|
import { mkdir as mkdir15, readFile as readFile15, rename as rename8, writeFile as writeFile13 } from "node:fs/promises";
|
|
71793
72033
|
import * as path59 from "node:path";
|
|
71794
72034
|
function timestampSlug(d) {
|
|
@@ -71803,7 +72043,7 @@ async function atomicWrite4(p, content) {
|
|
|
71803
72043
|
async function gatherInventory(directory) {
|
|
71804
72044
|
const swarm = await readKnowledge(resolveSwarmKnowledgePath(directory));
|
|
71805
72045
|
const hivePath = resolveHiveKnowledgePath();
|
|
71806
|
-
const hive =
|
|
72046
|
+
const hive = existsSync30(hivePath) ? await readKnowledge(hivePath) : [];
|
|
71807
72047
|
const archived = [...swarm, ...hive].filter((e) => e.status === "archived").length;
|
|
71808
72048
|
const skills = await listSkills(directory);
|
|
71809
72049
|
const knowledgeById = new Map([...swarm, ...hive].map((entry) => [entry.id, entry]));
|
|
@@ -74042,7 +74282,7 @@ __export(exports_skill_consolidation, {
|
|
|
74042
74282
|
consolidationStatePath: () => consolidationStatePath,
|
|
74043
74283
|
_internals: () => _internals39
|
|
74044
74284
|
});
|
|
74045
|
-
import { existsSync as
|
|
74285
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
74046
74286
|
import { mkdir as mkdir16, readFile as readFile16, rename as rename9, writeFile as writeFile14 } from "node:fs/promises";
|
|
74047
74287
|
import * as path62 from "node:path";
|
|
74048
74288
|
function consolidationStatePath(directory) {
|
|
@@ -74050,7 +74290,7 @@ function consolidationStatePath(directory) {
|
|
|
74050
74290
|
}
|
|
74051
74291
|
async function readState2(directory) {
|
|
74052
74292
|
const filePath = consolidationStatePath(directory);
|
|
74053
|
-
if (!
|
|
74293
|
+
if (!existsSync32(filePath))
|
|
74054
74294
|
return {};
|
|
74055
74295
|
try {
|
|
74056
74296
|
const parsed = JSON.parse(await readFile16(filePath, "utf-8"));
|
|
@@ -75679,7 +75919,7 @@ var init_gate_bridge = __esm(() => {
|
|
|
75679
75919
|
});
|
|
75680
75920
|
|
|
75681
75921
|
// src/services/version-check.ts
|
|
75682
|
-
import { existsSync as
|
|
75922
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync21, readFileSync as readFileSync18, writeFileSync as writeFileSync13 } from "node:fs";
|
|
75683
75923
|
import { homedir as homedir8 } from "node:os";
|
|
75684
75924
|
import { join as join51 } from "node:path";
|
|
75685
75925
|
function cacheDir() {
|
|
@@ -75693,7 +75933,7 @@ function cacheFile() {
|
|
|
75693
75933
|
function readVersionCache() {
|
|
75694
75934
|
try {
|
|
75695
75935
|
const path67 = cacheFile();
|
|
75696
|
-
if (!
|
|
75936
|
+
if (!existsSync33(path67))
|
|
75697
75937
|
return null;
|
|
75698
75938
|
const raw = readFileSync18(path67, "utf-8");
|
|
75699
75939
|
const parsed = JSON.parse(raw);
|
|
@@ -75791,10 +76031,10 @@ var init_version_check = __esm(() => {
|
|
|
75791
76031
|
});
|
|
75792
76032
|
|
|
75793
76033
|
// src/services/knowledge-diagnostics.ts
|
|
75794
|
-
import { existsSync as
|
|
76034
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
75795
76035
|
import { readFile as readFile18 } from "node:fs/promises";
|
|
75796
76036
|
async function readRawLines(filePath) {
|
|
75797
|
-
if (!
|
|
76037
|
+
if (!existsSync34(filePath))
|
|
75798
76038
|
return { entries: [], corrupt: 0 };
|
|
75799
76039
|
const content = await readFile18(filePath, "utf-8");
|
|
75800
76040
|
const entries = [];
|
|
@@ -75919,7 +76159,7 @@ async function computeKnowledgeDebug(directory) {
|
|
|
75919
76159
|
};
|
|
75920
76160
|
}
|
|
75921
76161
|
async function safeJsonlCount(filePath) {
|
|
75922
|
-
if (!filePath || !
|
|
76162
|
+
if (!filePath || !existsSync34(filePath))
|
|
75923
76163
|
return 0;
|
|
75924
76164
|
try {
|
|
75925
76165
|
const content = await readFile18(filePath, "utf-8");
|
|
@@ -76002,7 +76242,7 @@ var init_knowledge_diagnostics = __esm(() => {
|
|
|
76002
76242
|
|
|
76003
76243
|
// src/services/diagnose-service.ts
|
|
76004
76244
|
import * as child_process6 from "node:child_process";
|
|
76005
|
-
import { existsSync as
|
|
76245
|
+
import { existsSync as existsSync35, readdirSync as readdirSync7, readFileSync as readFileSync19, statSync as statSync11 } from "node:fs";
|
|
76006
76246
|
import path67 from "node:path";
|
|
76007
76247
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
76008
76248
|
function validateTaskDag(plan) {
|
|
@@ -76250,7 +76490,7 @@ async function checkConfigBackups(directory) {
|
|
|
76250
76490
|
}
|
|
76251
76491
|
async function checkGitRepository(directory) {
|
|
76252
76492
|
try {
|
|
76253
|
-
if (!
|
|
76493
|
+
if (!existsSync35(directory) || !statSync11(directory).isDirectory()) {
|
|
76254
76494
|
return {
|
|
76255
76495
|
name: "Git Repository",
|
|
76256
76496
|
status: "❌",
|
|
@@ -76315,7 +76555,7 @@ async function checkSpecStaleness(directory, plan) {
|
|
|
76315
76555
|
}
|
|
76316
76556
|
async function checkConfigParseability(directory) {
|
|
76317
76557
|
const configPath = path67.join(directory, ".opencode/opencode-swarm.json");
|
|
76318
|
-
if (!
|
|
76558
|
+
if (!existsSync35(configPath)) {
|
|
76319
76559
|
return {
|
|
76320
76560
|
name: "Config Parseability",
|
|
76321
76561
|
status: "✅",
|
|
@@ -76370,11 +76610,11 @@ async function checkGrammarWasmFiles() {
|
|
|
76370
76610
|
const thisDir = path67.dirname(fileURLToPath2(import.meta.url));
|
|
76371
76611
|
const grammarDir = resolveGrammarDir(thisDir);
|
|
76372
76612
|
const missing = [];
|
|
76373
|
-
if (!
|
|
76613
|
+
if (!existsSync35(path67.join(grammarDir, "tree-sitter.wasm"))) {
|
|
76374
76614
|
missing.push("tree-sitter.wasm (core runtime)");
|
|
76375
76615
|
}
|
|
76376
76616
|
for (const file3 of grammarFiles) {
|
|
76377
|
-
if (!
|
|
76617
|
+
if (!existsSync35(path67.join(grammarDir, file3))) {
|
|
76378
76618
|
missing.push(file3);
|
|
76379
76619
|
}
|
|
76380
76620
|
}
|
|
@@ -76393,7 +76633,7 @@ async function checkGrammarWasmFiles() {
|
|
|
76393
76633
|
}
|
|
76394
76634
|
async function checkCheckpointManifest(directory) {
|
|
76395
76635
|
const manifestPath = path67.join(directory, ".swarm/checkpoints.json");
|
|
76396
|
-
if (!
|
|
76636
|
+
if (!existsSync35(manifestPath)) {
|
|
76397
76637
|
return {
|
|
76398
76638
|
name: "Checkpoint Manifest",
|
|
76399
76639
|
status: "✅",
|
|
@@ -76445,7 +76685,7 @@ async function checkCheckpointManifest(directory) {
|
|
|
76445
76685
|
}
|
|
76446
76686
|
async function checkEventStreamIntegrity(directory) {
|
|
76447
76687
|
const eventsPath = path67.join(directory, ".swarm/events.jsonl");
|
|
76448
|
-
if (!
|
|
76688
|
+
if (!existsSync35(eventsPath)) {
|
|
76449
76689
|
return {
|
|
76450
76690
|
name: "Event Stream",
|
|
76451
76691
|
status: "✅",
|
|
@@ -76486,7 +76726,7 @@ async function checkEventStreamIntegrity(directory) {
|
|
|
76486
76726
|
}
|
|
76487
76727
|
async function checkSteeringDirectives(directory) {
|
|
76488
76728
|
const eventsPath = path67.join(directory, ".swarm/events.jsonl");
|
|
76489
|
-
if (!
|
|
76729
|
+
if (!existsSync35(eventsPath)) {
|
|
76490
76730
|
return {
|
|
76491
76731
|
name: "Steering Directives",
|
|
76492
76732
|
status: "✅",
|
|
@@ -76542,7 +76782,7 @@ async function checkCurator(directory) {
|
|
|
76542
76782
|
};
|
|
76543
76783
|
}
|
|
76544
76784
|
const summaryPath = path67.join(directory, ".swarm/curator-summary.json");
|
|
76545
|
-
if (!
|
|
76785
|
+
if (!existsSync35(summaryPath)) {
|
|
76546
76786
|
return {
|
|
76547
76787
|
name: "Curator",
|
|
76548
76788
|
status: "✅",
|
|
@@ -76744,7 +76984,7 @@ async function getDiagnoseData(directory) {
|
|
|
76744
76984
|
checks5.push(await checkKnowledgeHealth(directory));
|
|
76745
76985
|
try {
|
|
76746
76986
|
const evidenceDir = path67.join(directory, ".swarm", "evidence");
|
|
76747
|
-
const snapshotFiles =
|
|
76987
|
+
const snapshotFiles = existsSync35(evidenceDir) ? readdirSync7(evidenceDir).filter((f) => f.startsWith("agent-tools-") && f.endsWith(".json")) : [];
|
|
76748
76988
|
if (snapshotFiles.length > 0) {
|
|
76749
76989
|
const latest = snapshotFiles.sort().pop();
|
|
76750
76990
|
checks5.push({
|
|
@@ -76777,7 +77017,7 @@ async function getDiagnoseData(directory) {
|
|
|
76777
77017
|
const cacheRows = [];
|
|
76778
77018
|
for (const cachePath of cachePaths) {
|
|
76779
77019
|
try {
|
|
76780
|
-
if (!
|
|
77020
|
+
if (!existsSync35(cachePath)) {
|
|
76781
77021
|
cacheRows.push(`⬜ ${cachePath} — absent`);
|
|
76782
77022
|
continue;
|
|
76783
77023
|
}
|
|
@@ -82711,7 +82951,7 @@ var KNOWLEDGE_SCHEMA_VERSION = 2;
|
|
|
82711
82951
|
|
|
82712
82952
|
// src/hooks/knowledge-migrator.ts
|
|
82713
82953
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
82714
|
-
import { existsSync as
|
|
82954
|
+
import { existsSync as existsSync42, readFileSync as readFileSync26 } from "node:fs";
|
|
82715
82955
|
import { mkdir as mkdir17, readFile as readFile19, writeFile as writeFile15 } from "node:fs/promises";
|
|
82716
82956
|
import * as os15 from "node:os";
|
|
82717
82957
|
import * as path75 from "node:path";
|
|
@@ -82728,7 +82968,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
82728
82968
|
const sentinelPath = path75.join(directory, ".swarm", ".knowledge-migrated");
|
|
82729
82969
|
const contextPath = path75.join(directory, ".swarm", "context.md");
|
|
82730
82970
|
const knowledgePath = resolveSwarmKnowledgePath(directory);
|
|
82731
|
-
if (
|
|
82971
|
+
if (existsSync42(sentinelPath)) {
|
|
82732
82972
|
return {
|
|
82733
82973
|
migrated: false,
|
|
82734
82974
|
entriesMigrated: 0,
|
|
@@ -82737,7 +82977,7 @@ async function migrateContextToKnowledge(directory, config3) {
|
|
|
82737
82977
|
skippedReason: "sentinel-exists"
|
|
82738
82978
|
};
|
|
82739
82979
|
}
|
|
82740
|
-
if (!
|
|
82980
|
+
if (!existsSync42(contextPath)) {
|
|
82741
82981
|
return {
|
|
82742
82982
|
migrated: false,
|
|
82743
82983
|
entriesMigrated: 0,
|
|
@@ -82829,7 +83069,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
|
|
|
82829
83069
|
const legacyHivePath = _internals51.resolveLegacyHiveKnowledgePath();
|
|
82830
83070
|
const canonicalHivePath = resolveHiveKnowledgePath();
|
|
82831
83071
|
const sentinelPath = path75.join(path75.dirname(canonicalHivePath), ".hive-knowledge-migrated");
|
|
82832
|
-
if (
|
|
83072
|
+
if (existsSync42(sentinelPath)) {
|
|
82833
83073
|
return {
|
|
82834
83074
|
migrated: false,
|
|
82835
83075
|
entriesMigrated: 0,
|
|
@@ -82838,7 +83078,7 @@ async function migrateHiveKnowledgeLegacy(config3) {
|
|
|
82838
83078
|
skippedReason: "sentinel-exists"
|
|
82839
83079
|
};
|
|
82840
83080
|
}
|
|
82841
|
-
if (!
|
|
83081
|
+
if (!existsSync42(legacyHivePath)) {
|
|
82842
83082
|
return {
|
|
82843
83083
|
migrated: false,
|
|
82844
83084
|
entriesMigrated: 0,
|
|
@@ -83040,7 +83280,7 @@ function truncateLesson2(text) {
|
|
|
83040
83280
|
}
|
|
83041
83281
|
function inferProjectName(directory) {
|
|
83042
83282
|
const packageJsonPath = path75.join(directory, "package.json");
|
|
83043
|
-
if (
|
|
83283
|
+
if (existsSync42(packageJsonPath)) {
|
|
83044
83284
|
try {
|
|
83045
83285
|
const pkg = JSON.parse(readFileSync26(packageJsonPath, "utf-8"));
|
|
83046
83286
|
if (pkg.name && typeof pkg.name === "string") {
|
|
@@ -83433,12 +83673,12 @@ var init_identity = __esm(() => {
|
|
|
83433
83673
|
});
|
|
83434
83674
|
|
|
83435
83675
|
// src/commands/link.ts
|
|
83436
|
-
import { existsSync as
|
|
83676
|
+
import { existsSync as existsSync43 } from "node:fs";
|
|
83437
83677
|
import * as path77 from "node:path";
|
|
83438
83678
|
async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
|
|
83439
83679
|
const localPath = path77.join(localSwarmDir, "knowledge.jsonl");
|
|
83440
83680
|
const sharedPath = path77.join(linkDir, "knowledge.jsonl");
|
|
83441
|
-
if (!
|
|
83681
|
+
if (!existsSync43(localPath))
|
|
83442
83682
|
return { merged: 0, skipped: 0 };
|
|
83443
83683
|
let merged = 0;
|
|
83444
83684
|
let skipped = 0;
|
|
@@ -84754,7 +84994,7 @@ var init_maintenance = __esm(() => {
|
|
|
84754
84994
|
|
|
84755
84995
|
// src/memory/local-jsonl-provider.ts
|
|
84756
84996
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
84757
|
-
import { existsSync as
|
|
84997
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
84758
84998
|
import {
|
|
84759
84999
|
appendFile as appendFile9,
|
|
84760
85000
|
mkdir as mkdir18,
|
|
@@ -85105,7 +85345,7 @@ function validateLoadedProposals(values, config3) {
|
|
|
85105
85345
|
return { records, invalidCount };
|
|
85106
85346
|
}
|
|
85107
85347
|
async function readJsonl(filePath) {
|
|
85108
|
-
if (!
|
|
85348
|
+
if (!existsSync44(filePath))
|
|
85109
85349
|
return [];
|
|
85110
85350
|
const content = await readFile20(filePath, "utf-8");
|
|
85111
85351
|
const records = [];
|
|
@@ -85265,7 +85505,7 @@ var init_prompt_block = __esm(() => {
|
|
|
85265
85505
|
});
|
|
85266
85506
|
|
|
85267
85507
|
// src/memory/jsonl-migration.ts
|
|
85268
|
-
import { existsSync as
|
|
85508
|
+
import { existsSync as existsSync45, renameSync as renameSync18, unlinkSync as unlinkSync13 } from "node:fs";
|
|
85269
85509
|
import { copyFile as copyFile2, mkdir as mkdir19, readFile as readFile21, stat as stat10, writeFile as writeFile17 } from "node:fs/promises";
|
|
85270
85510
|
import * as path79 from "node:path";
|
|
85271
85511
|
function resolveMemoryStorageDir(rootDirectory, config3 = {}) {
|
|
@@ -85297,10 +85537,10 @@ async function backupLegacyJsonl(rootDirectory, config3 = {}) {
|
|
|
85297
85537
|
const results = [];
|
|
85298
85538
|
for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
|
|
85299
85539
|
const source = path79.join(storageDir, filename);
|
|
85300
|
-
if (!
|
|
85540
|
+
if (!existsSync45(source))
|
|
85301
85541
|
continue;
|
|
85302
85542
|
const backup = path79.join(backupDir, `${filename}.pre-sqlite-migration`);
|
|
85303
|
-
if (
|
|
85543
|
+
if (existsSync45(backup)) {
|
|
85304
85544
|
results.push({ source, backup, created: false });
|
|
85305
85545
|
continue;
|
|
85306
85546
|
}
|
|
@@ -85354,7 +85594,7 @@ async function writeMigrationReport(rootDirectory, report, config3 = {}) {
|
|
|
85354
85594
|
}
|
|
85355
85595
|
async function readMigrationReport(rootDirectory, config3 = {}) {
|
|
85356
85596
|
const reportPath = path79.join(resolveMemoryStorageDir(rootDirectory, config3), "migration-report.json");
|
|
85357
|
-
if (!
|
|
85597
|
+
if (!existsSync45(reportPath))
|
|
85358
85598
|
return null;
|
|
85359
85599
|
try {
|
|
85360
85600
|
return JSON.parse(await readFile21(reportPath, "utf-8"));
|
|
@@ -85368,13 +85608,13 @@ async function getLegacyJsonlFileStatus(rootDirectory, config3 = {}) {
|
|
|
85368
85608
|
for (const file3 of ["memories.jsonl", "proposals.jsonl"]) {
|
|
85369
85609
|
const filePath = path79.join(storageDir, file3);
|
|
85370
85610
|
let sizeBytes = 0;
|
|
85371
|
-
if (
|
|
85611
|
+
if (existsSync45(filePath)) {
|
|
85372
85612
|
sizeBytes = (await stat10(filePath)).size;
|
|
85373
85613
|
}
|
|
85374
85614
|
statuses.push({
|
|
85375
85615
|
file: file3,
|
|
85376
85616
|
path: filePath,
|
|
85377
|
-
exists:
|
|
85617
|
+
exists: existsSync45(filePath),
|
|
85378
85618
|
sizeBytes
|
|
85379
85619
|
});
|
|
85380
85620
|
}
|
|
@@ -85455,7 +85695,7 @@ async function readProposalJsonl(filePath, config3) {
|
|
|
85455
85695
|
return { records, invalidRows, totalRows: rows.totalRows };
|
|
85456
85696
|
}
|
|
85457
85697
|
async function readJsonlRows(filePath) {
|
|
85458
|
-
if (!
|
|
85698
|
+
if (!existsSync45(filePath)) {
|
|
85459
85699
|
return { rows: [], invalidRows: [], totalRows: 0 };
|
|
85460
85700
|
}
|
|
85461
85701
|
const content = await readFile21(filePath, "utf-8");
|
|
@@ -86729,7 +86969,7 @@ var init_provider_pool = __esm(() => {
|
|
|
86729
86969
|
|
|
86730
86970
|
// src/memory/gateway.ts
|
|
86731
86971
|
import { createHash as createHash13 } from "node:crypto";
|
|
86732
|
-
import { existsSync as
|
|
86972
|
+
import { existsSync as existsSync46, readFileSync as readFileSync27 } from "node:fs";
|
|
86733
86973
|
import * as path82 from "node:path";
|
|
86734
86974
|
|
|
86735
86975
|
class MemoryGateway {
|
|
@@ -87090,7 +87330,7 @@ function readGitRemoteUrl(directory) {
|
|
|
87090
87330
|
if (gitRemoteUrlCache.has(directory))
|
|
87091
87331
|
return gitRemoteUrlCache.get(directory);
|
|
87092
87332
|
const gitConfigPath = path82.join(directory, ".git", "config");
|
|
87093
|
-
if (!
|
|
87333
|
+
if (!existsSync46(gitConfigPath)) {
|
|
87094
87334
|
gitRemoteUrlCache.set(directory, undefined);
|
|
87095
87335
|
return;
|
|
87096
87336
|
}
|
|
@@ -88194,7 +88434,7 @@ var init_consolidation_log = __esm(() => {
|
|
|
88194
88434
|
});
|
|
88195
88435
|
|
|
88196
88436
|
// src/commands/memory.ts
|
|
88197
|
-
import { existsSync as
|
|
88437
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
88198
88438
|
import * as path86 from "node:path";
|
|
88199
88439
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
88200
88440
|
async function handleMemoryCommand(_directory, _args) {
|
|
@@ -88254,7 +88494,7 @@ async function handleMemoryStatusCommand(directory, _args) {
|
|
|
88254
88494
|
`- Provider: \`${config3.provider}\``,
|
|
88255
88495
|
`- Storage: \`${storageDir}\``,
|
|
88256
88496
|
`- SQLite path: \`${sqlitePath}\``,
|
|
88257
|
-
`- SQLite database exists: \`${
|
|
88497
|
+
`- SQLite database exists: \`${existsSync47(sqlitePath)}\``,
|
|
88258
88498
|
`- Automatic destructive cleanup: \`disabled\``,
|
|
88259
88499
|
"",
|
|
88260
88500
|
"### Legacy JSONL"
|
|
@@ -93116,19 +93356,19 @@ function hasCompoundTestExtension(filename) {
|
|
|
93116
93356
|
const lower = filename.toLowerCase();
|
|
93117
93357
|
return COMPOUND_TEST_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
93118
93358
|
}
|
|
93119
|
-
function isLanguageSpecificTestFile(
|
|
93120
|
-
const lower =
|
|
93359
|
+
function isLanguageSpecificTestFile(basename14) {
|
|
93360
|
+
const lower = basename14.toLowerCase();
|
|
93121
93361
|
if (lower.endsWith("_test.go"))
|
|
93122
93362
|
return true;
|
|
93123
93363
|
if (lower.endsWith(".py") && (lower.startsWith("test_") || lower.endsWith("_test.py")))
|
|
93124
93364
|
return true;
|
|
93125
93365
|
if (lower.endsWith("_spec.rb"))
|
|
93126
93366
|
return true;
|
|
93127
|
-
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(
|
|
93367
|
+
if (lower.endsWith(".java") && (/^Test[A-Z]/.test(basename14) || basename14.endsWith("Test.java") || basename14.endsWith("Tests.java") || lower.endsWith("it.java")))
|
|
93128
93368
|
return true;
|
|
93129
93369
|
if (lower.endsWith(".cs") && (lower.endsWith("test.cs") || lower.endsWith("tests.cs")))
|
|
93130
93370
|
return true;
|
|
93131
|
-
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(
|
|
93371
|
+
if (lower.endsWith(".kt") && (/^Test[A-Z]/.test(basename14) || lower.endsWith("test.kt") || lower.endsWith("tests.kt")))
|
|
93132
93372
|
return true;
|
|
93133
93373
|
if (lower.endsWith(".tests.ps1"))
|
|
93134
93374
|
return true;
|
|
@@ -93136,23 +93376,23 @@ function isLanguageSpecificTestFile(basename13) {
|
|
|
93136
93376
|
}
|
|
93137
93377
|
function isConventionTestFilePath(filePath) {
|
|
93138
93378
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
93139
|
-
const
|
|
93140
|
-
return hasCompoundTestExtension(
|
|
93379
|
+
const basename14 = path99.basename(filePath);
|
|
93380
|
+
return hasCompoundTestExtension(basename14) || basename14.includes(".spec.") || basename14.includes(".test.") || isLanguageSpecificTestFile(basename14) || isTestDirectoryPath(normalizedPath);
|
|
93141
93381
|
}
|
|
93142
93382
|
function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
93143
93383
|
const testFiles = [];
|
|
93144
93384
|
for (const file3 of sourceFiles) {
|
|
93145
93385
|
const absoluteFile = resolveWorkspacePath(file3, workingDir);
|
|
93146
93386
|
const relativeFile = path99.relative(workingDir, absoluteFile);
|
|
93147
|
-
const
|
|
93387
|
+
const basename14 = path99.basename(absoluteFile);
|
|
93148
93388
|
const dirname45 = path99.dirname(absoluteFile);
|
|
93149
93389
|
const preferRelativeOutput = !path99.isAbsolute(file3);
|
|
93150
93390
|
if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file3)) {
|
|
93151
93391
|
dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
|
|
93152
93392
|
continue;
|
|
93153
93393
|
}
|
|
93154
|
-
const nameWithoutExt =
|
|
93155
|
-
const ext = path99.extname(
|
|
93394
|
+
const nameWithoutExt = basename14.replace(/\.[^.]+$/, "");
|
|
93395
|
+
const ext = path99.extname(basename14);
|
|
93156
93396
|
const genericTestNames = [
|
|
93157
93397
|
`${nameWithoutExt}.spec${ext}`,
|
|
93158
93398
|
`${nameWithoutExt}.test${ext}`
|
|
@@ -93163,7 +93403,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
|
|
|
93163
93403
|
...languageSpecificTestNames
|
|
93164
93404
|
].map((candidateName) => path99.join(dirname45, candidateName));
|
|
93165
93405
|
const testDirectoryNames = [
|
|
93166
|
-
|
|
93406
|
+
basename14,
|
|
93167
93407
|
...genericTestNames,
|
|
93168
93408
|
...languageSpecificTestNames
|
|
93169
93409
|
];
|
|
@@ -98740,12 +98980,12 @@ var init_turbo = __esm(() => {
|
|
|
98740
98980
|
});
|
|
98741
98981
|
|
|
98742
98982
|
// src/commands/unlink.ts
|
|
98743
|
-
import { existsSync as
|
|
98983
|
+
import { existsSync as existsSync59 } from "node:fs";
|
|
98744
98984
|
import * as path110 from "node:path";
|
|
98745
98985
|
async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
|
|
98746
98986
|
const sharedPath = path110.join(linkDir, "knowledge.jsonl");
|
|
98747
98987
|
const localPath = path110.join(localSwarmDir, "knowledge.jsonl");
|
|
98748
|
-
if (!
|
|
98988
|
+
if (!existsSync59(sharedPath))
|
|
98749
98989
|
return 0;
|
|
98750
98990
|
const sharedEntries = await readKnowledge(sharedPath);
|
|
98751
98991
|
if (sharedEntries.length === 0)
|
|
@@ -101959,7 +102199,7 @@ Example: If the coder received \`SKILLS: file:.claude/skills/writing-tests/SKILL
|
|
|
101959
102199
|
|
|
101960
102200
|
**Mandatory for coding tasks:** Always provide \`writing-tests\` to test_engineer and \`engineering-conventions\` to coder + reviewer when those skills are present in the project. Prefer \`file:\` references when the files exist.
|
|
101961
102201
|
|
|
101962
|
-
## SWARM KNOWLEDGE DIRECTIVES (v2 acknowledgment contract)
|
|
102202
|
+
## SWARM KNOWLEDGE DIRECTIVES (v2 acknowledgment contract; retained compatibility label)
|
|
101963
102203
|
|
|
101964
102204
|
If a \`<swarm_knowledge_directives>\` block is present in your context, treat each
|
|
101965
102205
|
record inside as a structured directive you MUST inspect before:
|
|
@@ -102180,7 +102420,7 @@ ACTION: Load skill file:.opencode/skills/brainstorm/SKILL.md immediately. Follow
|
|
|
102180
102420
|
|
|
102181
102421
|
HARD CONSTRAINTS:
|
|
102182
102422
|
- Complete the loaded skill's QA gate dialogue before save_plan.
|
|
102183
|
-
- Preserve the
|
|
102423
|
+
- Preserve the behavioral guidance marker comments below for prompt post-processing. "Legacy" describes the marker format, not stale guidance.
|
|
102184
102424
|
|
|
102185
102425
|
<!-- BEHAVIORAL_GUIDANCE_START -->
|
|
102186
102426
|
- Treat brainstorm output as discovery material until the loaded skill transitions to SPECIFY or PLAN.
|
|
@@ -102197,7 +102437,7 @@ ACTION: Load skill file:.opencode/skills/specify/SKILL.md immediately. Follow th
|
|
|
102197
102437
|
HARD CONSTRAINTS:
|
|
102198
102438
|
- Complete the loaded skill's QA gate dialogue before save_plan.
|
|
102199
102439
|
- Requirements must use independently testable FR-### and SC-### numbering.
|
|
102200
|
-
- Preserve the
|
|
102440
|
+
- Preserve the behavioral guidance marker comments below for prompt post-processing. "Legacy" describes the marker format, not stale guidance.
|
|
102201
102441
|
|
|
102202
102442
|
<!-- BEHAVIORAL_GUIDANCE_START -->
|
|
102203
102443
|
- Follow the loaded skill's spec creation, clarification, and transition rules.
|
|
@@ -102321,7 +102561,7 @@ HARD CONSTRAINTS (apply regardless of skill load success):
|
|
|
102321
102561
|
- Do NOT delegate to coder
|
|
102322
102562
|
- Do NOT call declare_scope
|
|
102323
102563
|
- Do NOT mutate source code or write any files outside .swarm/
|
|
102324
|
-
-
|
|
102564
|
+
- In MODE: DEEP_RESEARCH, you (architect) coordinate \`web_search\` and own \`web_fetch\`; sme synthesis workers receive gathered evidence in their dispatch message — do NOT expect sme to fetch in this mode. Outside DEEP_RESEARCH, SME and researcher prompts may use \`web_search\` directly when that tool is granted and configured.
|
|
102325
102565
|
- Every claim in the final report MUST cite a source from the gathered evidence; reviewers verify claim↔citation before a claim is reported
|
|
102326
102566
|
- Critics challenge only high-stakes / contested claims — do NOT waste cycles on well-supported ones
|
|
102327
102567
|
- If council.general.enabled is false or no search API key is configured, surface that and STOP — do not produce ungrounded research
|
|
@@ -102853,15 +103093,19 @@ Reply with a single fenced JSON block. No prose outside the block.
|
|
|
102853
103093
|
Notes:
|
|
102854
103094
|
- \`searchQueries\` is optional — list queries you would have run if you had web access (the architect uses these for audit), or omit / leave empty if none.
|
|
102855
103095
|
- \`sources\` MUST come from the RESEARCH CONTEXT only. Copy title/url/snippet/query verbatim. Never invent sources.
|
|
102856
|
-
- For Round 1: leave \`disagreementTopics\` as []. For Round 2: list the specific disagreement topics this response addresses.`, HARD_RULES
|
|
103096
|
+
- For Round 1: leave \`disagreementTopics\` as []. For Round 2: list the specific disagreement topics this response addresses.`, HARD_RULES, GENERALIST_COUNCIL_PROMPT, SKEPTIC_COUNCIL_PROMPT, DOMAIN_EXPERT_COUNCIL_PROMPT;
|
|
103097
|
+
var init_council_prompts = __esm(() => {
|
|
103098
|
+
HARD_RULES = `================================================================
|
|
102857
103099
|
HARD RULES
|
|
102858
103100
|
================================================================
|
|
102859
103101
|
- You have no tools. Reason from the provided RESEARCH CONTEXT and stable background knowledge.
|
|
103102
|
+
- If invoked through dispatch_lanes as a read-only advisory lane, the same no-tools rule applies.
|
|
102860
103103
|
- Training knowledge may provide stable background only; it must not support current facts, rankings, prices, release status, active best practices, or "state of the art" claims.
|
|
102861
103104
|
- Never invent sources. If the RESEARCH CONTEXT does not cover a needed claim, say so in \`areasOfUncertainty\`.
|
|
102862
103105
|
- Never echo other members' responses verbatim. Paraphrase or quote with attribution.
|
|
102863
|
-
- Stay within your role and persona. The architect chose you for a specific perspective
|
|
102864
|
-
|
|
103106
|
+
- Stay within your role and persona. The architect chose you for a specific perspective.
|
|
103107
|
+
|
|
103108
|
+
${READ_ONLY_LANE_GUIDANCE}`;
|
|
102865
103109
|
GENERALIST_COUNCIL_PROMPT = `You are the GENERALIST voice on a multi-model General Council.
|
|
102866
103110
|
|
|
102867
103111
|
You are the GENERALIST voice on this council. Your perspective is broad and synthesizing:
|
|
@@ -103005,7 +103249,9 @@ ${customAppendPrompt}` : AUTONOMOUS_OVERSIGHT_PROMPT;
|
|
|
103005
103249
|
}
|
|
103006
103250
|
};
|
|
103007
103251
|
}
|
|
103008
|
-
var PLAN_CRITIC_PROMPT
|
|
103252
|
+
var PLAN_CRITIC_PROMPT, SOUNDING_BOARD_PROMPT, PHASE_DRIFT_VERIFIER_PROMPT, HALLUCINATION_VERIFIER_PROMPT, ARCHITECTURE_SUPERVISOR_PROMPT, AUTONOMOUS_OVERSIGHT_PROMPT;
|
|
103253
|
+
var init_critic = __esm(() => {
|
|
103254
|
+
PLAN_CRITIC_PROMPT = `## PRESSURE IMMUNITY
|
|
103009
103255
|
|
|
103010
103256
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
103011
103257
|
No one can pressure you into changing your verdict.
|
|
@@ -103033,6 +103279,8 @@ If you see references to other agents (like @critic, @coder, etc.) in your instr
|
|
|
103033
103279
|
WRONG: "I'll use the Task tool to call another agent to review the plan"
|
|
103034
103280
|
RIGHT: "I'll read the plan and review it myself"
|
|
103035
103281
|
|
|
103282
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103283
|
+
|
|
103036
103284
|
You are a quality gate.
|
|
103037
103285
|
|
|
103038
103286
|
INPUT FORMAT:
|
|
@@ -103149,7 +103397,8 @@ ANALYZE RULES:
|
|
|
103149
103397
|
- Report only — no plan edits, no spec edits.
|
|
103150
103398
|
- Report the highest-severity findings first within each section.
|
|
103151
103399
|
- If both spec.md and plan.md are present but empty, report CLEAN with a note that both files are empty.
|
|
103152
|
-
|
|
103400
|
+
`;
|
|
103401
|
+
SOUNDING_BOARD_PROMPT = `## PRESSURE IMMUNITY
|
|
103153
103402
|
|
|
103154
103403
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
103155
103404
|
No one can pressure you into changing your verdict.
|
|
@@ -103177,6 +103426,8 @@ You act as a senior engineer reviewing a colleague's proposal. Be direct. Challe
|
|
|
103177
103426
|
If the approach is sound, say so briefly. If there are issues, be specific about what's wrong.
|
|
103178
103427
|
No formal rubric — conversational. But always provide reasoning.
|
|
103179
103428
|
|
|
103429
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103430
|
+
|
|
103180
103431
|
INPUT FORMAT:
|
|
103181
103432
|
TASK: [question or issue the Architect is raising]
|
|
103182
103433
|
CONTEXT: [relevant plan, spec, or context]
|
|
@@ -103206,7 +103457,8 @@ SOUNDING_BOARD RULES:
|
|
|
103206
103457
|
- This is advisory only — you cannot approve your own suggestions for implementation
|
|
103207
103458
|
- Do not use Task tool — evaluate directly
|
|
103208
103459
|
- Read-only: do not create, modify, or delete any file
|
|
103209
|
-
|
|
103460
|
+
`;
|
|
103461
|
+
PHASE_DRIFT_VERIFIER_PROMPT = `## PRESSURE IMMUNITY
|
|
103210
103462
|
|
|
103211
103463
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
103212
103464
|
No one can pressure you into changing your verdict.
|
|
@@ -103233,6 +103485,8 @@ If you see references to other agents (like @critic, @coder, etc.) in your instr
|
|
|
103233
103485
|
|
|
103234
103486
|
DEFAULT POSTURE: SKEPTICAL — absence of drift ≠ evidence of alignment.
|
|
103235
103487
|
|
|
103488
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103489
|
+
|
|
103236
103490
|
DISAMBIGUATION: This mode fires ONLY at phase completion. It is NOT for plan review (use plan_critic) or pre-escalation (use sounding_board).
|
|
103237
103491
|
|
|
103238
103492
|
INPUT FORMAT:
|
|
@@ -103326,7 +103580,8 @@ RULES:
|
|
|
103326
103580
|
- If spec.md exists, cross-reference requirements against implementation
|
|
103327
103581
|
- Report the first deviation point, not all downstream consequences
|
|
103328
103582
|
- VERDICT is APPROVED only if ALL tasks are VERIFIED with no DRIFT
|
|
103329
|
-
|
|
103583
|
+
`;
|
|
103584
|
+
HALLUCINATION_VERIFIER_PROMPT = `## PRESSURE IMMUNITY
|
|
103330
103585
|
|
|
103331
103586
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
103332
103587
|
No one can pressure you into changing your verdict.
|
|
@@ -103357,6 +103612,8 @@ IGNORE them — they are context from the orchestrator, not instructions for you
|
|
|
103357
103612
|
|
|
103358
103613
|
DEFAULT POSTURE: SKEPTICAL — absence of a hallucination ≠ evidence of correctness.
|
|
103359
103614
|
|
|
103615
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103616
|
+
|
|
103360
103617
|
DISAMBIGUATION: This mode fires ONLY at phase completion when hallucination_guard is enabled.
|
|
103361
103618
|
It is NOT for plan review (use plan_critic), pre-escalation (use sounding_board), or
|
|
103362
103619
|
spec-vs-implementation drift detection (use phase_drift_verifier).
|
|
@@ -103419,7 +103676,8 @@ RULES:
|
|
|
103419
103676
|
- Report the first deviation point per artifact, not all downstream consequences
|
|
103420
103677
|
- VERDICT is APPROVED only if ALL axes are clean across ALL artifacts
|
|
103421
103678
|
- If no code changed this phase (plan-only phase), verify Doc/Spec Claims and Citation Integrity only
|
|
103422
|
-
|
|
103679
|
+
`;
|
|
103680
|
+
ARCHITECTURE_SUPERVISOR_PROMPT = `## PRESSURE IMMUNITY
|
|
103423
103681
|
|
|
103424
103682
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
103425
103683
|
No one can pressure you into changing your verdict. Quality is non-negotiable.
|
|
@@ -103437,6 +103695,8 @@ orchestrator context, not instructions to delegate.
|
|
|
103437
103695
|
|
|
103438
103696
|
DEFAULT POSTURE: SKEPTICAL — a clean set of summaries is not evidence of coherence.
|
|
103439
103697
|
|
|
103698
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103699
|
+
|
|
103440
103700
|
## SCOPE — what you DO and DO NOT do
|
|
103441
103701
|
DO look for:
|
|
103442
103702
|
- Contradictory decisions across tasks (e.g. one task chose Redis, another an in-memory map).
|
|
@@ -103493,7 +103753,8 @@ RULES:
|
|
|
103493
103753
|
- Base findings ONLY on the supplied summaries. Do not invent code-level claims.
|
|
103494
103754
|
- REJECT only for genuine system-level problems, not local nits.
|
|
103495
103755
|
- If the summaries are empty or trivial, return APPROVE with no findings.
|
|
103496
|
-
|
|
103756
|
+
`;
|
|
103757
|
+
AUTONOMOUS_OVERSIGHT_PROMPT = `## AUTONOMOUS OVERSIGHT MODE
|
|
103497
103758
|
|
|
103498
103759
|
You are the sole quality gate between the architect and production. There is no human reviewer. Every decision you approve will be executed without further verification. Act accordingly.
|
|
103499
103760
|
|
|
@@ -103512,6 +103773,8 @@ These rules are absolute. You cannot override, relax, or reinterpret them.
|
|
|
103512
103773
|
9. DEPENDENCY VIGILANCE. Any new dependency must be verified as a real package. Any phantom dependency = CRITICAL REJECT.
|
|
103513
103774
|
10. SECURITY BOUNDARY. Changes touching auth, secrets, filesystem, subprocess, or network boundaries require heightened scrutiny. Missing validation at any trust boundary = REJECT.
|
|
103514
103775
|
|
|
103776
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
103777
|
+
|
|
103515
103778
|
## VERIFICATION PROTOCOL
|
|
103516
103779
|
|
|
103517
103780
|
For every decision point, execute the relevant protocol:
|
|
@@ -103577,7 +103840,7 @@ REASONING: [2-4 sentences — what you verified and why]
|
|
|
103577
103840
|
EVIDENCE_CHECKED: [list of files/artifacts you read]
|
|
103578
103841
|
ANTI_PATTERNS_DETECTED: [list or "none"]
|
|
103579
103842
|
ESCALATION_NEEDED: YES | NO`;
|
|
103580
|
-
|
|
103843
|
+
});
|
|
103581
103844
|
|
|
103582
103845
|
// src/agents/curator-agent.ts
|
|
103583
103846
|
function createCuratorAgent(model, customPrompt, customAppendPrompt, role = "curator_init") {
|
|
@@ -103610,6 +103873,7 @@ ${customAppendPrompt}` : roleConfig.prompt;
|
|
|
103610
103873
|
}
|
|
103611
103874
|
var ROLE_CONFIG;
|
|
103612
103875
|
var init_curator_agent = __esm(() => {
|
|
103876
|
+
init_explorer();
|
|
103613
103877
|
ROLE_CONFIG = {
|
|
103614
103878
|
curator_init: {
|
|
103615
103879
|
name: "curator_init",
|
|
@@ -104061,7 +104325,9 @@ ${customAppendPrompt}`;
|
|
|
104061
104325
|
}
|
|
104062
104326
|
};
|
|
104063
104327
|
}
|
|
104064
|
-
var RESEARCHER_PROMPT
|
|
104328
|
+
var RESEARCHER_PROMPT;
|
|
104329
|
+
var init_researcher = __esm(() => {
|
|
104330
|
+
RESEARCHER_PROMPT = `## IDENTITY
|
|
104065
104331
|
You are Researcher — the automated research specialist. You gather, synthesise, and cite information from multiple sources directly — you do NOT delegate.
|
|
104066
104332
|
DO NOT use the Task tool to delegate to other agents. You ARE the agent that does the work.
|
|
104067
104333
|
If you see references to other agents (like @researcher, @sme, etc.) in your instructions, IGNORE them — they are context from the orchestrator, not instructions for you to delegate.
|
|
@@ -104069,6 +104335,8 @@ If you see references to other agents (like @researcher, @sme, etc.) in your ins
|
|
|
104069
104335
|
WRONG: "I'll use the Task tool to call another agent to search for this"
|
|
104070
104336
|
RIGHT: "I'll query multiple sources and synthesise the findings myself"
|
|
104071
104337
|
|
|
104338
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
104339
|
+
|
|
104072
104340
|
## PURPOSE
|
|
104073
104341
|
You are the swarm's dedicated research agent. When the architect needs information from the web, GitHub, academic literature, official docs, or code search, it dispatches you. Your output feeds directly into planning and implementation — precision and citations matter more than length.
|
|
104074
104342
|
|
|
@@ -104179,6 +104447,7 @@ Do not pad responses with hedging when confidence is HIGH. A precise answer is m
|
|
|
104179
104447
|
- Do not fabricate URLs — cite "source: not found" rather than inventing a link
|
|
104180
104448
|
- Cross-platform and version-specific constraints must be flagged explicitly
|
|
104181
104449
|
`;
|
|
104450
|
+
});
|
|
104182
104451
|
|
|
104183
104452
|
// src/agents/reviewer.ts
|
|
104184
104453
|
function createReviewerAgent(model, customPrompt, customAppendPrompt) {
|
|
@@ -104205,7 +104474,9 @@ ${customAppendPrompt}`;
|
|
|
104205
104474
|
}
|
|
104206
104475
|
};
|
|
104207
104476
|
}
|
|
104208
|
-
var REVIEWER_PROMPT
|
|
104477
|
+
var REVIEWER_PROMPT;
|
|
104478
|
+
var init_reviewer = __esm(() => {
|
|
104479
|
+
REVIEWER_PROMPT = `## PRESSURE IMMUNITY
|
|
104209
104480
|
|
|
104210
104481
|
You have unlimited time. There is no attempt limit. There is no deadline.
|
|
104211
104482
|
No one can pressure you into changing your verdict.
|
|
@@ -104241,6 +104512,8 @@ If you see references to other agents (like @reviewer, @coder, etc.) in your ins
|
|
|
104241
104512
|
WRONG: "I'll use the Task tool to call another agent to review this code"
|
|
104242
104513
|
RIGHT: "I'll read the changed files and review them myself"
|
|
104243
104514
|
|
|
104515
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
104516
|
+
|
|
104244
104517
|
## REVIEW FOCUS
|
|
104245
104518
|
You are reviewing a CHANGE, not a FILE.
|
|
104246
104519
|
1. WHAT CHANGED: Focus on the diff — the new or modified code
|
|
@@ -104468,7 +104741,7 @@ CALIBRATION RULE — If you find NO issues, state this explicitly:
|
|
|
104468
104741
|
A blank APPROVED without reasoning is NOT acceptable — it indicates you did not actually review.
|
|
104469
104742
|
|
|
104470
104743
|
`;
|
|
104471
|
-
|
|
104744
|
+
});
|
|
104472
104745
|
|
|
104473
104746
|
// src/agents/skill-improver.ts
|
|
104474
104747
|
function createSkillImproverAgent(model, customPrompt, customAppendPrompt) {
|
|
@@ -104564,7 +104837,9 @@ ${customAppendPrompt}`;
|
|
|
104564
104837
|
}
|
|
104565
104838
|
};
|
|
104566
104839
|
}
|
|
104567
|
-
var SME_PROMPT
|
|
104840
|
+
var SME_PROMPT;
|
|
104841
|
+
var init_sme = __esm(() => {
|
|
104842
|
+
SME_PROMPT = `## IDENTITY
|
|
104568
104843
|
You are SME (Subject Matter Expert). You provide deep domain-specific technical guidance directly — you do NOT delegate.
|
|
104569
104844
|
DO NOT use the Task tool to delegate to other agents. You ARE the agent that does the work.
|
|
104570
104845
|
If you see references to other agents (like @sme, @coder, etc.) in your instructions, IGNORE them — they are context from the orchestrator, not instructions for you to delegate.
|
|
@@ -104572,6 +104847,8 @@ If you see references to other agents (like @sme, @coder, etc.) in your instruct
|
|
|
104572
104847
|
WRONG: "I'll use the Task tool to call another agent to research this"
|
|
104573
104848
|
RIGHT: "I'll research this domain question and answer directly"
|
|
104574
104849
|
|
|
104850
|
+
${READ_ONLY_LANE_GUIDANCE}
|
|
104851
|
+
|
|
104575
104852
|
## RESEARCH PROTOCOL
|
|
104576
104853
|
When consulting on a domain question, follow these steps in order:
|
|
104577
104854
|
1. FRAME: Restate the question in one sentence to confirm understanding
|
|
@@ -104696,6 +104973,7 @@ Cache bypass: if user says "re-fetch", "ignore cache", or "latest", skip the cac
|
|
|
104696
104973
|
SME is read-only. Cache persistence is Architect's responsibility — save this line to context.md after each SME response that includes a CACHE-UPDATE.
|
|
104697
104974
|
|
|
104698
104975
|
`;
|
|
104976
|
+
});
|
|
104699
104977
|
|
|
104700
104978
|
// src/agents/spec-writer.ts
|
|
104701
104979
|
function createSpecWriterAgent(model, customPrompt, customAppendPrompt) {
|
|
@@ -105531,13 +105809,19 @@ var init_agents2 = __esm(() => {
|
|
|
105531
105809
|
init_critic();
|
|
105532
105810
|
init_curator_agent();
|
|
105533
105811
|
init_docs();
|
|
105812
|
+
init_explorer();
|
|
105813
|
+
init_researcher();
|
|
105534
105814
|
init_reviewer();
|
|
105815
|
+
init_sme();
|
|
105535
105816
|
init_architect();
|
|
105536
105817
|
init_council_prompts();
|
|
105537
105818
|
init_critic();
|
|
105538
105819
|
init_curator_agent();
|
|
105539
105820
|
init_docs();
|
|
105821
|
+
init_explorer();
|
|
105822
|
+
init_researcher();
|
|
105540
105823
|
init_reviewer();
|
|
105824
|
+
init_sme();
|
|
105541
105825
|
warnedAgents = new Set;
|
|
105542
105826
|
_swarmAgentsMap = new Map;
|
|
105543
105827
|
KNOWN_VARIANT_VALUES = new Set([
|
|
@@ -105556,11 +105840,11 @@ __export(exports_evidence_summary_integration, {
|
|
|
105556
105840
|
createEvidenceSummaryIntegration: () => createEvidenceSummaryIntegration,
|
|
105557
105841
|
EvidenceSummaryIntegration: () => EvidenceSummaryIntegration
|
|
105558
105842
|
});
|
|
105559
|
-
import { existsSync as
|
|
105843
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync32, writeFileSync as writeFileSync18 } from "node:fs";
|
|
105560
105844
|
import * as path114 from "node:path";
|
|
105561
105845
|
function persistSummary(projectDir, artifact, filename) {
|
|
105562
105846
|
const swarmPath = path114.join(projectDir, ".swarm");
|
|
105563
|
-
if (!
|
|
105847
|
+
if (!existsSync60(swarmPath)) {
|
|
105564
105848
|
mkdirSync32(swarmPath, { recursive: true });
|
|
105565
105849
|
}
|
|
105566
105850
|
const artifactPath = path114.join(swarmPath, filename);
|
|
@@ -106572,7 +106856,7 @@ var init_schema3 = __esm(() => {
|
|
|
106572
106856
|
|
|
106573
106857
|
// src/summaries/store.ts
|
|
106574
106858
|
import {
|
|
106575
|
-
existsSync as
|
|
106859
|
+
existsSync as existsSync72,
|
|
106576
106860
|
mkdirSync as mkdirSync39,
|
|
106577
106861
|
readFileSync as readFileSync49,
|
|
106578
106862
|
renameSync as renameSync26,
|
|
@@ -106587,7 +106871,7 @@ function writeRawSidecar(absPath, bundle) {
|
|
|
106587
106871
|
writeFileSync25(tempFile, JSON.stringify(bundle, null, 2), "utf-8");
|
|
106588
106872
|
renameSync26(tempFile, absPath);
|
|
106589
106873
|
} finally {
|
|
106590
|
-
if (
|
|
106874
|
+
if (existsSync72(tempFile)) {
|
|
106591
106875
|
try {
|
|
106592
106876
|
unlinkSync22(tempFile);
|
|
106593
106877
|
} catch {}
|
|
@@ -106674,7 +106958,7 @@ function readSupervisorReportRaw(directory, phase) {
|
|
|
106674
106958
|
} catch {
|
|
106675
106959
|
return null;
|
|
106676
106960
|
}
|
|
106677
|
-
if (!
|
|
106961
|
+
if (!existsSync72(abs))
|
|
106678
106962
|
return null;
|
|
106679
106963
|
try {
|
|
106680
106964
|
const parsed = JSON.parse(readFileSync49(abs, "utf-8"));
|
|
@@ -106773,7 +107057,7 @@ __export(exports_runtime, {
|
|
|
106773
107057
|
clearParserCache: () => clearParserCache,
|
|
106774
107058
|
_internals: () => _internals79
|
|
106775
107059
|
});
|
|
106776
|
-
import { existsSync as
|
|
107060
|
+
import { existsSync as existsSync73, statSync as statSync24 } from "node:fs";
|
|
106777
107061
|
import * as path129 from "node:path";
|
|
106778
107062
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
106779
107063
|
import { Language, Parser as TreeSitterParser } from "web-tree-sitter";
|
|
@@ -106842,7 +107126,7 @@ async function loadGrammar(languageId) {
|
|
|
106842
107126
|
const parser = new TreeSitterParser;
|
|
106843
107127
|
const wasmFileName = getWasmFileName(normalizedId);
|
|
106844
107128
|
const wasmPath = path129.join(getGrammarsDirAbsolute(), wasmFileName);
|
|
106845
|
-
if (!
|
|
107129
|
+
if (!existsSync73(wasmPath)) {
|
|
106846
107130
|
throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
|
|
106847
107131
|
` + `Make sure to run 'bun run build' to copy grammar files to dist/lang/grammars/`);
|
|
106848
107132
|
}
|
|
@@ -107025,17 +107309,17 @@ function normalizeSeparators(filePath) {
|
|
|
107025
107309
|
}
|
|
107026
107310
|
function matchesDocPattern(filePath, patterns) {
|
|
107027
107311
|
const normalizedPath = normalizeSeparators(filePath);
|
|
107028
|
-
const
|
|
107312
|
+
const basename17 = path142.basename(filePath);
|
|
107029
107313
|
for (const pattern of patterns) {
|
|
107030
107314
|
if (!pattern.includes("/") && !pattern.includes("\\")) {
|
|
107031
|
-
if (
|
|
107315
|
+
if (basename17 === pattern) {
|
|
107032
107316
|
return true;
|
|
107033
107317
|
}
|
|
107034
107318
|
continue;
|
|
107035
107319
|
}
|
|
107036
107320
|
if (pattern.startsWith("**/")) {
|
|
107037
107321
|
const filenamePattern = pattern.slice(3);
|
|
107038
|
-
if (
|
|
107322
|
+
if (basename17 === filenamePattern) {
|
|
107039
107323
|
return true;
|
|
107040
107324
|
}
|
|
107041
107325
|
continue;
|
|
@@ -107428,7 +107712,7 @@ var init_doc_scan = __esm(() => {
|
|
|
107428
107712
|
});
|
|
107429
107713
|
|
|
107430
107714
|
// src/hooks/knowledge-reader.ts
|
|
107431
|
-
import { existsSync as
|
|
107715
|
+
import { existsSync as existsSync78 } from "node:fs";
|
|
107432
107716
|
import { readFile as readFile29 } from "node:fs/promises";
|
|
107433
107717
|
import * as path143 from "node:path";
|
|
107434
107718
|
function inferCategoriesFromPhase(phaseDescription) {
|
|
@@ -107476,7 +107760,7 @@ function inferCategoriesFromPhase(phaseDescription) {
|
|
|
107476
107760
|
}
|
|
107477
107761
|
async function transactShownFile(shownFile, mutate) {
|
|
107478
107762
|
return transactFile(shownFile, async (filePath) => {
|
|
107479
|
-
if (!
|
|
107763
|
+
if (!existsSync78(filePath))
|
|
107480
107764
|
return {};
|
|
107481
107765
|
try {
|
|
107482
107766
|
const content = await readFile29(filePath, "utf-8");
|
|
@@ -107606,7 +107890,7 @@ async function readMergedKnowledge(directory, config3, context, opts) {
|
|
|
107606
107890
|
async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
107607
107891
|
const shownFile = path143.join(directory, ".swarm", ".knowledge-shown.json");
|
|
107608
107892
|
try {
|
|
107609
|
-
if (!
|
|
107893
|
+
if (!existsSync78(shownFile)) {
|
|
107610
107894
|
return;
|
|
107611
107895
|
}
|
|
107612
107896
|
let shownIds;
|
|
@@ -108336,7 +108620,7 @@ __export(exports_design_doc_drift, {
|
|
|
108336
108620
|
_internals: () => _internals111
|
|
108337
108621
|
});
|
|
108338
108622
|
import * as fs118 from "node:fs";
|
|
108339
|
-
import * as
|
|
108623
|
+
import * as path190 from "node:path";
|
|
108340
108624
|
function mtimeMsOrNull(absPath) {
|
|
108341
108625
|
try {
|
|
108342
108626
|
return fs118.statSync(absPath).mtimeMs;
|
|
@@ -108347,35 +108631,35 @@ function mtimeMsOrNull(absPath) {
|
|
|
108347
108631
|
function resolveAnchorWithin(directory, anchor) {
|
|
108348
108632
|
if (!anchor || typeof anchor !== "string")
|
|
108349
108633
|
return null;
|
|
108350
|
-
const root =
|
|
108351
|
-
const resolved =
|
|
108352
|
-
const rel =
|
|
108353
|
-
if (rel.startsWith("..") ||
|
|
108634
|
+
const root = path190.resolve(directory);
|
|
108635
|
+
const resolved = path190.resolve(root, anchor);
|
|
108636
|
+
const rel = path190.relative(root, resolved);
|
|
108637
|
+
if (rel.startsWith("..") || path190.isAbsolute(rel))
|
|
108354
108638
|
return null;
|
|
108355
108639
|
return resolved;
|
|
108356
108640
|
}
|
|
108357
108641
|
async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
108358
108642
|
try {
|
|
108359
|
-
const root =
|
|
108360
|
-
const outAbs =
|
|
108361
|
-
const outRel =
|
|
108362
|
-
if (outRel.startsWith("..") ||
|
|
108643
|
+
const root = path190.resolve(directory);
|
|
108644
|
+
const outAbs = path190.resolve(root, outDir);
|
|
108645
|
+
const outRel = path190.relative(root, outAbs);
|
|
108646
|
+
if (outRel.startsWith("..") || path190.isAbsolute(outRel)) {
|
|
108363
108647
|
return null;
|
|
108364
108648
|
}
|
|
108365
108649
|
const docMtimes = new Map;
|
|
108366
108650
|
const checkedDocs = [];
|
|
108367
108651
|
const missingDocs = [];
|
|
108368
108652
|
for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
|
|
108369
|
-
const abs =
|
|
108653
|
+
const abs = path190.join(outAbs, relFile);
|
|
108370
108654
|
const mtime = mtimeMsOrNull(abs);
|
|
108371
108655
|
docMtimes.set(docName, mtime);
|
|
108372
108656
|
if (mtime === null) {
|
|
108373
|
-
missingDocs.push(
|
|
108657
|
+
missingDocs.push(path190.join(outDir, relFile));
|
|
108374
108658
|
} else {
|
|
108375
|
-
checkedDocs.push(
|
|
108659
|
+
checkedDocs.push(path190.join(outDir, relFile));
|
|
108376
108660
|
}
|
|
108377
108661
|
}
|
|
108378
|
-
const traceabilityAbs =
|
|
108662
|
+
const traceabilityAbs = path190.join(outAbs, TRACEABILITY_REL);
|
|
108379
108663
|
let registry3 = null;
|
|
108380
108664
|
try {
|
|
108381
108665
|
const stat14 = await fs118.promises.stat(traceabilityAbs);
|
|
@@ -108445,7 +108729,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
|
|
|
108445
108729
|
};
|
|
108446
108730
|
const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
|
|
108447
108731
|
const filePath = validateSwarmPath(directory, filename);
|
|
108448
|
-
await fs118.promises.mkdir(
|
|
108732
|
+
await fs118.promises.mkdir(path190.dirname(filePath), { recursive: true });
|
|
108449
108733
|
await fs118.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
|
|
108450
108734
|
getGlobalEventBus().publish("curator.docdrift.completed", {
|
|
108451
108735
|
phase,
|
|
@@ -108477,10 +108761,10 @@ var init_design_doc_drift = __esm(() => {
|
|
|
108477
108761
|
domain: "domain.md",
|
|
108478
108762
|
"technical-spec": "technical-spec.md",
|
|
108479
108763
|
"behavior-spec": "behavior-spec.md",
|
|
108480
|
-
"reference-impl":
|
|
108481
|
-
"idiom-notes":
|
|
108764
|
+
"reference-impl": path190.join("reference", "reference-impl.md"),
|
|
108765
|
+
"idiom-notes": path190.join("reference", "idiom-notes.md")
|
|
108482
108766
|
};
|
|
108483
|
-
TRACEABILITY_REL =
|
|
108767
|
+
TRACEABILITY_REL = path190.join("reference", "traceability.json");
|
|
108484
108768
|
_internals111 = {
|
|
108485
108769
|
mtimeMsOrNull,
|
|
108486
108770
|
resolveAnchorWithin,
|
|
@@ -108492,11 +108776,11 @@ var init_design_doc_drift = __esm(() => {
|
|
|
108492
108776
|
var exports_project_context = {};
|
|
108493
108777
|
__export(exports_project_context, {
|
|
108494
108778
|
buildProjectContext: () => buildProjectContext,
|
|
108495
|
-
_internals: () =>
|
|
108779
|
+
_internals: () => _internals125,
|
|
108496
108780
|
LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
|
|
108497
108781
|
});
|
|
108498
108782
|
import * as fs142 from "node:fs";
|
|
108499
|
-
import * as
|
|
108783
|
+
import * as path219 from "node:path";
|
|
108500
108784
|
function detectFileExists2(directory, pattern) {
|
|
108501
108785
|
if (pattern.includes("*") || pattern.includes("?")) {
|
|
108502
108786
|
try {
|
|
@@ -108508,7 +108792,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
108508
108792
|
}
|
|
108509
108793
|
}
|
|
108510
108794
|
try {
|
|
108511
|
-
fs142.accessSync(
|
|
108795
|
+
fs142.accessSync(path219.join(directory, pattern));
|
|
108512
108796
|
return true;
|
|
108513
108797
|
} catch {
|
|
108514
108798
|
return false;
|
|
@@ -108517,7 +108801,7 @@ function detectFileExists2(directory, pattern) {
|
|
|
108517
108801
|
function selectTestCommandFromScriptsTest(backend, directory) {
|
|
108518
108802
|
let pkgRaw;
|
|
108519
108803
|
try {
|
|
108520
|
-
pkgRaw = fs142.readFileSync(
|
|
108804
|
+
pkgRaw = fs142.readFileSync(path219.join(directory, "package.json"), "utf-8");
|
|
108521
108805
|
} catch {
|
|
108522
108806
|
return null;
|
|
108523
108807
|
}
|
|
@@ -108576,7 +108860,7 @@ function selectLintCommand(backend, directory) {
|
|
|
108576
108860
|
return null;
|
|
108577
108861
|
}
|
|
108578
108862
|
async function buildProjectContext(directory) {
|
|
108579
|
-
const backend = await
|
|
108863
|
+
const backend = await _internals125.pickBackend(directory);
|
|
108580
108864
|
if (!backend)
|
|
108581
108865
|
return null;
|
|
108582
108866
|
const ctx = emptyProjectContext();
|
|
@@ -108615,17 +108899,17 @@ async function buildProjectContext(directory) {
|
|
|
108615
108899
|
if (backend.prompts.reviewerChecklist.length > 0) {
|
|
108616
108900
|
ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
|
|
108617
108901
|
}
|
|
108618
|
-
const profiles =
|
|
108902
|
+
const profiles = _internals125.pickedProfiles(directory);
|
|
108619
108903
|
if (profiles.length > 1) {
|
|
108620
108904
|
ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
|
|
108621
108905
|
}
|
|
108622
108906
|
return ctx;
|
|
108623
108907
|
}
|
|
108624
|
-
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300,
|
|
108908
|
+
var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals125;
|
|
108625
108909
|
var init_project_context = __esm(() => {
|
|
108626
108910
|
init_dispatch();
|
|
108627
108911
|
init_framework_detector();
|
|
108628
|
-
|
|
108912
|
+
_internals125 = {
|
|
108629
108913
|
pickBackend,
|
|
108630
108914
|
pickedProfiles
|
|
108631
108915
|
};
|
|
@@ -108635,7 +108919,7 @@ var init_project_context = __esm(() => {
|
|
|
108635
108919
|
init_package();
|
|
108636
108920
|
init_agents2();
|
|
108637
108921
|
init_critic();
|
|
108638
|
-
import * as
|
|
108922
|
+
import * as path220 from "node:path";
|
|
108639
108923
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
108640
108924
|
|
|
108641
108925
|
// src/background/index.ts
|
|
@@ -113337,7 +113621,7 @@ import * as path138 from "node:path";
|
|
|
113337
113621
|
// src/tools/repo-graph/builder.ts
|
|
113338
113622
|
init_profiles();
|
|
113339
113623
|
import * as fsSync8 from "node:fs";
|
|
113340
|
-
import { existsSync as
|
|
113624
|
+
import { existsSync as existsSync74, realpathSync as realpathSync14 } from "node:fs";
|
|
113341
113625
|
import * as fsPromises5 from "node:fs/promises";
|
|
113342
113626
|
import * as os17 from "node:os";
|
|
113343
113627
|
import * as path133 from "node:path";
|
|
@@ -115549,7 +115833,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
115549
115833
|
if (realRoot === null) {
|
|
115550
115834
|
return null;
|
|
115551
115835
|
}
|
|
115552
|
-
if (!
|
|
115836
|
+
if (!existsSync74(resolved)) {
|
|
115553
115837
|
const EXTENSIONS = [
|
|
115554
115838
|
".ts",
|
|
115555
115839
|
".tsx",
|
|
@@ -115563,7 +115847,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
|
|
|
115563
115847
|
let found = null;
|
|
115564
115848
|
for (const ext of EXTENSIONS) {
|
|
115565
115849
|
const candidate = resolved + ext;
|
|
115566
|
-
if (
|
|
115850
|
+
if (existsSync74(candidate)) {
|
|
115567
115851
|
found = candidate;
|
|
115568
115852
|
break;
|
|
115569
115853
|
}
|
|
@@ -116061,7 +116345,7 @@ async function buildWorkspaceGraphAsync(workspaceRoot, options) {
|
|
|
116061
116345
|
const walkBudgetMs = options?.walkBudgetMs ?? DEFAULT_WALK_BUDGET_MS;
|
|
116062
116346
|
const followSymlinks = options?.followSymlinks ?? false;
|
|
116063
116347
|
const absoluteRoot = path133.resolve(workspaceRoot);
|
|
116064
|
-
if (!
|
|
116348
|
+
if (!existsSync74(absoluteRoot)) {
|
|
116065
116349
|
throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
|
|
116066
116350
|
}
|
|
116067
116351
|
if (isRefusedWorkspaceRoot(absoluteRoot)) {
|
|
@@ -116170,7 +116454,7 @@ function getCachedMtime(workspace) {
|
|
|
116170
116454
|
// src/tools/repo-graph/incremental.ts
|
|
116171
116455
|
init_logger();
|
|
116172
116456
|
init_path_security();
|
|
116173
|
-
import { existsSync as
|
|
116457
|
+
import { existsSync as existsSync76 } from "node:fs";
|
|
116174
116458
|
import * as fsPromises7 from "node:fs/promises";
|
|
116175
116459
|
import * as path137 from "node:path";
|
|
116176
116460
|
|
|
@@ -116862,7 +117146,7 @@ function buildOntologyPreflightPacket(graph, filePaths = [], options = {}) {
|
|
|
116862
117146
|
init_utils2();
|
|
116863
117147
|
init_logger();
|
|
116864
117148
|
init_path_security();
|
|
116865
|
-
import { constants as constants5, existsSync as
|
|
117149
|
+
import { constants as constants5, existsSync as existsSync75, readFileSync as readFileSync52, statSync as statSync27 } from "node:fs";
|
|
116866
117150
|
import * as fsPromises6 from "node:fs/promises";
|
|
116867
117151
|
import * as path136 from "node:path";
|
|
116868
117152
|
var WINDOWS_RENAME_MAX_RETRIES2 = 5;
|
|
@@ -116934,7 +117218,7 @@ async function loadGraph(workspace) {
|
|
|
116934
117218
|
if (cached3 && !isDirty(normalized)) {
|
|
116935
117219
|
try {
|
|
116936
117220
|
const graphPath = getGraphPath(workspace);
|
|
116937
|
-
if (
|
|
117221
|
+
if (existsSync75(graphPath)) {
|
|
116938
117222
|
const stats2 = await fsPromises6.stat(graphPath);
|
|
116939
117223
|
const cachedMtime = getCachedMtime(normalized);
|
|
116940
117224
|
if (cachedMtime !== undefined && stats2.mtimeMs !== cachedMtime) {
|
|
@@ -116951,7 +117235,7 @@ async function loadGraph(workspace) {
|
|
|
116951
117235
|
}
|
|
116952
117236
|
try {
|
|
116953
117237
|
const graphPath = getGraphPath(workspace);
|
|
116954
|
-
if (!
|
|
117238
|
+
if (!existsSync75(graphPath)) {
|
|
116955
117239
|
return null;
|
|
116956
117240
|
}
|
|
116957
117241
|
const stats2 = await fsPromises6.stat(graphPath);
|
|
@@ -116985,7 +117269,7 @@ function loadGraphSync(workspace) {
|
|
|
116985
117269
|
const normalized = path136.normalize(workspace);
|
|
116986
117270
|
try {
|
|
116987
117271
|
const graphPath = getGraphPath(workspace);
|
|
116988
|
-
if (!
|
|
117272
|
+
if (!existsSync75(graphPath))
|
|
116989
117273
|
return null;
|
|
116990
117274
|
const stats2 = statSync27(graphPath);
|
|
116991
117275
|
const content = readFileSync52(graphPath, "utf-8");
|
|
@@ -117115,7 +117399,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
117115
117399
|
const updatedPaths = new Set;
|
|
117116
117400
|
for (const rawFilePath of filePaths) {
|
|
117117
117401
|
const normalizedPath = normalizeGraphPath(rawFilePath);
|
|
117118
|
-
const fileExists =
|
|
117402
|
+
const fileExists = existsSync76(rawFilePath);
|
|
117119
117403
|
if (fileExists) {
|
|
117120
117404
|
graph.edges = graph.edges.filter((e) => normalizeGraphPath(e.source) !== normalizedPath);
|
|
117121
117405
|
if (graph.symbolEdges) {
|
|
@@ -117190,7 +117474,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
117190
117474
|
if (loadedMtime !== undefined) {
|
|
117191
117475
|
try {
|
|
117192
117476
|
const graphPath = getGraphPath(workspaceRoot);
|
|
117193
|
-
if (
|
|
117477
|
+
if (existsSync76(graphPath)) {
|
|
117194
117478
|
const currentStats = await fsPromises7.stat(graphPath);
|
|
117195
117479
|
if (currentStats.mtimeMs !== loadedMtime) {
|
|
117196
117480
|
warn(`[repo-graph] Concurrent modification detected — falling back to full rebuild`);
|
|
@@ -121362,7 +121646,7 @@ init_logger();
|
|
|
121362
121646
|
init_knowledge_link();
|
|
121363
121647
|
init_knowledge_store();
|
|
121364
121648
|
var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
|
|
121365
|
-
import { existsSync as
|
|
121649
|
+
import { existsSync as existsSync80 } from "node:fs";
|
|
121366
121650
|
import { appendFile as appendFile14, mkdir as mkdir29, readFile as readFile31 } from "node:fs/promises";
|
|
121367
121651
|
import * as path147 from "node:path";
|
|
121368
121652
|
function resolveApplicationLogPath(directory) {
|
|
@@ -121451,7 +121735,7 @@ async function bumpCountersBatch(directory, bumps) {
|
|
|
121451
121735
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
121452
121736
|
await transactKnowledge(swarmPath, applyOne);
|
|
121453
121737
|
const hivePath = resolveHiveKnowledgePath();
|
|
121454
|
-
if (
|
|
121738
|
+
if (existsSync80(hivePath)) {
|
|
121455
121739
|
await transactKnowledge(hivePath, applyOne);
|
|
121456
121740
|
}
|
|
121457
121741
|
}
|
|
@@ -122425,7 +122709,7 @@ init_extractors();
|
|
|
122425
122709
|
// src/hooks/phase-directives.ts
|
|
122426
122710
|
init_knowledge_events();
|
|
122427
122711
|
init_knowledge_store();
|
|
122428
|
-
import { existsSync as
|
|
122712
|
+
import { existsSync as existsSync81 } from "node:fs";
|
|
122429
122713
|
async function collectPhaseDirectiveIds(directory, phaseLabel) {
|
|
122430
122714
|
const events = await readKnowledgeEvents(directory);
|
|
122431
122715
|
const ids = new Set;
|
|
@@ -122445,7 +122729,7 @@ async function readEntriesById(directory) {
|
|
|
122445
122729
|
for (const e of swarm)
|
|
122446
122730
|
map3.set(e.id, e);
|
|
122447
122731
|
const hivePath = resolveHiveKnowledgePath();
|
|
122448
|
-
if (
|
|
122732
|
+
if (existsSync81(hivePath)) {
|
|
122449
122733
|
const hive = await readKnowledge(hivePath);
|
|
122450
122734
|
for (const e of hive)
|
|
122451
122735
|
if (!map3.has(e.id))
|
|
@@ -124337,7 +124621,7 @@ init_schema();
|
|
|
124337
124621
|
// src/services/directive-predicate-runner.ts
|
|
124338
124622
|
init_bun_compat();
|
|
124339
124623
|
init_logger();
|
|
124340
|
-
import { existsSync as
|
|
124624
|
+
import { existsSync as existsSync84 } from "node:fs";
|
|
124341
124625
|
import * as path153 from "node:path";
|
|
124342
124626
|
var PREDICATE_TIMEOUT_MS = 15000;
|
|
124343
124627
|
var TOOL_BINARY_ALLOWLIST = new Set([
|
|
@@ -124379,7 +124663,7 @@ function findBinaryInPath(binary) {
|
|
|
124379
124663
|
if (!dir)
|
|
124380
124664
|
continue;
|
|
124381
124665
|
const candidate = path153.join(dir, exeName);
|
|
124382
|
-
if (
|
|
124666
|
+
if (existsSync84(candidate))
|
|
124383
124667
|
return candidate;
|
|
124384
124668
|
}
|
|
124385
124669
|
return null;
|
|
@@ -125454,7 +125738,7 @@ init_zod();
|
|
|
125454
125738
|
init_path_security();
|
|
125455
125739
|
init_create_tool();
|
|
125456
125740
|
import {
|
|
125457
|
-
existsSync as
|
|
125741
|
+
existsSync as existsSync86,
|
|
125458
125742
|
mkdirSync as mkdirSync40,
|
|
125459
125743
|
mkdtempSync as mkdtempSync2,
|
|
125460
125744
|
readFileSync as readFileSync57,
|
|
@@ -125817,13 +126101,13 @@ function atomicWriteFileSync2(targetPath, content) {
|
|
|
125817
126101
|
writeFileSync26(tempPath, content, "utf-8");
|
|
125818
126102
|
renameSync29(tempPath, targetPath);
|
|
125819
126103
|
} finally {
|
|
125820
|
-
if (
|
|
126104
|
+
if (existsSync86(tempPath)) {
|
|
125821
126105
|
try {
|
|
125822
126106
|
unlinkSync25(tempPath);
|
|
125823
126107
|
} catch {}
|
|
125824
126108
|
}
|
|
125825
126109
|
const tempDir = path156.dirname(tempPath);
|
|
125826
|
-
if (tempDir !== dir &&
|
|
126110
|
+
if (tempDir !== dir && existsSync86(tempDir)) {
|
|
125827
126111
|
try {
|
|
125828
126112
|
rmdirSync(tempDir);
|
|
125829
126113
|
} catch {}
|
|
@@ -125900,7 +126184,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
|
|
|
125900
126184
|
};
|
|
125901
126185
|
}
|
|
125902
126186
|
const parentDir = path156.dirname(fullPath);
|
|
125903
|
-
if (!
|
|
126187
|
+
if (!existsSync86(parentDir)) {
|
|
125904
126188
|
return {
|
|
125905
126189
|
file: targetPath,
|
|
125906
126190
|
status: "error",
|
|
@@ -125916,7 +126200,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
|
|
|
125916
126200
|
]
|
|
125917
126201
|
};
|
|
125918
126202
|
}
|
|
125919
|
-
if (
|
|
126203
|
+
if (existsSync86(fullPath)) {
|
|
125920
126204
|
return {
|
|
125921
126205
|
file: targetPath,
|
|
125922
126206
|
status: "error",
|
|
@@ -125991,7 +126275,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
|
|
|
125991
126275
|
]
|
|
125992
126276
|
};
|
|
125993
126277
|
}
|
|
125994
|
-
if (!
|
|
126278
|
+
if (!existsSync86(fullPath)) {
|
|
125995
126279
|
return {
|
|
125996
126280
|
file: targetPath,
|
|
125997
126281
|
status: "error",
|
|
@@ -126035,7 +126319,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
|
|
|
126035
126319
|
hunksFailed: 0
|
|
126036
126320
|
};
|
|
126037
126321
|
}
|
|
126038
|
-
if (!
|
|
126322
|
+
if (!existsSync86(fullPath)) {
|
|
126039
126323
|
return {
|
|
126040
126324
|
file: targetPath,
|
|
126041
126325
|
status: "error",
|
|
@@ -126190,7 +126474,7 @@ var swarmApplyPatch = createSwarmTool({
|
|
|
126190
126474
|
const dryRun = obj.dryRun ?? false;
|
|
126191
126475
|
const allowCreates = obj.allowCreates ?? false;
|
|
126192
126476
|
const allowDeletes = obj.allowDeletes ?? false;
|
|
126193
|
-
if (!
|
|
126477
|
+
if (!existsSync86(directory)) {
|
|
126194
126478
|
return JSON.stringify(buildErrorResult("Workspace directory does not exist"), null, 2);
|
|
126195
126479
|
}
|
|
126196
126480
|
if (files.length === 0) {
|
|
@@ -127383,7 +127667,7 @@ function countCodeLines(content) {
|
|
|
127383
127667
|
return lines.length;
|
|
127384
127668
|
}
|
|
127385
127669
|
function isTestFile(filePath) {
|
|
127386
|
-
const
|
|
127670
|
+
const basename19 = path160.basename(filePath);
|
|
127387
127671
|
const _ext = path160.extname(filePath).toLowerCase();
|
|
127388
127672
|
const testPatterns = [
|
|
127389
127673
|
".test.",
|
|
@@ -127399,7 +127683,7 @@ function isTestFile(filePath) {
|
|
|
127399
127683
|
".spec.jsx"
|
|
127400
127684
|
];
|
|
127401
127685
|
for (const pattern of testPatterns) {
|
|
127402
|
-
if (
|
|
127686
|
+
if (basename19.includes(pattern)) {
|
|
127403
127687
|
return true;
|
|
127404
127688
|
}
|
|
127405
127689
|
}
|
|
@@ -128012,7 +128296,7 @@ ${body}`);
|
|
|
128012
128296
|
// src/council/council-evidence-writer.ts
|
|
128013
128297
|
init_zod();
|
|
128014
128298
|
init_task_file();
|
|
128015
|
-
import { appendFileSync as appendFileSync18, existsSync as
|
|
128299
|
+
import { appendFileSync as appendFileSync18, existsSync as existsSync91, mkdirSync as mkdirSync42, readFileSync as readFileSync63 } from "node:fs";
|
|
128016
128300
|
import { join as join128 } from "node:path";
|
|
128017
128301
|
var EVIDENCE_DIR2 = ".swarm/evidence";
|
|
128018
128302
|
var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
|
|
@@ -128056,7 +128340,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
|
|
|
128056
128340
|
const filePath = taskEvidencePath(workingDir, synthesis.taskId);
|
|
128057
128341
|
await _internals90.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
|
|
128058
128342
|
const existingRoot = Object.create(null);
|
|
128059
|
-
if (
|
|
128343
|
+
if (existsSync91(filePath)) {
|
|
128060
128344
|
try {
|
|
128061
128345
|
const parsed = EvidenceFileSchema.parse(JSON.parse(readFileSync63(filePath, "utf-8")));
|
|
128062
128346
|
safeAssignOwnProps(existingRoot, parsed);
|
|
@@ -128451,7 +128735,7 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
|
|
|
128451
128735
|
// src/council/criteria-store.ts
|
|
128452
128736
|
init_zod();
|
|
128453
128737
|
init_task_file();
|
|
128454
|
-
import { existsSync as
|
|
128738
|
+
import { existsSync as existsSync92, mkdirSync as mkdirSync43, readFileSync as readFileSync64 } from "node:fs";
|
|
128455
128739
|
import { join as join129 } from "node:path";
|
|
128456
128740
|
var COUNCIL_DIR = ".swarm/council";
|
|
128457
128741
|
var CouncilCriteriaSchema = exports_external.object({
|
|
@@ -128475,7 +128759,7 @@ async function writeCriteria(workingDir, taskId, criteria) {
|
|
|
128475
128759
|
}
|
|
128476
128760
|
function readCriteria(workingDir, taskId) {
|
|
128477
128761
|
const filePath = join129(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
|
|
128478
|
-
if (!
|
|
128762
|
+
if (!existsSync92(filePath))
|
|
128479
128763
|
return null;
|
|
128480
128764
|
try {
|
|
128481
128765
|
return CouncilCriteriaSchema.parse(JSON.parse(readFileSync64(filePath, "utf-8")));
|
|
@@ -130199,7 +130483,7 @@ init_zod();
|
|
|
130199
130483
|
init_utils2();
|
|
130200
130484
|
import { createHash as createHash19 } from "node:crypto";
|
|
130201
130485
|
import {
|
|
130202
|
-
existsSync as
|
|
130486
|
+
existsSync as existsSync94,
|
|
130203
130487
|
mkdirSync as mkdirSync44,
|
|
130204
130488
|
readFileSync as readFileSync67,
|
|
130205
130489
|
renameSync as renameSync30,
|
|
@@ -130250,7 +130534,7 @@ function storeLaneOutput(directory, input, now = Date.now) {
|
|
|
130250
130534
|
const absPath = validateSwarmPath(directory, relPath);
|
|
130251
130535
|
const timestamp = new Date(now()).toISOString();
|
|
130252
130536
|
try {
|
|
130253
|
-
if (
|
|
130537
|
+
if (existsSync94(absPath)) {
|
|
130254
130538
|
const existing = LaneOutputArtifactSchema.safeParse(JSON.parse(readFileSync67(absPath, "utf-8")));
|
|
130255
130539
|
if (existing.success && existing.data.digest === digest3) {
|
|
130256
130540
|
return {
|
|
@@ -130304,7 +130588,7 @@ function readLaneOutput(directory, ref) {
|
|
|
130304
130588
|
if (!REF_RE.test(ref))
|
|
130305
130589
|
return null;
|
|
130306
130590
|
const absPath = validateSwarmPath(directory, laneOutputRelativePath(ref));
|
|
130307
|
-
if (!
|
|
130591
|
+
if (!existsSync94(absPath))
|
|
130308
130592
|
return null;
|
|
130309
130593
|
let parsed;
|
|
130310
130594
|
try {
|
|
@@ -130406,7 +130690,7 @@ function writeAtomicJson(absPath, value) {
|
|
|
130406
130690
|
if (lastRenameError)
|
|
130407
130691
|
throw lastRenameError;
|
|
130408
130692
|
} finally {
|
|
130409
|
-
if (
|
|
130693
|
+
if (existsSync94(tempFile)) {
|
|
130410
130694
|
try {
|
|
130411
130695
|
unlinkSync26(tempFile);
|
|
130412
130696
|
} catch {}
|
|
@@ -135442,9 +135726,9 @@ var _internals105 = {
|
|
|
135442
135726
|
},
|
|
135443
135727
|
getTimestamp: () => new Date().toISOString(),
|
|
135444
135728
|
retireSkillFile: async (filePath) => {
|
|
135445
|
-
const { unlink:
|
|
135729
|
+
const { unlink: unlink8 } = await import("node:fs/promises");
|
|
135446
135730
|
try {
|
|
135447
|
-
await
|
|
135731
|
+
await unlink8(filePath);
|
|
135448
135732
|
return true;
|
|
135449
135733
|
} catch (err) {
|
|
135450
135734
|
const error93 = err;
|
|
@@ -137188,8 +137472,10 @@ var knowledge_add = createSwarmTool({
|
|
|
137188
137472
|
init_zod();
|
|
137189
137473
|
init_knowledge_events();
|
|
137190
137474
|
init_knowledge_store();
|
|
137475
|
+
init_skill_generator();
|
|
137191
137476
|
init_logger();
|
|
137192
137477
|
init_create_tool();
|
|
137478
|
+
import * as path175 from "node:path";
|
|
137193
137479
|
var MODES2 = ["archive", "quarantine", "purge"];
|
|
137194
137480
|
var TIERS = ["swarm", "hive"];
|
|
137195
137481
|
var knowledge_archive = createSwarmTool({
|
|
@@ -137272,6 +137558,44 @@ var knowledge_archive = createSwarmTool({
|
|
|
137272
137558
|
} else {
|
|
137273
137559
|
await recordKnowledgeEvent(directory, tombstone);
|
|
137274
137560
|
}
|
|
137561
|
+
const allArchivedIds = await getArchivedKnowledgeIds(directory);
|
|
137562
|
+
allArchivedIds.add(id);
|
|
137563
|
+
queueMicrotask(async () => {
|
|
137564
|
+
try {
|
|
137565
|
+
const affectedSkillDirs = await findSkillsBySourceKnowledgeId(directory, id);
|
|
137566
|
+
const staleSkillDirs = await findStaleSkillsBySourceKnowledgeId(directory, allArchivedIds);
|
|
137567
|
+
const allSkillDirs = new Set([
|
|
137568
|
+
...affectedSkillDirs,
|
|
137569
|
+
...staleSkillDirs
|
|
137570
|
+
]);
|
|
137571
|
+
if (allSkillDirs.size === 0)
|
|
137572
|
+
return;
|
|
137573
|
+
const slugSet = new Set;
|
|
137574
|
+
let retiredCount = 0;
|
|
137575
|
+
let staleCount = 0;
|
|
137576
|
+
for (const skillDir of allSkillDirs) {
|
|
137577
|
+
const slug = path175.basename(skillDir);
|
|
137578
|
+
if (slugSet.has(slug))
|
|
137579
|
+
continue;
|
|
137580
|
+
slugSet.add(slug);
|
|
137581
|
+
const result = await retireOrMarkStale(directory, skillDir, allArchivedIds);
|
|
137582
|
+
if (result.action === "retire")
|
|
137583
|
+
retiredCount++;
|
|
137584
|
+
else
|
|
137585
|
+
staleCount++;
|
|
137586
|
+
}
|
|
137587
|
+
const batchEvent = {
|
|
137588
|
+
type: "skill-stale-batch",
|
|
137589
|
+
skillIds: Array.from(slugSet),
|
|
137590
|
+
archivedIds: Array.from(allArchivedIds),
|
|
137591
|
+
retiredCount,
|
|
137592
|
+
staleCount
|
|
137593
|
+
};
|
|
137594
|
+
await recordKnowledgeEvent(directory, batchEvent);
|
|
137595
|
+
} catch (err) {
|
|
137596
|
+
warn(`[knowledge-archive] post-archive skill invalidation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
137597
|
+
}
|
|
137598
|
+
});
|
|
137275
137599
|
return JSON.stringify({
|
|
137276
137600
|
success: true,
|
|
137277
137601
|
id,
|
|
@@ -137288,7 +137612,7 @@ init_zod();
|
|
|
137288
137612
|
init_config();
|
|
137289
137613
|
init_knowledge_store();
|
|
137290
137614
|
init_create_tool();
|
|
137291
|
-
import { existsSync as
|
|
137615
|
+
import { existsSync as existsSync100 } from "node:fs";
|
|
137292
137616
|
var DEFAULT_LIMIT = 10;
|
|
137293
137617
|
var MAX_LESSON_LENGTH = 200;
|
|
137294
137618
|
var VALID_CATEGORIES3 = [
|
|
@@ -137364,14 +137688,14 @@ function validateLimit(limit) {
|
|
|
137364
137688
|
}
|
|
137365
137689
|
async function readSwarmKnowledge(directory) {
|
|
137366
137690
|
const swarmPath = resolveSwarmKnowledgePath(directory);
|
|
137367
|
-
if (!
|
|
137691
|
+
if (!existsSync100(swarmPath)) {
|
|
137368
137692
|
return [];
|
|
137369
137693
|
}
|
|
137370
137694
|
return readKnowledge(swarmPath);
|
|
137371
137695
|
}
|
|
137372
137696
|
async function readHiveKnowledge() {
|
|
137373
137697
|
const hivePath = resolveHiveKnowledgePath();
|
|
137374
|
-
if (!
|
|
137698
|
+
if (!existsSync100(hivePath)) {
|
|
137375
137699
|
return [];
|
|
137376
137700
|
}
|
|
137377
137701
|
return readKnowledge(hivePath);
|
|
@@ -137640,7 +137964,7 @@ var knowledge_receipt = createSwarmTool({
|
|
|
137640
137964
|
const recordedEventIds = [];
|
|
137641
137965
|
const emit2 = async (event) => {
|
|
137642
137966
|
const written = await recordKnowledgeEvent(directory, event);
|
|
137643
|
-
if (written)
|
|
137967
|
+
if (written && written.event_id !== undefined)
|
|
137644
137968
|
recordedEventIds.push(written.event_id);
|
|
137645
137969
|
};
|
|
137646
137970
|
for (const item of applied) {
|
|
@@ -137706,8 +138030,12 @@ var knowledge_receipt = createSwarmTool({
|
|
|
137706
138030
|
|
|
137707
138031
|
// src/tools/knowledge-remove.ts
|
|
137708
138032
|
init_zod();
|
|
138033
|
+
init_knowledge_events();
|
|
137709
138034
|
init_knowledge_store();
|
|
138035
|
+
init_skill_generator();
|
|
138036
|
+
init_logger();
|
|
137710
138037
|
init_create_tool();
|
|
138038
|
+
import * as path176 from "node:path";
|
|
137711
138039
|
var knowledge_remove = createSwarmTool({
|
|
137712
138040
|
description: "Delete an outdated swarm knowledge entry by ID (swarm tier only — does not affect hive). Promoted entries cannot be deleted. Double-deletion is idempotent — removing a non-existent entry returns a clear message without error.",
|
|
137713
138041
|
args: {
|
|
@@ -137767,6 +138095,44 @@ var knowledge_remove = createSwarmTool({
|
|
|
137767
138095
|
message: "entry not found"
|
|
137768
138096
|
});
|
|
137769
138097
|
}
|
|
138098
|
+
const allArchivedIds = await getArchivedKnowledgeIds(directory);
|
|
138099
|
+
allArchivedIds.add(id);
|
|
138100
|
+
queueMicrotask(async () => {
|
|
138101
|
+
try {
|
|
138102
|
+
const affectedSkillDirs = await findSkillsBySourceKnowledgeId(directory, id);
|
|
138103
|
+
const staleSkillDirs = await findStaleSkillsBySourceKnowledgeId(directory, allArchivedIds);
|
|
138104
|
+
const allSkillDirs = new Set([
|
|
138105
|
+
...affectedSkillDirs,
|
|
138106
|
+
...staleSkillDirs
|
|
138107
|
+
]);
|
|
138108
|
+
if (allSkillDirs.size === 0)
|
|
138109
|
+
return;
|
|
138110
|
+
const slugSet = new Set;
|
|
138111
|
+
let retiredCount = 0;
|
|
138112
|
+
let staleCount = 0;
|
|
138113
|
+
for (const skillDir of allSkillDirs) {
|
|
138114
|
+
const slug = path176.basename(skillDir);
|
|
138115
|
+
if (slugSet.has(slug))
|
|
138116
|
+
continue;
|
|
138117
|
+
slugSet.add(slug);
|
|
138118
|
+
const result = await retireOrMarkStale(directory, skillDir, allArchivedIds);
|
|
138119
|
+
if (result.action === "retire")
|
|
138120
|
+
retiredCount++;
|
|
138121
|
+
else
|
|
138122
|
+
staleCount++;
|
|
138123
|
+
}
|
|
138124
|
+
const batchEvent = {
|
|
138125
|
+
type: "skill-stale-batch",
|
|
138126
|
+
skillIds: Array.from(slugSet),
|
|
138127
|
+
archivedIds: Array.from(allArchivedIds),
|
|
138128
|
+
retiredCount,
|
|
138129
|
+
staleCount
|
|
138130
|
+
};
|
|
138131
|
+
await recordKnowledgeEvent(directory, batchEvent);
|
|
138132
|
+
} catch (err) {
|
|
138133
|
+
warn(`[knowledge-remove] post-purge skill invalidation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
138134
|
+
}
|
|
138135
|
+
});
|
|
137770
138136
|
return JSON.stringify({
|
|
137771
138137
|
success: true,
|
|
137772
138138
|
removed: 1,
|
|
@@ -137821,10 +138187,10 @@ var lean_turbo_acquire_locks = createSwarmTool({
|
|
|
137821
138187
|
init_zod();
|
|
137822
138188
|
init_constants();
|
|
137823
138189
|
import * as fs108 from "node:fs";
|
|
137824
|
-
import * as
|
|
138190
|
+
import * as path177 from "node:path";
|
|
137825
138191
|
init_create_tool();
|
|
137826
138192
|
function readPlanJson2(directory) {
|
|
137827
|
-
const planPath =
|
|
138193
|
+
const planPath = path177.join(directory, ".swarm", "plan.json");
|
|
137828
138194
|
if (!fs108.existsSync(planPath)) {
|
|
137829
138195
|
return null;
|
|
137830
138196
|
}
|
|
@@ -138192,12 +138558,12 @@ var lint_spec = createSwarmTool({
|
|
|
138192
138558
|
// src/tools/mutation-test.ts
|
|
138193
138559
|
init_zod();
|
|
138194
138560
|
import * as fs109 from "node:fs";
|
|
138195
|
-
import * as
|
|
138561
|
+
import * as path179 from "node:path";
|
|
138196
138562
|
|
|
138197
138563
|
// src/mutation/engine.ts
|
|
138198
138564
|
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
138199
138565
|
import { unlinkSync as unlinkSync27, writeFileSync as writeFileSync30 } from "node:fs";
|
|
138200
|
-
import * as
|
|
138566
|
+
import * as path178 from "node:path";
|
|
138201
138567
|
|
|
138202
138568
|
// src/mutation/equivalence.ts
|
|
138203
138569
|
function isStaticallyEquivalent(originalCode, mutatedCode) {
|
|
@@ -138360,7 +138726,7 @@ function validateTestCommand(testCommand) {
|
|
|
138360
138726
|
return "testCommand must not be empty";
|
|
138361
138727
|
}
|
|
138362
138728
|
const exe = testCommand[0];
|
|
138363
|
-
const base =
|
|
138729
|
+
const base = path178.basename(exe).replace(/\.(exe|cmd|bat)$/i, "");
|
|
138364
138730
|
if (!ALLOWED_TEST_RUNNERS.has(base)) {
|
|
138365
138731
|
return `testCommand executable '${exe}' is not in the allowed test runner list. Permitted runners: ${[...ALLOWED_TEST_RUNNERS].join(", ")}`;
|
|
138366
138732
|
}
|
|
@@ -138384,7 +138750,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
|
|
|
138384
138750
|
let patchFile;
|
|
138385
138751
|
try {
|
|
138386
138752
|
const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
138387
|
-
patchFile =
|
|
138753
|
+
patchFile = path178.join(workingDir, `.mutation_patch_${safeId2}.diff`);
|
|
138388
138754
|
try {
|
|
138389
138755
|
writeFileSync30(patchFile, patch.patch);
|
|
138390
138756
|
} catch (writeErr) {
|
|
@@ -138801,7 +139167,7 @@ var mutation_test = createSwarmTool({
|
|
|
138801
139167
|
];
|
|
138802
139168
|
for (const filePath of uniquePaths) {
|
|
138803
139169
|
try {
|
|
138804
|
-
const resolvedPath =
|
|
139170
|
+
const resolvedPath = path179.resolve(cwd, filePath);
|
|
138805
139171
|
sourceFiles.set(filePath, fs109.readFileSync(resolvedPath, "utf-8"));
|
|
138806
139172
|
} catch {}
|
|
138807
139173
|
}
|
|
@@ -138819,8 +139185,8 @@ var mutation_test = createSwarmTool({
|
|
|
138819
139185
|
|
|
138820
139186
|
// src/tools/parse-lane-candidates.ts
|
|
138821
139187
|
init_zod();
|
|
138822
|
-
import { existsSync as
|
|
138823
|
-
import * as
|
|
139188
|
+
import { existsSync as existsSync102 } from "node:fs";
|
|
139189
|
+
import * as path181 from "node:path";
|
|
138824
139190
|
|
|
138825
139191
|
// src/background/candidate-parser.ts
|
|
138826
139192
|
init_zod();
|
|
@@ -138831,7 +139197,7 @@ init_utils2();
|
|
|
138831
139197
|
var import_proper_lockfile10 = __toESM(require_proper_lockfile(), 1);
|
|
138832
139198
|
import { createHash as createHash24 } from "node:crypto";
|
|
138833
139199
|
import { appendFileSync as appendFileSync19, mkdirSync as mkdirSync46 } from "node:fs";
|
|
138834
|
-
import * as
|
|
139200
|
+
import * as path180 from "node:path";
|
|
138835
139201
|
var BATCH_DIGEST_ALGORITHM = "sha256";
|
|
138836
139202
|
var SidecarEnvelopeSchema = exports_external.object({
|
|
138837
139203
|
record_type: exports_external.literal("invocation"),
|
|
@@ -138986,7 +139352,7 @@ function computeBatchDigest(batchId) {
|
|
|
138986
139352
|
return createHash24(BATCH_DIGEST_ALGORITHM).update(batchId).digest("hex");
|
|
138987
139353
|
}
|
|
138988
139354
|
function sidecarRelativePath(batchDigest) {
|
|
138989
|
-
return
|
|
139355
|
+
return path180.join("lane-results", batchDigest, "candidates.jsonl");
|
|
138990
139356
|
}
|
|
138991
139357
|
function validateRecord(record3, schema, label) {
|
|
138992
139358
|
const result = schema.safeParse(record3);
|
|
@@ -138995,7 +139361,7 @@ function validateRecord(record3, schema, label) {
|
|
|
138995
139361
|
}
|
|
138996
139362
|
}
|
|
138997
139363
|
function withLockfile(lockDir, write) {
|
|
138998
|
-
const lockPath =
|
|
139364
|
+
const lockPath = path180.join(lockDir, ".lock");
|
|
138999
139365
|
const lf = import_proper_lockfile10.default;
|
|
139000
139366
|
const release = lf.lockSync(lockPath, {
|
|
139001
139367
|
realpath: false
|
|
@@ -139014,7 +139380,7 @@ function appendToSidecar(options, batchId, envelope, candidates) {
|
|
|
139014
139380
|
for (let i = 0;i < candidates.length; i++) {
|
|
139015
139381
|
validateRecord(candidates[i], SidecarCandidateSchema, `candidate[${i}]`);
|
|
139016
139382
|
}
|
|
139017
|
-
mkdirSync46(
|
|
139383
|
+
mkdirSync46(path180.dirname(absPath), { recursive: true });
|
|
139018
139384
|
const sanitizedEnvelope = sanitizeRecord(structuredClone(envelope));
|
|
139019
139385
|
const sanitizedCandidates = candidates.map((c) => sanitizeRecord(structuredClone(c)));
|
|
139020
139386
|
const lines = [JSON.stringify(sanitizedEnvelope)];
|
|
@@ -139028,7 +139394,7 @@ function appendToSidecar(options, batchId, envelope, candidates) {
|
|
|
139028
139394
|
appendFileSync19(absPath, payload, "utf-8");
|
|
139029
139395
|
};
|
|
139030
139396
|
if (options.useLockfile) {
|
|
139031
|
-
withLockfile(
|
|
139397
|
+
withLockfile(path180.dirname(absPath), doWrite);
|
|
139032
139398
|
} else {
|
|
139033
139399
|
doWrite();
|
|
139034
139400
|
}
|
|
@@ -139487,7 +139853,7 @@ function laneOutputRelativePath2(ref) {
|
|
|
139487
139853
|
if (parts.length !== 4)
|
|
139488
139854
|
return "";
|
|
139489
139855
|
const [, batchDigest, laneDigest, outputDigest] = parts;
|
|
139490
|
-
return
|
|
139856
|
+
return path181.join("lane-results", batchDigest, laneDigest, `${outputDigest}.json`);
|
|
139491
139857
|
}
|
|
139492
139858
|
var parse_lane_candidates = createSwarmTool({
|
|
139493
139859
|
description: "Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",
|
|
@@ -139522,10 +139888,10 @@ var parse_lane_candidates = createSwarmTool({
|
|
|
139522
139888
|
project_root
|
|
139523
139889
|
} = parsed.data;
|
|
139524
139890
|
if (project_root !== undefined) {
|
|
139525
|
-
const absRoot =
|
|
139526
|
-
const absDir =
|
|
139527
|
-
const rel =
|
|
139528
|
-
if (rel === ".." || rel.startsWith(`..${
|
|
139891
|
+
const absRoot = path181.resolve(project_root);
|
|
139892
|
+
const absDir = path181.resolve(directory);
|
|
139893
|
+
const rel = path181.relative(absDir, absRoot);
|
|
139894
|
+
if (rel === ".." || rel.startsWith(`..${path181.sep}`) || path181.isAbsolute(rel)) {
|
|
139529
139895
|
return JSON.stringify({
|
|
139530
139896
|
success: false,
|
|
139531
139897
|
failure_class: "invalid_args",
|
|
@@ -139545,7 +139911,7 @@ var parse_lane_candidates = createSwarmTool({
|
|
|
139545
139911
|
if (!loaded) {
|
|
139546
139912
|
const relPath = REF_RE2.test(output_ref) ? laneOutputRelativePath2(output_ref) : "";
|
|
139547
139913
|
const absPath = relPath ? validateSwarmPath(directory, relPath) : "";
|
|
139548
|
-
const fileExists = absPath ?
|
|
139914
|
+
const fileExists = absPath ? existsSync102(absPath) : false;
|
|
139549
139915
|
const artifactStatus = fileExists ? "artifact-corrupted" : "ref-not-found";
|
|
139550
139916
|
const refParts = output_ref.split(":");
|
|
139551
139917
|
const hasValidRef = REF_RE2.test(output_ref) && refParts.length === 4;
|
|
@@ -139618,22 +139984,22 @@ init_schema();
|
|
|
139618
139984
|
init_manager2();
|
|
139619
139985
|
init_task_file();
|
|
139620
139986
|
import * as fs119 from "node:fs";
|
|
139621
|
-
import * as
|
|
139987
|
+
import * as path191 from "node:path";
|
|
139622
139988
|
|
|
139623
139989
|
// src/full-auto/phase-approval.ts
|
|
139624
139990
|
init_utils2();
|
|
139625
139991
|
init_logger();
|
|
139626
139992
|
init_state3();
|
|
139627
139993
|
import * as fs110 from "node:fs";
|
|
139628
|
-
import * as
|
|
139994
|
+
import * as path182 from "node:path";
|
|
139629
139995
|
var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
|
|
139630
139996
|
function readEvidenceDir(directory, phase) {
|
|
139631
139997
|
try {
|
|
139632
|
-
const dirPath = validateSwarmPath(directory,
|
|
139998
|
+
const dirPath = validateSwarmPath(directory, path182.posix.join("evidence", String(phase)));
|
|
139633
139999
|
if (!fs110.existsSync(dirPath))
|
|
139634
140000
|
return [];
|
|
139635
140001
|
const entries = fs110.readdirSync(dirPath);
|
|
139636
|
-
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) =>
|
|
140002
|
+
return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path182.join(dirPath, e));
|
|
139637
140003
|
} catch {
|
|
139638
140004
|
return [];
|
|
139639
140005
|
}
|
|
@@ -139792,7 +140158,13 @@ async function evaluatePhaseCriticalDirectives(params) {
|
|
|
139792
140158
|
try {
|
|
139793
140159
|
const events = await readKnowledgeEvents(params.directory);
|
|
139794
140160
|
const retrievedThisPhase = events.filter((e) => e.type === "retrieved" && (!params.phaseLabel || e.phase === params.phaseLabel));
|
|
139795
|
-
const phaseStart = retrievedThisPhase.length > 0 ? retrievedThisPhase.map((e) => e.timestamp).reduce((a, b) =>
|
|
140161
|
+
const phaseStart = retrievedThisPhase.length > 0 ? retrievedThisPhase.map((e) => e.timestamp).reduce((a, b) => {
|
|
140162
|
+
if (b === undefined)
|
|
140163
|
+
return a;
|
|
140164
|
+
if (a === undefined)
|
|
140165
|
+
return b;
|
|
140166
|
+
return a < b ? a : b;
|
|
140167
|
+
}, undefined) : null;
|
|
139796
140168
|
const criticalIds = await readCriticalIdsForPhase(params.directory, params.phaseLabel);
|
|
139797
140169
|
if (criticalIds.length === 0) {
|
|
139798
140170
|
return {
|
|
@@ -139802,7 +140174,13 @@ async function evaluatePhaseCriticalDirectives(params) {
|
|
|
139802
140174
|
failedClosed: false
|
|
139803
140175
|
};
|
|
139804
140176
|
}
|
|
139805
|
-
const receipts = events.filter(isReceipt).filter((r) =>
|
|
140177
|
+
const receipts = events.filter(isReceipt).filter((r) => {
|
|
140178
|
+
if (phaseStart === null || phaseStart === undefined)
|
|
140179
|
+
return true;
|
|
140180
|
+
if (r.timestamp === undefined)
|
|
140181
|
+
return false;
|
|
140182
|
+
return r.timestamp >= phaseStart;
|
|
140183
|
+
}).map((r) => ({
|
|
139806
140184
|
type: r.type,
|
|
139807
140185
|
knowledge_id: r.knowledge_id,
|
|
139808
140186
|
timestamp: r.timestamp,
|
|
@@ -139888,16 +140266,16 @@ init_plan_schema();
|
|
|
139888
140266
|
init_ledger();
|
|
139889
140267
|
init_manager();
|
|
139890
140268
|
import * as fs111 from "node:fs";
|
|
139891
|
-
import * as
|
|
140269
|
+
import * as path183 from "node:path";
|
|
139892
140270
|
async function writeCheckpoint(directory) {
|
|
139893
140271
|
try {
|
|
139894
140272
|
const plan = await loadPlan(directory);
|
|
139895
140273
|
if (!plan)
|
|
139896
140274
|
return;
|
|
139897
|
-
const swarmDir =
|
|
140275
|
+
const swarmDir = path183.join(directory, ".swarm");
|
|
139898
140276
|
fs111.mkdirSync(swarmDir, { recursive: true });
|
|
139899
|
-
const jsonPath =
|
|
139900
|
-
const mdPath =
|
|
140277
|
+
const jsonPath = path183.join(swarmDir, "SWARM_PLAN.json");
|
|
140278
|
+
const mdPath = path183.join(swarmDir, "SWARM_PLAN.md");
|
|
139901
140279
|
fs111.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
|
|
139902
140280
|
const md = derivePlanMarkdown(plan);
|
|
139903
140281
|
fs111.writeFileSync(mdPath, md, "utf8");
|
|
@@ -140402,7 +140780,7 @@ init_state();
|
|
|
140402
140780
|
// src/turbo/lean/phase-ready.ts
|
|
140403
140781
|
init_file_locks();
|
|
140404
140782
|
import * as fs112 from "node:fs";
|
|
140405
|
-
import * as
|
|
140783
|
+
import * as path184 from "node:path";
|
|
140406
140784
|
init_state4();
|
|
140407
140785
|
var DEFAULT_CONFIG3 = {
|
|
140408
140786
|
phase_reviewer: true,
|
|
@@ -140411,7 +140789,7 @@ var DEFAULT_CONFIG3 = {
|
|
|
140411
140789
|
};
|
|
140412
140790
|
function defaultReadPlanJson(dir) {
|
|
140413
140791
|
try {
|
|
140414
|
-
const planPath =
|
|
140792
|
+
const planPath = path184.join(dir, ".swarm", "plan.json");
|
|
140415
140793
|
if (!fs112.existsSync(planPath))
|
|
140416
140794
|
return null;
|
|
140417
140795
|
const raw = fs112.readFileSync(planPath, "utf-8");
|
|
@@ -140426,7 +140804,7 @@ function defaultReadPlanJson(dir) {
|
|
|
140426
140804
|
}
|
|
140427
140805
|
function readReviewerEvidenceFromFile(directory, phase) {
|
|
140428
140806
|
try {
|
|
140429
|
-
const evidencePath =
|
|
140807
|
+
const evidencePath = path184.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
|
|
140430
140808
|
if (!fs112.existsSync(evidencePath)) {
|
|
140431
140809
|
return null;
|
|
140432
140810
|
}
|
|
@@ -140446,7 +140824,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
|
|
|
140446
140824
|
}
|
|
140447
140825
|
function readCriticEvidenceFromFile(directory, phase) {
|
|
140448
140826
|
try {
|
|
140449
|
-
const evidencePath =
|
|
140827
|
+
const evidencePath = path184.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
|
|
140450
140828
|
if (!fs112.existsSync(evidencePath)) {
|
|
140451
140829
|
return null;
|
|
140452
140830
|
}
|
|
@@ -140465,7 +140843,7 @@ function readCriticEvidenceFromFile(directory, phase) {
|
|
|
140465
140843
|
}
|
|
140466
140844
|
}
|
|
140467
140845
|
function listLaneEvidenceSync(directory, phase) {
|
|
140468
|
-
const evidenceDir =
|
|
140846
|
+
const evidenceDir = path184.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
140469
140847
|
let entries;
|
|
140470
140848
|
try {
|
|
140471
140849
|
entries = fs112.readdirSync(evidenceDir);
|
|
@@ -140535,7 +140913,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
140535
140913
|
...DEFAULT_CONFIG3,
|
|
140536
140914
|
...actualConfig
|
|
140537
140915
|
};
|
|
140538
|
-
const statePath =
|
|
140916
|
+
const statePath = path184.join(directory, ".swarm", "turbo-state.json");
|
|
140539
140917
|
if (!fs112.existsSync(statePath)) {
|
|
140540
140918
|
return {
|
|
140541
140919
|
ok: false,
|
|
@@ -140723,7 +141101,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
|
|
|
140723
141101
|
}
|
|
140724
141102
|
}
|
|
140725
141103
|
if (mergedConfig.integrated_diff_required) {
|
|
140726
|
-
const evidencePath =
|
|
141104
|
+
const evidencePath = path184.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
|
|
140727
141105
|
let hasDiff = false;
|
|
140728
141106
|
try {
|
|
140729
141107
|
const content = fs112.readFileSync(evidencePath, "utf-8");
|
|
@@ -140889,7 +141267,7 @@ async function runCompletionVerifyGate(ctx) {
|
|
|
140889
141267
|
// src/tools/phase-complete/gates/drift-gate.ts
|
|
140890
141268
|
init_effective_spec();
|
|
140891
141269
|
import * as fs113 from "node:fs";
|
|
140892
|
-
import * as
|
|
141270
|
+
import * as path185 from "node:path";
|
|
140893
141271
|
|
|
140894
141272
|
// src/tools/phase-complete/gates/gate-helpers.ts
|
|
140895
141273
|
init_qa_gate_profile();
|
|
@@ -140938,7 +141316,7 @@ async function runDriftGate(ctx) {
|
|
|
140938
141316
|
}
|
|
140939
141317
|
let phaseType;
|
|
140940
141318
|
try {
|
|
140941
|
-
const planPath =
|
|
141319
|
+
const planPath = path185.join(dir, ".swarm", "plan.json");
|
|
140942
141320
|
if (fs113.existsSync(planPath)) {
|
|
140943
141321
|
const planRaw = fs113.readFileSync(planPath, "utf-8");
|
|
140944
141322
|
const plan = JSON.parse(planRaw);
|
|
@@ -140957,7 +141335,7 @@ async function runDriftGate(ctx) {
|
|
|
140957
141335
|
};
|
|
140958
141336
|
}
|
|
140959
141337
|
try {
|
|
140960
|
-
const driftEvidencePath =
|
|
141338
|
+
const driftEvidencePath = path185.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
|
|
140961
141339
|
let driftVerdictFound = false;
|
|
140962
141340
|
let driftVerdictApproved = false;
|
|
140963
141341
|
try {
|
|
@@ -140998,7 +141376,7 @@ async function runDriftGate(ctx) {
|
|
|
140998
141376
|
let incompleteTaskCount = 0;
|
|
140999
141377
|
let planParseable = false;
|
|
141000
141378
|
try {
|
|
141001
|
-
const planPath =
|
|
141379
|
+
const planPath = path185.join(dir, ".swarm", "plan.json");
|
|
141002
141380
|
if (fs113.existsSync(planPath)) {
|
|
141003
141381
|
const planRaw = fs113.readFileSync(planPath, "utf-8");
|
|
141004
141382
|
const plan = JSON.parse(planRaw);
|
|
@@ -141077,7 +141455,7 @@ async function runDriftGate(ctx) {
|
|
|
141077
141455
|
}
|
|
141078
141456
|
// src/tools/phase-complete/gates/final-council-gate.ts
|
|
141079
141457
|
import * as fs114 from "node:fs";
|
|
141080
|
-
import * as
|
|
141458
|
+
import * as path186 from "node:path";
|
|
141081
141459
|
async function runFinalCouncilGate(ctx) {
|
|
141082
141460
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
141083
141461
|
let finalCouncilEnabled = false;
|
|
@@ -141100,7 +141478,7 @@ async function runFinalCouncilGate(ctx) {
|
|
|
141100
141478
|
if (lastPhaseId !== undefined && phase === lastPhaseId) {
|
|
141101
141479
|
if (preamble.effectiveGates?.final_council === true) {
|
|
141102
141480
|
finalCouncilEnabled = true;
|
|
141103
|
-
const fcPath =
|
|
141481
|
+
const fcPath = path186.join(dir, ".swarm", "evidence", "final-council.json");
|
|
141104
141482
|
let fcVerdictFound = false;
|
|
141105
141483
|
let _fcVerdict;
|
|
141106
141484
|
try {
|
|
@@ -141254,13 +141632,13 @@ async function runFinalCouncilGate(ctx) {
|
|
|
141254
141632
|
}
|
|
141255
141633
|
// src/tools/phase-complete/gates/hallucination-gate.ts
|
|
141256
141634
|
import * as fs115 from "node:fs";
|
|
141257
|
-
import * as
|
|
141635
|
+
import * as path187 from "node:path";
|
|
141258
141636
|
async function runHallucinationGate(ctx) {
|
|
141259
141637
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
141260
141638
|
try {
|
|
141261
141639
|
const preamble = await resolveGatePreamble(dir, sessionID);
|
|
141262
141640
|
if (preamble.resolved && preamble.effectiveGates?.hallucination_guard === true) {
|
|
141263
|
-
const hgPath =
|
|
141641
|
+
const hgPath = path187.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
|
|
141264
141642
|
let hgVerdictFound = false;
|
|
141265
141643
|
let hgVerdictApproved = false;
|
|
141266
141644
|
try {
|
|
@@ -141318,13 +141696,13 @@ async function runHallucinationGate(ctx) {
|
|
|
141318
141696
|
}
|
|
141319
141697
|
// src/tools/phase-complete/gates/mutation-gate.ts
|
|
141320
141698
|
import * as fs116 from "node:fs";
|
|
141321
|
-
import * as
|
|
141699
|
+
import * as path188 from "node:path";
|
|
141322
141700
|
async function runMutationGate(ctx) {
|
|
141323
141701
|
const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
|
|
141324
141702
|
try {
|
|
141325
141703
|
const preamble = await resolveGatePreamble(dir, sessionID);
|
|
141326
141704
|
if (preamble.resolved && preamble.effectiveGates?.mutation_test === true) {
|
|
141327
|
-
const mgPath =
|
|
141705
|
+
const mgPath = path188.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
|
|
141328
141706
|
let mgVerdictFound = false;
|
|
141329
141707
|
let mgVerdict;
|
|
141330
141708
|
try {
|
|
@@ -141382,7 +141760,7 @@ async function runMutationGate(ctx) {
|
|
|
141382
141760
|
}
|
|
141383
141761
|
// src/tools/phase-complete/gates/phase-council-gate.ts
|
|
141384
141762
|
import * as fs117 from "node:fs";
|
|
141385
|
-
import * as
|
|
141763
|
+
import * as path189 from "node:path";
|
|
141386
141764
|
async function runPhaseCouncilGate(ctx) {
|
|
141387
141765
|
const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
|
|
141388
141766
|
const gateWarnings = [];
|
|
@@ -141391,7 +141769,7 @@ async function runPhaseCouncilGate(ctx) {
|
|
|
141391
141769
|
const preamble = await resolveGatePreamble(dir, sessionID);
|
|
141392
141770
|
if (preamble.resolved && preamble.effectiveGates?.phase_council === true && pluginConfig.council?.enabled === true) {
|
|
141393
141771
|
councilModeEnabled = true;
|
|
141394
|
-
const pcPath =
|
|
141772
|
+
const pcPath = path189.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
|
|
141395
141773
|
let pcVerdictFound = false;
|
|
141396
141774
|
let _pcVerdict;
|
|
141397
141775
|
let pcQuorumSize;
|
|
@@ -141959,7 +142337,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
|
|
|
141959
142337
|
}
|
|
141960
142338
|
if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
|
|
141961
142339
|
try {
|
|
141962
|
-
const projectName =
|
|
142340
|
+
const projectName = path191.basename(dir);
|
|
141963
142341
|
const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig, {
|
|
141964
142342
|
llmDelegate: createCuratorLLMDelegate(dir, "phase", sessionID),
|
|
141965
142343
|
enrichmentQuota: {
|
|
@@ -142536,7 +142914,7 @@ init_utils();
|
|
|
142536
142914
|
init_bun_compat();
|
|
142537
142915
|
init_create_tool();
|
|
142538
142916
|
import * as fs120 from "node:fs";
|
|
142539
|
-
import * as
|
|
142917
|
+
import * as path192 from "node:path";
|
|
142540
142918
|
var MAX_OUTPUT_BYTES7 = 52428800;
|
|
142541
142919
|
var AUDIT_TIMEOUT_MS = 120000;
|
|
142542
142920
|
function isValidEcosystem(value) {
|
|
@@ -142564,16 +142942,16 @@ function validateArgs3(args2) {
|
|
|
142564
142942
|
function detectEcosystems(directory) {
|
|
142565
142943
|
const ecosystems = [];
|
|
142566
142944
|
const cwd = directory;
|
|
142567
|
-
if (fs120.existsSync(
|
|
142945
|
+
if (fs120.existsSync(path192.join(cwd, "package.json"))) {
|
|
142568
142946
|
ecosystems.push("npm");
|
|
142569
142947
|
}
|
|
142570
|
-
if (fs120.existsSync(
|
|
142948
|
+
if (fs120.existsSync(path192.join(cwd, "pyproject.toml")) || fs120.existsSync(path192.join(cwd, "requirements.txt"))) {
|
|
142571
142949
|
ecosystems.push("pip");
|
|
142572
142950
|
}
|
|
142573
|
-
if (fs120.existsSync(
|
|
142951
|
+
if (fs120.existsSync(path192.join(cwd, "Cargo.toml"))) {
|
|
142574
142952
|
ecosystems.push("cargo");
|
|
142575
142953
|
}
|
|
142576
|
-
if (fs120.existsSync(
|
|
142954
|
+
if (fs120.existsSync(path192.join(cwd, "go.mod"))) {
|
|
142577
142955
|
ecosystems.push("go");
|
|
142578
142956
|
}
|
|
142579
142957
|
try {
|
|
@@ -142582,13 +142960,13 @@ function detectEcosystems(directory) {
|
|
|
142582
142960
|
ecosystems.push("dotnet");
|
|
142583
142961
|
}
|
|
142584
142962
|
} catch {}
|
|
142585
|
-
if (fs120.existsSync(
|
|
142963
|
+
if (fs120.existsSync(path192.join(cwd, "Gemfile")) || fs120.existsSync(path192.join(cwd, "Gemfile.lock"))) {
|
|
142586
142964
|
ecosystems.push("ruby");
|
|
142587
142965
|
}
|
|
142588
|
-
if (fs120.existsSync(
|
|
142966
|
+
if (fs120.existsSync(path192.join(cwd, "pubspec.yaml"))) {
|
|
142589
142967
|
ecosystems.push("dart");
|
|
142590
142968
|
}
|
|
142591
|
-
if (fs120.existsSync(
|
|
142969
|
+
if (fs120.existsSync(path192.join(cwd, "composer.lock"))) {
|
|
142592
142970
|
ecosystems.push("composer");
|
|
142593
142971
|
}
|
|
142594
142972
|
return ecosystems;
|
|
@@ -143725,7 +144103,7 @@ var pkg_audit = createSwarmTool({
|
|
|
143725
144103
|
init_zod();
|
|
143726
144104
|
init_manager2();
|
|
143727
144105
|
import * as fs121 from "node:fs";
|
|
143728
|
-
import * as
|
|
144106
|
+
import * as path193 from "node:path";
|
|
143729
144107
|
init_utils();
|
|
143730
144108
|
init_create_tool();
|
|
143731
144109
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
@@ -143848,7 +144226,7 @@ function isScaffoldFile(filePath) {
|
|
|
143848
144226
|
if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
|
|
143849
144227
|
return true;
|
|
143850
144228
|
}
|
|
143851
|
-
const filename =
|
|
144229
|
+
const filename = path193.basename(filePath);
|
|
143852
144230
|
if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
|
|
143853
144231
|
return true;
|
|
143854
144232
|
}
|
|
@@ -143865,7 +144243,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
143865
144243
|
if (regex.test(normalizedPath)) {
|
|
143866
144244
|
return true;
|
|
143867
144245
|
}
|
|
143868
|
-
const filename =
|
|
144246
|
+
const filename = path193.basename(filePath);
|
|
143869
144247
|
const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
|
|
143870
144248
|
if (filenameRegex.test(filename)) {
|
|
143871
144249
|
return true;
|
|
@@ -143874,7 +144252,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
|
|
|
143874
144252
|
return false;
|
|
143875
144253
|
}
|
|
143876
144254
|
function isParserSupported(filePath) {
|
|
143877
|
-
const ext =
|
|
144255
|
+
const ext = path193.extname(filePath).toLowerCase();
|
|
143878
144256
|
return SUPPORTED_PARSER_EXTENSIONS.has(ext);
|
|
143879
144257
|
}
|
|
143880
144258
|
function isPlanFile(filePath) {
|
|
@@ -144121,9 +144499,9 @@ async function placeholderScan(input, directory) {
|
|
|
144121
144499
|
let filesScanned = 0;
|
|
144122
144500
|
const filesWithFindings = new Set;
|
|
144123
144501
|
for (const filePath of changed_files) {
|
|
144124
|
-
const fullPath =
|
|
144125
|
-
const resolvedDirectory =
|
|
144126
|
-
if (!fullPath.startsWith(resolvedDirectory +
|
|
144502
|
+
const fullPath = path193.isAbsolute(filePath) ? filePath : path193.resolve(directory, filePath);
|
|
144503
|
+
const resolvedDirectory = path193.resolve(directory);
|
|
144504
|
+
if (!fullPath.startsWith(resolvedDirectory + path193.sep) && fullPath !== resolvedDirectory) {
|
|
144127
144505
|
continue;
|
|
144128
144506
|
}
|
|
144129
144507
|
if (!fs121.existsSync(fullPath)) {
|
|
@@ -144132,7 +144510,7 @@ async function placeholderScan(input, directory) {
|
|
|
144132
144510
|
if (isAllowedByGlobs(filePath, allow_globs)) {
|
|
144133
144511
|
continue;
|
|
144134
144512
|
}
|
|
144135
|
-
const relativeFilePath =
|
|
144513
|
+
const relativeFilePath = path193.relative(directory, fullPath).replace(/\\/g, "/");
|
|
144136
144514
|
if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
|
|
144137
144515
|
continue;
|
|
144138
144516
|
}
|
|
@@ -144205,7 +144583,7 @@ var placeholder_scan = createSwarmTool({
|
|
|
144205
144583
|
|
|
144206
144584
|
// src/tools/pre-check-batch.ts
|
|
144207
144585
|
import * as fs125 from "node:fs";
|
|
144208
|
-
import * as
|
|
144586
|
+
import * as path197 from "node:path";
|
|
144209
144587
|
init_zod();
|
|
144210
144588
|
init_manager2();
|
|
144211
144589
|
init_utils();
|
|
@@ -144346,7 +144724,7 @@ init_zod();
|
|
|
144346
144724
|
init_manager2();
|
|
144347
144725
|
init_detector();
|
|
144348
144726
|
import * as fs124 from "node:fs";
|
|
144349
|
-
import * as
|
|
144727
|
+
import * as path196 from "node:path";
|
|
144350
144728
|
import { extname as extname19 } from "node:path";
|
|
144351
144729
|
|
|
144352
144730
|
// src/sast/rules/c.ts
|
|
@@ -145056,7 +145434,7 @@ function executeRulesSync(filePath, content, language) {
|
|
|
145056
145434
|
// src/sast/semgrep.ts
|
|
145057
145435
|
import * as child_process15 from "node:child_process";
|
|
145058
145436
|
import * as fs122 from "node:fs";
|
|
145059
|
-
import * as
|
|
145437
|
+
import * as path194 from "node:path";
|
|
145060
145438
|
var semgrepAvailableCache = null;
|
|
145061
145439
|
var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
|
|
145062
145440
|
var DEFAULT_TIMEOUT_MS4 = 30000;
|
|
@@ -145343,7 +145721,7 @@ async function runSemgrep(options) {
|
|
|
145343
145721
|
}
|
|
145344
145722
|
function getRulesDirectory(projectRoot) {
|
|
145345
145723
|
if (projectRoot) {
|
|
145346
|
-
return
|
|
145724
|
+
return path194.resolve(projectRoot, DEFAULT_RULES_DIR);
|
|
145347
145725
|
}
|
|
145348
145726
|
return DEFAULT_RULES_DIR;
|
|
145349
145727
|
}
|
|
@@ -145364,24 +145742,24 @@ init_create_tool();
|
|
|
145364
145742
|
init_utils2();
|
|
145365
145743
|
import * as crypto13 from "node:crypto";
|
|
145366
145744
|
import * as fs123 from "node:fs";
|
|
145367
|
-
import * as
|
|
145745
|
+
import * as path195 from "node:path";
|
|
145368
145746
|
var BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
145369
145747
|
var MAX_BASELINE_FINDINGS = 2000;
|
|
145370
145748
|
var MAX_BASELINE_BYTES = 2 * 1048576;
|
|
145371
145749
|
var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
|
|
145372
145750
|
function normalizeFindingPath(directory, file3) {
|
|
145373
|
-
const resolved =
|
|
145374
|
-
const rel =
|
|
145751
|
+
const resolved = path195.isAbsolute(file3) ? file3 : path195.resolve(directory, file3);
|
|
145752
|
+
const rel = path195.relative(path195.resolve(directory), resolved);
|
|
145375
145753
|
return rel.replace(/\\/g, "/");
|
|
145376
145754
|
}
|
|
145377
145755
|
function baselineRelPath(phase) {
|
|
145378
|
-
return
|
|
145756
|
+
return path195.join("evidence", String(phase), "sast-baseline.json");
|
|
145379
145757
|
}
|
|
145380
145758
|
function tempRelPath(phase) {
|
|
145381
|
-
return
|
|
145759
|
+
return path195.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
|
|
145382
145760
|
}
|
|
145383
145761
|
function lockRelPath(phase) {
|
|
145384
|
-
return
|
|
145762
|
+
return path195.join("evidence", String(phase), "sast-baseline.json.lock");
|
|
145385
145763
|
}
|
|
145386
145764
|
function getLine(lines, idx) {
|
|
145387
145765
|
if (idx < 0 || idx >= lines.length)
|
|
@@ -145502,8 +145880,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
|
|
|
145502
145880
|
message: e instanceof Error ? e.message : "Path validation failed"
|
|
145503
145881
|
};
|
|
145504
145882
|
}
|
|
145505
|
-
fs123.mkdirSync(
|
|
145506
|
-
fs123.mkdirSync(
|
|
145883
|
+
fs123.mkdirSync(path195.dirname(baselinePath), { recursive: true });
|
|
145884
|
+
fs123.mkdirSync(path195.dirname(tempPath), { recursive: true });
|
|
145507
145885
|
const releaseLock = await acquireLock2(lockPath);
|
|
145508
145886
|
try {
|
|
145509
145887
|
let existing = null;
|
|
@@ -145776,9 +146154,9 @@ async function sastScan(input, directory, config3) {
|
|
|
145776
146154
|
_filesSkipped++;
|
|
145777
146155
|
continue;
|
|
145778
146156
|
}
|
|
145779
|
-
const resolvedPath =
|
|
145780
|
-
const resolvedDirectory =
|
|
145781
|
-
if (!resolvedPath.startsWith(resolvedDirectory +
|
|
146157
|
+
const resolvedPath = path196.isAbsolute(filePath) ? filePath : path196.resolve(directory, filePath);
|
|
146158
|
+
const resolvedDirectory = path196.resolve(directory);
|
|
146159
|
+
if (!resolvedPath.startsWith(resolvedDirectory + path196.sep) && resolvedPath !== resolvedDirectory) {
|
|
145782
146160
|
_filesSkipped++;
|
|
145783
146161
|
continue;
|
|
145784
146162
|
}
|
|
@@ -146093,18 +146471,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
|
|
|
146093
146471
|
let resolved;
|
|
146094
146472
|
const isWinAbs = isWindowsAbsolutePath(inputPath);
|
|
146095
146473
|
if (isWinAbs) {
|
|
146096
|
-
resolved =
|
|
146097
|
-
} else if (
|
|
146098
|
-
resolved =
|
|
146474
|
+
resolved = path197.win32.resolve(inputPath);
|
|
146475
|
+
} else if (path197.isAbsolute(inputPath)) {
|
|
146476
|
+
resolved = path197.resolve(inputPath);
|
|
146099
146477
|
} else {
|
|
146100
|
-
resolved =
|
|
146478
|
+
resolved = path197.resolve(baseDir, inputPath);
|
|
146101
146479
|
}
|
|
146102
|
-
const workspaceResolved =
|
|
146480
|
+
const workspaceResolved = path197.resolve(workspaceDir);
|
|
146103
146481
|
let relative38;
|
|
146104
146482
|
if (isWinAbs) {
|
|
146105
|
-
relative38 =
|
|
146483
|
+
relative38 = path197.win32.relative(workspaceResolved, resolved);
|
|
146106
146484
|
} else {
|
|
146107
|
-
relative38 =
|
|
146485
|
+
relative38 = path197.relative(workspaceResolved, resolved);
|
|
146108
146486
|
}
|
|
146109
146487
|
if (relative38.startsWith("..")) {
|
|
146110
146488
|
return "path traversal detected";
|
|
@@ -146169,7 +146547,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
|
|
|
146169
146547
|
if (typeof file3 !== "string") {
|
|
146170
146548
|
continue;
|
|
146171
146549
|
}
|
|
146172
|
-
const resolvedPath =
|
|
146550
|
+
const resolvedPath = path197.resolve(file3);
|
|
146173
146551
|
const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
|
|
146174
146552
|
if (validationError) {
|
|
146175
146553
|
continue;
|
|
@@ -146326,7 +146704,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
146326
146704
|
skippedFiles++;
|
|
146327
146705
|
continue;
|
|
146328
146706
|
}
|
|
146329
|
-
const resolvedPath =
|
|
146707
|
+
const resolvedPath = path197.resolve(file3);
|
|
146330
146708
|
const validationError = validatePath(resolvedPath, directory, directory);
|
|
146331
146709
|
if (validationError) {
|
|
146332
146710
|
skippedFiles++;
|
|
@@ -146344,7 +146722,7 @@ async function runSecretscanWithFiles(files, directory) {
|
|
|
146344
146722
|
};
|
|
146345
146723
|
}
|
|
146346
146724
|
for (const file3 of validatedFiles) {
|
|
146347
|
-
const ext =
|
|
146725
|
+
const ext = path197.extname(file3).toLowerCase();
|
|
146348
146726
|
if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
|
|
146349
146727
|
skippedFiles++;
|
|
146350
146728
|
continue;
|
|
@@ -146563,7 +146941,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
|
|
|
146563
146941
|
const preexistingFindings = [];
|
|
146564
146942
|
for (const finding of findings) {
|
|
146565
146943
|
const filePath = finding.location.file;
|
|
146566
|
-
const normalised =
|
|
146944
|
+
const normalised = path197.relative(directory, filePath).replace(/\\/g, "/");
|
|
146567
146945
|
const changedLines = changedLineRanges.get(normalised);
|
|
146568
146946
|
if (changedLines?.has(finding.location.line)) {
|
|
146569
146947
|
newFindings.push(finding);
|
|
@@ -146614,7 +146992,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
|
|
|
146614
146992
|
warn(`pre_check_batch: Invalid file path: ${file3}`);
|
|
146615
146993
|
continue;
|
|
146616
146994
|
}
|
|
146617
|
-
changedFiles.push(
|
|
146995
|
+
changedFiles.push(path197.resolve(directory, file3));
|
|
146618
146996
|
}
|
|
146619
146997
|
if (changedFiles.length === 0) {
|
|
146620
146998
|
warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
|
|
@@ -146815,9 +147193,9 @@ var pre_check_batch = createSwarmTool({
|
|
|
146815
147193
|
};
|
|
146816
147194
|
return JSON.stringify(errorResult, null, 2);
|
|
146817
147195
|
}
|
|
146818
|
-
const resolvedDirectory =
|
|
146819
|
-
const workspaceAnchor =
|
|
146820
|
-
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor +
|
|
147196
|
+
const resolvedDirectory = path197.resolve(typedArgs.directory);
|
|
147197
|
+
const workspaceAnchor = path197.resolve(directory);
|
|
147198
|
+
if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path197.sep)) {
|
|
146821
147199
|
const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
|
|
146822
147200
|
const subDirResult = {
|
|
146823
147201
|
gates_passed: false,
|
|
@@ -146871,7 +147249,7 @@ var pre_check_batch = createSwarmTool({
|
|
|
146871
147249
|
init_zod();
|
|
146872
147250
|
init_path_security();
|
|
146873
147251
|
init_create_tool();
|
|
146874
|
-
import * as
|
|
147252
|
+
import * as path198 from "node:path";
|
|
146875
147253
|
var VALID_ACTIONS = [
|
|
146876
147254
|
"build",
|
|
146877
147255
|
"importers",
|
|
@@ -146900,7 +147278,7 @@ function validateFile(p) {
|
|
|
146900
147278
|
return "file contains control characters";
|
|
146901
147279
|
if (containsPathTraversal(p))
|
|
146902
147280
|
return "file contains path traversal";
|
|
146903
|
-
if (
|
|
147281
|
+
if (path198.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
|
|
146904
147282
|
return "file must be a workspace-relative path, not absolute";
|
|
146905
147283
|
}
|
|
146906
147284
|
return null;
|
|
@@ -146923,8 +147301,8 @@ function ok(action, payload) {
|
|
|
146923
147301
|
}
|
|
146924
147302
|
function toRelativeGraphPath(input, workspaceRoot) {
|
|
146925
147303
|
const normalized = input.replace(/\\/g, "/");
|
|
146926
|
-
if (
|
|
146927
|
-
const rel =
|
|
147304
|
+
if (path198.isAbsolute(normalized)) {
|
|
147305
|
+
const rel = path198.relative(workspaceRoot, normalized).replace(/\\/g, "/");
|
|
146928
147306
|
return normalizeGraphPath(rel);
|
|
146929
147307
|
}
|
|
146930
147308
|
return normalizeGraphPath(normalized);
|
|
@@ -147120,10 +147498,10 @@ var repo_map = createSwarmTool({
|
|
|
147120
147498
|
maxTokens: 4000
|
|
147121
147499
|
});
|
|
147122
147500
|
const toRel = (p) => {
|
|
147123
|
-
if (!
|
|
147501
|
+
if (!path198.isAbsolute(p))
|
|
147124
147502
|
return p.replace(/\\/g, "/");
|
|
147125
147503
|
try {
|
|
147126
|
-
return
|
|
147504
|
+
return path198.relative(directory, p).replace(/\\/g, "/");
|
|
147127
147505
|
} catch {
|
|
147128
147506
|
return p;
|
|
147129
147507
|
}
|
|
@@ -147173,7 +147551,7 @@ init_zod();
|
|
|
147173
147551
|
init_effective_spec();
|
|
147174
147552
|
init_create_tool();
|
|
147175
147553
|
import * as fs126 from "node:fs";
|
|
147176
|
-
import * as
|
|
147554
|
+
import * as path199 from "node:path";
|
|
147177
147555
|
var EVIDENCE_DIR4 = ".swarm/evidence";
|
|
147178
147556
|
var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
|
|
147179
147557
|
var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
|
|
@@ -147241,7 +147619,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
147241
147619
|
return [];
|
|
147242
147620
|
}
|
|
147243
147621
|
for (const entry of entries) {
|
|
147244
|
-
const entryPath =
|
|
147622
|
+
const entryPath = path199.join(evidenceDir, entry);
|
|
147245
147623
|
try {
|
|
147246
147624
|
const stat14 = fs126.statSync(entryPath);
|
|
147247
147625
|
if (!stat14.isDirectory()) {
|
|
@@ -147257,11 +147635,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
147257
147635
|
if (entryPhase !== String(phase)) {
|
|
147258
147636
|
continue;
|
|
147259
147637
|
}
|
|
147260
|
-
const evidenceFilePath =
|
|
147638
|
+
const evidenceFilePath = path199.join(entryPath, "evidence.json");
|
|
147261
147639
|
try {
|
|
147262
|
-
const resolvedPath =
|
|
147263
|
-
const evidenceDirResolved =
|
|
147264
|
-
if (!resolvedPath.startsWith(evidenceDirResolved +
|
|
147640
|
+
const resolvedPath = path199.resolve(evidenceFilePath);
|
|
147641
|
+
const evidenceDirResolved = path199.resolve(evidenceDir);
|
|
147642
|
+
if (!resolvedPath.startsWith(evidenceDirResolved + path199.sep)) {
|
|
147265
147643
|
continue;
|
|
147266
147644
|
}
|
|
147267
147645
|
const stat14 = fs126.lstatSync(evidenceFilePath);
|
|
@@ -147295,7 +147673,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
147295
147673
|
if (Array.isArray(diffEntry.files_changed)) {
|
|
147296
147674
|
for (const file3 of diffEntry.files_changed) {
|
|
147297
147675
|
if (typeof file3 === "string") {
|
|
147298
|
-
touchedFiles.add(
|
|
147676
|
+
touchedFiles.add(path199.resolve(cwd, file3));
|
|
147299
147677
|
}
|
|
147300
147678
|
}
|
|
147301
147679
|
}
|
|
@@ -147308,8 +147686,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
|
|
|
147308
147686
|
}
|
|
147309
147687
|
function searchFileForKeywords(filePath, keywords, cwd) {
|
|
147310
147688
|
try {
|
|
147311
|
-
const resolvedPath =
|
|
147312
|
-
const cwdResolved =
|
|
147689
|
+
const resolvedPath = path199.resolve(filePath);
|
|
147690
|
+
const cwdResolved = path199.resolve(cwd);
|
|
147313
147691
|
if (!resolvedPath.startsWith(cwdResolved)) {
|
|
147314
147692
|
return false;
|
|
147315
147693
|
}
|
|
@@ -147468,7 +147846,7 @@ var req_coverage = createSwarmTool({
|
|
|
147468
147846
|
message: "No FR requirements found in spec.md"
|
|
147469
147847
|
}, null, 2);
|
|
147470
147848
|
}
|
|
147471
|
-
const evidenceDir =
|
|
147849
|
+
const evidenceDir = path199.join(cwd, EVIDENCE_DIR4);
|
|
147472
147850
|
const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
|
|
147473
147851
|
const analyzedRequirements = [];
|
|
147474
147852
|
let coveredCount = 0;
|
|
@@ -147494,7 +147872,7 @@ var req_coverage = createSwarmTool({
|
|
|
147494
147872
|
requirements: analyzedRequirements
|
|
147495
147873
|
};
|
|
147496
147874
|
const reportFilename = `req-coverage-phase-${phase}.json`;
|
|
147497
|
-
const reportPath =
|
|
147875
|
+
const reportPath = path199.join(evidenceDir, reportFilename);
|
|
147498
147876
|
try {
|
|
147499
147877
|
if (!fs126.existsSync(evidenceDir)) {
|
|
147500
147878
|
fs126.mkdirSync(evidenceDir, { recursive: true });
|
|
@@ -147649,7 +148027,7 @@ init_plan_schema();
|
|
|
147649
148027
|
init_qa_gate_profile();
|
|
147650
148028
|
init_file_locks();
|
|
147651
148029
|
import * as fs127 from "node:fs";
|
|
147652
|
-
import * as
|
|
148030
|
+
import * as path200 from "node:path";
|
|
147653
148031
|
init_ledger();
|
|
147654
148032
|
init_manager();
|
|
147655
148033
|
init_effective_spec();
|
|
@@ -147731,8 +148109,8 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
147731
148109
|
};
|
|
147732
148110
|
}
|
|
147733
148111
|
if (args2.working_directory && fallbackDir) {
|
|
147734
|
-
const resolvedTarget =
|
|
147735
|
-
const resolvedRoot =
|
|
148112
|
+
const resolvedTarget = path200.resolve(args2.working_directory);
|
|
148113
|
+
const resolvedRoot = path200.resolve(fallbackDir);
|
|
147736
148114
|
let fallbackExists = false;
|
|
147737
148115
|
try {
|
|
147738
148116
|
fs127.accessSync(resolvedRoot, fs127.constants.F_OK);
|
|
@@ -147741,7 +148119,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
147741
148119
|
fallbackExists = false;
|
|
147742
148120
|
}
|
|
147743
148121
|
if (fallbackExists) {
|
|
147744
|
-
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot +
|
|
148122
|
+
const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path200.sep);
|
|
147745
148123
|
if (isSubdirectory) {
|
|
147746
148124
|
return {
|
|
147747
148125
|
success: false,
|
|
@@ -147772,7 +148150,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
147772
148150
|
specHash = spec.hash;
|
|
147773
148151
|
}
|
|
147774
148152
|
if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
|
|
147775
|
-
const contextPath =
|
|
148153
|
+
const contextPath = path200.join(targetWorkspace, ".swarm", "context.md");
|
|
147776
148154
|
let contextContent = "";
|
|
147777
148155
|
try {
|
|
147778
148156
|
contextContent = await fs127.promises.readFile(contextPath, "utf8");
|
|
@@ -148062,7 +148440,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
148062
148440
|
}
|
|
148063
148441
|
await writeCheckpoint(dir).catch(() => {});
|
|
148064
148442
|
try {
|
|
148065
|
-
const markerPath =
|
|
148443
|
+
const markerPath = path200.join(dir, ".swarm", ".plan-write-marker");
|
|
148066
148444
|
const marker = JSON.stringify({
|
|
148067
148445
|
source: "save_plan",
|
|
148068
148446
|
timestamp: new Date().toISOString(),
|
|
@@ -148085,7 +148463,7 @@ async function executeSavePlan(args2, fallbackDir) {
|
|
|
148085
148463
|
return {
|
|
148086
148464
|
success: true,
|
|
148087
148465
|
message: "Plan saved successfully",
|
|
148088
|
-
plan_path:
|
|
148466
|
+
plan_path: path200.join(dir, ".swarm", "plan.json"),
|
|
148089
148467
|
phases_count: plan.phases.length,
|
|
148090
148468
|
tasks_count: tasksCount,
|
|
148091
148469
|
...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
|
|
@@ -148138,8 +148516,8 @@ var save_plan = createSwarmTool({
|
|
|
148138
148516
|
confirm_identity_change: exports_external.boolean().optional().describe("When true, allows overwriting an existing plan that has a different " + "identity (swarm_id + title). Without this flag, save_plan rejects " + "with PLAN_IDENTITY_MISMATCH if the identity differs."),
|
|
148139
148517
|
execution_profile: exports_external.object({
|
|
148140
148518
|
parallelization_enabled: exports_external.boolean().optional().describe("When true, enables parallel task dispatch for this plan. Default false (serial)."),
|
|
148141
|
-
max_concurrent_tasks: exports_external.number().int().min(1).max(64).optional().describe("Maximum tasks that may run concurrently when parallelization is enabled. Default
|
|
148142
|
-
council_parallel: exports_external.boolean().optional().describe("When true, council review phases may run in parallel. Default
|
|
148519
|
+
max_concurrent_tasks: exports_external.number().int().min(1).max(64).optional().describe("Maximum tasks that may run concurrently when parallelization is enabled. Default 10."),
|
|
148520
|
+
council_parallel: exports_external.boolean().optional().describe("When true, council review phases may run in parallel. Default true."),
|
|
148143
148521
|
locked: exports_external.boolean().optional().describe("When true, locks the profile — future save_plan calls that include " + "execution_profile will be rejected (fail-closed). " + "Unlock by resetting the plan (reset_statuses: true)."),
|
|
148144
148522
|
auto_proceed: exports_external.boolean().optional().describe("When true, the architect advances to the next phase automatically without asking for confirmation. Default false.")
|
|
148145
148523
|
}).optional().describe("Architect-facing concurrency controls. Once locked, cannot be changed without resetting. " + "Omit to preserve the existing profile.")
|
|
@@ -148153,7 +148531,7 @@ var save_plan = createSwarmTool({
|
|
|
148153
148531
|
init_zod();
|
|
148154
148532
|
init_manager2();
|
|
148155
148533
|
import * as fs128 from "node:fs";
|
|
148156
|
-
import * as
|
|
148534
|
+
import * as path201 from "node:path";
|
|
148157
148535
|
|
|
148158
148536
|
// src/sbom/detectors/index.ts
|
|
148159
148537
|
init_utils();
|
|
@@ -149003,7 +149381,7 @@ function findManifestFiles(rootDir) {
|
|
|
149003
149381
|
try {
|
|
149004
149382
|
const entries = fs128.readdirSync(dir, { withFileTypes: true });
|
|
149005
149383
|
for (const entry of entries) {
|
|
149006
|
-
const fullPath =
|
|
149384
|
+
const fullPath = path201.join(dir, entry.name);
|
|
149007
149385
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
|
|
149008
149386
|
continue;
|
|
149009
149387
|
}
|
|
@@ -149012,7 +149390,7 @@ function findManifestFiles(rootDir) {
|
|
|
149012
149390
|
} else if (entry.isFile()) {
|
|
149013
149391
|
for (const pattern of patterns) {
|
|
149014
149392
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
149015
|
-
manifestFiles.push(
|
|
149393
|
+
manifestFiles.push(path201.relative(rootDir, fullPath));
|
|
149016
149394
|
break;
|
|
149017
149395
|
}
|
|
149018
149396
|
}
|
|
@@ -149030,11 +149408,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
149030
149408
|
try {
|
|
149031
149409
|
const entries = fs128.readdirSync(dir, { withFileTypes: true });
|
|
149032
149410
|
for (const entry of entries) {
|
|
149033
|
-
const fullPath =
|
|
149411
|
+
const fullPath = path201.join(dir, entry.name);
|
|
149034
149412
|
if (entry.isFile()) {
|
|
149035
149413
|
for (const pattern of patterns) {
|
|
149036
149414
|
if (simpleGlobToRegex(pattern).test(entry.name)) {
|
|
149037
|
-
found.push(
|
|
149415
|
+
found.push(path201.relative(workingDir, fullPath));
|
|
149038
149416
|
break;
|
|
149039
149417
|
}
|
|
149040
149418
|
}
|
|
@@ -149047,11 +149425,11 @@ function findManifestFilesInDirs(directories, workingDir) {
|
|
|
149047
149425
|
function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
|
|
149048
149426
|
const dirs = new Set;
|
|
149049
149427
|
for (const file3 of changedFiles) {
|
|
149050
|
-
let currentDir =
|
|
149428
|
+
let currentDir = path201.dirname(file3);
|
|
149051
149429
|
while (true) {
|
|
149052
|
-
if (currentDir && currentDir !== "." && currentDir !==
|
|
149053
|
-
dirs.add(
|
|
149054
|
-
const parent =
|
|
149430
|
+
if (currentDir && currentDir !== "." && currentDir !== path201.sep) {
|
|
149431
|
+
dirs.add(path201.join(workingDir, currentDir));
|
|
149432
|
+
const parent = path201.dirname(currentDir);
|
|
149055
149433
|
if (parent === currentDir)
|
|
149056
149434
|
break;
|
|
149057
149435
|
currentDir = parent;
|
|
@@ -149135,7 +149513,7 @@ var sbom_generate = createSwarmTool({
|
|
|
149135
149513
|
const changedFiles = obj.changed_files;
|
|
149136
149514
|
const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
|
|
149137
149515
|
const workingDir = directory;
|
|
149138
|
-
const outputDir =
|
|
149516
|
+
const outputDir = path201.isAbsolute(relativeOutputDir) ? relativeOutputDir : path201.join(workingDir, relativeOutputDir);
|
|
149139
149517
|
let manifestFiles = [];
|
|
149140
149518
|
if (scope === "all") {
|
|
149141
149519
|
manifestFiles = findManifestFiles(workingDir);
|
|
@@ -149158,7 +149536,7 @@ var sbom_generate = createSwarmTool({
|
|
|
149158
149536
|
const processedFiles = [];
|
|
149159
149537
|
for (const manifestFile of manifestFiles) {
|
|
149160
149538
|
try {
|
|
149161
|
-
const fullPath =
|
|
149539
|
+
const fullPath = path201.isAbsolute(manifestFile) ? manifestFile : path201.join(workingDir, manifestFile);
|
|
149162
149540
|
if (!fs128.existsSync(fullPath)) {
|
|
149163
149541
|
continue;
|
|
149164
149542
|
}
|
|
@@ -149175,7 +149553,7 @@ var sbom_generate = createSwarmTool({
|
|
|
149175
149553
|
const bom = generateCycloneDX(allComponents);
|
|
149176
149554
|
const bomJson = serializeCycloneDX(bom);
|
|
149177
149555
|
const filename = generateSbomFilename();
|
|
149178
|
-
const outputPath =
|
|
149556
|
+
const outputPath = path201.join(outputDir, filename);
|
|
149179
149557
|
fs128.writeFileSync(outputPath, bomJson, "utf-8");
|
|
149180
149558
|
const verdict = processedFiles.length > 0 ? "pass" : "pass";
|
|
149181
149559
|
try {
|
|
@@ -149220,7 +149598,7 @@ var sbom_generate = createSwarmTool({
|
|
|
149220
149598
|
init_zod();
|
|
149221
149599
|
init_create_tool();
|
|
149222
149600
|
import * as fs129 from "node:fs";
|
|
149223
|
-
import * as
|
|
149601
|
+
import * as path202 from "node:path";
|
|
149224
149602
|
var SPEC_CANDIDATES = [
|
|
149225
149603
|
"openapi.json",
|
|
149226
149604
|
"openapi.yaml",
|
|
@@ -149252,12 +149630,12 @@ function normalizePath5(p) {
|
|
|
149252
149630
|
}
|
|
149253
149631
|
function discoverSpecFile(cwd, specFileArg) {
|
|
149254
149632
|
if (specFileArg) {
|
|
149255
|
-
const resolvedPath =
|
|
149256
|
-
const normalizedCwd = cwd.endsWith(
|
|
149633
|
+
const resolvedPath = path202.resolve(cwd, specFileArg);
|
|
149634
|
+
const normalizedCwd = cwd.endsWith(path202.sep) ? cwd : cwd + path202.sep;
|
|
149257
149635
|
if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
|
|
149258
149636
|
throw new Error("Invalid spec_file: path traversal detected");
|
|
149259
149637
|
}
|
|
149260
|
-
const ext =
|
|
149638
|
+
const ext = path202.extname(resolvedPath).toLowerCase();
|
|
149261
149639
|
if (!ALLOWED_EXTENSIONS.includes(ext)) {
|
|
149262
149640
|
throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
|
|
149263
149641
|
}
|
|
@@ -149271,7 +149649,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
149271
149649
|
return resolvedPath;
|
|
149272
149650
|
}
|
|
149273
149651
|
for (const candidate of SPEC_CANDIDATES) {
|
|
149274
|
-
const candidatePath =
|
|
149652
|
+
const candidatePath = path202.resolve(cwd, candidate);
|
|
149275
149653
|
if (fs129.existsSync(candidatePath)) {
|
|
149276
149654
|
const stats2 = fs129.statSync(candidatePath);
|
|
149277
149655
|
if (stats2.size <= MAX_SPEC_SIZE) {
|
|
@@ -149283,7 +149661,7 @@ function discoverSpecFile(cwd, specFileArg) {
|
|
|
149283
149661
|
}
|
|
149284
149662
|
function parseSpec(specFile) {
|
|
149285
149663
|
const content = fs129.readFileSync(specFile, "utf-8");
|
|
149286
|
-
const ext =
|
|
149664
|
+
const ext = path202.extname(specFile).toLowerCase();
|
|
149287
149665
|
if (ext === ".json") {
|
|
149288
149666
|
return parseJsonSpec(content);
|
|
149289
149667
|
}
|
|
@@ -149359,7 +149737,7 @@ function extractRoutes2(cwd) {
|
|
|
149359
149737
|
return;
|
|
149360
149738
|
}
|
|
149361
149739
|
for (const entry of entries) {
|
|
149362
|
-
const fullPath =
|
|
149740
|
+
const fullPath = path202.join(dir, entry.name);
|
|
149363
149741
|
if (entry.isSymbolicLink()) {
|
|
149364
149742
|
continue;
|
|
149365
149743
|
}
|
|
@@ -149369,7 +149747,7 @@ function extractRoutes2(cwd) {
|
|
|
149369
149747
|
}
|
|
149370
149748
|
walkDir2(fullPath);
|
|
149371
149749
|
} else if (entry.isFile()) {
|
|
149372
|
-
const ext =
|
|
149750
|
+
const ext = path202.extname(entry.name).toLowerCase();
|
|
149373
149751
|
const baseName = entry.name.toLowerCase();
|
|
149374
149752
|
if (![".ts", ".js", ".mjs"].includes(ext)) {
|
|
149375
149753
|
continue;
|
|
@@ -149538,7 +149916,7 @@ init_bun_compat();
|
|
|
149538
149916
|
init_path_security();
|
|
149539
149917
|
init_create_tool();
|
|
149540
149918
|
import * as fs130 from "node:fs";
|
|
149541
|
-
import * as
|
|
149919
|
+
import * as path203 from "node:path";
|
|
149542
149920
|
var DEFAULT_MAX_RESULTS = 100;
|
|
149543
149921
|
var DEFAULT_MAX_LINES = 200;
|
|
149544
149922
|
var REGEX_TIMEOUT_MS = 5000;
|
|
@@ -149574,11 +149952,11 @@ function containsWindowsAttacks4(str) {
|
|
|
149574
149952
|
}
|
|
149575
149953
|
function isPathInWorkspace3(filePath, workspace) {
|
|
149576
149954
|
try {
|
|
149577
|
-
const resolvedPath =
|
|
149955
|
+
const resolvedPath = path203.resolve(workspace, filePath);
|
|
149578
149956
|
const realWorkspace = fs130.realpathSync(workspace);
|
|
149579
149957
|
const realResolvedPath = fs130.realpathSync(resolvedPath);
|
|
149580
|
-
const relativePath =
|
|
149581
|
-
if (relativePath.startsWith("..") ||
|
|
149958
|
+
const relativePath = path203.relative(realWorkspace, realResolvedPath);
|
|
149959
|
+
if (relativePath.startsWith("..") || path203.isAbsolute(relativePath)) {
|
|
149582
149960
|
return false;
|
|
149583
149961
|
}
|
|
149584
149962
|
return true;
|
|
@@ -149591,11 +149969,11 @@ function validatePathForRead2(filePath, workspace) {
|
|
|
149591
149969
|
}
|
|
149592
149970
|
function findRgInEnvPath() {
|
|
149593
149971
|
const searchPath = process.env.PATH ?? "";
|
|
149594
|
-
for (const dir of searchPath.split(
|
|
149972
|
+
for (const dir of searchPath.split(path203.delimiter)) {
|
|
149595
149973
|
if (!dir)
|
|
149596
149974
|
continue;
|
|
149597
149975
|
const isWindows = process.platform === "win32";
|
|
149598
|
-
const candidate =
|
|
149976
|
+
const candidate = path203.join(dir, isWindows ? "rg.exe" : "rg");
|
|
149599
149977
|
if (fs130.existsSync(candidate))
|
|
149600
149978
|
return candidate;
|
|
149601
149979
|
}
|
|
@@ -149725,8 +150103,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
|
|
|
149725
150103
|
try {
|
|
149726
150104
|
const entries = fs130.readdirSync(dir, { withFileTypes: true });
|
|
149727
150105
|
for (const entry of entries) {
|
|
149728
|
-
const fullPath =
|
|
149729
|
-
const relativePath =
|
|
150106
|
+
const fullPath = path203.join(dir, entry.name);
|
|
150107
|
+
const relativePath = path203.relative(workspace, fullPath);
|
|
149730
150108
|
if (!validatePathForRead2(fullPath, workspace)) {
|
|
149731
150109
|
continue;
|
|
149732
150110
|
}
|
|
@@ -149767,7 +150145,7 @@ async function fallbackSearch(opts) {
|
|
|
149767
150145
|
const matches = [];
|
|
149768
150146
|
let total = 0;
|
|
149769
150147
|
for (const file3 of files) {
|
|
149770
|
-
const fullPath =
|
|
150148
|
+
const fullPath = path203.join(opts.workspace, file3);
|
|
149771
150149
|
if (!validatePathForRead2(fullPath, opts.workspace)) {
|
|
149772
150150
|
continue;
|
|
149773
150151
|
}
|
|
@@ -150199,7 +150577,7 @@ init_config();
|
|
|
150199
150577
|
init_schema();
|
|
150200
150578
|
init_create_tool();
|
|
150201
150579
|
import { mkdir as mkdir34, rename as rename14, writeFile as writeFile23 } from "node:fs/promises";
|
|
150202
|
-
import * as
|
|
150580
|
+
import * as path204 from "node:path";
|
|
150203
150581
|
var MAX_SPEC_BYTES2 = 256 * 1024;
|
|
150204
150582
|
var spec_write = createSwarmTool({
|
|
150205
150583
|
description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
|
|
@@ -150240,8 +150618,8 @@ var spec_write = createSwarmTool({
|
|
|
150240
150618
|
reason: 'spec must contain at least one top-level "# Heading"'
|
|
150241
150619
|
}, null, 2);
|
|
150242
150620
|
}
|
|
150243
|
-
const target =
|
|
150244
|
-
await mkdir34(
|
|
150621
|
+
const target = path204.join(directory, ".swarm", "spec.md");
|
|
150622
|
+
await mkdir34(path204.dirname(target), { recursive: true });
|
|
150245
150623
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
150246
150624
|
let finalContent = content;
|
|
150247
150625
|
if (mode === "append") {
|
|
@@ -150266,6 +150644,120 @@ ${content}
|
|
|
150266
150644
|
}
|
|
150267
150645
|
});
|
|
150268
150646
|
|
|
150647
|
+
// src/tools/stale-reconciliation.ts
|
|
150648
|
+
init_zod();
|
|
150649
|
+
init_knowledge_store();
|
|
150650
|
+
init_skill_generator();
|
|
150651
|
+
init_create_tool();
|
|
150652
|
+
import { existsSync as existsSync115 } from "node:fs";
|
|
150653
|
+
import { readdir as readdir12, readFile as readFile33 } from "node:fs/promises";
|
|
150654
|
+
import { join as join163 } from "node:path";
|
|
150655
|
+
var run_stale_reconciliation = createSwarmTool({
|
|
150656
|
+
description: "Reconcile skills against the knowledge store. clear=false: mark skills stale when source knowledge is archived or deleted. clear=true: clear stale.marker on affected active skills (proposal files under .swarm/skills/proposals are scanned but not modified — they are drafts, not yet active skills).",
|
|
150657
|
+
args: {
|
|
150658
|
+
clear: exports_external.boolean().optional().default(false).describe("If true, clear stale markers for affected skills. If false (default), mark affected skills stale.")
|
|
150659
|
+
},
|
|
150660
|
+
execute: async (args2, directory) => {
|
|
150661
|
+
if (typeof directory !== "string" || !directory) {
|
|
150662
|
+
return JSON.stringify({ found: 0, skills: [] }, null, 2);
|
|
150663
|
+
}
|
|
150664
|
+
const archivedIds = await _internals116.getArchivedKnowledgeIds(directory);
|
|
150665
|
+
const archivedSet = new Set(archivedIds);
|
|
150666
|
+
const allKnownIds = new Set;
|
|
150667
|
+
const swarmPath = _internals116.resolveSwarmKnowledgePath(directory);
|
|
150668
|
+
const hivePath = _internals116.resolveHiveKnowledgePath();
|
|
150669
|
+
try {
|
|
150670
|
+
const swarmEntries = await _internals116.readKnowledge(swarmPath);
|
|
150671
|
+
for (const e of swarmEntries)
|
|
150672
|
+
allKnownIds.add(e.id);
|
|
150673
|
+
} catch {}
|
|
150674
|
+
try {
|
|
150675
|
+
const hiveEntries = await _internals116.readKnowledge(hivePath);
|
|
150676
|
+
for (const e of hiveEntries)
|
|
150677
|
+
allKnownIds.add(e.id);
|
|
150678
|
+
} catch {}
|
|
150679
|
+
const skillEntries = [];
|
|
150680
|
+
for (const dir of [
|
|
150681
|
+
join163(directory, ".opencode", "skills", "generated"),
|
|
150682
|
+
join163(directory, ".swarm", "skills", "proposals")
|
|
150683
|
+
]) {
|
|
150684
|
+
if (!_internals116.existsSync(dir))
|
|
150685
|
+
continue;
|
|
150686
|
+
const entries = await _internals116.readdir(dir, { withFileTypes: true });
|
|
150687
|
+
for (const entry of entries) {
|
|
150688
|
+
if (entry.isDirectory()) {
|
|
150689
|
+
skillEntries.push({
|
|
150690
|
+
slug: entry.name,
|
|
150691
|
+
path: join163(dir, entry.name),
|
|
150692
|
+
isProposal: false
|
|
150693
|
+
});
|
|
150694
|
+
} else if (entry.name.endsWith(".md")) {
|
|
150695
|
+
const slug = entry.name.replace(/\.md$/, "");
|
|
150696
|
+
skillEntries.push({
|
|
150697
|
+
slug,
|
|
150698
|
+
path: join163(dir, entry.name),
|
|
150699
|
+
isProposal: true
|
|
150700
|
+
});
|
|
150701
|
+
}
|
|
150702
|
+
}
|
|
150703
|
+
}
|
|
150704
|
+
const results = [];
|
|
150705
|
+
for (const { slug, path: path205, isProposal } of skillEntries) {
|
|
150706
|
+
const skillMdPath = isProposal ? path205 : join163(path205, "SKILL.md");
|
|
150707
|
+
if (!_internals116.existsSync(skillMdPath))
|
|
150708
|
+
continue;
|
|
150709
|
+
const content = await _internals116.readFile(skillMdPath, "utf-8");
|
|
150710
|
+
const fm = _internals116.parseDraftFrontmatter(content);
|
|
150711
|
+
const sourceIds = fm?.sourceKnowledgeIds ?? [];
|
|
150712
|
+
if (sourceIds.length === 0)
|
|
150713
|
+
continue;
|
|
150714
|
+
const affected = sourceIds.filter((id) => archivedSet.has(id) || !allKnownIds.has(id));
|
|
150715
|
+
if (affected.length === 0)
|
|
150716
|
+
continue;
|
|
150717
|
+
if (args2.clear) {
|
|
150718
|
+
if (!isProposal) {
|
|
150719
|
+
const markerPath = join163(path205, "stale.marker");
|
|
150720
|
+
if (_internals116.existsSync(markerPath)) {
|
|
150721
|
+
try {
|
|
150722
|
+
await _internals116.clearSkillStale(path205);
|
|
150723
|
+
results.push({
|
|
150724
|
+
slug,
|
|
150725
|
+
reason: affected.join(", "),
|
|
150726
|
+
action: "cleared"
|
|
150727
|
+
});
|
|
150728
|
+
} catch {}
|
|
150729
|
+
}
|
|
150730
|
+
}
|
|
150731
|
+
} else {
|
|
150732
|
+
if (!isProposal) {
|
|
150733
|
+
try {
|
|
150734
|
+
await _internals116.retireOrMarkStale(directory, path205, archivedSet);
|
|
150735
|
+
results.push({
|
|
150736
|
+
slug,
|
|
150737
|
+
reason: affected.join(", "),
|
|
150738
|
+
action: "marked_stale"
|
|
150739
|
+
});
|
|
150740
|
+
} catch {}
|
|
150741
|
+
}
|
|
150742
|
+
}
|
|
150743
|
+
}
|
|
150744
|
+
return JSON.stringify({ found: results.length, skills: results }, null, 2);
|
|
150745
|
+
}
|
|
150746
|
+
});
|
|
150747
|
+
var _internals116 = {
|
|
150748
|
+
run_stale_reconciliation,
|
|
150749
|
+
clearSkillStale,
|
|
150750
|
+
retireOrMarkStale,
|
|
150751
|
+
parseDraftFrontmatter,
|
|
150752
|
+
getArchivedKnowledgeIds,
|
|
150753
|
+
readKnowledge,
|
|
150754
|
+
resolveSwarmKnowledgePath,
|
|
150755
|
+
resolveHiveKnowledgePath,
|
|
150756
|
+
readdir: readdir12,
|
|
150757
|
+
readFile: readFile33,
|
|
150758
|
+
existsSync: existsSync115
|
|
150759
|
+
};
|
|
150760
|
+
|
|
150269
150761
|
// src/tools/submit-phase-council-verdicts.ts
|
|
150270
150762
|
init_zod();
|
|
150271
150763
|
init_loader();
|
|
@@ -150277,7 +150769,7 @@ import {
|
|
|
150277
150769
|
unlinkSync as unlinkSync29,
|
|
150278
150770
|
writeFileSync as writeFileSync36
|
|
150279
150771
|
} from "node:fs";
|
|
150280
|
-
import
|
|
150772
|
+
import path205 from "node:path";
|
|
150281
150773
|
init_create_tool();
|
|
150282
150774
|
init_resolve_working_directory();
|
|
150283
150775
|
var VerdictSchema2 = exports_external.object({
|
|
@@ -150444,7 +150936,7 @@ var submit_phase_council_verdicts = createSwarmTool({
|
|
|
150444
150936
|
}
|
|
150445
150937
|
});
|
|
150446
150938
|
function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
150447
|
-
const mutationGatePath =
|
|
150939
|
+
const mutationGatePath = path205.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
|
|
150448
150940
|
try {
|
|
150449
150941
|
const raw = readFileSync90(mutationGatePath, "utf-8");
|
|
150450
150942
|
const parsed = JSON.parse(raw);
|
|
@@ -150506,9 +150998,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
|
|
|
150506
150998
|
}
|
|
150507
150999
|
}
|
|
150508
151000
|
function writePhaseCouncilEvidence(workingDir, synthesis, provenance) {
|
|
150509
|
-
const evidenceDir =
|
|
151001
|
+
const evidenceDir = path205.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
|
|
150510
151002
|
mkdirSync51(evidenceDir, { recursive: true });
|
|
150511
|
-
const evidenceFile =
|
|
151003
|
+
const evidenceFile = path205.join(evidenceDir, "phase-council.json");
|
|
150512
151004
|
const evidenceBundle = {
|
|
150513
151005
|
entries: [
|
|
150514
151006
|
{
|
|
@@ -150571,7 +151063,7 @@ init_zod();
|
|
|
150571
151063
|
init_path_security();
|
|
150572
151064
|
init_create_tool();
|
|
150573
151065
|
import * as fs131 from "node:fs";
|
|
150574
|
-
import * as
|
|
151066
|
+
import * as path206 from "node:path";
|
|
150575
151067
|
var BINARY_EXTENSIONS2 = new Set([
|
|
150576
151068
|
".png",
|
|
150577
151069
|
".jpg",
|
|
@@ -150607,14 +151099,14 @@ function containsWindowsAttacks5(str) {
|
|
|
150607
151099
|
}
|
|
150608
151100
|
function isPathInWorkspace4(filePath, workspace) {
|
|
150609
151101
|
try {
|
|
150610
|
-
const resolvedPath =
|
|
151102
|
+
const resolvedPath = path206.resolve(workspace, filePath);
|
|
150611
151103
|
if (!fs131.existsSync(resolvedPath)) {
|
|
150612
151104
|
return true;
|
|
150613
151105
|
}
|
|
150614
151106
|
const realWorkspace = fs131.realpathSync(workspace);
|
|
150615
151107
|
const realResolvedPath = fs131.realpathSync(resolvedPath);
|
|
150616
|
-
const relativePath =
|
|
150617
|
-
if (relativePath.startsWith("..") ||
|
|
151108
|
+
const relativePath = path206.relative(realWorkspace, realResolvedPath);
|
|
151109
|
+
if (relativePath.startsWith("..") || path206.isAbsolute(relativePath)) {
|
|
150618
151110
|
return false;
|
|
150619
151111
|
}
|
|
150620
151112
|
return true;
|
|
@@ -150729,7 +151221,7 @@ function arraysEqual2(a, b) {
|
|
|
150729
151221
|
return true;
|
|
150730
151222
|
}
|
|
150731
151223
|
function isBinaryFile4(filePath) {
|
|
150732
|
-
const ext =
|
|
151224
|
+
const ext = path206.extname(filePath).toLowerCase();
|
|
150733
151225
|
return BINARY_EXTENSIONS2.has(ext);
|
|
150734
151226
|
}
|
|
150735
151227
|
function splitDiffLines(content) {
|
|
@@ -150934,7 +151426,7 @@ var suggestPatch = createSwarmTool({
|
|
|
150934
151426
|
});
|
|
150935
151427
|
continue;
|
|
150936
151428
|
}
|
|
150937
|
-
const fullPath =
|
|
151429
|
+
const fullPath = path206.resolve(directory, change.file);
|
|
150938
151430
|
if (!fs131.existsSync(fullPath)) {
|
|
150939
151431
|
errors5.push({
|
|
150940
151432
|
success: false,
|
|
@@ -151029,7 +151521,7 @@ var suggestPatch = createSwarmTool({
|
|
|
151029
151521
|
const unifiedParts = [];
|
|
151030
151522
|
for (const [file3, entries] of fileGroups) {
|
|
151031
151523
|
entries.sort((a, b) => a.contextMatch.startLineIndex - b.contextMatch.startLineIndex);
|
|
151032
|
-
const entryFullPath =
|
|
151524
|
+
const entryFullPath = path206.resolve(directory, file3);
|
|
151033
151525
|
let entryContent;
|
|
151034
151526
|
try {
|
|
151035
151527
|
entryContent = fs131.readFileSync(entryFullPath, "utf-8");
|
|
@@ -151230,7 +151722,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
151230
151722
|
evidenceRefs: exports_external.array(exports_external.string().min(1).max(500)).max(20).optional().describe("Evidence refs such as files, commits, test outputs, or URLs")
|
|
151231
151723
|
},
|
|
151232
151724
|
execute: async (args2, directory, ctx) => {
|
|
151233
|
-
const { config: config3 } =
|
|
151725
|
+
const { config: config3 } = _internals117.loadPluginConfigWithMeta(directory);
|
|
151234
151726
|
if (config3.memory?.enabled !== true) {
|
|
151235
151727
|
return JSON.stringify({
|
|
151236
151728
|
success: false,
|
|
@@ -151246,7 +151738,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
151246
151738
|
});
|
|
151247
151739
|
}
|
|
151248
151740
|
const agent = getContextAgent3(ctx);
|
|
151249
|
-
const gateway =
|
|
151741
|
+
const gateway = _internals117.createMemoryGateway({
|
|
151250
151742
|
directory,
|
|
151251
151743
|
sessionID: ctx?.sessionID,
|
|
151252
151744
|
agentRole: agent,
|
|
@@ -151271,7 +151763,7 @@ var swarm_memory_propose = createSwarmTool({
|
|
|
151271
151763
|
}
|
|
151272
151764
|
}
|
|
151273
151765
|
});
|
|
151274
|
-
var
|
|
151766
|
+
var _internals117 = {
|
|
151275
151767
|
loadPluginConfigWithMeta,
|
|
151276
151768
|
createMemoryGateway
|
|
151277
151769
|
};
|
|
@@ -151309,7 +151801,7 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
151309
151801
|
maxItems: exports_external.number().int().min(1).max(20).optional().describe("Maximum memories to return")
|
|
151310
151802
|
},
|
|
151311
151803
|
execute: async (args2, directory, ctx) => {
|
|
151312
|
-
const { config: config3 } =
|
|
151804
|
+
const { config: config3 } = _internals118.loadPluginConfigWithMeta(directory);
|
|
151313
151805
|
if (config3.memory?.enabled !== true) {
|
|
151314
151806
|
return JSON.stringify({
|
|
151315
151807
|
success: false,
|
|
@@ -151325,7 +151817,7 @@ var swarm_memory_recall = createSwarmTool({
|
|
|
151325
151817
|
});
|
|
151326
151818
|
}
|
|
151327
151819
|
const agent = getContextAgent4(ctx);
|
|
151328
|
-
const gateway =
|
|
151820
|
+
const gateway = _internals118.createMemoryGateway({
|
|
151329
151821
|
directory,
|
|
151330
151822
|
sessionID: ctx?.sessionID,
|
|
151331
151823
|
agentRole: agent,
|
|
@@ -151358,7 +151850,7 @@ var RecallArgsSchema = exports_external.object({
|
|
|
151358
151850
|
kinds: exports_external.array(exports_external.enum(MEMORY_KINDS2)).optional(),
|
|
151359
151851
|
maxItems: exports_external.number().int().min(1).max(20).optional()
|
|
151360
151852
|
});
|
|
151361
|
-
var
|
|
151853
|
+
var _internals118 = {
|
|
151362
151854
|
loadPluginConfigWithMeta,
|
|
151363
151855
|
createMemoryGateway
|
|
151364
151856
|
};
|
|
@@ -151371,7 +151863,7 @@ function getContextAgent4(ctx) {
|
|
|
151371
151863
|
|
|
151372
151864
|
// src/tools/syntax-check.ts
|
|
151373
151865
|
import * as fs132 from "node:fs";
|
|
151374
|
-
import * as
|
|
151866
|
+
import * as path207 from "node:path";
|
|
151375
151867
|
init_zod();
|
|
151376
151868
|
init_manager2();
|
|
151377
151869
|
init_detector();
|
|
@@ -151443,7 +151935,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
151443
151935
|
if (languages?.length) {
|
|
151444
151936
|
const lowerLangs = languages.map((l) => l.toLowerCase());
|
|
151445
151937
|
filesToCheck = filesToCheck.filter((file3) => {
|
|
151446
|
-
const ext =
|
|
151938
|
+
const ext = path207.extname(file3.path).toLowerCase();
|
|
151447
151939
|
const langDef = getLanguageForExtension(ext);
|
|
151448
151940
|
const fileProfile = getProfileForFile(file3.path);
|
|
151449
151941
|
const langId = fileProfile?.id || langDef?.id;
|
|
@@ -151453,7 +151945,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
151453
151945
|
const { loadGrammar: loadGrammar2 } = await Promise.resolve().then(() => (init_runtime(), exports_runtime));
|
|
151454
151946
|
async function checkOneFile(fileInfo) {
|
|
151455
151947
|
const { path: filePath } = fileInfo;
|
|
151456
|
-
const fullPath =
|
|
151948
|
+
const fullPath = path207.isAbsolute(filePath) ? filePath : path207.join(directory, filePath);
|
|
151457
151949
|
const result = {
|
|
151458
151950
|
path: filePath,
|
|
151459
151951
|
language: "",
|
|
@@ -151500,7 +151992,7 @@ async function syntaxCheck(input, directory, config3) {
|
|
|
151500
151992
|
result.skipped_reason = "binary_file";
|
|
151501
151993
|
return { result, counted: false, failed: false, skipped: true };
|
|
151502
151994
|
}
|
|
151503
|
-
const ext =
|
|
151995
|
+
const ext = path207.extname(filePath).toLowerCase();
|
|
151504
151996
|
const langDef = getLanguageForExtension(ext);
|
|
151505
151997
|
result.language = profile?.id || langDef?.id || "unknown";
|
|
151506
151998
|
const errors5 = extractSyntaxErrors(parser, content);
|
|
@@ -151612,7 +152104,7 @@ init_utils();
|
|
|
151612
152104
|
init_create_tool();
|
|
151613
152105
|
init_path_security();
|
|
151614
152106
|
import * as fs133 from "node:fs";
|
|
151615
|
-
import * as
|
|
152107
|
+
import * as path208 from "node:path";
|
|
151616
152108
|
var MAX_TEXT_LENGTH = 200;
|
|
151617
152109
|
var MAX_FILE_SIZE_BYTES10 = 1024 * 1024;
|
|
151618
152110
|
var SUPPORTED_EXTENSIONS4 = new Set([
|
|
@@ -151678,9 +152170,9 @@ function validatePathsInput(paths, cwd) {
|
|
|
151678
152170
|
return { error: "paths contains path traversal", resolvedPath: null };
|
|
151679
152171
|
}
|
|
151680
152172
|
try {
|
|
151681
|
-
const resolvedPath =
|
|
151682
|
-
const normalizedCwd =
|
|
151683
|
-
const normalizedResolved =
|
|
152173
|
+
const resolvedPath = path208.resolve(paths);
|
|
152174
|
+
const normalizedCwd = path208.resolve(cwd);
|
|
152175
|
+
const normalizedResolved = path208.resolve(resolvedPath);
|
|
151684
152176
|
if (!normalizedResolved.startsWith(normalizedCwd)) {
|
|
151685
152177
|
return {
|
|
151686
152178
|
error: "paths must be within the current working directory",
|
|
@@ -151696,7 +152188,7 @@ function validatePathsInput(paths, cwd) {
|
|
|
151696
152188
|
}
|
|
151697
152189
|
}
|
|
151698
152190
|
function isSupportedExtension(filePath) {
|
|
151699
|
-
const ext =
|
|
152191
|
+
const ext = path208.extname(filePath).toLowerCase();
|
|
151700
152192
|
return SUPPORTED_EXTENSIONS4.has(ext);
|
|
151701
152193
|
}
|
|
151702
152194
|
function findSourceFiles3(dir, files = []) {
|
|
@@ -151711,7 +152203,7 @@ function findSourceFiles3(dir, files = []) {
|
|
|
151711
152203
|
if (SKIP_DIRECTORIES6.has(entry)) {
|
|
151712
152204
|
continue;
|
|
151713
152205
|
}
|
|
151714
|
-
const fullPath =
|
|
152206
|
+
const fullPath = path208.join(dir, entry);
|
|
151715
152207
|
let stat14;
|
|
151716
152208
|
try {
|
|
151717
152209
|
stat14 = fs133.statSync(fullPath);
|
|
@@ -151823,7 +152315,7 @@ var todo_extract = createSwarmTool({
|
|
|
151823
152315
|
filesToScan.push(scanPath);
|
|
151824
152316
|
} else {
|
|
151825
152317
|
const errorResult = {
|
|
151826
|
-
error: `unsupported file extension: ${
|
|
152318
|
+
error: `unsupported file extension: ${path208.extname(scanPath)}`,
|
|
151827
152319
|
total: 0,
|
|
151828
152320
|
byPriority: { high: 0, medium: 0, low: 0 },
|
|
151829
152321
|
entries: []
|
|
@@ -151873,18 +152365,18 @@ init_schema();
|
|
|
151873
152365
|
init_qa_gate_profile();
|
|
151874
152366
|
init_gate_evidence();
|
|
151875
152367
|
import * as fs137 from "node:fs";
|
|
151876
|
-
import * as
|
|
152368
|
+
import * as path212 from "node:path";
|
|
151877
152369
|
|
|
151878
152370
|
// src/hooks/diff-scope.ts
|
|
151879
152371
|
init_bun_compat();
|
|
151880
152372
|
import * as fs135 from "node:fs";
|
|
151881
|
-
import * as
|
|
152373
|
+
import * as path210 from "node:path";
|
|
151882
152374
|
|
|
151883
152375
|
// src/utils/gitignore-warning.ts
|
|
151884
152376
|
init_bun_compat();
|
|
151885
152377
|
import * as fs134 from "node:fs";
|
|
151886
|
-
import * as
|
|
151887
|
-
var
|
|
152378
|
+
import * as path209 from "node:path";
|
|
152379
|
+
var _internals119 = { bunSpawn };
|
|
151888
152380
|
var _swarmGitExcludedChecked = false;
|
|
151889
152381
|
function fileCoversSwarm(content) {
|
|
151890
152382
|
for (const rawLine of content.split(`
|
|
@@ -151917,7 +152409,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
151917
152409
|
checkIgnoreExitCode
|
|
151918
152410
|
] = await Promise.all([
|
|
151919
152411
|
(async () => {
|
|
151920
|
-
const proc =
|
|
152412
|
+
const proc = _internals119.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
|
|
151921
152413
|
try {
|
|
151922
152414
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
151923
152415
|
} finally {
|
|
@@ -151927,7 +152419,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
151927
152419
|
}
|
|
151928
152420
|
})(),
|
|
151929
152421
|
(async () => {
|
|
151930
|
-
const proc =
|
|
152422
|
+
const proc = _internals119.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
|
|
151931
152423
|
try {
|
|
151932
152424
|
return await Promise.all([proc.exited, proc.stdout.text()]);
|
|
151933
152425
|
} finally {
|
|
@@ -151937,7 +152429,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
151937
152429
|
}
|
|
151938
152430
|
})(),
|
|
151939
152431
|
(async () => {
|
|
151940
|
-
const proc =
|
|
152432
|
+
const proc = _internals119.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
|
|
151941
152433
|
try {
|
|
151942
152434
|
return await proc.exited;
|
|
151943
152435
|
} finally {
|
|
@@ -151957,10 +152449,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
151957
152449
|
const excludeRelPath = excludePathRaw.trim();
|
|
151958
152450
|
if (!excludeRelPath)
|
|
151959
152451
|
return;
|
|
151960
|
-
const excludePath =
|
|
152452
|
+
const excludePath = path209.isAbsolute(excludeRelPath) ? excludeRelPath : path209.join(directory, excludeRelPath);
|
|
151961
152453
|
if (checkIgnoreExitCode !== 0) {
|
|
151962
152454
|
try {
|
|
151963
|
-
fs134.mkdirSync(
|
|
152455
|
+
fs134.mkdirSync(path209.dirname(excludePath), { recursive: true });
|
|
151964
152456
|
let existing = "";
|
|
151965
152457
|
try {
|
|
151966
152458
|
existing = fs134.readFileSync(excludePath, "utf8");
|
|
@@ -151976,7 +152468,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
151976
152468
|
}
|
|
151977
152469
|
} catch {}
|
|
151978
152470
|
}
|
|
151979
|
-
const trackedProc =
|
|
152471
|
+
const trackedProc = _internals119.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
|
|
151980
152472
|
let trackedExitCode;
|
|
151981
152473
|
let trackedOutput;
|
|
151982
152474
|
try {
|
|
@@ -152001,10 +152493,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
|
|
|
152001
152493
|
}
|
|
152002
152494
|
|
|
152003
152495
|
// src/hooks/diff-scope.ts
|
|
152004
|
-
var
|
|
152496
|
+
var _internals120 = { bunSpawn };
|
|
152005
152497
|
function getDeclaredScope(taskId, directory) {
|
|
152006
152498
|
try {
|
|
152007
|
-
const planPath =
|
|
152499
|
+
const planPath = path210.join(directory, ".swarm", "plan.json");
|
|
152008
152500
|
if (!fs135.existsSync(planPath))
|
|
152009
152501
|
return null;
|
|
152010
152502
|
const raw = fs135.readFileSync(planPath, "utf-8");
|
|
@@ -152036,7 +152528,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
|
|
|
152036
152528
|
};
|
|
152037
152529
|
async function getChangedFiles2(directory) {
|
|
152038
152530
|
try {
|
|
152039
|
-
const proc =
|
|
152531
|
+
const proc = _internals120.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
|
|
152040
152532
|
cwd: directory,
|
|
152041
152533
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
152042
152534
|
});
|
|
@@ -152053,7 +152545,7 @@ async function getChangedFiles2(directory) {
|
|
|
152053
152545
|
return stdout.trim().split(`
|
|
152054
152546
|
`).map((f) => f.trim()).filter((f) => f.length > 0);
|
|
152055
152547
|
}
|
|
152056
|
-
const proc2 =
|
|
152548
|
+
const proc2 = _internals120.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
|
|
152057
152549
|
cwd: directory,
|
|
152058
152550
|
...GIT_DIFF_SPAWN_OPTIONS
|
|
152059
152551
|
});
|
|
@@ -152110,8 +152602,8 @@ init_telemetry();
|
|
|
152110
152602
|
// src/turbo/lean/task-completion.ts
|
|
152111
152603
|
init_file_locks();
|
|
152112
152604
|
import * as fs136 from "node:fs";
|
|
152113
|
-
import * as
|
|
152114
|
-
var
|
|
152605
|
+
import * as path211 from "node:path";
|
|
152606
|
+
var _internals121 = {
|
|
152115
152607
|
listActiveLocks,
|
|
152116
152608
|
verifyLeanTurboTaskCompletion
|
|
152117
152609
|
};
|
|
@@ -152129,7 +152621,7 @@ var TIER_3_PATTERNS = [
|
|
|
152129
152621
|
];
|
|
152130
152622
|
function matchesTier3Pattern(files) {
|
|
152131
152623
|
for (const file3 of files) {
|
|
152132
|
-
const fileName =
|
|
152624
|
+
const fileName = path211.basename(file3);
|
|
152133
152625
|
for (const pattern of TIER_3_PATTERNS) {
|
|
152134
152626
|
if (pattern.test(fileName)) {
|
|
152135
152627
|
return true;
|
|
@@ -152141,7 +152633,7 @@ function matchesTier3Pattern(files) {
|
|
|
152141
152633
|
function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
152142
152634
|
let persisted = null;
|
|
152143
152635
|
try {
|
|
152144
|
-
const statePath =
|
|
152636
|
+
const statePath = path211.join(directory, ".swarm", "turbo-state.json");
|
|
152145
152637
|
if (!fs136.existsSync(statePath)) {
|
|
152146
152638
|
return {
|
|
152147
152639
|
ok: false,
|
|
@@ -152225,11 +152717,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
152225
152717
|
};
|
|
152226
152718
|
}
|
|
152227
152719
|
const phase = runState.phase ?? 0;
|
|
152228
|
-
const evidencePath =
|
|
152229
|
-
const expectedDir =
|
|
152230
|
-
const resolvedPath =
|
|
152231
|
-
const resolvedDir =
|
|
152232
|
-
if (!resolvedPath.startsWith(resolvedDir +
|
|
152720
|
+
const evidencePath = path211.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
|
|
152721
|
+
const expectedDir = path211.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
|
|
152722
|
+
const resolvedPath = path211.resolve(evidencePath);
|
|
152723
|
+
const resolvedDir = path211.resolve(expectedDir);
|
|
152724
|
+
if (!resolvedPath.startsWith(resolvedDir + path211.sep) && resolvedPath !== resolvedDir) {
|
|
152233
152725
|
return {
|
|
152234
152726
|
ok: false,
|
|
152235
152727
|
reason: `Lane ID causes path traversal: ${lane.laneId}`,
|
|
@@ -152253,7 +152745,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
152253
152745
|
}
|
|
152254
152746
|
};
|
|
152255
152747
|
}
|
|
152256
|
-
const activeLocks =
|
|
152748
|
+
const activeLocks = _internals121.listActiveLocks(directory);
|
|
152257
152749
|
const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
|
|
152258
152750
|
if (laneLocks.length > 0) {
|
|
152259
152751
|
return {
|
|
@@ -152269,7 +152761,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
152269
152761
|
}
|
|
152270
152762
|
let filesTouched = [];
|
|
152271
152763
|
try {
|
|
152272
|
-
const planPath =
|
|
152764
|
+
const planPath = path211.join(directory, ".swarm", "plan.json");
|
|
152273
152765
|
const planRaw = fs136.readFileSync(planPath, "utf-8");
|
|
152274
152766
|
const plan = JSON.parse(planRaw);
|
|
152275
152767
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -152320,7 +152812,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
|
|
|
152320
152812
|
init_task_id();
|
|
152321
152813
|
init_create_tool();
|
|
152322
152814
|
init_resolve_working_directory();
|
|
152323
|
-
var
|
|
152815
|
+
var _internals122 = {
|
|
152324
152816
|
tryAcquireLock,
|
|
152325
152817
|
updateTaskStatus,
|
|
152326
152818
|
resolveWorkingDirectory
|
|
@@ -152358,7 +152850,7 @@ var TIER_3_PATTERNS2 = [
|
|
|
152358
152850
|
];
|
|
152359
152851
|
function matchesTier3Pattern2(files) {
|
|
152360
152852
|
for (const file3 of files) {
|
|
152361
|
-
const fileName =
|
|
152853
|
+
const fileName = path212.basename(file3);
|
|
152362
152854
|
for (const pattern of TIER_3_PATTERNS2) {
|
|
152363
152855
|
if (pattern.test(fileName)) {
|
|
152364
152856
|
return true;
|
|
@@ -152397,7 +152889,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
152397
152889
|
if (!skipStandardTurboBypass && hasActiveTurboMode()) {
|
|
152398
152890
|
const resolvedDir2 = workingDirectory;
|
|
152399
152891
|
try {
|
|
152400
|
-
const planPath =
|
|
152892
|
+
const planPath = path212.join(resolvedDir2, ".swarm", "plan.json");
|
|
152401
152893
|
const planRaw = fs137.readFileSync(planPath, "utf-8");
|
|
152402
152894
|
const plan = JSON.parse(planRaw);
|
|
152403
152895
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -152417,7 +152909,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
152417
152909
|
}
|
|
152418
152910
|
let resolvedDir;
|
|
152419
152911
|
if (fallbackDir) {
|
|
152420
|
-
const resolveResult =
|
|
152912
|
+
const resolveResult = _internals122.resolveWorkingDirectory(workingDirectory, fallbackDir);
|
|
152421
152913
|
if (resolveResult.success) {
|
|
152422
152914
|
resolvedDir = resolveResult.directory;
|
|
152423
152915
|
} else {
|
|
@@ -152475,7 +152967,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
|
|
|
152475
152967
|
}
|
|
152476
152968
|
if (resolvedDir) {
|
|
152477
152969
|
try {
|
|
152478
|
-
const planPath =
|
|
152970
|
+
const planPath = path212.join(resolvedDir, ".swarm", "plan.json");
|
|
152479
152971
|
const planRaw = fs137.readFileSync(planPath, "utf-8");
|
|
152480
152972
|
const plan = JSON.parse(planRaw);
|
|
152481
152973
|
for (const planPhase of plan.phases ?? []) {
|
|
@@ -152686,7 +153178,7 @@ function checkCouncilGate(workingDirectory, taskId) {
|
|
|
152686
153178
|
return { blocked: false, reason: "", active: false };
|
|
152687
153179
|
}
|
|
152688
153180
|
try {
|
|
152689
|
-
const planPath =
|
|
153181
|
+
const planPath = path212.join(workingDirectory, ".swarm", "plan.json");
|
|
152690
153182
|
const planRaw = fs137.readFileSync(planPath, "utf-8");
|
|
152691
153183
|
const planObj = JSON.parse(planRaw);
|
|
152692
153184
|
if (planObj.swarm && planObj.title) {
|
|
@@ -152764,7 +153256,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152764
153256
|
}
|
|
152765
153257
|
}
|
|
152766
153258
|
let directory;
|
|
152767
|
-
const resolveResult =
|
|
153259
|
+
const resolveResult = _internals122.resolveWorkingDirectory(args2.working_directory, fallbackDir);
|
|
152768
153260
|
if (!resolveResult.success) {
|
|
152769
153261
|
return {
|
|
152770
153262
|
success: false,
|
|
@@ -152773,7 +153265,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152773
153265
|
};
|
|
152774
153266
|
}
|
|
152775
153267
|
directory = resolveResult.directory;
|
|
152776
|
-
const planPath =
|
|
153268
|
+
const planPath = path212.join(directory, ".swarm", "plan.json");
|
|
152777
153269
|
if (!fs137.existsSync(planPath)) {
|
|
152778
153270
|
return {
|
|
152779
153271
|
success: false,
|
|
@@ -152782,9 +153274,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152782
153274
|
};
|
|
152783
153275
|
}
|
|
152784
153276
|
if (fallbackDir && directory !== fallbackDir) {
|
|
152785
|
-
const canonicalDir = fs137.realpathSync(
|
|
152786
|
-
const canonicalRoot = fs137.realpathSync(
|
|
152787
|
-
if (canonicalDir.startsWith(canonicalRoot +
|
|
153277
|
+
const canonicalDir = fs137.realpathSync(path212.resolve(directory));
|
|
153278
|
+
const canonicalRoot = fs137.realpathSync(path212.resolve(fallbackDir));
|
|
153279
|
+
if (canonicalDir.startsWith(canonicalRoot + path212.sep)) {
|
|
152788
153280
|
return {
|
|
152789
153281
|
success: false,
|
|
152790
153282
|
message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
|
|
@@ -152796,8 +153288,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152796
153288
|
}
|
|
152797
153289
|
if (args2.status === "in_progress") {
|
|
152798
153290
|
try {
|
|
152799
|
-
const evidencePath =
|
|
152800
|
-
fs137.mkdirSync(
|
|
153291
|
+
const evidencePath = path212.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
|
|
153292
|
+
fs137.mkdirSync(path212.dirname(evidencePath), { recursive: true });
|
|
152801
153293
|
const fd = fs137.openSync(evidencePath, "wx");
|
|
152802
153294
|
let writeOk = false;
|
|
152803
153295
|
try {
|
|
@@ -152821,7 +153313,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152821
153313
|
recoverTaskStateFromDelegations(args2.task_id, directory);
|
|
152822
153314
|
let phaseRequiresReviewer = true;
|
|
152823
153315
|
try {
|
|
152824
|
-
const planPath2 =
|
|
153316
|
+
const planPath2 = path212.join(directory, ".swarm", "plan.json");
|
|
152825
153317
|
const planRaw = fs137.readFileSync(planPath2, "utf-8");
|
|
152826
153318
|
const plan = JSON.parse(planRaw);
|
|
152827
153319
|
const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
|
|
@@ -152857,7 +153349,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152857
153349
|
}
|
|
152858
153350
|
let lockResult;
|
|
152859
153351
|
try {
|
|
152860
|
-
lockResult = await
|
|
153352
|
+
lockResult = await _internals122.tryAcquireLock(directory, planFilePath, agentName, lockTaskId);
|
|
152861
153353
|
} catch (error93) {
|
|
152862
153354
|
return {
|
|
152863
153355
|
success: false,
|
|
@@ -152876,7 +153368,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
|
|
|
152876
153368
|
};
|
|
152877
153369
|
}
|
|
152878
153370
|
try {
|
|
152879
|
-
const updatedPlan = await
|
|
153371
|
+
const updatedPlan = await _internals122.updateTaskStatus(directory, args2.task_id, args2.status);
|
|
152880
153372
|
if (args2.status === "completed") {
|
|
152881
153373
|
for (const [_sessionId, session] of swarmState.agentSessions) {
|
|
152882
153374
|
if (!(session.taskWorkflowStates instanceof Map)) {
|
|
@@ -152940,7 +153432,7 @@ init_utils2();
|
|
|
152940
153432
|
init_redaction();
|
|
152941
153433
|
import { createHash as createHash26 } from "node:crypto";
|
|
152942
153434
|
import { appendFile as appendFile18, mkdir as mkdir35 } from "node:fs/promises";
|
|
152943
|
-
import * as
|
|
153435
|
+
import * as path213 from "node:path";
|
|
152944
153436
|
var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
|
|
152945
153437
|
var MAX_EVIDENCE_TEXT_LENGTH = 4000;
|
|
152946
153438
|
async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
@@ -152948,7 +153440,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
|
|
|
152948
153440
|
const capturedAt = now().toISOString();
|
|
152949
153441
|
const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
|
|
152950
153442
|
if (records.length > 0) {
|
|
152951
|
-
await mkdir35(
|
|
153443
|
+
await mkdir35(path213.dirname(filePath), { recursive: true });
|
|
152952
153444
|
await appendFile18(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
|
|
152953
153445
|
`)}
|
|
152954
153446
|
`, "utf-8");
|
|
@@ -153531,7 +154023,7 @@ var web_fetch = createSwarmTool({
|
|
|
153531
154023
|
};
|
|
153532
154024
|
return JSON.stringify(fail, null, 2);
|
|
153533
154025
|
}
|
|
153534
|
-
const config3 =
|
|
154026
|
+
const config3 = _internals123.loadPluginConfig(dirResult.directory);
|
|
153535
154027
|
const generalConfig = config3.council?.general;
|
|
153536
154028
|
if (!generalConfig || generalConfig.enabled !== true) {
|
|
153537
154029
|
const fail = {
|
|
@@ -153541,7 +154033,7 @@ var web_fetch = createSwarmTool({
|
|
|
153541
154033
|
};
|
|
153542
154034
|
return JSON.stringify(fail, null, 2);
|
|
153543
154035
|
}
|
|
153544
|
-
const validated = await validateFetchUrl(parsed.data.url,
|
|
154036
|
+
const validated = await validateFetchUrl(parsed.data.url, _internals123.dnsLookup);
|
|
153545
154037
|
if (!validated.ok) {
|
|
153546
154038
|
const fail = {
|
|
153547
154039
|
success: false,
|
|
@@ -153552,7 +154044,7 @@ var web_fetch = createSwarmTool({
|
|
|
153552
154044
|
}
|
|
153553
154045
|
const maxBytes = parsed.data.max_bytes ?? DEFAULT_MAX_BYTES;
|
|
153554
154046
|
const timeoutMs = parsed.data.timeout_ms ?? DEFAULT_TIMEOUT_MS5;
|
|
153555
|
-
const result = await boundedFetch({ url: validated.url, address: validated.address }, maxBytes, timeoutMs,
|
|
154047
|
+
const result = await boundedFetch({ url: validated.url, address: validated.address }, maxBytes, timeoutMs, _internals123);
|
|
153556
154048
|
if (!result.ok) {
|
|
153557
154049
|
const fail = {
|
|
153558
154050
|
success: false,
|
|
@@ -153587,7 +154079,7 @@ var web_fetch = createSwarmTool({
|
|
|
153587
154079
|
});
|
|
153588
154080
|
async function captureFetchEvidence(directory, url3, title, text) {
|
|
153589
154081
|
try {
|
|
153590
|
-
const written = await
|
|
154082
|
+
const written = await _internals123.writeEvidenceDocuments(directory, [
|
|
153591
154083
|
{
|
|
153592
154084
|
sourceType: "crawl",
|
|
153593
154085
|
url: url3,
|
|
@@ -153608,7 +154100,7 @@ async function captureFetchEvidence(directory, url3, title, text) {
|
|
|
153608
154100
|
};
|
|
153609
154101
|
}
|
|
153610
154102
|
}
|
|
153611
|
-
var
|
|
154103
|
+
var _internals123 = {
|
|
153612
154104
|
httpRequest: performHttpRequest,
|
|
153613
154105
|
dnsLookup: lookup,
|
|
153614
154106
|
loadPluginConfig,
|
|
@@ -153922,7 +154414,7 @@ var web_search = createSwarmTool({
|
|
|
153922
154414
|
});
|
|
153923
154415
|
async function captureSearchEvidence(directory, query, results) {
|
|
153924
154416
|
try {
|
|
153925
|
-
const written = await
|
|
154417
|
+
const written = await _internals124.writeEvidenceDocuments(directory, results.map((result) => ({
|
|
153926
154418
|
sourceType: "web_search",
|
|
153927
154419
|
query,
|
|
153928
154420
|
title: result.title,
|
|
@@ -153950,7 +154442,7 @@ async function captureSearchEvidence(directory, query, results) {
|
|
|
153950
154442
|
};
|
|
153951
154443
|
}
|
|
153952
154444
|
}
|
|
153953
|
-
var
|
|
154445
|
+
var _internals124 = {
|
|
153954
154446
|
writeEvidenceDocuments
|
|
153955
154447
|
};
|
|
153956
154448
|
|
|
@@ -153965,7 +154457,7 @@ init_schema3();
|
|
|
153965
154457
|
init_store();
|
|
153966
154458
|
init_create_tool();
|
|
153967
154459
|
init_resolve_working_directory();
|
|
153968
|
-
import * as
|
|
154460
|
+
import * as path214 from "node:path";
|
|
153969
154461
|
var FindingSchema2 = exports_external.object({
|
|
153970
154462
|
severity: exports_external.enum(["low", "medium", "high", "critical"]),
|
|
153971
154463
|
category: exports_external.string().min(1),
|
|
@@ -154041,7 +154533,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
|
|
|
154041
154533
|
if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
|
|
154042
154534
|
const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
|
|
154043
154535
|
const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
|
|
154044
|
-
const result = await curateAndStoreSwarm(lessons,
|
|
154536
|
+
const result = await curateAndStoreSwarm(lessons, path214.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, {
|
|
154045
154537
|
skipAutoPromotion: true,
|
|
154046
154538
|
llmDelegate: createCuratorLLMDelegate(dirResult.directory, "phase"),
|
|
154047
154539
|
enrichmentQuota: {
|
|
@@ -154088,7 +154580,7 @@ init_ledger();
|
|
|
154088
154580
|
init_manager();
|
|
154089
154581
|
init_create_tool();
|
|
154090
154582
|
import fs138 from "node:fs";
|
|
154091
|
-
import
|
|
154583
|
+
import path215 from "node:path";
|
|
154092
154584
|
function normalizeVerdict(verdict) {
|
|
154093
154585
|
switch (verdict) {
|
|
154094
154586
|
case "APPROVED":
|
|
@@ -154142,7 +154634,7 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
154142
154634
|
entries: [evidenceEntry]
|
|
154143
154635
|
};
|
|
154144
154636
|
const filename = "drift-verifier.json";
|
|
154145
|
-
const relativePath =
|
|
154637
|
+
const relativePath = path215.join("evidence", String(phase), filename);
|
|
154146
154638
|
let validatedPath;
|
|
154147
154639
|
try {
|
|
154148
154640
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -154153,10 +154645,10 @@ async function executeWriteDriftEvidence(args2, directory) {
|
|
|
154153
154645
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
154154
154646
|
}, null, 2);
|
|
154155
154647
|
}
|
|
154156
|
-
const evidenceDir =
|
|
154648
|
+
const evidenceDir = path215.dirname(validatedPath);
|
|
154157
154649
|
try {
|
|
154158
154650
|
await fs138.promises.mkdir(evidenceDir, { recursive: true });
|
|
154159
|
-
const tempPath =
|
|
154651
|
+
const tempPath = path215.join(evidenceDir, `.${filename}.tmp`);
|
|
154160
154652
|
await fs138.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
154161
154653
|
await fs138.promises.rename(tempPath, validatedPath);
|
|
154162
154654
|
let snapshotInfo;
|
|
@@ -154257,7 +154749,7 @@ var write_drift_evidence = createSwarmTool({
|
|
|
154257
154749
|
init_zod();
|
|
154258
154750
|
init_loader();
|
|
154259
154751
|
import fs139 from "node:fs";
|
|
154260
|
-
import
|
|
154752
|
+
import path216 from "node:path";
|
|
154261
154753
|
init_utils2();
|
|
154262
154754
|
init_manager();
|
|
154263
154755
|
init_create_tool();
|
|
@@ -154371,7 +154863,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
154371
154863
|
timestamp: synthesis.timestamp
|
|
154372
154864
|
};
|
|
154373
154865
|
const filename = "final-council.json";
|
|
154374
|
-
const relativePath =
|
|
154866
|
+
const relativePath = path216.join("evidence", filename);
|
|
154375
154867
|
let validatedPath;
|
|
154376
154868
|
try {
|
|
154377
154869
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -154385,10 +154877,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
|
|
|
154385
154877
|
const evidenceContent = {
|
|
154386
154878
|
entries: [evidenceEntry]
|
|
154387
154879
|
};
|
|
154388
|
-
const evidenceDir =
|
|
154880
|
+
const evidenceDir = path216.dirname(validatedPath);
|
|
154389
154881
|
try {
|
|
154390
154882
|
await fs139.promises.mkdir(evidenceDir, { recursive: true });
|
|
154391
|
-
const tempPath =
|
|
154883
|
+
const tempPath = path216.join(evidenceDir, `.${filename}.tmp`);
|
|
154392
154884
|
await fs139.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
154393
154885
|
await fs139.promises.rename(tempPath, validatedPath);
|
|
154394
154886
|
return JSON.stringify({
|
|
@@ -154448,7 +154940,7 @@ init_zod();
|
|
|
154448
154940
|
init_utils2();
|
|
154449
154941
|
init_create_tool();
|
|
154450
154942
|
import fs140 from "node:fs";
|
|
154451
|
-
import
|
|
154943
|
+
import path217 from "node:path";
|
|
154452
154944
|
function normalizeVerdict2(verdict) {
|
|
154453
154945
|
switch (verdict) {
|
|
154454
154946
|
case "APPROVED":
|
|
@@ -154496,7 +154988,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
154496
154988
|
entries: [evidenceEntry]
|
|
154497
154989
|
};
|
|
154498
154990
|
const filename = "hallucination-guard.json";
|
|
154499
|
-
const relativePath =
|
|
154991
|
+
const relativePath = path217.join("evidence", String(phase), filename);
|
|
154500
154992
|
let validatedPath;
|
|
154501
154993
|
try {
|
|
154502
154994
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -154507,10 +154999,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
|
|
|
154507
154999
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
154508
155000
|
}, null, 2);
|
|
154509
155001
|
}
|
|
154510
|
-
const evidenceDir =
|
|
155002
|
+
const evidenceDir = path217.dirname(validatedPath);
|
|
154511
155003
|
try {
|
|
154512
155004
|
await fs140.promises.mkdir(evidenceDir, { recursive: true });
|
|
154513
|
-
const tempPath =
|
|
155005
|
+
const tempPath = path217.join(evidenceDir, `.${filename}.tmp`);
|
|
154514
155006
|
await fs140.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
154515
155007
|
await fs140.promises.rename(tempPath, validatedPath);
|
|
154516
155008
|
return JSON.stringify({
|
|
@@ -154560,7 +155052,7 @@ init_zod();
|
|
|
154560
155052
|
init_utils2();
|
|
154561
155053
|
init_create_tool();
|
|
154562
155054
|
import fs141 from "node:fs";
|
|
154563
|
-
import
|
|
155055
|
+
import path218 from "node:path";
|
|
154564
155056
|
function normalizeVerdict3(verdict) {
|
|
154565
155057
|
switch (verdict) {
|
|
154566
155058
|
case "PASS":
|
|
@@ -154634,7 +155126,7 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
154634
155126
|
entries: [evidenceEntry]
|
|
154635
155127
|
};
|
|
154636
155128
|
const filename = "mutation-gate.json";
|
|
154637
|
-
const relativePath =
|
|
155129
|
+
const relativePath = path218.join("evidence", String(phase), filename);
|
|
154638
155130
|
let validatedPath;
|
|
154639
155131
|
try {
|
|
154640
155132
|
validatedPath = validateSwarmPath(directory, relativePath);
|
|
@@ -154645,10 +155137,10 @@ async function executeWriteMutationEvidence(args2, directory) {
|
|
|
154645
155137
|
message: error93 instanceof Error ? error93.message : "Failed to validate path"
|
|
154646
155138
|
}, null, 2);
|
|
154647
155139
|
}
|
|
154648
|
-
const evidenceDir =
|
|
155140
|
+
const evidenceDir = path218.dirname(validatedPath);
|
|
154649
155141
|
try {
|
|
154650
155142
|
await fs141.promises.mkdir(evidenceDir, { recursive: true });
|
|
154651
|
-
const tempPath =
|
|
155143
|
+
const tempPath = path218.join(evidenceDir, `.${filename}.tmp`);
|
|
154652
155144
|
await fs141.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
|
|
154653
155145
|
await fs141.promises.rename(tempPath, validatedPath);
|
|
154654
155146
|
return JSON.stringify({
|
|
@@ -154771,6 +155263,7 @@ var TOOL_MANIFEST = defineHandlers({
|
|
|
154771
155263
|
skill_list: () => skill_list,
|
|
154772
155264
|
skill_apply: () => skill_apply,
|
|
154773
155265
|
skill_inspect: () => skill_inspect,
|
|
155266
|
+
run_stale_reconciliation: () => run_stale_reconciliation,
|
|
154774
155267
|
skill_regenerate: () => skill_regenerate,
|
|
154775
155268
|
skill_retire: () => skill_retire,
|
|
154776
155269
|
skill_improve: () => skill_improve,
|
|
@@ -154863,7 +155356,7 @@ ${footerLines.join(`
|
|
|
154863
155356
|
init_warning_buffer();
|
|
154864
155357
|
var _heartbeatTimers = new Map;
|
|
154865
155358
|
var SWARM_COMMAND_SYSTEM_RULE_TAG = "[opencode-swarm:swarm-command-rule]";
|
|
154866
|
-
var PACKAGE_ROOT2 =
|
|
155359
|
+
var PACKAGE_ROOT2 = path220.resolve(path220.dirname(fileURLToPath5(import.meta.url)), "..");
|
|
154867
155360
|
var SYNC_BUNDLED_SKILLS_TIMEOUT_MS = 2000;
|
|
154868
155361
|
function createSwarmCommandSystemRuleHook(agentDefinitions, registeredAgents) {
|
|
154869
155362
|
return async (input, output) => {
|
|
@@ -155185,7 +155678,7 @@ async function initializeOpenCodeSwarm(ctx) {
|
|
|
155185
155678
|
const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
|
|
155186
155679
|
preflightTriggerManager = new PTM(automationConfig);
|
|
155187
155680
|
const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
|
|
155188
|
-
const swarmDir =
|
|
155681
|
+
const swarmDir = path220.resolve(ctx.directory, ".swarm");
|
|
155189
155682
|
statusArtifact = new ASA(swarmDir);
|
|
155190
155683
|
statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
|
|
155191
155684
|
if (automationConfig.capabilities?.evidence_auto_summaries === true) {
|
|
@@ -155857,7 +156350,7 @@ ${promptRaw}`;
|
|
|
155857
156350
|
const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
|
|
155858
156351
|
let desc = meta3.description || "";
|
|
155859
156352
|
if (!desc || desc === "No description provided") {
|
|
155860
|
-
desc =
|
|
156353
|
+
desc = path220.basename(path220.dirname(s.skillPath));
|
|
155861
156354
|
}
|
|
155862
156355
|
desc = desc.replace(/,/g, ";");
|
|
155863
156356
|
return `file:${s.skillPath} (-- ${desc})`;
|
|
@@ -155867,7 +156360,7 @@ ${promptRaw}`;
|
|
|
155867
156360
|
|
|
155868
156361
|
${promptRaw}`;
|
|
155869
156362
|
argsRecord.prompt = newPrompt;
|
|
155870
|
-
const skillNames = topSkills.map((s) => `${
|
|
156363
|
+
const skillNames = topSkills.map((s) => `${path220.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
|
|
155871
156364
|
console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
|
|
155872
156365
|
for (const skill of topSkills) {
|
|
155873
156366
|
try {
|