@jstn-sdk/ma 0.1.13 → 0.14.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/.agents/plugins/marketplace.json +0 -0
- package/.codex/agents/Architect.toml +1 -0
- package/.codex/agents/Auditor.toml +1 -0
- package/.codex/agents/Builder.toml +1 -0
- package/.codex/agents/Flow.toml +1 -0
- package/.codex/agents/Sage.toml +1 -0
- package/.codex/agents/Vibe.toml +1 -0
- package/.codex/hooks.json +12 -2
- package/.codex/prompts/enforcement.md +0 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +0 -0
- package/COVERAGE.md +7 -7
- package/DEMO.md +15 -6
- package/LICENSE +0 -0
- package/README.md +126 -793
- package/bin/ma.js +585 -97
- package/data/clone-data.ledger.json +0 -0
- package/data/clone-data.proof.json +0 -0
- package/data/clone-data.rvf +0 -0
- package/docs/README.md +8 -2
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +28 -4
- package/docs/installed-sdk.md +0 -0
- package/docs/mcp-setup.md +30 -1
- package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.0.json} +77 -77
- package/docs/qa/release-readiness-0.1.5.md +0 -0
- package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.0.md} +12 -12
- package/docs/quality.md +24 -0
- package/docs/reference/native-engineering-patterns.md +0 -0
- package/docs/reference/native-security-playbooks.md +0 -0
- package/docs/reference/native-source-selection.md +0 -0
- package/docs/reference/native-style-and-deslop.md +0 -0
- package/docs/release-spec.md +27 -14
- package/docs/skills.md +1 -1
- package/index.js +73 -0
- package/mcp/collections.json +0 -0
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +179 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/playbooks.js +0 -0
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +8 -3
- package/mcp/local/trace.js +0 -0
- package/mcp/local-capabilities.json +9 -0
- package/mcp/native-playbooks.json +0 -0
- package/mcp/servers.json +0 -0
- package/package.json +26 -4
- 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 +2 -2
- package/plugins/meta-architect/obsidian/main.js +137 -4
- package/plugins/meta-architect/obsidian/manifest.json +1 -1
- package/plugins/meta-architect/obsidian/styles.css +0 -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 +0 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +0 -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 +0 -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 +0 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -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 +0 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/schemas/autonomous-task-queue.schema.json +56 -0
- package/schemas/handoff-packet.schema.json +36 -0
- package/schemas/setup-receipt.schema.json +28 -0
- package/schemas/skill-frontmatter.schema.json +20 -0
- package/schemas/support-bundle.schema.json +37 -0
- package/schemas/task-contract.schema.json +31 -0
- package/scripts/active-autonomy-hook.mjs +141 -11
- package/scripts/biome-staged.js +0 -0
- package/scripts/build-linux-packages.mjs +7 -3
- package/scripts/cleanup-test-fixtures.sh +55 -0
- package/scripts/context-hydration-hook.mjs +89 -0
- package/scripts/demo-smoke.js +285 -0
- package/scripts/doctor.js +10 -8
- package/scripts/install.sh +33 -4
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-lib.mjs +0 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/postinstall.js +17 -10
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +0 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +72 -7
- package/scripts/release-verify.js +100 -7
- package/scripts/setup-npmrc.js +48 -23
- package/scripts/skills-install.js +9 -2
- package/scripts/skills-manifest.js +2 -21
- package/scripts/skills-pack.js +2 -2
- package/scripts/skills-validate.js +5 -55
- 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 +0 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +0 -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 +0 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/index.json +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 +0 -0
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +0 -0
- package/skills/tdd/SKILL.md +0 -0
- package/skills/tdd/agents/openai.yaml +0 -0
- package/skills/vet/SKILL.md +0 -0
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +0 -0
- package/skills/vibe/SKILL.md +0 -0
- package/skills/vibe/agents/openai.yaml +0 -0
- package/sprint/00-idea.md +0 -0
- package/sprint/01-architecture.md +0 -0
- package/sprint/02-oss-evidence.md +0 -0
- package/sprint/03-logic.md +0 -0
- package/sprint/04-security.md +0 -0
- package/sprint/05-dx-ux.md +0 -0
- package/sprint/06-build-plan.md +0 -0
- package/sprint/07-release.md +0 -0
- package/src/agents.js +279 -0
- package/src/bootstrap.js +252 -63
- package/src/build-gate.js +0 -0
- package/src/codex-app-server.js +291 -0
- package/src/decision-log.js +0 -0
- package/src/fs-utils.js +175 -4
- package/src/launcher.js +24 -21
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +140 -7
- package/src/paths.js +6 -1
- package/src/policy.js +2 -2
- package/src/prelaunch.js +189 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +62 -0
- package/src/release-operations.js +62 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +0 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +0 -0
- package/src/runtime/architect-review.js +248 -10
- package/src/runtime/autonomous-tasks.js +408 -0
- package/src/runtime/build-readiness.js +0 -0
- package/src/runtime/code-graph-rehearse.js +0 -0
- package/src/runtime/codeburn-core.js +112 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +40 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +0 -0
- package/src/runtime/detached-provider.js +82 -14
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +0 -0
- package/src/runtime/exposure-catalog.js +0 -0
- package/src/runtime/graphify-core.js +167 -0
- package/src/runtime/guidance-stack.js +9 -2
- package/src/runtime/handoff-packets.js +92 -0
- package/src/runtime/headroom-core.js +104 -0
- package/src/runtime/helper-orchestration-core.js +0 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +110 -4
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +0 -0
- package/src/runtime/maestro-manager.js +0 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +0 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +0 -0
- package/src/runtime/obsidian-integration-core.js +255 -17
- package/src/runtime/obsidian-plugin-bridge.js +344 -38
- package/src/runtime/orchestrator.js +0 -0
- package/src/runtime/pi-maestro-core.js +89 -0
- package/src/runtime/preferences.js +79 -0
- package/src/runtime/project-context.js +636 -0
- package/src/runtime/prompt-strategy-core.js +0 -0
- package/src/runtime/quorum-review.js +0 -0
- package/src/runtime/ralph-execution-core.js +0 -0
- package/src/runtime/redaction-gateway.js +218 -19
- package/src/runtime/runtime-state.js +94 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +0 -0
- package/src/runtime/signal-hooks.js +13 -0
- package/src/runtime/skills-registry-export.js +92 -8
- package/src/runtime/startup-path.js +0 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +373 -50
- package/src/runtime/workspace-intelligence-runtime.js +0 -0
- package/src/runtime/workspace-virtualizer.js +0 -0
- package/src/runtime/workspaces.js +0 -0
- package/src/runtime-artifacts.js +0 -0
- package/src/setup-lifecycle.js +359 -0
- package/src/skill-frontmatter.js +78 -0
- package/src/skill-installer.js +226 -71
- package/src/skills.js +297 -19
- package/src/state-sync.js +0 -0
- package/src/test-fixtures.js +543 -0
- package/src/tui/grid.js +67 -0
- package/src/tui/status-grid.js +23 -0
- package/support-bundle.json +114 -0
- package/templates/AGENTS.md +6 -2
- package/templates/catalog-manifest.json +0 -0
- package/templates/model-instructions/core.md +0 -0
- package/templates/model-instructions/release.md +0 -0
- package/templates/model-instructions/security.md +0 -0
- package/templates/quality/ai-quality-rules.yml +37 -0
- 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 -8
- package/docs/onboarding.md +0 -81
- package/docs/prompt-guidance-contract.md +0 -17
- package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
- package/docs/skills-publishing.md +0 -255
package/src/mcp-live-client.js
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { maskSensitiveText } from "./runtime/redaction-gateway.js";
|
|
6
|
+
|
|
7
|
+
const packageMetadata = JSON.parse(
|
|
8
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
export function resolveMcpClientVersion(metadata) {
|
|
12
|
+
return typeof metadata?.version === "string" && metadata.version.trim()
|
|
13
|
+
? metadata.version
|
|
14
|
+
: "0.0.0-dev";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const mcpClientVersion = resolveMcpClientVersion(packageMetadata);
|
|
2
18
|
|
|
3
19
|
const GITMCP_ENDPOINT_PATTERN = /^https:\/\/gitmcp\.io\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
4
20
|
const BRIDGE_COMMAND_ENV = "MA_MCP_REMOTE_BRIDGE_CMD";
|
|
5
21
|
const REQUEST_TIMEOUT_ENV = "MA_MCP_REQUEST_TIMEOUT_MS";
|
|
6
22
|
const DEFAULT_REQUEST_TIMEOUT_MS = 15000;
|
|
23
|
+
const BRIDGE_POLICY_PATH = path.join("mcp", "bridge.json");
|
|
7
24
|
|
|
8
25
|
function readRequestTimeoutMs() {
|
|
9
26
|
const raw = process.env[REQUEST_TIMEOUT_ENV]?.trim();
|
|
@@ -43,12 +60,46 @@ export function hasConfiguredMcpRemoteBridge() {
|
|
|
43
60
|
|
|
44
61
|
export function createMcpLiveClient(endpoint) {
|
|
45
62
|
if (hasConfiguredMcpRemoteBridge()) {
|
|
46
|
-
return new McpStdioBridgeClient(
|
|
63
|
+
return new McpStdioBridgeClient(
|
|
64
|
+
endpoint,
|
|
65
|
+
process.env[BRIDGE_COMMAND_ENV],
|
|
66
|
+
spawn,
|
|
67
|
+
getMcpBridgeConfiguration(),
|
|
68
|
+
);
|
|
47
69
|
}
|
|
48
70
|
|
|
49
71
|
return new McpSseClient(endpoint);
|
|
50
72
|
}
|
|
51
73
|
|
|
74
|
+
export function getMcpBridgeConfiguration(root = process.env.MA_ROOT ?? process.cwd()) {
|
|
75
|
+
const allowedCommands = new Set(
|
|
76
|
+
(process.env.MA_MCP_REMOTE_BRIDGE_ALLOWLIST ?? "")
|
|
77
|
+
.split(",")
|
|
78
|
+
.map((value) => value.trim())
|
|
79
|
+
.filter(Boolean),
|
|
80
|
+
);
|
|
81
|
+
const configPath = path.join(root, BRIDGE_POLICY_PATH);
|
|
82
|
+
try {
|
|
83
|
+
const config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
84
|
+
for (const command of config.allowedCommands ?? []) {
|
|
85
|
+
if (typeof command === "string" && command.trim()) allowedCommands.add(command.trim());
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
configured: true,
|
|
89
|
+
configPath,
|
|
90
|
+
allowedCommands: [...allowedCommands],
|
|
91
|
+
source: "environment+project",
|
|
92
|
+
};
|
|
93
|
+
} catch {
|
|
94
|
+
return {
|
|
95
|
+
configured: true,
|
|
96
|
+
configPath,
|
|
97
|
+
allowedCommands: [...allowedCommands],
|
|
98
|
+
source: allowedCommands.size > 0 ? "environment" : "none",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
52
103
|
export class McpSseClient {
|
|
53
104
|
constructor(baseUrl) {
|
|
54
105
|
this.baseUrl = baseUrl;
|
|
@@ -93,7 +144,7 @@ export class McpSseClient {
|
|
|
93
144
|
capabilities: {},
|
|
94
145
|
clientInfo: {
|
|
95
146
|
name: "meta-architect",
|
|
96
|
-
version:
|
|
147
|
+
version: mcpClientVersion,
|
|
97
148
|
},
|
|
98
149
|
});
|
|
99
150
|
|
|
@@ -227,10 +278,11 @@ export class McpSseClient {
|
|
|
227
278
|
}
|
|
228
279
|
|
|
229
280
|
export class McpStdioBridgeClient {
|
|
230
|
-
constructor(endpoint, commandTemplate, spawnImpl = spawn) {
|
|
281
|
+
constructor(endpoint, commandTemplate, spawnImpl = spawn, bridgeConfiguration = {}) {
|
|
231
282
|
this.endpoint = endpoint;
|
|
232
283
|
this.commandTemplate = commandTemplate;
|
|
233
284
|
this.spawnImpl = spawnImpl;
|
|
285
|
+
this.bridgeConfiguration = bridgeConfiguration;
|
|
234
286
|
this.child = null;
|
|
235
287
|
this.buffer = "";
|
|
236
288
|
this.pending = new Map();
|
|
@@ -240,10 +292,18 @@ export class McpStdioBridgeClient {
|
|
|
240
292
|
}
|
|
241
293
|
|
|
242
294
|
async connect() {
|
|
243
|
-
const { command, args } = buildBridgeCommand(
|
|
295
|
+
const { command, args } = buildBridgeCommand(
|
|
296
|
+
this.commandTemplate,
|
|
297
|
+
this.endpoint,
|
|
298
|
+
this.bridgeConfiguration,
|
|
299
|
+
);
|
|
244
300
|
this.child = this.spawnImpl(command, args, {
|
|
245
301
|
stdio: ["pipe", "pipe", "pipe"],
|
|
246
|
-
env:
|
|
302
|
+
env: buildBridgeEnv(),
|
|
303
|
+
});
|
|
304
|
+
await writeBridgeReceipt(this.endpoint, command, args, {
|
|
305
|
+
status: "started",
|
|
306
|
+
pid: this.child.pid ?? null,
|
|
247
307
|
});
|
|
248
308
|
|
|
249
309
|
this.child.stdout.setEncoding("utf8");
|
|
@@ -254,6 +314,10 @@ export class McpStdioBridgeClient {
|
|
|
254
314
|
});
|
|
255
315
|
this.child.on("error", (error) => {
|
|
256
316
|
this.closed = true;
|
|
317
|
+
void writeBridgeReceipt(this.endpoint, command, args, {
|
|
318
|
+
status: "failed",
|
|
319
|
+
error: error.message,
|
|
320
|
+
});
|
|
257
321
|
for (const [, handlers] of this.pending) {
|
|
258
322
|
handlers.reject(new Error(`MCP bridge failed to start: ${error.message}`));
|
|
259
323
|
}
|
|
@@ -261,6 +325,12 @@ export class McpStdioBridgeClient {
|
|
|
261
325
|
});
|
|
262
326
|
this.child.on("exit", (code, signal) => {
|
|
263
327
|
this.closed = true;
|
|
328
|
+
void writeBridgeReceipt(this.endpoint, command, args, {
|
|
329
|
+
status: "exited",
|
|
330
|
+
code,
|
|
331
|
+
signal,
|
|
332
|
+
stderr: this.stderr,
|
|
333
|
+
});
|
|
264
334
|
const reason = signal
|
|
265
335
|
? `MCP bridge exited with signal ${signal}`
|
|
266
336
|
: `MCP bridge exited with code ${code}`;
|
|
@@ -275,7 +345,7 @@ export class McpStdioBridgeClient {
|
|
|
275
345
|
capabilities: {},
|
|
276
346
|
clientInfo: {
|
|
277
347
|
name: "meta-architect",
|
|
278
|
-
version:
|
|
348
|
+
version: mcpClientVersion,
|
|
279
349
|
},
|
|
280
350
|
});
|
|
281
351
|
|
|
@@ -373,7 +443,7 @@ export class McpStdioBridgeClient {
|
|
|
373
443
|
}
|
|
374
444
|
}
|
|
375
445
|
|
|
376
|
-
function buildBridgeCommand(commandTemplate, endpoint) {
|
|
446
|
+
function buildBridgeCommand(commandTemplate, endpoint, bridgeConfiguration = {}) {
|
|
377
447
|
const template = commandTemplate?.trim();
|
|
378
448
|
if (!template) {
|
|
379
449
|
throw new Error(`${BRIDGE_COMMAND_ENV} is empty`);
|
|
@@ -390,9 +460,49 @@ function buildBridgeCommand(commandTemplate, endpoint) {
|
|
|
390
460
|
}
|
|
391
461
|
|
|
392
462
|
const [command, ...args] = substituted;
|
|
463
|
+
const allowedCommands = new Set(bridgeConfiguration.allowedCommands ?? []);
|
|
464
|
+
const commandName = path.basename(command);
|
|
465
|
+
if (!allowedCommands.has(command) && !allowedCommands.has(commandName)) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
`${BRIDGE_COMMAND_ENV} command is not allowlisted: ${command}. ` +
|
|
468
|
+
"Add its exact command or basename to MA_MCP_REMOTE_BRIDGE_ALLOWLIST or mcp/bridge.json.",
|
|
469
|
+
);
|
|
470
|
+
}
|
|
393
471
|
return { command, args };
|
|
394
472
|
}
|
|
395
473
|
|
|
474
|
+
async function writeBridgeReceipt(endpoint, command, args, details) {
|
|
475
|
+
const root = process.env.MA_ROOT ?? process.cwd();
|
|
476
|
+
const receiptDir = path.join(root, ".ma", "evidence", "mcp-bridge-receipts");
|
|
477
|
+
const safeError = details.error
|
|
478
|
+
? maskSensitiveText(String(details.error)).sanitizedText
|
|
479
|
+
: undefined;
|
|
480
|
+
const safeStderr = details.stderr
|
|
481
|
+
? maskSensitiveText(String(details.stderr)).sanitizedText
|
|
482
|
+
: undefined;
|
|
483
|
+
await fs.mkdir(receiptDir, { recursive: true }).catch(() => {});
|
|
484
|
+
await fs
|
|
485
|
+
.writeFile(
|
|
486
|
+
path.join(receiptDir, `bridge-${Date.now()}-${process.pid}.json`),
|
|
487
|
+
`${JSON.stringify(
|
|
488
|
+
{
|
|
489
|
+
schemaVersion: "0.1.0",
|
|
490
|
+
record_type: "mcp_bridge_receipt",
|
|
491
|
+
generatedAt: new Date().toISOString(),
|
|
492
|
+
endpoint,
|
|
493
|
+
command,
|
|
494
|
+
args,
|
|
495
|
+
...details,
|
|
496
|
+
...(safeError ? { error: safeError } : {}),
|
|
497
|
+
...(safeStderr ? { stderr: safeStderr } : {}),
|
|
498
|
+
},
|
|
499
|
+
null,
|
|
500
|
+
)}\n`,
|
|
501
|
+
{ mode: 0o600 },
|
|
502
|
+
)
|
|
503
|
+
.catch(() => {});
|
|
504
|
+
}
|
|
505
|
+
|
|
396
506
|
async function readResponsePreview(response) {
|
|
397
507
|
try {
|
|
398
508
|
return (await response.text()).replace(/\s+/g, " ").trim().slice(0, 240);
|
|
@@ -457,6 +567,29 @@ function splitCommand(command) {
|
|
|
457
567
|
return parts;
|
|
458
568
|
}
|
|
459
569
|
|
|
570
|
+
function buildBridgeEnv() {
|
|
571
|
+
const passthroughKeys = new Set([
|
|
572
|
+
"PATH",
|
|
573
|
+
"HOME",
|
|
574
|
+
"USERPROFILE",
|
|
575
|
+
"TMPDIR",
|
|
576
|
+
"TMP",
|
|
577
|
+
"TEMP",
|
|
578
|
+
"LANG",
|
|
579
|
+
"LC_ALL",
|
|
580
|
+
"SYSTEMROOT",
|
|
581
|
+
"COMSPEC",
|
|
582
|
+
"MA_ROOT",
|
|
583
|
+
]);
|
|
584
|
+
const env = {};
|
|
585
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
586
|
+
if (passthroughKeys.has(key)) {
|
|
587
|
+
env[key] = value;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return env;
|
|
591
|
+
}
|
|
592
|
+
|
|
460
593
|
export function parseSseEvent(rawEvent) {
|
|
461
594
|
const event = { event: "message", data: "" };
|
|
462
595
|
for (const line of rawEvent.split("\n")) {
|
package/src/paths.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
import { fileURLToPath } from "node:url";
|
|
3
4
|
|
|
@@ -6,7 +7,11 @@ const __dirname = path.dirname(__filename);
|
|
|
6
7
|
|
|
7
8
|
export const packageRoot = path.resolve(__dirname, "..");
|
|
8
9
|
export function getRepoRoot() {
|
|
9
|
-
|
|
10
|
+
const root = process.env.MA_ROOT ? path.resolve(process.env.MA_ROOT) : process.cwd();
|
|
11
|
+
if (fs.realpathSync(root) !== root) {
|
|
12
|
+
throw new Error(`Repository root cannot traverse symlinks: ${root}`);
|
|
13
|
+
}
|
|
14
|
+
return root;
|
|
10
15
|
}
|
|
11
16
|
|
|
12
17
|
export function getRuntimeRoot() {
|
package/src/policy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function validateReleaseOrigin(originBranch) {
|
|
2
|
-
if (originBranch === "
|
|
2
|
+
if (originBranch === "dev") {
|
|
3
3
|
return true;
|
|
4
4
|
}
|
|
5
5
|
|
|
@@ -15,7 +15,7 @@ export function rejectsDirectProdPromotion(originBranch) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function validateMergeTarget(sourceBranch, targetBranch) {
|
|
18
|
-
return sourceBranch.startsWith("feature/") && targetBranch === "
|
|
18
|
+
return sourceBranch.startsWith("feature/") && targetBranch === "dev";
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function canMarkBuildDone(releaseState) {
|
package/src/prelaunch.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
5
|
+
import readline from "node:readline/promises";
|
|
6
|
+
import { agentRegistry, detectInstalled, listAgents } from "./agents.js";
|
|
7
|
+
import {
|
|
8
|
+
createSkillCompatibilityPayload,
|
|
9
|
+
writeSkillCompatibilityExport,
|
|
10
|
+
} from "./runtime/skills-registry-export.js";
|
|
11
|
+
import { ensureSkillsInstalled, ensureSupportBundleInstalled } from "./skill-installer.js";
|
|
12
|
+
|
|
13
|
+
const selectionFile = ".ma/prelaunch.json";
|
|
14
|
+
const projectSignals = {
|
|
15
|
+
codex: [".codex", "AGENTS.md"],
|
|
16
|
+
opencode: [".opencode"],
|
|
17
|
+
"gemini-cli": [".gemini", "GEMINI.md"],
|
|
18
|
+
amp: [".amp"],
|
|
19
|
+
cursor: [".cursor"],
|
|
20
|
+
windsurf: [".windsurf"],
|
|
21
|
+
cline: [".cline"],
|
|
22
|
+
continue: [".continue"],
|
|
23
|
+
roo: [".roo"],
|
|
24
|
+
"kiro-cli": [".kiro"],
|
|
25
|
+
junie: [".junie"],
|
|
26
|
+
};
|
|
27
|
+
const globalSignals = {
|
|
28
|
+
codex: ["~/.codex"],
|
|
29
|
+
opencode: ["~/.config/opencode"],
|
|
30
|
+
"gemini-cli": ["~/.gemini"],
|
|
31
|
+
amp: ["~/.config/agents"],
|
|
32
|
+
cursor: ["~/.cursor"],
|
|
33
|
+
windsurf: ["~/.codeium/windsurf"],
|
|
34
|
+
cline: ["~/.cline"],
|
|
35
|
+
continue: ["~/.continue"],
|
|
36
|
+
roo: ["~/.roo"],
|
|
37
|
+
"kiro-cli": ["~/.kiro"],
|
|
38
|
+
junie: ["~/.junie"],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function expandHome(value) {
|
|
42
|
+
return value.startsWith("~/") ? path.join(os.homedir(), value.slice(2)) : value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function exists(target) {
|
|
46
|
+
try {
|
|
47
|
+
await fs.access(target);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function detectPrelaunchTargets(cwd = process.cwd()) {
|
|
55
|
+
const targets = listAgents().map((agent) => {
|
|
56
|
+
const definition = agentRegistry[agent.id];
|
|
57
|
+
const projectPath =
|
|
58
|
+
definition?.isUniversal && agent.id === "universal"
|
|
59
|
+
? path.join(cwd, ".agents")
|
|
60
|
+
: path.join(cwd, agent.skillsDir);
|
|
61
|
+
const globalPath = expandHome(agent.globalSkillsDir);
|
|
62
|
+
return {
|
|
63
|
+
id: agent.id,
|
|
64
|
+
displayName: agent.displayName,
|
|
65
|
+
surface: agent.surface,
|
|
66
|
+
project: projectPath,
|
|
67
|
+
global: globalPath,
|
|
68
|
+
projectSignals: (projectSignals[agent.id] ?? []).map((signal) => path.join(cwd, signal)),
|
|
69
|
+
globalSignals: (globalSignals[agent.id] ?? []).map(expandHome),
|
|
70
|
+
projectDetected: false,
|
|
71
|
+
globalDetected: false,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
for (const target of targets) {
|
|
76
|
+
const installed = target.surface === "cli" && detectInstalled(target.id).installed;
|
|
77
|
+
target.projectDetected =
|
|
78
|
+
(target.id === "universal" && (await exists(target.project))) ||
|
|
79
|
+
(await Promise.all(target.projectSignals.map(exists))).some(Boolean);
|
|
80
|
+
target.globalDetected =
|
|
81
|
+
installed ||
|
|
82
|
+
(target.id === "universal" && (await exists(target.global))) ||
|
|
83
|
+
(await Promise.all(target.globalSignals.map(exists))).some(Boolean);
|
|
84
|
+
delete target.projectSignals;
|
|
85
|
+
delete target.globalSignals;
|
|
86
|
+
}
|
|
87
|
+
return targets;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function readSelection(cwd) {
|
|
91
|
+
try {
|
|
92
|
+
const value = JSON.parse(await fs.readFile(path.join(cwd, selectionFile), "utf8"));
|
|
93
|
+
if (
|
|
94
|
+
(value.scope === "project" || value.scope === "global") &&
|
|
95
|
+
Array.isArray(value.targets) &&
|
|
96
|
+
value.targets.every((target) => typeof target === "string" && agentRegistry[target])
|
|
97
|
+
) {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function choosePrelaunchInstall({
|
|
107
|
+
cwd = process.cwd(),
|
|
108
|
+
interactive = Boolean(input.isTTY && output.isTTY),
|
|
109
|
+
} = {}) {
|
|
110
|
+
if (!interactive || process.env.MA_SKIP_PRELAUNCH === "1") return null;
|
|
111
|
+
const previous = await readSelection(cwd);
|
|
112
|
+
if (previous) return previous;
|
|
113
|
+
|
|
114
|
+
const detected = await detectPrelaunchTargets(cwd);
|
|
115
|
+
const detectedIds = detected
|
|
116
|
+
.filter((target) => target.projectDetected || target.globalDetected)
|
|
117
|
+
.map((target) => target.id);
|
|
118
|
+
const suggested = detectedIds.length > 0 ? detectedIds : ["codex"];
|
|
119
|
+
console.log("Meta-Architect pre-launch setup");
|
|
120
|
+
console.log("Detected targets:");
|
|
121
|
+
for (const target of detected) {
|
|
122
|
+
if (target.projectDetected || target.globalDetected) {
|
|
123
|
+
console.log(`- ${target.id}: ${target.projectDetected ? "project" : "user"}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const rl = readline.createInterface({ input, output });
|
|
127
|
+
try {
|
|
128
|
+
const answer = await rl.question(
|
|
129
|
+
`Install scope and targets [project:${suggested.join(",")}]: `,
|
|
130
|
+
);
|
|
131
|
+
const value = answer.trim() || `project:${suggested.join(",")}`;
|
|
132
|
+
const [scope, targetValue] = value.split(":", 2);
|
|
133
|
+
const targets = (targetValue || "codex")
|
|
134
|
+
.split(",")
|
|
135
|
+
.map((target) => target.trim())
|
|
136
|
+
.filter((target, index, values) => agentRegistry[target] && values.indexOf(target) === index);
|
|
137
|
+
if (!(scope === "project" || scope === "global") || targets.length === 0) {
|
|
138
|
+
throw new Error("Use project:codex,cursor or global:codex,cursor");
|
|
139
|
+
}
|
|
140
|
+
return { schemaVersion: "0.1.0", scope, targets };
|
|
141
|
+
} finally {
|
|
142
|
+
rl.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function installPrelaunchSelection(selection, cwd = process.cwd()) {
|
|
147
|
+
if (
|
|
148
|
+
!selection ||
|
|
149
|
+
!["project", "global"].includes(selection.scope) ||
|
|
150
|
+
!Array.isArray(selection.targets) ||
|
|
151
|
+
selection.targets.length === 0 ||
|
|
152
|
+
selection.targets.some((target) => typeof target !== "string" || !agentRegistry[target])
|
|
153
|
+
) {
|
|
154
|
+
throw new Error("Invalid pre-launch selection");
|
|
155
|
+
}
|
|
156
|
+
const payload = createSkillCompatibilityPayload({
|
|
157
|
+
name: "meta-architect",
|
|
158
|
+
description: "Meta-Architect host compatibility entrypoint.",
|
|
159
|
+
capabilities: ["maestro", "agent-compatibility"],
|
|
160
|
+
});
|
|
161
|
+
const results = [];
|
|
162
|
+
if (selection.targets.includes("codex")) {
|
|
163
|
+
const skillsRoot =
|
|
164
|
+
selection.scope === "global" ? undefined : path.join(cwd, ".agents", "skills");
|
|
165
|
+
const supportRoot =
|
|
166
|
+
selection.scope === "global" ? undefined : path.join(cwd, ".ma", "support-bundle");
|
|
167
|
+
results.push(
|
|
168
|
+
await ensureSkillsInstalled({ targetRoot: skillsRoot }),
|
|
169
|
+
await ensureSupportBundleInstalled({ targetRoot: supportRoot }),
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
for (const target of selection.targets) {
|
|
173
|
+
if (selection.scope === "global" && target === "codex") continue;
|
|
174
|
+
results.push(
|
|
175
|
+
await writeSkillCompatibilityExport({
|
|
176
|
+
payload,
|
|
177
|
+
agentType: target,
|
|
178
|
+
cwd,
|
|
179
|
+
global: selection.scope === "global",
|
|
180
|
+
agentRootExists: true,
|
|
181
|
+
}),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
await fs.mkdir(path.join(cwd, ".ma"), { recursive: true });
|
|
185
|
+
await fs.writeFile(path.join(cwd, selectionFile), `${JSON.stringify(selection, null, 2)}\n`, {
|
|
186
|
+
mode: 0o600,
|
|
187
|
+
});
|
|
188
|
+
return { selection, results };
|
|
189
|
+
}
|