@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
|
@@ -48,6 +48,13 @@ Use the core repo when you want to develop Meta-Architect itself. Use the plugin
|
|
|
48
48
|
|
|
49
49
|
The plugin-facing bundle should be consumed alongside the repository’s documented packaging/install flow.
|
|
50
50
|
|
|
51
|
+
Recommended CLI install for macOS, Linux, WSL, and Git-Bash:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# One-line install (POSIX shells only; use WSL/Git-Bash on Windows)
|
|
55
|
+
curl -fsSL https://cdn.jsdelivr.net/gh/JustineDevs/meta-architect@main/scripts/install.sh | sh
|
|
56
|
+
```
|
|
57
|
+
|
|
51
58
|
Canonical package/runtime path:
|
|
52
59
|
|
|
53
60
|
Debian-family install:
|
|
@@ -131,7 +138,7 @@ When consuming the plugin:
|
|
|
131
138
|
The plugin version should track the release scope of the core repo.
|
|
132
139
|
|
|
133
140
|
For this repository:
|
|
134
|
-
- plugin scope is aligned to Meta-Architect `v0.1.
|
|
141
|
+
- plugin scope is aligned to Meta-Architect `v0.1.13`
|
|
135
142
|
- any breaking contract change should be versioned intentionally
|
|
136
143
|
|
|
137
144
|
The plugin is one distribution surface of the same product, not a separate product line.
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
const { MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } = require("obsidian");
|
|
2
|
+
|
|
3
|
+
const DEFAULT_SETTINGS = {
|
|
4
|
+
projectName: "Meta-Architect",
|
|
5
|
+
activeContextPath: "Meta-Architect/Plugin Context/Active Note Context.md",
|
|
6
|
+
queuePath: "Meta-Architect/Plugin Requests/request-queue.json",
|
|
7
|
+
attachmentDir: "Meta-Architect/Attachments",
|
|
8
|
+
sourceWorkspace: "",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const FORBIDDEN_TARGETS = [".ma/release.json", ".ma/decisions.json", ".ma/plans/", ".ma/specs/"];
|
|
12
|
+
|
|
13
|
+
module.exports = class MetaArchitectPlugin extends Plugin {
|
|
14
|
+
async onload() {
|
|
15
|
+
this.settings = Object.assign({}, DEFAULT_SETTINGS, (await this.loadData()) || {});
|
|
16
|
+
this.addRibbonIcon("network", "Send current note/selection to MA", async () => {
|
|
17
|
+
await this.captureActiveNote();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const statusBarItem = this.addStatusBarItem();
|
|
21
|
+
statusBarItem.addClass("ma-status");
|
|
22
|
+
statusBarItem.setText("MA: vault context");
|
|
23
|
+
|
|
24
|
+
this.addCommand({
|
|
25
|
+
id: "ma-capture-active-note",
|
|
26
|
+
name: "Send current note/selection to MA",
|
|
27
|
+
callback: async () => this.captureActiveNote(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
this.addCommand({
|
|
31
|
+
id: "ma-drain-request-queue",
|
|
32
|
+
name: "Drain MA request queue",
|
|
33
|
+
callback: async () => {
|
|
34
|
+
const result = await this.drainRequestQueue();
|
|
35
|
+
new Notice(
|
|
36
|
+
`MA queue drained: ${result.processed.length} processed, ${result.refused.length} refused`,
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.addCommand({
|
|
42
|
+
id: "ma-open-context-preview",
|
|
43
|
+
name: "Preview current MA context",
|
|
44
|
+
checkCallback: (checking) => {
|
|
45
|
+
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
|
46
|
+
if (!view) return false;
|
|
47
|
+
if (!checking) new ContextPreviewModal(this.app, this.createSelectionContext()).open();
|
|
48
|
+
return true;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.addCommand({
|
|
53
|
+
id: "ma-open-map",
|
|
54
|
+
name: "Open MA map of content",
|
|
55
|
+
callback: async () => this.openNote("Meta-Architect/Map of Content.md"),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.addSettingTab(new MetaArchitectSettingTab(this.app, this));
|
|
59
|
+
this.registerProtocolHandler();
|
|
60
|
+
this.registerVaultWatchers();
|
|
61
|
+
this.registerInterval(
|
|
62
|
+
window.setInterval(() => this.drainRequestQueue().catch(() => {}), 30 * 1000),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async loadSettings() {
|
|
67
|
+
this.settings = Object.assign({}, DEFAULT_SETTINGS, (await this.loadData()) || {});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async saveSettings() {
|
|
71
|
+
await this.saveData(this.settings);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
createSelectionContext() {
|
|
75
|
+
const file = this.app.workspace.getActiveFile();
|
|
76
|
+
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
|
77
|
+
const leaf = this.app.workspace.activeLeaf;
|
|
78
|
+
const editor = view?.editor || leaf?.view?.editor;
|
|
79
|
+
const selectedText = editor?.getSelection?.() || "";
|
|
80
|
+
return {
|
|
81
|
+
record_type: "obsidian_active_note_context",
|
|
82
|
+
records_as: "vault_context",
|
|
83
|
+
build_evidence: false,
|
|
84
|
+
captured_at: new Date().toISOString(),
|
|
85
|
+
active_note_path: file?.path || null,
|
|
86
|
+
selected_text: selectedText,
|
|
87
|
+
selected_text_char_count: selectedText.length,
|
|
88
|
+
cursor: editor?.getCursor?.() || null,
|
|
89
|
+
pane_state: leaf?.getViewState?.() || null,
|
|
90
|
+
metadata: file ? this.app.metadataCache.getFileCache(file) || {} : {},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async captureActiveNote() {
|
|
95
|
+
const context = this.createSelectionContext();
|
|
96
|
+
const file = this.app.workspace.getActiveFile();
|
|
97
|
+
if (file) {
|
|
98
|
+
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
|
99
|
+
frontmatter.ma_records_as = "vault_context";
|
|
100
|
+
frontmatter.ma_project = this.settings.projectName;
|
|
101
|
+
frontmatter.ma_capabilities = [
|
|
102
|
+
"obsidian_integration_core",
|
|
103
|
+
"active_note_selection_context",
|
|
104
|
+
"metadata_cache_deep_graph",
|
|
105
|
+
];
|
|
106
|
+
if (this.settings.sourceWorkspace) {
|
|
107
|
+
frontmatter.ma_source_workspace = this.settings.sourceWorkspace;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
await this.writeVaultContextNote(
|
|
112
|
+
this.settings.activeContextPath,
|
|
113
|
+
this.renderContextNote(context),
|
|
114
|
+
true,
|
|
115
|
+
);
|
|
116
|
+
await this.writeBinaryAttachment(
|
|
117
|
+
`${this.settings.attachmentDir}/active-context-${Date.now()}.json`,
|
|
118
|
+
JSON.stringify(context, null, 2),
|
|
119
|
+
"application/json",
|
|
120
|
+
);
|
|
121
|
+
new Notice("MA captured current Obsidian context");
|
|
122
|
+
return context;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
renderContextNote(context) {
|
|
126
|
+
const activeLink = context.active_note_path
|
|
127
|
+
? this.app.fileManager.generateMarkdownLink(
|
|
128
|
+
this.app.vault.getAbstractFileByPath(context.active_note_path),
|
|
129
|
+
this.settings.activeContextPath,
|
|
130
|
+
undefined,
|
|
131
|
+
"active note",
|
|
132
|
+
)
|
|
133
|
+
: "none";
|
|
134
|
+
return withVaultContextFrontmatter(`# Active Note Context
|
|
135
|
+
|
|
136
|
+
- Active note: ${activeLink}
|
|
137
|
+
- Selection chars: ${context.selected_text_char_count}
|
|
138
|
+
- Cursor: ${JSON.stringify(context.cursor)}
|
|
139
|
+
- Captured: ${context.captured_at}
|
|
140
|
+
|
|
141
|
+
## Selected Text
|
|
142
|
+
|
|
143
|
+
${context.selected_text || "_No active selection captured._"}
|
|
144
|
+
|
|
145
|
+
## Obsidian MetadataCache
|
|
146
|
+
|
|
147
|
+
\`\`\`json
|
|
148
|
+
${JSON.stringify(context.metadata, null, 2)}
|
|
149
|
+
\`\`\`
|
|
150
|
+
|
|
151
|
+
## Pane State
|
|
152
|
+
|
|
153
|
+
\`\`\`json
|
|
154
|
+
${JSON.stringify(context.pane_state || {}, null, 2)}
|
|
155
|
+
\`\`\`
|
|
156
|
+
`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
registerProtocolHandler() {
|
|
160
|
+
this.registerObsidianProtocolHandler("ma", async (params) => {
|
|
161
|
+
if (params.action === "queue") {
|
|
162
|
+
await this.queueRequest(params);
|
|
163
|
+
new Notice("MA request queued");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (params.action === "capture" || params.open === "active") {
|
|
167
|
+
await this.captureActiveNote();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
await this.openNote(params.path || "Meta-Architect/Map of Content.md");
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
registerVaultWatchers() {
|
|
175
|
+
for (const eventName of ["create", "modify", "delete", "rename"]) {
|
|
176
|
+
this.registerEvent(
|
|
177
|
+
this.app.vault.on(eventName, () => {
|
|
178
|
+
this.drainRequestQueue().catch(() => {});
|
|
179
|
+
}),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
for (const eventName of ["resolved", "changed", "deleted"]) {
|
|
183
|
+
this.registerEvent(
|
|
184
|
+
this.app.metadataCache.on(eventName, () => {
|
|
185
|
+
this.drainRequestQueue().catch(() => {});
|
|
186
|
+
}),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
for (const eventName of ["active-leaf-change", "layout-change"]) {
|
|
190
|
+
this.registerEvent(
|
|
191
|
+
this.app.workspace.on(eventName, () => {
|
|
192
|
+
this.drainRequestQueue().catch(() => {});
|
|
193
|
+
}),
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async queueRequest(params) {
|
|
199
|
+
await this.ensureFolder(this.pathParent(this.settings.queuePath));
|
|
200
|
+
const file = this.app.vault.getAbstractFileByPath(this.settings.queuePath);
|
|
201
|
+
const queue = file ? JSON.parse(await this.app.vault.read(file)) : [];
|
|
202
|
+
queue.push({
|
|
203
|
+
...params,
|
|
204
|
+
id: params.id || `ma-${Date.now()}`,
|
|
205
|
+
queued_at: new Date().toISOString(),
|
|
206
|
+
records_as: "vault_context",
|
|
207
|
+
});
|
|
208
|
+
const payload = `${JSON.stringify(queue, null, 2)}\n`;
|
|
209
|
+
if (file) await this.app.vault.modify(file, payload);
|
|
210
|
+
else await this.app.vault.create(this.settings.queuePath, payload);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async drainRequestQueue() {
|
|
214
|
+
const file = this.app.vault.getAbstractFileByPath(this.settings.queuePath);
|
|
215
|
+
const queue = file ? JSON.parse(await this.app.vault.read(file)) : [];
|
|
216
|
+
const processed = [];
|
|
217
|
+
const refused = [];
|
|
218
|
+
for (const request of queue) {
|
|
219
|
+
try {
|
|
220
|
+
const target = request.note_path || request.path || "";
|
|
221
|
+
if (target) assertSafeVaultPath(target);
|
|
222
|
+
if (request.action === "capture_active_note") {
|
|
223
|
+
processed.push(await this.captureActiveNote());
|
|
224
|
+
} else if (request.action === "create_note") {
|
|
225
|
+
processed.push(await this.writeVaultContextNote(target, request.content, true));
|
|
226
|
+
} else if (request.action === "rename_note") {
|
|
227
|
+
assertSafeVaultPath(request.to);
|
|
228
|
+
const fileToRename = this.app.vault.getAbstractFileByPath(request.from);
|
|
229
|
+
await this.app.fileManager.renameFile(fileToRename, request.to);
|
|
230
|
+
processed.push({ action: "rename_note", from: request.from, to: request.to });
|
|
231
|
+
} else if (request.action === "write_attachment") {
|
|
232
|
+
processed.push(
|
|
233
|
+
await this.writeBinaryAttachment(target, request.data || "", request.content_type),
|
|
234
|
+
);
|
|
235
|
+
} else {
|
|
236
|
+
throw new Error(`unsupported_action:${request.action}`);
|
|
237
|
+
}
|
|
238
|
+
} catch (error) {
|
|
239
|
+
refused.push({
|
|
240
|
+
action: request?.action || null,
|
|
241
|
+
reason: error.message,
|
|
242
|
+
records_as: "vault_context",
|
|
243
|
+
build_evidence: false,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (file && queue.length > 0) await this.app.vault.modify(file, "[]\n");
|
|
248
|
+
return {
|
|
249
|
+
record_type: "obsidian_plugin_queue_drain",
|
|
250
|
+
records_as: "vault_context",
|
|
251
|
+
build_evidence: false,
|
|
252
|
+
processed,
|
|
253
|
+
refused,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async writeVaultContextNote(notePath, content, overwrite) {
|
|
258
|
+
assertSafeVaultPath(notePath);
|
|
259
|
+
if (!content?.trim()) throw new Error("vault_context note content required");
|
|
260
|
+
await this.ensureFolder(this.pathParent(notePath));
|
|
261
|
+
const file = this.app.vault.getAbstractFileByPath(notePath);
|
|
262
|
+
const payload = withVaultContextFrontmatter(content);
|
|
263
|
+
if (file && overwrite) await this.app.vault.modify(file, payload);
|
|
264
|
+
else if (file) throw new Error(`note_exists:${notePath}`);
|
|
265
|
+
else await this.app.vault.create(notePath, payload);
|
|
266
|
+
return {
|
|
267
|
+
action: "write_vault_context_note",
|
|
268
|
+
note_path: notePath,
|
|
269
|
+
records_as: "vault_context",
|
|
270
|
+
build_evidence: false,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async writeBinaryAttachment(attachmentPath, data, contentType) {
|
|
275
|
+
assertSafeVaultPath(attachmentPath);
|
|
276
|
+
await this.ensureFolder(this.pathParent(attachmentPath));
|
|
277
|
+
const bytes = new TextEncoder().encode(String(data || ""));
|
|
278
|
+
if (this.app.vault.createBinary) {
|
|
279
|
+
await this.app.vault.createBinary(attachmentPath, bytes.buffer);
|
|
280
|
+
} else {
|
|
281
|
+
await this.app.vault.adapter.writeBinary(attachmentPath, bytes.buffer);
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
action: "write_attachment",
|
|
285
|
+
attachment_path: attachmentPath,
|
|
286
|
+
content_type: contentType || "application/octet-stream",
|
|
287
|
+
records_as: "vault_context",
|
|
288
|
+
build_evidence: false,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async openNote(notePath) {
|
|
293
|
+
const file = this.app.vault.getAbstractFileByPath(notePath);
|
|
294
|
+
if (!file) {
|
|
295
|
+
new Notice(`MA note not found: ${notePath}`);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
await this.app.workspace.getLeaf(true).openFile(file);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async ensureFolder(folderPath) {
|
|
302
|
+
if (!folderPath || folderPath === ".") return;
|
|
303
|
+
const segments = folderPath.split("/").filter(Boolean);
|
|
304
|
+
let current = "";
|
|
305
|
+
for (const segment of segments) {
|
|
306
|
+
current = current ? `${current}/${segment}` : segment;
|
|
307
|
+
if (!this.app.vault.getAbstractFileByPath(current)) {
|
|
308
|
+
await this.app.vault.createFolder(current).catch(() => {});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
pathParent(filePath) {
|
|
314
|
+
const parts = filePath.split("/");
|
|
315
|
+
parts.pop();
|
|
316
|
+
return parts.join("/");
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
class ContextPreviewModal extends Modal {
|
|
321
|
+
constructor(app, context) {
|
|
322
|
+
super(app);
|
|
323
|
+
this.context = context;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
onOpen() {
|
|
327
|
+
this.contentEl.addClass("ma-context-modal");
|
|
328
|
+
this.contentEl.createEl("h2", { text: "Meta-Architect Context Preview" });
|
|
329
|
+
this.contentEl.createEl("pre", { text: JSON.stringify(this.context, null, 2) });
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
onClose() {
|
|
333
|
+
this.contentEl.empty();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
class MetaArchitectSettingTab extends PluginSettingTab {
|
|
338
|
+
constructor(app, plugin) {
|
|
339
|
+
super(app, plugin);
|
|
340
|
+
this.plugin = plugin;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
display() {
|
|
344
|
+
const { containerEl } = this;
|
|
345
|
+
containerEl.empty();
|
|
346
|
+
containerEl.createEl("h2", { text: "Meta-Architect" });
|
|
347
|
+
|
|
348
|
+
new Setting(containerEl)
|
|
349
|
+
.setName("Project name")
|
|
350
|
+
.setDesc("Stored in MA frontmatter as ma_project.")
|
|
351
|
+
.addText((text) =>
|
|
352
|
+
text.setValue(this.plugin.settings.projectName).onChange(async (value) => {
|
|
353
|
+
this.plugin.settings.projectName = value || "Meta-Architect";
|
|
354
|
+
await this.plugin.saveSettings();
|
|
355
|
+
}),
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
new Setting(containerEl)
|
|
359
|
+
.setName("Active context note")
|
|
360
|
+
.setDesc("Where captured note/selection context is written.")
|
|
361
|
+
.addText((text) =>
|
|
362
|
+
text.setValue(this.plugin.settings.activeContextPath).onChange(async (value) => {
|
|
363
|
+
this.plugin.settings.activeContextPath = value || DEFAULT_SETTINGS.activeContextPath;
|
|
364
|
+
await this.plugin.saveSettings();
|
|
365
|
+
}),
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function withVaultContextFrontmatter(content) {
|
|
371
|
+
if (content.trimStart().startsWith("---")) {
|
|
372
|
+
return content;
|
|
373
|
+
}
|
|
374
|
+
return `---
|
|
375
|
+
ma_records_as: vault_context
|
|
376
|
+
ma_project: Meta-Architect
|
|
377
|
+
ma_capabilities:
|
|
378
|
+
- obsidian_integration_core
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
${content}`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function assertSafeVaultPath(targetPath) {
|
|
385
|
+
const normalized = String(targetPath || "")
|
|
386
|
+
.replaceAll("\\", "/")
|
|
387
|
+
.replace(/^\/+/, "");
|
|
388
|
+
if (
|
|
389
|
+
!normalized ||
|
|
390
|
+
normalized === ".." ||
|
|
391
|
+
normalized.startsWith("../") ||
|
|
392
|
+
normalized.includes("/../")
|
|
393
|
+
) {
|
|
394
|
+
throw new Error("path_traversal_forbidden");
|
|
395
|
+
}
|
|
396
|
+
for (const forbidden of FORBIDDEN_TARGETS) {
|
|
397
|
+
if (normalized === forbidden || normalized.startsWith(forbidden)) {
|
|
398
|
+
throw new Error(`forbidden_authoritative_mutation:${forbidden}`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "meta-architect",
|
|
3
|
+
"name": "Meta-Architect",
|
|
4
|
+
"version": "0.1.13",
|
|
5
|
+
"minAppVersion": "1.5.0",
|
|
6
|
+
"description": "Connects active Obsidian notes, selections, graph metadata, canvases, attachments, and request queues to Meta-Architect vault context.",
|
|
7
|
+
"author": "JustineDevs",
|
|
8
|
+
"isDesktopOnly": false
|
|
9
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -11,9 +11,11 @@ Use this skill inside Codex to turn a product idea into a concrete architecture
|
|
|
11
11
|
|
|
12
12
|
Produce:
|
|
13
13
|
- problem framing
|
|
14
|
+
- `decision`, `status`, `evidence`, `blockers`, `next_allowed_triggers`
|
|
14
15
|
- user and workload assumptions
|
|
15
16
|
- system architecture and subsystem boundaries
|
|
16
17
|
- stack recommendation with tradeoffs
|
|
18
|
+
- rejected alternatives with rationale
|
|
17
19
|
- data model and storage choices
|
|
18
20
|
- auth, security, and operational concerns
|
|
19
21
|
- phased delivery plan
|
|
File without changes
|
|
@@ -14,11 +14,14 @@ Produce:
|
|
|
14
14
|
- blockers that still prevent implementation
|
|
15
15
|
- the narrowest viable build slice
|
|
16
16
|
- branch or worktree suggestions when relevant
|
|
17
|
+
- bounded execution state when the build lane is already in progress
|
|
17
18
|
- test and verification expectations
|
|
19
|
+
- repair path when the bounded slice needs another pass
|
|
18
20
|
- the exact next implementation step
|
|
19
21
|
|
|
20
22
|
## Rules
|
|
21
23
|
|
|
22
24
|
- Do not claim readiness if architecture, evidence, logic, security, or DX/UX gaps remain unresolved.
|
|
23
25
|
- Keep the recommended build slice small, testable, and reversible.
|
|
26
|
+
- Treat `$build` as the sole owner of `.ma/plans/build.md` and `build_status`.
|
|
24
27
|
- If the user wants code immediately and the path is clear, end with a concrete implementation plan rather than more review prose.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -10,7 +10,9 @@ Use this skill inside Codex to pressure-test how the system behaves, not just ho
|
|
|
10
10
|
## Output
|
|
11
11
|
|
|
12
12
|
Produce:
|
|
13
|
+
- `decision`, `status`, `evidence`, `blockers`, `next_allowed_triggers`
|
|
13
14
|
- key actors and system states
|
|
15
|
+
- state map and failure flows
|
|
14
16
|
- main flows and failure flows
|
|
15
17
|
- invariants and state transitions
|
|
16
18
|
- race conditions, dead ends, and consistency risks
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -11,8 +11,10 @@ Use this skill inside Codex to verify or challenge stack choices with real sourc
|
|
|
11
11
|
|
|
12
12
|
Produce:
|
|
13
13
|
- candidate tools, libraries, or services
|
|
14
|
+
- `decision`, `status`, `evidence`, `blockers`, `next_allowed_triggers`
|
|
14
15
|
- why each option fits or fails the architecture
|
|
15
16
|
- source-backed evidence from official docs, upstream repos, or approved GitMCP sources
|
|
17
|
+
- evidence grade and exact upstream mapping
|
|
16
18
|
- recommendation with tradeoffs
|
|
17
19
|
- unresolved gaps or missing evidence
|
|
18
20
|
- exact next trigger, usually `$flow`
|
|
File without changes
|
|
@@ -23,6 +23,14 @@ Use this reference pack inside `$sage` when the repo needs evidence-backed selec
|
|
|
23
23
|
- Claimed capability verified from a primary source
|
|
24
24
|
- Maturity caveats called out when evidence is weak
|
|
25
25
|
|
|
26
|
+
## Evidence grades
|
|
27
|
+
|
|
28
|
+
- `VERIFIED`: exact upstream mapping plus primary-source confirmation
|
|
29
|
+
- `PARTIAL`: candidate is mapped, but live proof or maturity proof is incomplete
|
|
30
|
+
- `MISSING`: no trustworthy exact upstream mapping yet
|
|
31
|
+
|
|
32
|
+
Always expose the evidence grade and the exact upstream mapping in user-facing `$sage` output.
|
|
33
|
+
|
|
26
34
|
## Native posture
|
|
27
35
|
|
|
28
36
|
Meta-Architect ships curated guidance and playbooks. It does not ship a raw mirror of external catalogs. External sources remain evidence inputs, not user-facing skill identities.
|
|
File without changes
|
|
File without changes
|
|
@@ -10,11 +10,13 @@ Use this skill inside Codex to review security posture before the build lane. `$
|
|
|
10
10
|
## Output
|
|
11
11
|
|
|
12
12
|
Produce:
|
|
13
|
+
- `decision`, `status`, `evidence`, `blockers`, `next_allowed_triggers`
|
|
13
14
|
- trust boundaries
|
|
14
15
|
- authn/authz expectations
|
|
15
16
|
- sensitive data paths
|
|
16
17
|
- abuse cases and likely failure modes
|
|
17
18
|
- concrete mitigations
|
|
19
|
+
- accepted risks
|
|
18
20
|
- release blockers vs acceptable risks
|
|
19
21
|
- exact next trigger, usually `$vibe`
|
|
20
22
|
|
|
File without changes
|
|
@@ -18,6 +18,13 @@ Use this reference pack inside `$vet` for repeatable trust-boundary reviews that
|
|
|
18
18
|
- Distinguish blockers from accepted risk.
|
|
19
19
|
- Route remediation back to the owning lane rather than creating a parallel security workflow.
|
|
20
20
|
|
|
21
|
+
## Adversarial hardening
|
|
22
|
+
|
|
23
|
+
- For higher-risk changes, run a bounded adversarial hardening pass before final approval.
|
|
24
|
+
- Keep the hardening work inside the private scratchpad/runtime layer.
|
|
25
|
+
- Return structured findings, not direct gate mutations.
|
|
26
|
+
- If the hardening pass cannot resolve or clearly classify the risk, keep `$vet` in a non-terminal state instead of over-approving.
|
|
27
|
+
|
|
21
28
|
## Product boundary
|
|
22
29
|
|
|
23
30
|
This pack deepens `$vet`; it does not create a new security skill family. Security patterns are packaged as Meta-Architect guidance, not as mirrored external catalogs or branded upstream surfaces.
|
|
@@ -10,8 +10,10 @@ Use this skill inside Codex to review whether the system will feel coherent for
|
|
|
10
10
|
## Output
|
|
11
11
|
|
|
12
12
|
Produce:
|
|
13
|
+
- `decision`, `status`, `evidence`, `blockers`, `next_allowed_triggers`
|
|
13
14
|
- developer workflow risks
|
|
14
15
|
- user workflow risks
|
|
16
|
+
- operator friction and user friction
|
|
15
17
|
- complexity hotspots
|
|
16
18
|
- onboarding or operability friction
|
|
17
19
|
- simplifications that improve clarity
|
|
File without changes
|