@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
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readJson, writeJson } from "../fs-utils.js";
|
|
4
|
+
|
|
5
|
+
export const runtimeSchemaVersion = "0.1.0";
|
|
6
|
+
|
|
7
|
+
const SCAN_ROOTS = [".ma/context", ".ma/learning", ".ma/hooks/receipts", ".ma/obsidian", "mcp"];
|
|
8
|
+
const ROOT_FILES = [".ma/setup-receipt.json"];
|
|
9
|
+
|
|
10
|
+
async function listJsonFiles(root, relative = "") {
|
|
11
|
+
const directory = path.join(root, relative);
|
|
12
|
+
let entries;
|
|
13
|
+
try {
|
|
14
|
+
entries = await fs.readdir(directory, { withFileTypes: true });
|
|
15
|
+
} catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const files = [];
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const child = path.join(relative, entry.name);
|
|
21
|
+
if (entry.isDirectory()) files.push(...(await listJsonFiles(root, child)));
|
|
22
|
+
else if (entry.isFile() && entry.name.endsWith(".json")) files.push(child);
|
|
23
|
+
}
|
|
24
|
+
return files;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function migrationFiles(root) {
|
|
28
|
+
const nested = (
|
|
29
|
+
await Promise.all(SCAN_ROOTS.map((relative) => listJsonFiles(root, relative)))
|
|
30
|
+
).flat();
|
|
31
|
+
return [...new Set([...nested, ...ROOT_FILES])].filter(async (relative) => {
|
|
32
|
+
try {
|
|
33
|
+
return (await fs.stat(path.join(root, relative))).isFile();
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Promise.filter is intentionally avoided: this keeps the scan synchronous in its final form.
|
|
41
|
+
async function existingMigrationFiles(root) {
|
|
42
|
+
const files = await migrationFiles(root);
|
|
43
|
+
return (
|
|
44
|
+
await Promise.all(
|
|
45
|
+
files.map(async (relative) => {
|
|
46
|
+
try {
|
|
47
|
+
return (await fs.stat(path.join(root, relative))).isFile() ? relative : null;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
).filter(Boolean);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function findOutdatedSchemas(root) {
|
|
57
|
+
const outdated = [];
|
|
58
|
+
for (const relative of await existingMigrationFiles(root)) {
|
|
59
|
+
try {
|
|
60
|
+
const value = await readJson(path.join(root, relative));
|
|
61
|
+
if (!value || Array.isArray(value) || typeof value !== "object") {
|
|
62
|
+
outdated.push({ path: relative, schemaVersion: null, error: "invalid_shape" });
|
|
63
|
+
} else if (value.schemaVersion !== runtimeSchemaVersion) {
|
|
64
|
+
outdated.push({
|
|
65
|
+
path: relative,
|
|
66
|
+
schemaVersion: value.schemaVersion ?? null,
|
|
67
|
+
expected: runtimeSchemaVersion,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
outdated.push({ path: relative, schemaVersion: null, error: "invalid_json" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return outdated;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function migrateSchemas(root, { dryRun = false, rollback = false } = {}) {
|
|
78
|
+
const files = await existingMigrationFiles(root);
|
|
79
|
+
if (rollback) return rollbackSchemas(root);
|
|
80
|
+
|
|
81
|
+
const plans = [];
|
|
82
|
+
for (const relative of files) {
|
|
83
|
+
try {
|
|
84
|
+
const value = await readJson(path.join(root, relative));
|
|
85
|
+
if (!value || Array.isArray(value) || typeof value !== "object") {
|
|
86
|
+
return {
|
|
87
|
+
status: "failed",
|
|
88
|
+
migrated: [],
|
|
89
|
+
errors: [{ path: relative, error: "invalid_shape" }],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (value.schemaVersion !== runtimeSchemaVersion) {
|
|
93
|
+
plans.push({ relative, value, from: value.schemaVersion ?? null });
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
return {
|
|
97
|
+
status: "failed",
|
|
98
|
+
migrated: [],
|
|
99
|
+
errors: [{ path: relative, error: "invalid_json" }],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (dryRun)
|
|
104
|
+
return {
|
|
105
|
+
status: plans.length ? "outdated" : "current",
|
|
106
|
+
dryRun: true,
|
|
107
|
+
migrated: plans.map(({ relative, from }) => ({
|
|
108
|
+
path: relative,
|
|
109
|
+
from,
|
|
110
|
+
to: runtimeSchemaVersion,
|
|
111
|
+
})),
|
|
112
|
+
errors: [],
|
|
113
|
+
};
|
|
114
|
+
if (plans.length === 0) return { status: "current", migrated: [], errors: [] };
|
|
115
|
+
|
|
116
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
117
|
+
const backupRoot = path.join(root, ".ma", "migrations", "backups", stamp);
|
|
118
|
+
for (const { relative, value } of plans) {
|
|
119
|
+
const target = path.join(root, relative);
|
|
120
|
+
const backup = path.join(backupRoot, relative);
|
|
121
|
+
await fs.mkdir(path.dirname(backup), { recursive: true });
|
|
122
|
+
await fs.copyFile(target, backup);
|
|
123
|
+
await writeJson(target, { ...value, schemaVersion: runtimeSchemaVersion });
|
|
124
|
+
}
|
|
125
|
+
await writeJson(path.join(root, ".ma", "migrations", "latest.json"), {
|
|
126
|
+
schemaVersion: runtimeSchemaVersion,
|
|
127
|
+
createdAt: new Date().toISOString(),
|
|
128
|
+
backupRoot: path.relative(root, backupRoot),
|
|
129
|
+
files: plans.map(({ relative }) => relative),
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
status: "migrated",
|
|
133
|
+
backupRoot: path.relative(root, backupRoot),
|
|
134
|
+
migrated: plans.map(({ relative, from }) => ({
|
|
135
|
+
path: relative,
|
|
136
|
+
from,
|
|
137
|
+
to: runtimeSchemaVersion,
|
|
138
|
+
})),
|
|
139
|
+
errors: [],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function rollbackSchemas(root) {
|
|
144
|
+
let receipt;
|
|
145
|
+
try {
|
|
146
|
+
receipt = await readJson(path.join(root, ".ma", "migrations", "latest.json"));
|
|
147
|
+
} catch {
|
|
148
|
+
return { status: "current", restored: [], errors: [] };
|
|
149
|
+
}
|
|
150
|
+
const restored = [];
|
|
151
|
+
for (const relative of receipt.files ?? []) {
|
|
152
|
+
const source = path.join(root, receipt.backupRoot, relative);
|
|
153
|
+
const target = path.join(root, relative);
|
|
154
|
+
try {
|
|
155
|
+
await fs.copyFile(source, target);
|
|
156
|
+
restored.push(relative);
|
|
157
|
+
} catch {
|
|
158
|
+
return { status: "failed", restored, errors: [{ path: relative, error: "backup_missing" }] };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return { status: "rolled_back", restored, errors: [] };
|
|
162
|
+
}
|
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { ensureDir, readJson, writeFileIfMissing } from "../fs-utils.js";
|
|
3
4
|
import { getRuntimeSubsystemPath } from "../paths.js";
|
|
4
5
|
|
|
@@ -65,3 +66,15 @@ export async function loadRuntimeHooksConfig() {
|
|
|
65
66
|
export async function loadRuntimeHooksAuditLog() {
|
|
66
67
|
return fs.readFile(getRuntimeHooksAuditPath(), "utf8");
|
|
67
68
|
}
|
|
69
|
+
|
|
70
|
+
export async function loadRuntimeHookReceipts() {
|
|
71
|
+
const root = path.join(getRuntimeHooksRoot(), "receipts");
|
|
72
|
+
const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
73
|
+
return Promise.all(
|
|
74
|
+
entries
|
|
75
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
|
|
76
|
+
.sort((left, right) => right.name.localeCompare(left.name))
|
|
77
|
+
.slice(0, 20)
|
|
78
|
+
.map((entry) => readJson(path.join(root, entry.name))),
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync as pathExistsSync } from "node:fs";
|
|
2
3
|
import fs from "node:fs/promises";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
6
|
+
import { getAgentInvocation } from "../agents.js";
|
|
5
7
|
import { ensureDir, readJson, writeFileIfMissing } from "../fs-utils.js";
|
|
6
8
|
import { getRepoRoot, getRuntimeSubsystemPath } from "../paths.js";
|
|
7
9
|
|
|
@@ -13,6 +15,13 @@ const configHome = process.env.XDG_CONFIG_HOME || path.join(home, ".config");
|
|
|
13
15
|
const codexHome = process.env.CODEX_HOME?.trim() || path.join(home, ".codex");
|
|
14
16
|
const claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || path.join(home, ".claude");
|
|
15
17
|
|
|
18
|
+
function getOpenClawGlobalSkillsDir() {
|
|
19
|
+
if (pathExistsSync(path.join(home, ".openclaw"))) return path.join(home, ".openclaw/skills");
|
|
20
|
+
if (pathExistsSync(path.join(home, ".clawdbot"))) return path.join(home, ".clawdbot/skills");
|
|
21
|
+
if (pathExistsSync(path.join(home, ".moltbot"))) return path.join(home, ".moltbot/skills");
|
|
22
|
+
return path.join(home, ".openclaw/skills");
|
|
23
|
+
}
|
|
24
|
+
|
|
16
25
|
const universalTargets = [
|
|
17
26
|
"codex",
|
|
18
27
|
"opencode",
|
|
@@ -105,7 +114,7 @@ const nonUniversalDirs = {
|
|
|
105
114
|
mux: ".mux/skills",
|
|
106
115
|
neovate: ".neovate/skills",
|
|
107
116
|
openclaw: "skills",
|
|
108
|
-
pi: ".pi/
|
|
117
|
+
pi: ".pi/skills",
|
|
109
118
|
pochi: ".pochi/skills",
|
|
110
119
|
adal: ".adal/skills",
|
|
111
120
|
qoder: ".qoder/skills",
|
|
@@ -120,11 +129,57 @@ const nonUniversalDirs = {
|
|
|
120
129
|
const globalDirOverrides = {
|
|
121
130
|
codex: path.join(codexHome, "skills"),
|
|
122
131
|
opencode: path.join(configHome, "opencode", "skills"),
|
|
123
|
-
cursor: path.join(home, ".
|
|
132
|
+
cursor: path.join(home, ".agents", "skills"),
|
|
124
133
|
amp: path.join(configHome, "agents", "skills"),
|
|
125
134
|
"claude-code": path.join(claudeHome, "skills"),
|
|
135
|
+
"gemini-cli": path.join(home, ".gemini", "skills"),
|
|
136
|
+
"github-copilot": path.join(home, ".copilot", "skills"),
|
|
137
|
+
antigravity: path.join(home, ".gemini", "antigravity", "skills"),
|
|
138
|
+
openclaw: getOpenClawGlobalSkillsDir(),
|
|
139
|
+
pi: path.join(home, ".pi", "agent", "skills"),
|
|
140
|
+
windsurf: path.join(home, ".codeium", "windsurf", "skills"),
|
|
141
|
+
goose: path.join(configHome, "goose", "skills"),
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const universalNativeContract = {
|
|
145
|
+
artifact: "skill",
|
|
146
|
+
path: `${canonicalSkillsDir}/{name}/SKILL.md`,
|
|
147
|
+
format: "markdown",
|
|
148
|
+
activation: "host-loads-canonical-agent-skills",
|
|
126
149
|
};
|
|
127
150
|
|
|
151
|
+
function surfaceForAgent(name) {
|
|
152
|
+
if (
|
|
153
|
+
[
|
|
154
|
+
"cursor",
|
|
155
|
+
"antigravity",
|
|
156
|
+
"windsurf",
|
|
157
|
+
"continue",
|
|
158
|
+
"roo",
|
|
159
|
+
"kiro-cli",
|
|
160
|
+
"junie",
|
|
161
|
+
"tabnine-cli",
|
|
162
|
+
"github-copilot",
|
|
163
|
+
].includes(name)
|
|
164
|
+
)
|
|
165
|
+
return "ide";
|
|
166
|
+
if (["devin", "openhands", "replit"].includes(name)) return "cloud";
|
|
167
|
+
return "cli";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function vendorForAgent(name) {
|
|
171
|
+
if (["codex", "deepagents"].includes(name)) return "openai";
|
|
172
|
+
if (["claude-code"].includes(name)) return "anthropic";
|
|
173
|
+
if (["gemini-cli", "antigravity", "dexto", "firebender", "kimi-cli"].includes(name))
|
|
174
|
+
return "google";
|
|
175
|
+
if (["github-copilot"].includes(name)) return "github";
|
|
176
|
+
if (["cursor", "windsurf", "continue", "roo", "kiro-cli", "junie", "tabnine-cli"].includes(name))
|
|
177
|
+
return "ide";
|
|
178
|
+
if (["openclaw", "pi", "hermes-agent"].includes(name))
|
|
179
|
+
return name === "pi" ? "pi" : name === "openclaw" ? "openclaw" : "nous-research";
|
|
180
|
+
return "community";
|
|
181
|
+
}
|
|
182
|
+
|
|
128
183
|
export const agentRegistry = Object.fromEntries([
|
|
129
184
|
...universalTargets.map((name) => [
|
|
130
185
|
name,
|
|
@@ -134,6 +189,12 @@ export const agentRegistry = Object.fromEntries([
|
|
|
134
189
|
skillsDir: canonicalSkillsDir,
|
|
135
190
|
globalSkillsDir: globalDirOverrides[name] ?? path.join(home, ".agents", "skills"),
|
|
136
191
|
universal: true,
|
|
192
|
+
vendor: vendorForAgent(name),
|
|
193
|
+
product: name,
|
|
194
|
+
surface: surfaceForAgent(name),
|
|
195
|
+
support: "native",
|
|
196
|
+
native_artifacts: [universalNativeContract],
|
|
197
|
+
verification: "distribution-contract",
|
|
137
198
|
},
|
|
138
199
|
]),
|
|
139
200
|
...nonUniversalTargets.map((name) => [
|
|
@@ -144,6 +205,19 @@ export const agentRegistry = Object.fromEntries([
|
|
|
144
205
|
skillsDir: nonUniversalDirs[name],
|
|
145
206
|
globalSkillsDir: globalDirOverrides[name] ?? path.join(home, nonUniversalDirs[name]),
|
|
146
207
|
universal: false,
|
|
208
|
+
vendor: vendorForAgent(name),
|
|
209
|
+
product: name,
|
|
210
|
+
surface: surfaceForAgent(name),
|
|
211
|
+
support: "native",
|
|
212
|
+
native_artifacts: [
|
|
213
|
+
{
|
|
214
|
+
artifact: "skill",
|
|
215
|
+
path: `${nonUniversalDirs[name]}/{name}/SKILL.md`,
|
|
216
|
+
format: "markdown",
|
|
217
|
+
activation: "host-loads-project-skill-directory",
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
verification: "distribution-contract",
|
|
147
221
|
},
|
|
148
222
|
]),
|
|
149
223
|
]);
|
|
@@ -161,6 +235,8 @@ export function createDefaultSkillsRegistryExport() {
|
|
|
161
235
|
canonical_dir: canonicalSkillsDir,
|
|
162
236
|
universal_targets: universalTargets,
|
|
163
237
|
non_universal_targets: nonUniversalTargets,
|
|
238
|
+
target_count: Object.keys(agentRegistry).length,
|
|
239
|
+
targets: agentRegistry,
|
|
164
240
|
authority_boundary: {
|
|
165
241
|
exported_payloads_may_mutate_release_state: false,
|
|
166
242
|
exported_payloads_are_managed_workers: false,
|
|
@@ -282,7 +358,7 @@ export function resolveSkillInstallPlan({
|
|
|
282
358
|
};
|
|
283
359
|
}
|
|
284
360
|
|
|
285
|
-
if (global && agent.universal) {
|
|
361
|
+
if (global && agent.universal && targetDir === canonicalDir) {
|
|
286
362
|
return {
|
|
287
363
|
action: "canonical-only",
|
|
288
364
|
canonicalDir,
|
|
@@ -303,9 +379,9 @@ export function resolveSkillInstallPlan({
|
|
|
303
379
|
}
|
|
304
380
|
|
|
305
381
|
return {
|
|
306
|
-
action: agent.universal ? "canonical-only" : "symlink",
|
|
382
|
+
action: agent.universal && targetDir === canonicalDir ? "canonical-only" : "symlink",
|
|
307
383
|
canonicalDir,
|
|
308
|
-
targetDir
|
|
384
|
+
targetDir,
|
|
309
385
|
skipped: false,
|
|
310
386
|
reason: agent.universal
|
|
311
387
|
? "universal agent reads canonical directory directly"
|
|
@@ -347,7 +423,7 @@ export function createSkillCompatibilityPayload({
|
|
|
347
423
|
};
|
|
348
424
|
}
|
|
349
425
|
|
|
350
|
-
export function renderSkillCompatibilitySkillMd(payload) {
|
|
426
|
+
export function renderSkillCompatibilitySkillMd(payload, { agentType = "codex" } = {}) {
|
|
351
427
|
if (payload?.record_type !== "skill_compatibility_payload") {
|
|
352
428
|
throw new Error("Expected skill compatibility payload");
|
|
353
429
|
}
|
|
@@ -362,6 +438,12 @@ export function renderSkillCompatibilitySkillMd(payload) {
|
|
|
362
438
|
"",
|
|
363
439
|
"This exported host payload is a compatibility entrypoint for Meta-Architect.",
|
|
364
440
|
"",
|
|
441
|
+
"## Invocation",
|
|
442
|
+
"",
|
|
443
|
+
`- Start the umbrella lane with \`${getAgentInvocation(agentType, agentType === "codex" ? "maestro" : payload.name)}\` in this host.`,
|
|
444
|
+
"- Dispatch to the canonical MA runtime as `ma run '$maestro'`.",
|
|
445
|
+
"- Lane aliases: `arch`, `sage`, `flow`, `vet`, `vibe`, and `build`.",
|
|
446
|
+
"",
|
|
365
447
|
"## Authority",
|
|
366
448
|
"",
|
|
367
449
|
"- Route execution through `$maestro` or the owning MA lane.",
|
|
@@ -402,6 +484,7 @@ export function createHostInstallReceipt({ payload, installPlan }) {
|
|
|
402
484
|
|
|
403
485
|
export function createSkillLockEntry({
|
|
404
486
|
payload,
|
|
487
|
+
agentType = "codex",
|
|
405
488
|
source = "meta-architect",
|
|
406
489
|
sourceType = "local",
|
|
407
490
|
sourceUrl = "skills/",
|
|
@@ -416,7 +499,7 @@ export function createSkillLockEntry({
|
|
|
416
499
|
throw new Error("Skill lock entry requires a compatibility payload");
|
|
417
500
|
}
|
|
418
501
|
|
|
419
|
-
const renderedPayload = renderSkillCompatibilitySkillMd(payload);
|
|
502
|
+
const renderedPayload = renderSkillCompatibilitySkillMd(payload, { agentType });
|
|
420
503
|
const folderHash =
|
|
421
504
|
skillFolderHash ??
|
|
422
505
|
createHash("sha256")
|
|
@@ -490,10 +573,11 @@ export async function writeSkillCompatibilityExport({
|
|
|
490
573
|
mode,
|
|
491
574
|
agentRootExists: effectiveAgentRootExists,
|
|
492
575
|
});
|
|
493
|
-
const skillMd = renderSkillCompatibilitySkillMd(payload);
|
|
576
|
+
const skillMd = renderSkillCompatibilitySkillMd(payload, { agentType });
|
|
494
577
|
const lockEntry = validateSkillLockEntry(
|
|
495
578
|
createSkillLockEntry({
|
|
496
579
|
payload,
|
|
580
|
+
agentType,
|
|
497
581
|
selectedAgentTargets: [agentType],
|
|
498
582
|
...lockMetadata,
|
|
499
583
|
}),
|
|
File without changes
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { ensureDir, readJson, writeJson } from "../fs-utils.js";
|
|
3
|
+
import { getRuntimeSubsystemPath } from "../paths.js";
|
|
4
|
+
|
|
5
|
+
export const taskContractSchemaVersion = "0.1.0";
|
|
6
|
+
|
|
7
|
+
export function getTaskContractRoot() {
|
|
8
|
+
return getRuntimeSubsystemPath("tasks", "contracts");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function safeContractId(id) {
|
|
12
|
+
if (String(id ?? "").includes("/") || String(id ?? "").includes("\\"))
|
|
13
|
+
throw new Error("task contract id is required");
|
|
14
|
+
const safe = String(id ?? "")
|
|
15
|
+
.trim()
|
|
16
|
+
.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
17
|
+
if (!safe || safe === "." || safe === "..") throw new Error("task contract id is required");
|
|
18
|
+
return safe;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createTaskContract({
|
|
22
|
+
goal,
|
|
23
|
+
contextUsed = [],
|
|
24
|
+
assumptions = [],
|
|
25
|
+
constraints = [],
|
|
26
|
+
risk = "medium",
|
|
27
|
+
verification = [],
|
|
28
|
+
stopCondition,
|
|
29
|
+
persist = true,
|
|
30
|
+
}) {
|
|
31
|
+
if (!goal || !stopCondition) throw new Error("task contract requires goal and stopCondition");
|
|
32
|
+
return validateTaskContract({
|
|
33
|
+
schemaVersion: taskContractSchemaVersion,
|
|
34
|
+
record_type: "task_contract",
|
|
35
|
+
goal,
|
|
36
|
+
context_used: contextUsed,
|
|
37
|
+
assumptions,
|
|
38
|
+
constraints,
|
|
39
|
+
risk,
|
|
40
|
+
verification,
|
|
41
|
+
stop_condition: stopCondition,
|
|
42
|
+
persist,
|
|
43
|
+
created_at: new Date().toISOString(),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function validateTaskContract(contract) {
|
|
48
|
+
if (
|
|
49
|
+
!contract ||
|
|
50
|
+
contract.schemaVersion !== taskContractSchemaVersion ||
|
|
51
|
+
contract.record_type !== "task_contract"
|
|
52
|
+
)
|
|
53
|
+
throw new Error("invalid task contract schema");
|
|
54
|
+
for (const field of ["goal", "stop_condition"]) {
|
|
55
|
+
if (typeof contract[field] !== "string" || contract[field].trim() === "")
|
|
56
|
+
throw new Error(`task contract requires ${field}`);
|
|
57
|
+
}
|
|
58
|
+
for (const field of ["context_used", "assumptions", "constraints", "verification"]) {
|
|
59
|
+
if (
|
|
60
|
+
!Array.isArray(contract[field]) ||
|
|
61
|
+
contract[field].some((value) => typeof value !== "string")
|
|
62
|
+
)
|
|
63
|
+
throw new Error(`task contract requires string array: ${field}`);
|
|
64
|
+
}
|
|
65
|
+
if (!["low", "medium", "high"].includes(contract.risk))
|
|
66
|
+
throw new Error(`Unsupported task contract risk: ${contract.risk}`);
|
|
67
|
+
return contract;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function writeTaskContract(id, contract) {
|
|
71
|
+
const contractId = safeContractId(id);
|
|
72
|
+
const validated = validateTaskContract(contract);
|
|
73
|
+
await ensureDir(getTaskContractRoot());
|
|
74
|
+
const contractPath = path.join(getTaskContractRoot(), `${contractId}.json`);
|
|
75
|
+
await writeJson(contractPath, validated);
|
|
76
|
+
return contractPath;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function loadTaskContract(id) {
|
|
80
|
+
return validateTaskContract(
|
|
81
|
+
await readJson(path.join(getTaskContractRoot(), `${safeContractId(id)}.json`)),
|
|
82
|
+
);
|
|
83
|
+
}
|