@jstn-sdk/ma 0.1.12 → 0.1.13
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/.agents/plugins/marketplace.json +0 -0
- package/.codex/agents/Architect.toml +0 -2
- package/.codex/agents/Auditor.toml +0 -2
- package/.codex/agents/Builder.toml +0 -2
- package/.codex/agents/Flow.toml +0 -2
- package/.codex/agents/Sage.toml +0 -2
- package/.codex/agents/Vibe.toml +0 -2
- package/.codex/hooks.json +14 -13
- package/.codex/prompts/enforcement.md +4 -0
- package/.codex/prompts/skill-contract.md +4 -0
- package/COVERAGE.md +211 -0
- package/DEMO.md +265 -0
- package/README.md +159 -16
- package/bin/ma.js +219 -14
- package/data/clone-data.ledger.json +41 -0
- package/data/clone-data.proof.json +50 -0
- package/data/clone-data.rvf +37 -0
- package/docs/README.md +4 -1
- package/docs/assets/image/Screenshot(1).png +0 -0
- package/docs/assets/image/Screenshot(2).png +0 -0
- package/docs/assets/image/Screenshot(3).png +0 -0
- package/docs/assets/image/Screenshot(4).png +0 -0
- package/docs/assets/image/Screenshot(5).png +0 -0
- package/docs/assets/image/Screenshot(6).png +0 -0
- package/docs/assets/image/Screenshot(7).png +0 -0
- package/docs/assets/image/Screenshot(8).png +0 -0
- package/docs/assets/image/Screenshot(9).png +0 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -0
- package/docs/getting-started.md +38 -22
- package/docs/installed-sdk.md +0 -0
- package/docs/mcp-setup.md +35 -0
- package/docs/onboarding.md +18 -2
- package/docs/prompt-guidance-contract.md +17 -0
- package/docs/prompt-guidance-fragments/active-autonomy-core.md +7 -0
- package/docs/qa/release-issue-gates-0.1.13.json +644 -0
- package/docs/qa/{release-readiness-0.1.12.md → release-readiness-0.1.13.md} +25 -9
- package/docs/qa/release-readiness-0.1.5.md +1 -1
- package/docs/reference/native-engineering-patterns.md +0 -0
- package/docs/reference/native-security-playbooks.md +6 -0
- package/docs/reference/native-source-selection.md +6 -0
- package/docs/reference/native-style-and-deslop.md +0 -0
- package/docs/release-spec.md +25 -9
- package/docs/skills.md +14 -1
- package/index.js +222 -2
- package/mcp/collections.json +23 -6
- package/mcp/local/code-intel.js +0 -0
- package/mcp/local/memory.js +0 -0
- package/mcp/local/playbooks.js +0 -0
- package/mcp/local/state.js +0 -0
- package/mcp/local/team-run.js +48 -1
- package/mcp/local/trace.js +0 -0
- package/mcp/local-capabilities.json +0 -0
- package/mcp/native-playbooks.json +0 -0
- package/mcp/servers.json +24 -0
- package/package.json +5 -2
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +8 -1
- package/plugins/meta-architect/obsidian/main.js +401 -0
- package/plugins/meta-architect/obsidian/manifest.json +9 -0
- package/plugins/meta-architect/obsidian/styles.css +7 -0
- package/plugins/meta-architect/skills/align/SKILL.md +0 -0
- package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +2 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +3 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
- package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
- package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
- package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +2 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +0 -0
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +0 -0
- package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +2 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +8 -0
- package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
- package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +2 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +7 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +2 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/scripts/active-autonomy-hook.mjs +96 -0
- package/scripts/biome-staged.js +0 -0
- package/scripts/build-linux-packages.mjs +0 -0
- package/scripts/doctor.js +17 -4
- package/scripts/install.sh +28 -0
- package/scripts/linux-package-lib.mjs +0 -0
- package/scripts/linux-package-smoke.mjs +0 -0
- package/scripts/plugin-sync.js +0 -0
- package/scripts/postinstall.js +0 -0
- package/scripts/ralph/prompt.md +35 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +0 -0
- package/scripts/release-verify.js +166 -1
- package/scripts/setup-npmrc.js +0 -0
- package/skills/align/SKILL.md +0 -0
- package/skills/align/agents/openai.yaml +0 -0
- package/skills/align/references/shared-language.md +0 -0
- package/skills/arch/SKILL.md +2 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +3 -0
- package/skills/build/agents/openai.yaml +0 -0
- package/skills/cleanup/SKILL.md +0 -0
- package/skills/cleanup/agents/openai.yaml +0 -0
- package/skills/cleanup/references/style-and-deslop.md +0 -0
- package/skills/diagnose/SKILL.md +0 -0
- package/skills/diagnose/agents/openai.yaml +0 -0
- package/skills/flow/SKILL.md +2 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/maestro/SKILL.md +0 -0
- package/skills/maestro/agents/openai.yaml +0 -0
- package/skills/maestro/references/core-release-rules.md +0 -0
- package/skills/maestro/references/native-ingest-map.md +0 -0
- package/skills/sage/SKILL.md +2 -0
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +8 -0
- package/skills/tdd/SKILL.md +0 -0
- package/skills/tdd/agents/openai.yaml +0 -0
- package/skills/vet/SKILL.md +2 -0
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +7 -0
- package/skills/vibe/SKILL.md +2 -0
- package/skills/vibe/agents/openai.yaml +0 -0
- package/src/bootstrap.js +17 -0
- package/src/build-gate.js +2 -2
- package/src/launcher.js +4 -0
- package/src/mcp-live-client.js +289 -3
- package/src/paths.js +4 -0
- package/src/policy.js +1 -1
- package/src/release-issue-gates.js +190 -0
- package/src/runtime/active-autonomy-core.js +208 -0
- package/src/runtime/alignment-sentinel.js +165 -0
- package/src/runtime/architect-review.js +88 -0
- package/src/runtime/build-readiness.js +28 -4
- package/src/runtime/code-graph-rehearse.js +113 -0
- package/src/runtime/context-economy-core.js +276 -0
- package/src/runtime/continuity-notes.js +0 -0
- package/src/runtime/core-source-ingest.js +379 -0
- package/src/runtime/detached-provider.js +74 -0
- package/src/runtime/environment-awareness-core.js +460 -0
- package/src/runtime/exposure-catalog.js +276 -0
- package/src/runtime/guidance-stack.js +0 -0
- package/src/runtime/helper-orchestration-core.js +307 -0
- package/src/runtime/learning-loop-core.js +238 -0
- package/src/runtime/maestro-events.js +18 -0
- package/src/runtime/maestro-manager.js +19 -0
- package/src/runtime/maestro-state.js +125 -0
- package/src/runtime/mcp-policy.js +192 -0
- package/src/runtime/obsidian-integration-core.js +851 -0
- package/src/runtime/obsidian-plugin-bridge.js +739 -0
- package/src/runtime/orchestrator.js +0 -0
- package/src/runtime/prompt-strategy-core.js +230 -0
- package/src/runtime/quorum-review.js +90 -0
- package/src/runtime/ralph-execution-core.js +217 -0
- package/src/runtime/redaction-gateway.js +174 -0
- package/src/runtime/runtime-state.js +843 -2
- package/src/runtime/semantic-recording-core.js +147 -0
- package/src/runtime/signal-hooks.js +15 -0
- package/src/runtime/skills-registry-export.js +670 -0
- package/src/runtime/startup-path.js +0 -0
- package/src/runtime/universal-plugin-broker-core.js +575 -0
- package/src/runtime/workspace-intelligence-runtime.js +674 -0
- package/src/runtime/workspace-virtualizer.js +102 -0
- package/src/runtime/workspaces.js +0 -0
- package/src/runtime-artifacts.js +225 -62
- package/src/skill-installer.js +0 -0
- package/src/skills.js +876 -84
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { ensureDir } from "../fs-utils.js";
|
|
5
|
+
import { getRuntimeSubsystemPath } from "../paths.js";
|
|
6
|
+
|
|
7
|
+
export function getRuntimeLogsRoot() {
|
|
8
|
+
return getRuntimeSubsystemPath("logs");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function resolveDetachedProvider() {
|
|
12
|
+
const preferred = process.env.MA_DETACHED_PROVIDER ?? "";
|
|
13
|
+
if (preferred === "tmux" || process.env.MA_TMUX_PROVIDER === "1") {
|
|
14
|
+
const probe = spawnSync("tmux", ["ls"], { encoding: "utf8" });
|
|
15
|
+
if (!probe.error) {
|
|
16
|
+
return "tmux";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return "none";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function launchDetachedTrack({ trackId, title, command, args = [] }) {
|
|
24
|
+
const provider = resolveDetachedProvider();
|
|
25
|
+
await ensureDir(getRuntimeLogsRoot());
|
|
26
|
+
const logPath = path.join(getRuntimeLogsRoot(), `${trackId}.log`);
|
|
27
|
+
|
|
28
|
+
if (provider !== "tmux") {
|
|
29
|
+
await fs.writeFile(
|
|
30
|
+
logPath,
|
|
31
|
+
`provider=none\ntitle=${title}\ncommand=${[command, ...args].join(" ")}\n`,
|
|
32
|
+
"utf8",
|
|
33
|
+
);
|
|
34
|
+
return {
|
|
35
|
+
provider: "none",
|
|
36
|
+
executionPane: null,
|
|
37
|
+
pid: null,
|
|
38
|
+
logPath,
|
|
39
|
+
started: false,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const sessionName = `ma_${trackId.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
44
|
+
const shellCommand = `${[command, ...args].join(" ")} > ${logPath} 2>&1`;
|
|
45
|
+
const started = spawnSync(
|
|
46
|
+
"tmux",
|
|
47
|
+
["new-session", "-d", "-s", sessionName, "/bin/sh", "-lc", shellCommand],
|
|
48
|
+
{ encoding: "utf8" },
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (started.status !== 0) {
|
|
52
|
+
await fs.writeFile(
|
|
53
|
+
logPath,
|
|
54
|
+
`provider=tmux\nstatus=failed\nstderr=${started.stderr ?? ""}\n`,
|
|
55
|
+
"utf8",
|
|
56
|
+
);
|
|
57
|
+
return {
|
|
58
|
+
provider: "tmux",
|
|
59
|
+
executionPane: sessionName,
|
|
60
|
+
pid: null,
|
|
61
|
+
logPath,
|
|
62
|
+
started: false,
|
|
63
|
+
error: started.stderr?.trim() || "tmux launch failed",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
provider: "tmux",
|
|
69
|
+
executionPane: sessionName,
|
|
70
|
+
pid: null,
|
|
71
|
+
logPath,
|
|
72
|
+
started: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { ensureDir, readJson, writeFileIfMissing, writeJson } from "../fs-utils.js";
|
|
5
|
+
import { getRepoRoot, getRuntimeSubsystemPath, packageRoot } from "../paths.js";
|
|
6
|
+
|
|
7
|
+
export const environmentAwarenessSchemaVersion = "0.1.0";
|
|
8
|
+
export const environmentCapabilityRecordType = "environment_capability";
|
|
9
|
+
|
|
10
|
+
const repoSkillSurfaces = [
|
|
11
|
+
{ relativePath: "skills", owner: "ma_owned", scope: "repo_local", capabilityType: "skill" },
|
|
12
|
+
{
|
|
13
|
+
relativePath: ".agents/skills",
|
|
14
|
+
owner: "host_native",
|
|
15
|
+
scope: "repo_local",
|
|
16
|
+
capabilityType: "skill",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
relativePath: ".codex/skills",
|
|
20
|
+
owner: "host_native",
|
|
21
|
+
scope: "repo_local",
|
|
22
|
+
capabilityType: "skill",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
relativePath: ".claude/skills",
|
|
26
|
+
owner: "host_native",
|
|
27
|
+
scope: "repo_local",
|
|
28
|
+
capabilityType: "skill",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
relativePath: ".cursor/rules",
|
|
32
|
+
owner: "host_native",
|
|
33
|
+
scope: "repo_local",
|
|
34
|
+
capabilityType: "rule",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
relativePath: ".windsurf",
|
|
38
|
+
owner: "host_native",
|
|
39
|
+
scope: "repo_local",
|
|
40
|
+
capabilityType: "rule",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
relativePath: "plugins/meta-architect/skills",
|
|
44
|
+
owner: "ma_owned",
|
|
45
|
+
scope: "repo_local",
|
|
46
|
+
capabilityType: "skill",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
const repoMcpSurfaces = [
|
|
51
|
+
{ relativePath: "mcp/servers.json", owner: "repo_local", scope: "repo_local" },
|
|
52
|
+
{ relativePath: "mcp/local-capabilities.json", owner: "ma_owned", scope: "repo_local" },
|
|
53
|
+
{ relativePath: ".mcp.json", owner: "repo_local", scope: "repo_local" },
|
|
54
|
+
{ relativePath: "plugins/meta-architect/.mcp.json", owner: "ma_owned", scope: "repo_local" },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const repoPluginSurfaces = [
|
|
58
|
+
{ relativePath: "plugins", owner: "repo_local", scope: "repo_local" },
|
|
59
|
+
{ relativePath: ".agents/plugins/marketplace.json", owner: "repo_local", scope: "repo_local" },
|
|
60
|
+
{
|
|
61
|
+
relativePath: "plugins/meta-architect/.codex-plugin/plugin.json",
|
|
62
|
+
owner: "ma_owned",
|
|
63
|
+
scope: "repo_local",
|
|
64
|
+
},
|
|
65
|
+
{ relativePath: "plugins/meta-architect/.app.json", owner: "ma_owned", scope: "repo_local" },
|
|
66
|
+
{
|
|
67
|
+
relativePath: "plugins/meta-architect/obsidian/manifest.json",
|
|
68
|
+
owner: "ma_owned",
|
|
69
|
+
scope: "repo_local",
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
const globalSkillSurfaces = [
|
|
74
|
+
[".codex/skills", "host_native"],
|
|
75
|
+
[".agents/skills", "host_native"],
|
|
76
|
+
[".claude/skills", "host_native"],
|
|
77
|
+
[".cursor/skills", "host_native"],
|
|
78
|
+
[".config/opencode/skills", "host_native"],
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
function normalizeName(value) {
|
|
82
|
+
return `${value ?? ""}`.trim();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function uniqueCapabilities(capabilities) {
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
return capabilities.filter((capability) => {
|
|
88
|
+
const key = [
|
|
89
|
+
capability.capability_type,
|
|
90
|
+
capability.source_scope,
|
|
91
|
+
capability.source_path,
|
|
92
|
+
capability.name,
|
|
93
|
+
].join("\0");
|
|
94
|
+
if (seen.has(key)) return false;
|
|
95
|
+
seen.add(key);
|
|
96
|
+
return true;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function redactGlobalPath(targetPath, home = os.homedir()) {
|
|
101
|
+
const normalizedHome = path.resolve(home);
|
|
102
|
+
const normalizedTarget = path.resolve(targetPath);
|
|
103
|
+
if (normalizedTarget === normalizedHome) return "~";
|
|
104
|
+
if (normalizedTarget.startsWith(`${normalizedHome}${path.sep}`)) {
|
|
105
|
+
return `~/${path.relative(normalizedHome, normalizedTarget).split(path.sep).join("/")}`;
|
|
106
|
+
}
|
|
107
|
+
return normalizedTarget;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function packageCapabilitySourcePath(repoRoot) {
|
|
111
|
+
const normalizedPackageRoot = path.resolve(packageRoot);
|
|
112
|
+
return normalizedPackageRoot === repoRoot ? "." : "package://@jstn-sdk/ma";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function pathExists(targetPath) {
|
|
116
|
+
try {
|
|
117
|
+
await fs.access(targetPath);
|
|
118
|
+
return true;
|
|
119
|
+
} catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function readJsonIfExists(targetPath) {
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(await fs.readFile(targetPath, "utf8"));
|
|
127
|
+
} catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function discoverSkillSurface({ rootPath, sourcePath, sourceScope, owner, capabilityType }) {
|
|
133
|
+
if (!(await pathExists(rootPath))) return [];
|
|
134
|
+
const entries = await fs.readdir(rootPath, { withFileTypes: true }).catch(() => []);
|
|
135
|
+
const capabilities = [];
|
|
136
|
+
for (const entry of entries) {
|
|
137
|
+
if (!entry.isDirectory()) continue;
|
|
138
|
+
const skillDir = path.join(rootPath, entry.name);
|
|
139
|
+
const skillMdPath = path.join(skillDir, "SKILL.md");
|
|
140
|
+
const hasSkillMd = await pathExists(skillMdPath);
|
|
141
|
+
const ruleFiles =
|
|
142
|
+
capabilityType === "rule"
|
|
143
|
+
? (await fs.readdir(skillDir).catch(() => [])).filter((file) => file.endsWith(".md"))
|
|
144
|
+
: [];
|
|
145
|
+
if (!hasSkillMd && ruleFiles.length === 0) continue;
|
|
146
|
+
capabilities.push(
|
|
147
|
+
createEnvironmentCapability({
|
|
148
|
+
name: entry.name,
|
|
149
|
+
capabilityType,
|
|
150
|
+
owner,
|
|
151
|
+
sourceScope,
|
|
152
|
+
sourcePath: `${sourcePath}/${entry.name}`,
|
|
153
|
+
entrypoint: hasSkillMd ? "SKILL.md" : ruleFiles[0],
|
|
154
|
+
confidence: hasSkillMd ? "high" : "medium",
|
|
155
|
+
}),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
return capabilities;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function discoverMcpSurface({ targetPath, sourcePath, owner, sourceScope }) {
|
|
162
|
+
const document = await readJsonIfExists(targetPath);
|
|
163
|
+
if (!document) return [];
|
|
164
|
+
const records = [];
|
|
165
|
+
const servers = document.mcpServers ?? document.servers ?? {};
|
|
166
|
+
if (Array.isArray(servers)) {
|
|
167
|
+
for (const server of servers) {
|
|
168
|
+
records.push(
|
|
169
|
+
createEnvironmentCapability({
|
|
170
|
+
name: normalizeName(server.name ?? server.category ?? server.capability),
|
|
171
|
+
capabilityType: "mcp_server",
|
|
172
|
+
owner,
|
|
173
|
+
sourceScope,
|
|
174
|
+
sourcePath,
|
|
175
|
+
entrypoint: normalizeName(server.endpoint ?? server.url ?? server.module),
|
|
176
|
+
confidence: "medium",
|
|
177
|
+
}),
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
} else if (servers && typeof servers === "object") {
|
|
181
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
182
|
+
records.push(
|
|
183
|
+
createEnvironmentCapability({
|
|
184
|
+
name,
|
|
185
|
+
capabilityType: "mcp_server",
|
|
186
|
+
owner,
|
|
187
|
+
sourceScope,
|
|
188
|
+
sourcePath,
|
|
189
|
+
entrypoint: normalizeName(server?.endpoint ?? server?.url ?? server?.command),
|
|
190
|
+
confidence: "medium",
|
|
191
|
+
}),
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const capabilities = Array.isArray(document.capabilities) ? document.capabilities : [];
|
|
196
|
+
for (const capability of capabilities) {
|
|
197
|
+
records.push(
|
|
198
|
+
createEnvironmentCapability({
|
|
199
|
+
name: normalizeName(capability.capability ?? capability.name),
|
|
200
|
+
capabilityType: "local_capability",
|
|
201
|
+
owner,
|
|
202
|
+
sourceScope,
|
|
203
|
+
sourcePath,
|
|
204
|
+
entrypoint: normalizeName(capability.module ?? capability.readinessCheck),
|
|
205
|
+
confidence: "high",
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return records.filter((record) => record.name);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async function discoverPluginSurface({ targetPath, sourcePath, owner, sourceScope }) {
|
|
213
|
+
if (!(await pathExists(targetPath))) return [];
|
|
214
|
+
const records = [];
|
|
215
|
+
const stat = await fs.stat(targetPath).catch(() => null);
|
|
216
|
+
if (!stat) return records;
|
|
217
|
+
if (stat.isDirectory()) {
|
|
218
|
+
const entries = await fs.readdir(targetPath, { withFileTypes: true }).catch(() => []);
|
|
219
|
+
for (const entry of entries) {
|
|
220
|
+
if (!entry.isDirectory()) continue;
|
|
221
|
+
records.push(
|
|
222
|
+
createEnvironmentCapability({
|
|
223
|
+
name: entry.name,
|
|
224
|
+
capabilityType: "plugin",
|
|
225
|
+
owner,
|
|
226
|
+
sourceScope,
|
|
227
|
+
sourcePath: `${sourcePath}/${entry.name}`,
|
|
228
|
+
entrypoint: null,
|
|
229
|
+
confidence: "medium",
|
|
230
|
+
}),
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
return records;
|
|
234
|
+
}
|
|
235
|
+
const document = await readJsonIfExists(targetPath);
|
|
236
|
+
records.push(
|
|
237
|
+
createEnvironmentCapability({
|
|
238
|
+
name: normalizeName(document?.name ?? document?.id ?? path.basename(sourcePath)),
|
|
239
|
+
capabilityType: "plugin",
|
|
240
|
+
owner,
|
|
241
|
+
sourceScope,
|
|
242
|
+
sourcePath,
|
|
243
|
+
entrypoint: path.basename(sourcePath),
|
|
244
|
+
confidence: document ? "high" : "low",
|
|
245
|
+
}),
|
|
246
|
+
);
|
|
247
|
+
return records.filter((record) => record.name);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function getEnvironmentAwarenessCorePath() {
|
|
251
|
+
return getRuntimeSubsystemPath("context", "environment-awareness-core.json");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function createEnvironmentCapability({
|
|
255
|
+
name,
|
|
256
|
+
capabilityType,
|
|
257
|
+
owner,
|
|
258
|
+
sourceScope,
|
|
259
|
+
sourcePath,
|
|
260
|
+
entrypoint = null,
|
|
261
|
+
confidence = "medium",
|
|
262
|
+
}) {
|
|
263
|
+
if (!name || !capabilityType || !owner || !sourceScope || !sourcePath) {
|
|
264
|
+
throw new Error("environment capability requires name, capabilityType, owner, scope, and path");
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
record_type: environmentCapabilityRecordType,
|
|
268
|
+
name,
|
|
269
|
+
capability_type: capabilityType,
|
|
270
|
+
owner,
|
|
271
|
+
source_scope: sourceScope,
|
|
272
|
+
source_path: sourcePath,
|
|
273
|
+
entrypoint,
|
|
274
|
+
confidence,
|
|
275
|
+
records_as: "available_capability",
|
|
276
|
+
never_records_as: "build_evidence",
|
|
277
|
+
may_use_when: ["task_relevant", "lane_approved", "safe_read_only"],
|
|
278
|
+
use_requires: ["$maestro_or_owning_lane_selection", "redaction_gateway_for_provider_bound_use"],
|
|
279
|
+
mutation_allowed: false,
|
|
280
|
+
authority: "$maestro_or_owning_lane",
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function createDefaultEnvironmentAwarenessCore({ capabilities = [] } = {}) {
|
|
285
|
+
return {
|
|
286
|
+
schemaVersion: environmentAwarenessSchemaVersion,
|
|
287
|
+
product: "Meta-Architect",
|
|
288
|
+
purpose:
|
|
289
|
+
"Discovers existing workspace, host, MCP, and plugin capabilities so MA can use relevant tools intentionally without taking ownership or treating them as build evidence.",
|
|
290
|
+
discovery_policy: {
|
|
291
|
+
default_scopes: ["repo_local", "package_local"],
|
|
292
|
+
global_scopes_require_opt_in: true,
|
|
293
|
+
auto_run_discovered_tools: false,
|
|
294
|
+
mutate_discovered_configs: false,
|
|
295
|
+
expose_private_global_paths: false,
|
|
296
|
+
records_as: "available_capability",
|
|
297
|
+
never_records_as: "build_evidence",
|
|
298
|
+
authority_returns_to: "$maestro_or_owning_lane",
|
|
299
|
+
},
|
|
300
|
+
known_surface_types: ["skill", "rule", "mcp_server", "local_capability", "plugin"],
|
|
301
|
+
capabilities: uniqueCapabilities(capabilities),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function validateEnvironmentAwarenessCore(value) {
|
|
306
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
307
|
+
throw new Error("environment awareness core must be an object");
|
|
308
|
+
}
|
|
309
|
+
if (value.schemaVersion !== environmentAwarenessSchemaVersion) {
|
|
310
|
+
throw new Error(`Unsupported environment awareness schemaVersion: ${value.schemaVersion}`);
|
|
311
|
+
}
|
|
312
|
+
if (value.discovery_policy?.records_as !== "available_capability") {
|
|
313
|
+
throw new Error("environment awareness must record as available_capability");
|
|
314
|
+
}
|
|
315
|
+
if (value.discovery_policy?.never_records_as !== "build_evidence") {
|
|
316
|
+
throw new Error("environment awareness must never record as build_evidence");
|
|
317
|
+
}
|
|
318
|
+
if (value.discovery_policy?.auto_run_discovered_tools !== false) {
|
|
319
|
+
throw new Error("environment awareness must not auto-run discovered tools");
|
|
320
|
+
}
|
|
321
|
+
if (!Array.isArray(value.capabilities)) {
|
|
322
|
+
throw new Error("environment awareness core requires capabilities array");
|
|
323
|
+
}
|
|
324
|
+
for (const capability of value.capabilities) {
|
|
325
|
+
if (
|
|
326
|
+
capability?.record_type !== environmentCapabilityRecordType ||
|
|
327
|
+
capability.records_as !== "available_capability" ||
|
|
328
|
+
capability.never_records_as !== "build_evidence" ||
|
|
329
|
+
capability.mutation_allowed !== false
|
|
330
|
+
) {
|
|
331
|
+
throw new Error("environment capabilities must be read-only available_capability records");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return value;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export async function discoverEnvironmentCapabilities({
|
|
338
|
+
cwd = getRepoRoot(),
|
|
339
|
+
home = os.homedir(),
|
|
340
|
+
includeGlobal = false,
|
|
341
|
+
} = {}) {
|
|
342
|
+
const repoRoot = path.resolve(cwd);
|
|
343
|
+
const capabilities = [];
|
|
344
|
+
for (const surface of repoSkillSurfaces) {
|
|
345
|
+
capabilities.push(
|
|
346
|
+
...(await discoverSkillSurface({
|
|
347
|
+
rootPath: path.join(repoRoot, surface.relativePath),
|
|
348
|
+
sourcePath: surface.relativePath,
|
|
349
|
+
sourceScope: surface.scope,
|
|
350
|
+
owner: surface.owner,
|
|
351
|
+
capabilityType: surface.capabilityType,
|
|
352
|
+
})),
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
for (const surface of repoMcpSurfaces) {
|
|
356
|
+
capabilities.push(
|
|
357
|
+
...(await discoverMcpSurface({
|
|
358
|
+
targetPath: path.join(repoRoot, surface.relativePath),
|
|
359
|
+
sourcePath: surface.relativePath,
|
|
360
|
+
sourceScope: surface.scope,
|
|
361
|
+
owner: surface.owner,
|
|
362
|
+
})),
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
for (const surface of repoPluginSurfaces) {
|
|
366
|
+
capabilities.push(
|
|
367
|
+
...(await discoverPluginSurface({
|
|
368
|
+
targetPath: path.join(repoRoot, surface.relativePath),
|
|
369
|
+
sourcePath: surface.relativePath,
|
|
370
|
+
sourceScope: surface.scope,
|
|
371
|
+
owner: surface.owner,
|
|
372
|
+
})),
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (includeGlobal) {
|
|
377
|
+
for (const [relativePath, owner] of globalSkillSurfaces) {
|
|
378
|
+
const rootPath = path.join(home, relativePath);
|
|
379
|
+
capabilities.push(
|
|
380
|
+
...(await discoverSkillSurface({
|
|
381
|
+
rootPath,
|
|
382
|
+
sourcePath: redactGlobalPath(rootPath, home),
|
|
383
|
+
sourceScope: "global_user_config",
|
|
384
|
+
owner,
|
|
385
|
+
capabilityType: "skill",
|
|
386
|
+
})),
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
capabilities.push(
|
|
392
|
+
createEnvironmentCapability({
|
|
393
|
+
name: "package-root",
|
|
394
|
+
capabilityType: "plugin",
|
|
395
|
+
owner: "ma_owned",
|
|
396
|
+
sourceScope: "package_local",
|
|
397
|
+
sourcePath: packageCapabilitySourcePath(repoRoot),
|
|
398
|
+
entrypoint: "package.json",
|
|
399
|
+
confidence: "high",
|
|
400
|
+
}),
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
return uniqueCapabilities(capabilities);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export async function createDiscoveredEnvironmentAwarenessCore(options = {}) {
|
|
407
|
+
return validateEnvironmentAwarenessCore(
|
|
408
|
+
createDefaultEnvironmentAwarenessCore({
|
|
409
|
+
capabilities: await discoverEnvironmentCapabilities(options),
|
|
410
|
+
}),
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function selectEnvironmentCapabilitiesForTask(core, taskIntent = "") {
|
|
415
|
+
const document = validateEnvironmentAwarenessCore(core);
|
|
416
|
+
const intent = taskIntent.toLowerCase();
|
|
417
|
+
const selected = document.capabilities.filter((capability) => {
|
|
418
|
+
const haystack = [
|
|
419
|
+
capability.name,
|
|
420
|
+
capability.capability_type,
|
|
421
|
+
capability.owner,
|
|
422
|
+
capability.source_path,
|
|
423
|
+
capability.entrypoint,
|
|
424
|
+
]
|
|
425
|
+
.filter(Boolean)
|
|
426
|
+
.join(" ")
|
|
427
|
+
.toLowerCase();
|
|
428
|
+
return intent
|
|
429
|
+
.split(/[^a-z0-9_-]+/i)
|
|
430
|
+
.filter((token) => token.length >= 3)
|
|
431
|
+
.some((token) => haystack.includes(token));
|
|
432
|
+
});
|
|
433
|
+
return {
|
|
434
|
+
record_type: "environment_capability_selection",
|
|
435
|
+
task_intent: taskIntent,
|
|
436
|
+
selected,
|
|
437
|
+
selected_count: selected.length,
|
|
438
|
+
records_as: "available_capability",
|
|
439
|
+
never_records_as: "build_evidence",
|
|
440
|
+
authority: "$maestro_or_owning_lane",
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export async function seedEnvironmentAwarenessCoreArtifacts(options = {}) {
|
|
445
|
+
await ensureDir(getRuntimeSubsystemPath("context"));
|
|
446
|
+
await writeFileIfMissing(
|
|
447
|
+
getEnvironmentAwarenessCorePath(),
|
|
448
|
+
`${JSON.stringify(await createDiscoveredEnvironmentAwarenessCore(options), null, 2)}\n`,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export async function refreshEnvironmentAwarenessCore(options = {}) {
|
|
453
|
+
const next = await createDiscoveredEnvironmentAwarenessCore(options);
|
|
454
|
+
await writeJson(getEnvironmentAwarenessCorePath(), next);
|
|
455
|
+
return next;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export async function loadEnvironmentAwarenessCore() {
|
|
459
|
+
return validateEnvironmentAwarenessCore(await readJson(getEnvironmentAwarenessCorePath()));
|
|
460
|
+
}
|