contextos-mcp 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/bin/mcp.mjs +61 -0
- package/bin/swarm.mjs +45 -0
- package/dist/agents/aider.d.ts +12 -0
- package/dist/agents/aider.js +192 -0
- package/dist/agents/aider.js.map +1 -0
- package/dist/agents/claude-code.d.ts +9 -0
- package/dist/agents/claude-code.js +236 -0
- package/dist/agents/claude-code.js.map +1 -0
- package/dist/agents/codex.d.ts +14 -0
- package/dist/agents/codex.js +203 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/direct-llm.d.ts +22 -0
- package/dist/agents/direct-llm.js +254 -0
- package/dist/agents/direct-llm.js.map +1 -0
- package/dist/agents/mock.d.ts +10 -0
- package/dist/agents/mock.js +170 -0
- package/dist/agents/mock.js.map +1 -0
- package/dist/agents/opencode.d.ts +23 -0
- package/dist/agents/opencode.js +631 -0
- package/dist/agents/opencode.js.map +1 -0
- package/dist/agents/provider.d.ts +11 -0
- package/dist/agents/provider.js +31 -0
- package/dist/agents/provider.js.map +1 -0
- package/dist/compression/compressor.d.ts +28 -0
- package/dist/compression/compressor.js +268 -0
- package/dist/compression/compressor.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/contextos/loader.d.ts +46 -0
- package/dist/contextos/loader.js +120 -0
- package/dist/contextos/loader.js.map +1 -0
- package/dist/contextos/selector.d.ts +46 -0
- package/dist/contextos/selector.js +80 -0
- package/dist/contextos/selector.js.map +1 -0
- package/dist/core/action-dispatcher.d.ts +15 -0
- package/dist/core/action-dispatcher.js +28 -0
- package/dist/core/action-dispatcher.js.map +1 -0
- package/dist/core/action-schema.d.ts +72 -0
- package/dist/core/action-schema.js +86 -0
- package/dist/core/action-schema.js.map +1 -0
- package/dist/core/repl-interface.d.ts +48 -0
- package/dist/core/repl-interface.js +5 -0
- package/dist/core/repl-interface.js.map +1 -0
- package/dist/core/repl.d.ts +59 -0
- package/dist/core/repl.js +353 -0
- package/dist/core/repl.js.map +1 -0
- package/dist/core/rlm.d.ts +65 -0
- package/dist/core/rlm.js +564 -0
- package/dist/core/rlm.js.map +1 -0
- package/dist/core/runtime.py +470 -0
- package/dist/core/types.d.ts +265 -0
- package/dist/core/types.js +19 -0
- package/dist/core/types.js.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.js +75 -0
- package/dist/env.js.map +1 -0
- package/dist/hooks/runner.d.ts +43 -0
- package/dist/hooks/runner.js +173 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/labs/cli.d.ts +15 -0
- package/dist/labs/cli.js +295 -0
- package/dist/labs/cli.js.map +1 -0
- package/dist/labs/episodic-memory.d.ts +132 -0
- package/dist/labs/episodic-memory.js +391 -0
- package/dist/labs/episodic-memory.js.map +1 -0
- package/dist/labs/interactive-swarm.d.ts +20 -0
- package/dist/labs/interactive-swarm.js +1173 -0
- package/dist/labs/interactive-swarm.js.map +1 -0
- package/dist/labs/interactive.d.ts +10 -0
- package/dist/labs/interactive.js +2099 -0
- package/dist/labs/interactive.js.map +1 -0
- package/dist/labs/ts-analyzer.d.ts +74 -0
- package/dist/labs/ts-analyzer.js +379 -0
- package/dist/labs/ts-analyzer.js.map +1 -0
- package/dist/labs/viewer.d.ts +12 -0
- package/dist/labs/viewer.js +1284 -0
- package/dist/labs/viewer.js.map +1 -0
- package/dist/main.d.ts +15 -0
- package/dist/main.js +247 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mcp/server.js +192775 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +117 -0
- package/dist/mcp/session.js +450 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/state.d.ts +42 -0
- package/dist/mcp/state.js +537 -0
- package/dist/mcp/state.js.map +1 -0
- package/dist/mcp/tools/contextos.d.ts +17 -0
- package/dist/mcp/tools/contextos.js +583 -0
- package/dist/mcp/tools/contextos.js.map +1 -0
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.js +393 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/orchestration/reviewer-gate.d.ts +43 -0
- package/dist/orchestration/reviewer-gate.js +280 -0
- package/dist/orchestration/reviewer-gate.js.map +1 -0
- package/dist/orchestration/reviewer-prompt.d.ts +18 -0
- package/dist/orchestration/reviewer-prompt.js +67 -0
- package/dist/orchestration/reviewer-prompt.js.map +1 -0
- package/dist/orchestration/verification-runner.d.ts +53 -0
- package/dist/orchestration/verification-runner.js +352 -0
- package/dist/orchestration/verification-runner.js.map +1 -0
- package/dist/plugins/adapter.d.ts +11 -0
- package/dist/plugins/adapter.js +11 -0
- package/dist/plugins/adapter.js.map +1 -0
- package/dist/plugins/core/archive.d.ts +9 -0
- package/dist/plugins/core/archive.js +128 -0
- package/dist/plugins/core/archive.js.map +1 -0
- package/dist/plugins/core/digest.d.ts +11 -0
- package/dist/plugins/core/digest.js +70 -0
- package/dist/plugins/core/digest.js.map +1 -0
- package/dist/plugins/core/grants.d.ts +22 -0
- package/dist/plugins/core/grants.js +90 -0
- package/dist/plugins/core/grants.js.map +1 -0
- package/dist/plugins/core/index.d.ts +10 -0
- package/dist/plugins/core/index.js +11 -0
- package/dist/plugins/core/index.js.map +1 -0
- package/dist/plugins/core/pinning.d.ts +15 -0
- package/dist/plugins/core/pinning.js +86 -0
- package/dist/plugins/core/pinning.js.map +1 -0
- package/dist/plugins/core/types.d.ts +105 -0
- package/dist/plugins/core/types.js +22 -0
- package/dist/plugins/core/types.js.map +1 -0
- package/dist/plugins/core/updater.d.ts +16 -0
- package/dist/plugins/core/updater.js +64 -0
- package/dist/plugins/core/updater.js.map +1 -0
- package/dist/plugins/loader.d.ts +65 -0
- package/dist/plugins/loader.js +110 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/prompts/orchestrator.d.ts +6 -0
- package/dist/prompts/orchestrator.js +114 -0
- package/dist/prompts/orchestrator.js.map +1 -0
- package/dist/routing/model-resolver.d.ts +27 -0
- package/dist/routing/model-resolver.js +265 -0
- package/dist/routing/model-resolver.js.map +1 -0
- package/dist/routing/model-router.d.ts +130 -0
- package/dist/routing/model-router.js +515 -0
- package/dist/routing/model-router.js.map +1 -0
- package/dist/runtime/attestations.cjs +260 -0
- package/dist/runtime/reviewer-pipeline.cjs +319 -0
- package/dist/runtime/sandbox.cjs +468 -0
- package/dist/runtime/state-machine.cjs +885 -0
- package/dist/runtime/thread-store.cjs +175 -0
- package/dist/runtime/transactional-git.cjs +315 -0
- package/dist/runtime/verification-pipeline.cjs +435 -0
- package/dist/sandbox/execution.d.ts +165 -0
- package/dist/sandbox/execution.js +497 -0
- package/dist/sandbox/execution.js.map +1 -0
- package/dist/security/file-policy.d.ts +22 -0
- package/dist/security/file-policy.js +53 -0
- package/dist/security/file-policy.js.map +1 -0
- package/dist/security/repository-boundary.d.ts +21 -0
- package/dist/security/repository-boundary.js +119 -0
- package/dist/security/repository-boundary.js.map +1 -0
- package/dist/security/secret-filter.d.ts +36 -0
- package/dist/security/secret-filter.js +149 -0
- package/dist/security/secret-filter.js.map +1 -0
- package/dist/swarm.d.ts +14 -0
- package/dist/swarm.js +624 -0
- package/dist/swarm.js.map +1 -0
- package/dist/threads/cache.d.ts +64 -0
- package/dist/threads/cache.js +241 -0
- package/dist/threads/cache.js.map +1 -0
- package/dist/threads/manager.d.ts +94 -0
- package/dist/threads/manager.js +914 -0
- package/dist/threads/manager.js.map +1 -0
- package/dist/ui/banner.d.ts +14 -0
- package/dist/ui/banner.js +42 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/dashboard.d.ts +33 -0
- package/dist/ui/dashboard.js +135 -0
- package/dist/ui/dashboard.js.map +1 -0
- package/dist/ui/index.d.ts +11 -0
- package/dist/ui/index.js +12 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/log.d.ts +39 -0
- package/dist/ui/log.js +126 -0
- package/dist/ui/log.js.map +1 -0
- package/dist/ui/onboarding.d.ts +14 -0
- package/dist/ui/onboarding.js +755 -0
- package/dist/ui/onboarding.js.map +1 -0
- package/dist/ui/run-log.d.ts +50 -0
- package/dist/ui/run-log.js +60 -0
- package/dist/ui/run-log.js.map +1 -0
- package/dist/ui/spinner.d.ts +41 -0
- package/dist/ui/spinner.js +172 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/streaming-feed.d.ts +72 -0
- package/dist/ui/streaming-feed.js +386 -0
- package/dist/ui/streaming-feed.js.map +1 -0
- package/dist/ui/summary.d.ts +18 -0
- package/dist/ui/summary.js +113 -0
- package/dist/ui/summary.js.map +1 -0
- package/dist/ui/text-input.d.ts +19 -0
- package/dist/ui/text-input.js +266 -0
- package/dist/ui/text-input.js.map +1 -0
- package/dist/ui/theme.d.ts +63 -0
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/command-exists.d.ts +11 -0
- package/dist/utils/command-exists.js +41 -0
- package/dist/utils/command-exists.js.map +1 -0
- package/dist/utils/process-security.d.ts +19 -0
- package/dist/utils/process-security.js +90 -0
- package/dist/utils/process-security.js.map +1 -0
- package/dist/utils/rolling-buffer.d.ts +16 -0
- package/dist/utils/rolling-buffer.js +30 -0
- package/dist/utils/rolling-buffer.js.map +1 -0
- package/dist/utils/safe-spawn.d.ts +13 -0
- package/dist/utils/safe-spawn.js +49 -0
- package/dist/utils/safe-spawn.js.map +1 -0
- package/dist/worktree/manager.d.ts +69 -0
- package/dist/worktree/manager.js +593 -0
- package/dist/worktree/manager.js.map +1 -0
- package/dist/worktree/merge.d.ts +58 -0
- package/dist/worktree/merge.js +389 -0
- package/dist/worktree/merge.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Assemble complete selected instructions with inspectable provenance and limits. */
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { assertWithinRepository } from "../security/repository-boundary.js";
|
|
6
|
+
import { selectContext } from "./selector.js";
|
|
7
|
+
/** Soft compatibility budget; selected bodies are never sliced. */
|
|
8
|
+
export const MAX_TOTAL_SKILLS_CHARS = 14000;
|
|
9
|
+
export function findAgentsDir(projectRoot) {
|
|
10
|
+
const root = path.resolve(projectRoot);
|
|
11
|
+
if (path.basename(root) === ".agents" && existsSync(root))
|
|
12
|
+
return root;
|
|
13
|
+
for (const candidate of [path.join(root, ".agents"), path.join(root, "..", ".agents")]) {
|
|
14
|
+
if (existsSync(candidate))
|
|
15
|
+
return path.resolve(candidate);
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
export class ContextAssemblyError extends Error {
|
|
20
|
+
code;
|
|
21
|
+
report;
|
|
22
|
+
constructor(code, message, report) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.code = code;
|
|
25
|
+
this.report = report;
|
|
26
|
+
this.name = "ContextAssemblyError";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function assembleContextPrompt(projectRoot, task, options = {}) {
|
|
30
|
+
for (const limit of [options.maxTotalSkillsChars, options.hardLimitChars]) {
|
|
31
|
+
if (limit !== undefined && (!Number.isSafeInteger(limit) || limit <= 0))
|
|
32
|
+
throw new Error("Context character limits must be positive integers");
|
|
33
|
+
}
|
|
34
|
+
const report = {
|
|
35
|
+
sources: [],
|
|
36
|
+
warnings: [],
|
|
37
|
+
omissions: [],
|
|
38
|
+
totalChars: 0,
|
|
39
|
+
skillChars: 0,
|
|
40
|
+
estimatedTokens: 0,
|
|
41
|
+
softSkillLimitChars: options.maxTotalSkillsChars ?? MAX_TOTAL_SKILLS_CHARS,
|
|
42
|
+
hardLimitChars: options.hardLimitChars,
|
|
43
|
+
};
|
|
44
|
+
const agentsDir = findAgentsDir(projectRoot);
|
|
45
|
+
if (!agentsDir)
|
|
46
|
+
return { prompt: "", report };
|
|
47
|
+
const repositoryRoot = assertWithinRepository(path.dirname(agentsDir), path.dirname(agentsDir));
|
|
48
|
+
const selection = selectContext(task, { ...options, rootDir: repositoryRoot });
|
|
49
|
+
report.warnings.push(...(selection.warnings || []));
|
|
50
|
+
report.omissions.push(...(selection.excluded || []));
|
|
51
|
+
const sections = [];
|
|
52
|
+
function load(file, kind, id) {
|
|
53
|
+
const safePath = assertWithinRepository(file, repositoryRoot);
|
|
54
|
+
if (!existsSync(safePath))
|
|
55
|
+
throw new ContextAssemblyError("CTX_PROMPT_MISSING_SOURCE", `Selected ${kind} source is missing: ${id}`, report);
|
|
56
|
+
const bytes = readFileSync(safePath);
|
|
57
|
+
const content = bytes.toString("utf8");
|
|
58
|
+
report.sources.push({
|
|
59
|
+
kind,
|
|
60
|
+
id,
|
|
61
|
+
path: path.relative(repositoryRoot, safePath).replace(/\\/g, "/"),
|
|
62
|
+
sha256: createHash("sha256").update(bytes).digest("hex"),
|
|
63
|
+
bytes: bytes.length,
|
|
64
|
+
chars: content.length,
|
|
65
|
+
});
|
|
66
|
+
return content;
|
|
67
|
+
}
|
|
68
|
+
const bootstrap = path.join(agentsDir, "AGENTS.md");
|
|
69
|
+
if (existsSync(bootstrap))
|
|
70
|
+
sections.push(load(bootstrap, "bootstrap", "AGENTS.md").trim());
|
|
71
|
+
for (const rule of selection.rules)
|
|
72
|
+
sections.push(`# Rule: ${rule}\n\n${load(path.join(agentsDir, "rules", rule), "rule", rule)}`);
|
|
73
|
+
for (const id of [...new Set(selection.skills)]) {
|
|
74
|
+
const source = selection.skillSources?.[id];
|
|
75
|
+
const entrypoint = selection.skillEntrypoints?.[id] || "SKILL.md";
|
|
76
|
+
let directory;
|
|
77
|
+
if (source) {
|
|
78
|
+
const manifest = assertWithinRepository(path.resolve(repositoryRoot, source), repositoryRoot);
|
|
79
|
+
directory = path.dirname(manifest);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Compatibility with older selectors; overrides precede generated projections.
|
|
83
|
+
directory = ["project/skills", "core/skills", "plugins", "skills", "generated/gemini/skills"]
|
|
84
|
+
.map((base) => path.join(agentsDir, base, id))
|
|
85
|
+
.find((candidate) => existsSync(path.join(candidate, entrypoint)));
|
|
86
|
+
}
|
|
87
|
+
if (!directory)
|
|
88
|
+
throw new ContextAssemblyError("CTX_PROMPT_MISSING_SOURCE", `Selected skill source is missing: ${id}`, report);
|
|
89
|
+
const raw = load(path.join(directory, entrypoint), "skill", id);
|
|
90
|
+
const body = raw.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, "").trim();
|
|
91
|
+
const relativeDirectory = path.relative(repositoryRoot, directory).replace(/\\/g, "/");
|
|
92
|
+
const formatted = `# Skill: ${id}\n\nResolve references relative to ${relativeDirectory}. Read them only when needed.\n\n${body}`;
|
|
93
|
+
report.skillChars += formatted.length;
|
|
94
|
+
sections.push(formatted);
|
|
95
|
+
}
|
|
96
|
+
const prompt = sections.length
|
|
97
|
+
? [
|
|
98
|
+
"Follow these project instructions within the user's authorized task and the instruction hierarchy.",
|
|
99
|
+
...sections,
|
|
100
|
+
].join("\n\n")
|
|
101
|
+
: "";
|
|
102
|
+
report.totalChars = prompt.length;
|
|
103
|
+
report.estimatedTokens = Math.ceil(prompt.length / 4);
|
|
104
|
+
if (report.skillChars > report.softSkillLimitChars)
|
|
105
|
+
report.warnings.push({
|
|
106
|
+
code: "CTX_PROMPT_SOFT_BUDGET_EXCEEDED",
|
|
107
|
+
message: `Selected full skill bodies occupy ${report.skillChars} characters; soft limit is ${report.softSkillLimitChars}.`,
|
|
108
|
+
});
|
|
109
|
+
if (options.hardLimitChars !== undefined && prompt.length > options.hardLimitChars) {
|
|
110
|
+
throw new ContextAssemblyError("CTX_PROMPT_HARD_BUDGET_EXCEEDED", `Complete prompt needs ${prompt.length} characters; hard limit is ${options.hardLimitChars}.`, report);
|
|
111
|
+
}
|
|
112
|
+
for (const warning of report.warnings)
|
|
113
|
+
process.stderr.write(`[contextos-loader] ${warning.code}: ${warning.message}\n`);
|
|
114
|
+
return { prompt, report };
|
|
115
|
+
}
|
|
116
|
+
/** Compatibility wrapper for existing agent call sites. */
|
|
117
|
+
export function buildContextPrompt(projectRoot, task, options = {}) {
|
|
118
|
+
return assembleContextPrompt(projectRoot, task, options).prompt;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/contextos/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextOS Selector — determines which rules and skills are relevant for a task.
|
|
3
|
+
*
|
|
4
|
+
* Unified with CanonicalResolver (.agents/resolver/canonical-resolver.js) for 100%
|
|
5
|
+
* parity between CLI and MCP runtimes:
|
|
6
|
+
* - Evidence-based scoring (aliases, keywords, file globs, nearest package)
|
|
7
|
+
* - Direct query to compiled registry (registry.v2.json)
|
|
8
|
+
* - Transitive dependency closure
|
|
9
|
+
* - Token budget planner and intent precedence
|
|
10
|
+
*/
|
|
11
|
+
export interface SelectedContext {
|
|
12
|
+
/** Always-loaded rules (e.g., AGENTS.md core principles). */
|
|
13
|
+
coreRules: string[];
|
|
14
|
+
/** Task-relevant rule files from rules/. */
|
|
15
|
+
rules: string[];
|
|
16
|
+
/** Task-relevant skill directories from core/skills/. */
|
|
17
|
+
skills: string[];
|
|
18
|
+
skillSources?: Record<string, string>;
|
|
19
|
+
skillEntrypoints?: Record<string, string>;
|
|
20
|
+
warnings?: Array<{
|
|
21
|
+
code: string;
|
|
22
|
+
message: string;
|
|
23
|
+
}>;
|
|
24
|
+
excluded?: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
reasonCode: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export interface SelectorOptions {
|
|
30
|
+
/** Root directory of the repository. */
|
|
31
|
+
rootDir?: string;
|
|
32
|
+
/** File paths touched or relevant to task for file-pattern boosting. */
|
|
33
|
+
files?: string[];
|
|
34
|
+
/** Custom soft token budget; defaults to the canonical resolver risk tier. */
|
|
35
|
+
contextBudgetTokens?: number;
|
|
36
|
+
maxSkills?: number;
|
|
37
|
+
explicitPhase?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Select relevant rules and skills for a given task description using the unified CanonicalResolver.
|
|
41
|
+
*
|
|
42
|
+
* @param task - The task description text
|
|
43
|
+
* @param options - Optional configuration (touched files and token budget)
|
|
44
|
+
* @returns SelectedContext with lists of relevant rule/skill identifiers
|
|
45
|
+
*/
|
|
46
|
+
export declare function selectContext(task: string, options?: SelectorOptions): SelectedContext;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextOS Selector — determines which rules and skills are relevant for a task.
|
|
3
|
+
*
|
|
4
|
+
* Unified with CanonicalResolver (.agents/resolver/canonical-resolver.js) for 100%
|
|
5
|
+
* parity between CLI and MCP runtimes:
|
|
6
|
+
* - Evidence-based scoring (aliases, keywords, file globs, nearest package)
|
|
7
|
+
* - Direct query to compiled registry (registry.v2.json)
|
|
8
|
+
* - Transitive dependency closure
|
|
9
|
+
* - Token budget planner and intent precedence
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { createRequire } from "node:module";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
/**
|
|
16
|
+
* Lazily loads the canonical resolver instance from .agents.
|
|
17
|
+
*/
|
|
18
|
+
function getCanonicalResolver(rootDir) {
|
|
19
|
+
const cwd = rootDir || process.cwd();
|
|
20
|
+
const candidatePaths = [
|
|
21
|
+
path.join(cwd, ".agents", "resolver", "canonical-resolver.js"),
|
|
22
|
+
path.join(cwd, "..", ".agents", "resolver", "canonical-resolver.js"),
|
|
23
|
+
];
|
|
24
|
+
for (const p of candidatePaths) {
|
|
25
|
+
if (existsSync(p)) {
|
|
26
|
+
try {
|
|
27
|
+
const mod = require(p);
|
|
28
|
+
if (mod?.CanonicalResolver) {
|
|
29
|
+
const resolvedRoot = path.dirname(path.dirname(path.dirname(p)));
|
|
30
|
+
return new mod.CanonicalResolver({ rootDir: resolvedRoot });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// fall through to fallback
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Select relevant rules and skills for a given task description using the unified CanonicalResolver.
|
|
42
|
+
*
|
|
43
|
+
* @param task - The task description text
|
|
44
|
+
* @param options - Optional configuration (touched files and token budget)
|
|
45
|
+
* @returns SelectedContext with lists of relevant rule/skill identifiers
|
|
46
|
+
*/
|
|
47
|
+
export function selectContext(task, options = {}) {
|
|
48
|
+
const canonical = getCanonicalResolver(options.rootDir);
|
|
49
|
+
if (!canonical) {
|
|
50
|
+
throw new Error("ContextOS CanonicalResolver is unavailable; refusing to produce incomplete context");
|
|
51
|
+
}
|
|
52
|
+
const res = canonical.resolve({
|
|
53
|
+
task,
|
|
54
|
+
files: options.files || [],
|
|
55
|
+
contextBudgetTokens: options.contextBudgetTokens,
|
|
56
|
+
maxSkills: options.maxSkills,
|
|
57
|
+
explicitPhase: options.explicitPhase,
|
|
58
|
+
});
|
|
59
|
+
const domainSkills = (res.selected || []).map((s) => s.id);
|
|
60
|
+
const skillSources = {};
|
|
61
|
+
const skillEntrypoints = {};
|
|
62
|
+
for (const id of domainSkills) {
|
|
63
|
+
const skill = canonical.registry?.skills?.[id];
|
|
64
|
+
const source = skill?.source;
|
|
65
|
+
if (source)
|
|
66
|
+
skillSources[id] = source;
|
|
67
|
+
if (skill?.entrypoint)
|
|
68
|
+
skillEntrypoints[id] = skill.entrypoint;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
coreRules: ["AGENTS.md"],
|
|
72
|
+
rules: [],
|
|
73
|
+
skills: domainSkills,
|
|
74
|
+
skillSources,
|
|
75
|
+
skillEntrypoints,
|
|
76
|
+
warnings: res.warnings || [],
|
|
77
|
+
excluded: res.excluded || [],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/contextos/selector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FinishAction, type InspectDiffAction, type MergeAction, type ReviewAction, type SpawnAction, type WaitAction } from "./action-schema.js";
|
|
2
|
+
export interface ActionHandlers {
|
|
3
|
+
spawn(action: SpawnAction): Promise<unknown>;
|
|
4
|
+
wait(action: WaitAction): Promise<unknown>;
|
|
5
|
+
inspectDiff(action: InspectDiffAction): Promise<unknown>;
|
|
6
|
+
review(action: ReviewAction): Promise<unknown>;
|
|
7
|
+
merge(action: MergeAction): Promise<unknown>;
|
|
8
|
+
finish(action: FinishAction): Promise<unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare class ActionDispatcher {
|
|
11
|
+
private readonly handlers;
|
|
12
|
+
constructor(handlers: ActionHandlers);
|
|
13
|
+
dispatch(input: unknown): Promise<unknown>;
|
|
14
|
+
private dispatchValidated;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { parseAction, } from "./action-schema.js";
|
|
2
|
+
export class ActionDispatcher {
|
|
3
|
+
handlers;
|
|
4
|
+
constructor(handlers) {
|
|
5
|
+
this.handlers = handlers;
|
|
6
|
+
}
|
|
7
|
+
async dispatch(input) {
|
|
8
|
+
const action = parseAction(input);
|
|
9
|
+
return this.dispatchValidated(action);
|
|
10
|
+
}
|
|
11
|
+
async dispatchValidated(action) {
|
|
12
|
+
switch (action.action) {
|
|
13
|
+
case "spawn":
|
|
14
|
+
return this.handlers.spawn(action);
|
|
15
|
+
case "wait":
|
|
16
|
+
return this.handlers.wait(action);
|
|
17
|
+
case "inspect_diff":
|
|
18
|
+
return this.handlers.inspectDiff(action);
|
|
19
|
+
case "review":
|
|
20
|
+
return this.handlers.review(action);
|
|
21
|
+
case "merge":
|
|
22
|
+
return this.handlers.merge(action);
|
|
23
|
+
case "finish":
|
|
24
|
+
return this.handlers.finish(action);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=action-dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-dispatcher.js","sourceRoot":"","sources":["../../src/core/action-dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAKN,WAAW,GAIX,MAAM,oBAAoB,CAAC;AAW5B,MAAM,OAAO,gBAAgB;IACC;IAA7B,YAA6B,QAAwB;QAAxB,aAAQ,GAAR,QAAQ,CAAgB;IAAG,CAAC;IAEzD,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC5B,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,MAAc;QAC7C,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,KAAK,OAAO;gBACX,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,KAAK,MAAM;gBACV,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnC,KAAK,cAAc;gBAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC1C,KAAK,QAAQ;gBACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACrC,KAAK,OAAO;gBACX,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,KAAK,QAAQ;gBACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;CACD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SpawnActionSchema: z.ZodObject<{
|
|
3
|
+
version: z.ZodLiteral<1>;
|
|
4
|
+
action: z.ZodLiteral<"spawn">;
|
|
5
|
+
task: z.ZodString;
|
|
6
|
+
writeScope: z.ZodArray<z.ZodString>;
|
|
7
|
+
focusFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
8
|
+
allowRepositoryWide: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
model: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strict>;
|
|
11
|
+
export declare const WaitActionSchema: z.ZodObject<{
|
|
12
|
+
version: z.ZodLiteral<1>;
|
|
13
|
+
action: z.ZodLiteral<"wait">;
|
|
14
|
+
threadIds: z.ZodArray<z.ZodString>;
|
|
15
|
+
}, z.core.$strict>;
|
|
16
|
+
export declare const InspectDiffActionSchema: z.ZodObject<{
|
|
17
|
+
version: z.ZodLiteral<1>;
|
|
18
|
+
action: z.ZodLiteral<"inspect_diff">;
|
|
19
|
+
threadId: z.ZodString;
|
|
20
|
+
}, z.core.$strict>;
|
|
21
|
+
export declare const ReviewActionSchema: z.ZodObject<{
|
|
22
|
+
version: z.ZodLiteral<1>;
|
|
23
|
+
action: z.ZodLiteral<"review">;
|
|
24
|
+
threadId: z.ZodString;
|
|
25
|
+
}, z.core.$strict>;
|
|
26
|
+
export declare const MergeActionSchema: z.ZodObject<{
|
|
27
|
+
version: z.ZodLiteral<1>;
|
|
28
|
+
action: z.ZodLiteral<"merge">;
|
|
29
|
+
threadId: z.ZodString;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
export declare const FinishActionSchema: z.ZodObject<{
|
|
32
|
+
version: z.ZodLiteral<1>;
|
|
33
|
+
action: z.ZodLiteral<"finish">;
|
|
34
|
+
summary: z.ZodString;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
export declare const ActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
37
|
+
version: z.ZodLiteral<1>;
|
|
38
|
+
action: z.ZodLiteral<"spawn">;
|
|
39
|
+
task: z.ZodString;
|
|
40
|
+
writeScope: z.ZodArray<z.ZodString>;
|
|
41
|
+
focusFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
42
|
+
allowRepositoryWide: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
+
model: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
45
|
+
version: z.ZodLiteral<1>;
|
|
46
|
+
action: z.ZodLiteral<"wait">;
|
|
47
|
+
threadIds: z.ZodArray<z.ZodString>;
|
|
48
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
49
|
+
version: z.ZodLiteral<1>;
|
|
50
|
+
action: z.ZodLiteral<"inspect_diff">;
|
|
51
|
+
threadId: z.ZodString;
|
|
52
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
53
|
+
version: z.ZodLiteral<1>;
|
|
54
|
+
action: z.ZodLiteral<"review">;
|
|
55
|
+
threadId: z.ZodString;
|
|
56
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
57
|
+
version: z.ZodLiteral<1>;
|
|
58
|
+
action: z.ZodLiteral<"merge">;
|
|
59
|
+
threadId: z.ZodString;
|
|
60
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
61
|
+
version: z.ZodLiteral<1>;
|
|
62
|
+
action: z.ZodLiteral<"finish">;
|
|
63
|
+
summary: z.ZodString;
|
|
64
|
+
}, z.core.$strict>], "action">;
|
|
65
|
+
export type SpawnAction = z.infer<typeof SpawnActionSchema>;
|
|
66
|
+
export type WaitAction = z.infer<typeof WaitActionSchema>;
|
|
67
|
+
export type InspectDiffAction = z.infer<typeof InspectDiffActionSchema>;
|
|
68
|
+
export type ReviewAction = z.infer<typeof ReviewActionSchema>;
|
|
69
|
+
export type MergeAction = z.infer<typeof MergeActionSchema>;
|
|
70
|
+
export type FinishAction = z.infer<typeof FinishActionSchema>;
|
|
71
|
+
export type Action = z.infer<typeof ActionSchema>;
|
|
72
|
+
export declare function parseAction(input: unknown): Action;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const version = z.literal(1);
|
|
4
|
+
const threadId = z
|
|
5
|
+
.string()
|
|
6
|
+
.min(1)
|
|
7
|
+
.max(200)
|
|
8
|
+
.regex(/^[A-Za-z0-9._:-]+$/);
|
|
9
|
+
const repositoryRelativePath = z
|
|
10
|
+
.string()
|
|
11
|
+
.min(1)
|
|
12
|
+
.max(1024)
|
|
13
|
+
.refine((value) => !value.includes("\0"), "Path cannot contain null bytes")
|
|
14
|
+
.refine((value) => !path.posix.isAbsolute(value) && !path.win32.isAbsolute(value), "Path must be relative")
|
|
15
|
+
.refine((value) => !value.replaceAll("\\", "/").split("/").includes(".."), "Path cannot traverse outside the repository");
|
|
16
|
+
export const SpawnActionSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
version,
|
|
19
|
+
action: z.literal("spawn"),
|
|
20
|
+
task: z.string().min(1).max(20_000),
|
|
21
|
+
writeScope: z.array(repositoryRelativePath).min(1).max(200),
|
|
22
|
+
focusFiles: z.array(repositoryRelativePath).max(200).optional(),
|
|
23
|
+
allowRepositoryWide: z.boolean().optional(),
|
|
24
|
+
model: z.string().min(1).max(200).optional(),
|
|
25
|
+
})
|
|
26
|
+
.strict()
|
|
27
|
+
.refine((data) => {
|
|
28
|
+
if (data.writeScope.includes(".")) {
|
|
29
|
+
return data.allowRepositoryWide === true;
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}, "Repository-wide write scope ('.') requires allowRepositoryWide to be true");
|
|
33
|
+
export const WaitActionSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
version,
|
|
36
|
+
action: z.literal("wait"),
|
|
37
|
+
threadIds: z.array(threadId).min(1).max(100),
|
|
38
|
+
})
|
|
39
|
+
.strict();
|
|
40
|
+
export const InspectDiffActionSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
version,
|
|
43
|
+
action: z.literal("inspect_diff"),
|
|
44
|
+
threadId,
|
|
45
|
+
})
|
|
46
|
+
.strict();
|
|
47
|
+
export const ReviewActionSchema = z
|
|
48
|
+
.object({
|
|
49
|
+
version,
|
|
50
|
+
action: z.literal("review"),
|
|
51
|
+
threadId,
|
|
52
|
+
})
|
|
53
|
+
.strict();
|
|
54
|
+
export const MergeActionSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
version,
|
|
57
|
+
action: z.literal("merge"),
|
|
58
|
+
threadId,
|
|
59
|
+
})
|
|
60
|
+
.strict();
|
|
61
|
+
export const FinishActionSchema = z
|
|
62
|
+
.object({
|
|
63
|
+
version,
|
|
64
|
+
action: z.literal("finish"),
|
|
65
|
+
summary: z.string().min(1).max(100_000),
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
|
+
export const ActionSchema = z.discriminatedUnion("action", [
|
|
69
|
+
SpawnActionSchema,
|
|
70
|
+
WaitActionSchema,
|
|
71
|
+
InspectDiffActionSchema,
|
|
72
|
+
ReviewActionSchema,
|
|
73
|
+
MergeActionSchema,
|
|
74
|
+
FinishActionSchema,
|
|
75
|
+
]);
|
|
76
|
+
export function parseAction(input) {
|
|
77
|
+
const result = ActionSchema.safeParse(input);
|
|
78
|
+
if (!result.success) {
|
|
79
|
+
const details = result.error.issues
|
|
80
|
+
.map((issue) => `${issue.path.join(".") || "payload"}: ${issue.message}`)
|
|
81
|
+
.join("; ");
|
|
82
|
+
throw new Error(`Invalid action payload: ${details}`);
|
|
83
|
+
}
|
|
84
|
+
return result.data;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=action-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-schema.js","sourceRoot":"","sources":["../../src/core/action-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common REPL interface and execution primitives for ContextOS / Swarm.
|
|
3
|
+
*/
|
|
4
|
+
/** Result of executing a code snippet in the REPL. */
|
|
5
|
+
export interface ExecResult {
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
hasFinal: boolean;
|
|
9
|
+
finalValue: string | null;
|
|
10
|
+
}
|
|
11
|
+
/** Callback the host provides to handle llm_query() calls. */
|
|
12
|
+
export type LlmQueryHandler = (subContext: string, instruction: string) => Promise<string>;
|
|
13
|
+
/** Callback the host provides to handle thread() calls. */
|
|
14
|
+
export type ThreadHandler = (task: string, context: string, agentBackend: string, model: string, files: string[]) => Promise<{
|
|
15
|
+
result: string;
|
|
16
|
+
success: boolean;
|
|
17
|
+
filesChanged: string[];
|
|
18
|
+
durationMs: number;
|
|
19
|
+
}>;
|
|
20
|
+
/** Callback the host provides to handle merge_threads() calls. */
|
|
21
|
+
export type MergeHandler = () => Promise<{
|
|
22
|
+
result: string;
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Common execution engine interface implemented by PythonRepl (legacy/optional Python subprocess).
|
|
27
|
+
*/
|
|
28
|
+
export interface Repl {
|
|
29
|
+
readonly isAlive: boolean;
|
|
30
|
+
/** Start/initialize the execution runtime. */
|
|
31
|
+
start(signal?: AbortSignal): Promise<void>;
|
|
32
|
+
/** Gracefully shut down and release resources. */
|
|
33
|
+
shutdown(): void;
|
|
34
|
+
/** Register callback for llm_query() calls. */
|
|
35
|
+
setLlmQueryHandler(handler: LlmQueryHandler): void;
|
|
36
|
+
/** Register callback for thread() calls. */
|
|
37
|
+
setThreadHandler(handler: ThreadHandler): void;
|
|
38
|
+
/** Register callback for merge_threads() calls. */
|
|
39
|
+
setMergeHandler(handler: MergeHandler): void;
|
|
40
|
+
/** Inject context string into the execution environment. */
|
|
41
|
+
setContext(text: string): Promise<void>;
|
|
42
|
+
/** Reset the FINAL sentinel flag. */
|
|
43
|
+
resetFinal(): Promise<void>;
|
|
44
|
+
/** Execute a code snippet and return captured output. */
|
|
45
|
+
execute(code: string): Promise<ExecResult>;
|
|
46
|
+
/** Execution language target ('javascript' or 'python'). */
|
|
47
|
+
getLanguage(): "javascript" | "python";
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repl-interface.js","sourceRoot":"","sources":["../../src/core/repl-interface.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent Python REPL manager for swarm-code.
|
|
3
|
+
*
|
|
4
|
+
* Spawns a single Python subprocess running `runtime.py` and keeps it alive
|
|
5
|
+
* across multiple RLM iterations. Communication uses line-delimited JSON
|
|
6
|
+
* over stdin/stdout.
|
|
7
|
+
*
|
|
8
|
+
* Extended from rlm-cli with thread_request and merge_request handlers.
|
|
9
|
+
*/
|
|
10
|
+
import type { ExecResult, LlmQueryHandler, MergeHandler, Repl, ThreadHandler } from "./repl-interface.js";
|
|
11
|
+
export * from "./repl-interface.js";
|
|
12
|
+
export declare class PythonRepl implements Repl {
|
|
13
|
+
private proc;
|
|
14
|
+
private rl;
|
|
15
|
+
private llmQueryHandler;
|
|
16
|
+
private threadHandler;
|
|
17
|
+
private mergeHandler;
|
|
18
|
+
/**
|
|
19
|
+
* Pending resolvers for messages we're waiting on from Python.
|
|
20
|
+
* Each entry maps a unique key (requestId or message type) to a one-shot resolve/reject pair.
|
|
21
|
+
* Using requestId prevents collisions when two messages of the same type are in-flight.
|
|
22
|
+
*/
|
|
23
|
+
private pending;
|
|
24
|
+
/** Whether the REPL subprocess is alive. */
|
|
25
|
+
get isAlive(): boolean;
|
|
26
|
+
getLanguage(): "javascript" | "python";
|
|
27
|
+
/**
|
|
28
|
+
* Start the Python subprocess and wait for it to signal readiness.
|
|
29
|
+
*/
|
|
30
|
+
start(signal?: AbortSignal): Promise<void>;
|
|
31
|
+
/** Register the callback that handles llm_query() calls from Python. */
|
|
32
|
+
setLlmQueryHandler(handler: LlmQueryHandler): void;
|
|
33
|
+
/** Register the callback that handles thread() calls from Python. */
|
|
34
|
+
setThreadHandler(handler: ThreadHandler): void;
|
|
35
|
+
/** Register the callback that handles merge_threads() calls from Python. */
|
|
36
|
+
setMergeHandler(handler: MergeHandler): void;
|
|
37
|
+
/** Inject the full context string into the Python REPL. */
|
|
38
|
+
setContext(text: string): Promise<void>;
|
|
39
|
+
/** Reset the Final sentinel variable. */
|
|
40
|
+
resetFinal(): Promise<void>;
|
|
41
|
+
/** Execute a code snippet and return the result. */
|
|
42
|
+
execute(code: string): Promise<ExecResult>;
|
|
43
|
+
/** Gracefully shut down the Python subprocess. */
|
|
44
|
+
shutdown(): void;
|
|
45
|
+
private send;
|
|
46
|
+
private handleLine;
|
|
47
|
+
private handleLlmQueryMessage;
|
|
48
|
+
private handleThreadRequestMessage;
|
|
49
|
+
private handleMergeRequestMessage;
|
|
50
|
+
/**
|
|
51
|
+
* Wait for an inbound message from Python.
|
|
52
|
+
* @param type - Message type to wait for.
|
|
53
|
+
* @param requestId - Optional unique key for request-response pairs.
|
|
54
|
+
* Prevents collisions when multiple in-flight messages share the same type.
|
|
55
|
+
* Falls back to `type` when omitted (safe for singleton messages like "ready").
|
|
56
|
+
*/
|
|
57
|
+
private waitForMessage;
|
|
58
|
+
private cleanup;
|
|
59
|
+
}
|