opencode-manifold 0.2.0 → 0.4.1
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/README.md +99 -6
- package/dist/index.js +127 -167
- package/package.json +1 -1
- package/src/templates/commands/manifold-init.md +5 -0
- package/src/templates/config/opencode.json +1 -5
package/README.md
CHANGED
|
@@ -43,7 +43,8 @@ Open Manifold requires:
|
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
2. Run opencode. The plugin auto-installs and generates
|
|
46
|
+
2. Run opencode. The plugin auto-installs and generates the global template source.
|
|
47
|
+
3. Run `/manifold-init` in the TUI to set up the project.
|
|
47
48
|
|
|
48
49
|
### Option B — Local plugin files
|
|
49
50
|
|
|
@@ -61,15 +62,17 @@ Open Manifold requires:
|
|
|
61
62
|
"plugin": ["/path/to/.opencode/plugins/opencode-manifold"]
|
|
62
63
|
}
|
|
63
64
|
```
|
|
64
|
-
4. Run opencode. The plugin generates
|
|
65
|
+
4. Run opencode. The plugin generates the global template source.
|
|
66
|
+
5. Run `/manifold-init` in the TUI to set up the project.
|
|
65
67
|
|
|
66
68
|
---
|
|
67
69
|
|
|
68
70
|
## Quick Start
|
|
69
71
|
|
|
70
72
|
1. **Install** using one of the methods above
|
|
71
|
-
2. **
|
|
72
|
-
3. **
|
|
73
|
+
2. **Run `/manifold-init`** in the opencode TUI to set up agents, skills, and the Manifold directory
|
|
74
|
+
3. **Create a plan** — any format (markdown, TODO list, email, meeting notes)
|
|
75
|
+
4. **Point the Lead Dev agent** at your plan file and tell it to execute
|
|
73
76
|
|
|
74
77
|
The Lead Dev will:
|
|
75
78
|
- Extract tasks from your plan
|
|
@@ -126,6 +129,76 @@ The sr/jr/debug loop enables cost-efficient workflows: a strong sr-dev paired wi
|
|
|
126
129
|
|
|
127
130
|
---
|
|
128
131
|
|
|
132
|
+
## Customizing Agents
|
|
133
|
+
|
|
134
|
+
Agents are markdown files with [opencode frontmatter](https://opencode.ai/docs/agents/) for configuration (description, mode, permissions, model) and a body that becomes the agent's system prompt.
|
|
135
|
+
|
|
136
|
+
Manifold uses a three-tier template system:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Bundled (inside npm package)
|
|
140
|
+
└── Never edit directly — overwritten on updates
|
|
141
|
+
│
|
|
142
|
+
▼ Plugin load (one-time, only copies missing files)
|
|
143
|
+
~/.config/opencode/manifold/ ← Global templates
|
|
144
|
+
├── agents/ (clerk.md, senior-dev.md, ...)
|
|
145
|
+
├── skills/ (manifold-workflow/, clerk-orchestration/, ...)
|
|
146
|
+
├── manifold/ (settings.json, schema.md, ...)
|
|
147
|
+
└── config/ (opencode.json)
|
|
148
|
+
│
|
|
149
|
+
▼ /manifold-init (only copies missing files)
|
|
150
|
+
Project root
|
|
151
|
+
├── .opencode/agents/ ← Per-project (editable)
|
|
152
|
+
├── .opencode/skills/
|
|
153
|
+
├── Manifold/
|
|
154
|
+
└── opencode.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Per-project customization
|
|
158
|
+
|
|
159
|
+
Edit files directly in `.opencode/agents/` or `.opencode/skills/`. These are never overwritten by `/manifold-init` — only files that don't exist yet are copied.
|
|
160
|
+
|
|
161
|
+
### Global customization
|
|
162
|
+
|
|
163
|
+
Edit files in `~/.config/opencode/manifold/`. All new projects initialized with `/manifold-init` will inherit your customized versions.
|
|
164
|
+
|
|
165
|
+
### Resetting
|
|
166
|
+
|
|
167
|
+
To reset a specific agent to its default, delete just that file and run `/manifold-init` again:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
rm .opencode/agents/senior-dev.md
|
|
171
|
+
# Then run /manifold-init
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
To reset all Manifold files, delete the directories and re-run:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
rm -rf .opencode/agents/ .opencode/skills/ Manifold/
|
|
178
|
+
# Then run /manifold-init
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Assigning models to agents
|
|
182
|
+
|
|
183
|
+
Add a `model` field to the agent's frontmatter or your `opencode.json`:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"agent": {
|
|
188
|
+
"senior-dev": {
|
|
189
|
+
"model": "anthropic/claude-sonnet-4-20250514"
|
|
190
|
+
},
|
|
191
|
+
"junior-dev": {
|
|
192
|
+
"model": "anthropic/claude-haiku-4-20250514"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
See the [Example Configurations](#example-configurations) section for model pairing suggestions.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
129
202
|
## Example Configurations
|
|
130
203
|
|
|
131
204
|
| Budget | Senior Dev | Junior Dev | Debug |
|
|
@@ -190,10 +263,10 @@ No mid-loop state recovery needed — restart the task, the Clerk's research pha
|
|
|
190
263
|
## FAQ
|
|
191
264
|
|
|
192
265
|
**Q: Do I need to configure agents?**
|
|
193
|
-
A: No.
|
|
266
|
+
A: No. Run `/manifold-init` once per project and it sets up agent definitions, skills, and configuration from templates.
|
|
194
267
|
|
|
195
268
|
**Q: Can I customize agents and skills?**
|
|
196
|
-
A: Yes.
|
|
269
|
+
A: Yes. See the [Customizing Agents](#customizing-agents) section for the full three-tier template system.
|
|
197
270
|
|
|
198
271
|
**Q: What is the Clerk's role?**
|
|
199
272
|
A: The Clerk has full project sight. It researches context (codebase-index, wiki, graph), composes scoped prompts for workers, and maintains the wiki.
|
|
@@ -215,6 +288,26 @@ A: The system is designed around the Clerk's ability to research context via sem
|
|
|
215
288
|
|
|
216
289
|
---
|
|
217
290
|
|
|
291
|
+
## Uninstall
|
|
292
|
+
|
|
293
|
+
To remove Open Manifold from a project:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
rm -rf .opencode/agents/ .opencode/skills/ Manifold/
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Then remove the manifold-specific keys from `opencode.json` (`agent.manifold`, `permission.clerk`, `permission.senior-dev`, `permission.junior-dev`, `permission.debug`).
|
|
300
|
+
|
|
301
|
+
To remove global templates:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
rm -rf ~/.config/opencode/manifold/ ~/.config/opencode/commands/manifold-init.md
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
To fully uninstall the plugin, also remove `"opencode-manifold"` from the `plugin` array in your global or project `opencode.json`.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
218
311
|
## License
|
|
219
312
|
|
|
220
313
|
GPL 3+. See LICENSE file.
|
package/dist/index.js
CHANGED
|
@@ -1,198 +1,149 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import { readFile, writeFile, mkdir, readdir
|
|
1
|
+
// src/init.ts
|
|
2
|
+
import { readFile, writeFile, mkdir, readdir } from "fs/promises";
|
|
3
3
|
import { existsSync } from "fs";
|
|
4
4
|
import { join, dirname } from "path";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
var __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
var bundledTemplatesDir = join(__dirname2, "..", "src", "templates");
|
|
9
|
+
var globalTemplatesDir = join(homedir(), ".config", "opencode", "manifold");
|
|
10
|
+
async function dirHasContent(dirPath) {
|
|
11
|
+
if (!existsSync(dirPath))
|
|
12
|
+
return false;
|
|
7
13
|
try {
|
|
8
|
-
await
|
|
9
|
-
return
|
|
14
|
+
const entries = await readdir(dirPath);
|
|
15
|
+
return entries.length > 0;
|
|
10
16
|
} catch {
|
|
11
17
|
return false;
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
|
-
async function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const content = await readFile(src);
|
|
20
|
-
await writeFile(dest, content);
|
|
21
|
-
}
|
|
22
|
-
async function copyDirectory(src, dest) {
|
|
23
|
-
if (!existsSync(dest)) {
|
|
24
|
-
await mkdir(dest, { recursive: true });
|
|
25
|
-
}
|
|
20
|
+
async function copyMissingFiles(src, dest) {
|
|
21
|
+
if (!existsSync(src))
|
|
22
|
+
return [];
|
|
23
|
+
await mkdir(dest, { recursive: true });
|
|
24
|
+
const copied = [];
|
|
26
25
|
const entries = await readdir(src, { withFileTypes: true });
|
|
27
26
|
for (const entry of entries) {
|
|
28
27
|
const srcPath = join(src, entry.name);
|
|
29
28
|
const destPath = join(dest, entry.name);
|
|
30
29
|
if (entry.isDirectory()) {
|
|
31
|
-
await
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const subCopied = await copyMissingFiles(srcPath, destPath);
|
|
31
|
+
if (subCopied.length > 0) {
|
|
32
|
+
copied.push(entry.name);
|
|
33
|
+
}
|
|
34
|
+
} else if (!existsSync(destPath)) {
|
|
35
|
+
await writeFile(destPath, await readFile(srcPath));
|
|
36
|
+
copied.push(entry.name);
|
|
34
37
|
}
|
|
35
38
|
}
|
|
39
|
+
return copied;
|
|
36
40
|
}
|
|
37
|
-
async function
|
|
38
|
-
|
|
41
|
+
async function mergeOpencodeConfig(projectDir) {
|
|
42
|
+
const configPath = join(projectDir, "opencode.json");
|
|
43
|
+
const templateConfigPath = join(globalTemplatesDir, "config", "opencode.json");
|
|
44
|
+
if (!existsSync(templateConfigPath))
|
|
45
|
+
return;
|
|
46
|
+
const templateConfig = JSON.parse(await readFile(templateConfigPath, "utf-8"));
|
|
47
|
+
if (!existsSync(configPath)) {
|
|
48
|
+
await writeFile(configPath, JSON.stringify(templateConfig, null, 2));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const existing = JSON.parse(await readFile(configPath, "utf-8"));
|
|
52
|
+
let changed = false;
|
|
53
|
+
if (templateConfig.agent?.manifold && !existing.agent?.manifold) {
|
|
54
|
+
existing.agent = existing.agent || {};
|
|
55
|
+
existing.agent.manifold = templateConfig.agent.manifold;
|
|
56
|
+
changed = true;
|
|
57
|
+
}
|
|
58
|
+
if (templateConfig.permission) {
|
|
59
|
+
for (const [key, value] of Object.entries(templateConfig.permission)) {
|
|
60
|
+
if (!existing.permission?.[key]) {
|
|
61
|
+
existing.permission = existing.permission || {};
|
|
62
|
+
existing.permission[key] = value;
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (changed) {
|
|
68
|
+
await writeFile(configPath, JSON.stringify(existing, null, 2));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function ensureGlobalTemplates(ctx) {
|
|
72
|
+
await ctx.client.app.log({
|
|
39
73
|
body: {
|
|
40
74
|
service: "opencode-manifold",
|
|
41
75
|
level: "info",
|
|
42
|
-
message:
|
|
76
|
+
message: "Checking global templates..."
|
|
43
77
|
}
|
|
44
78
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const opencodeSkillsPath = join(directory, ".opencode", "skills");
|
|
48
|
-
const opencodeJsonPath = join(directory, "opencode.json");
|
|
49
|
-
const pluginSourceDir = join(directory, "..", "node_modules", "opencode-manifold", "src", "templates");
|
|
50
|
-
const manifestPath = join(pluginSourceDir, "..", "..");
|
|
51
|
-
const templateSourceDir = existsSync(manifestPath) ? manifestPath : join(__dirname, "..", "templates");
|
|
52
|
-
const manifoldExists = await fileExists(manifoldPath);
|
|
53
|
-
if (!manifoldExists) {
|
|
54
|
-
await client.app.log({
|
|
79
|
+
if (!existsSync(bundledTemplatesDir)) {
|
|
80
|
+
await ctx.client.app.log({
|
|
55
81
|
body: {
|
|
56
82
|
service: "opencode-manifold",
|
|
57
|
-
level: "
|
|
58
|
-
message:
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
await mkdir(manifoldPath, { recursive: true });
|
|
62
|
-
await mkdir(join(manifoldPath, ".obsidian"), { recursive: true });
|
|
63
|
-
await mkdir(join(manifoldPath, "tasks"), { recursive: true });
|
|
64
|
-
await mkdir(join(manifoldPath, "graph"), { recursive: true });
|
|
65
|
-
const templateManifold = join(templateSourceDir, "manifold");
|
|
66
|
-
if (existsSync(templateManifold)) {
|
|
67
|
-
const files = [
|
|
68
|
-
"settings.json",
|
|
69
|
-
"plans.json",
|
|
70
|
-
"state.json",
|
|
71
|
-
"index.md",
|
|
72
|
-
"log.md",
|
|
73
|
-
"schema.md"
|
|
74
|
-
];
|
|
75
|
-
for (const file of files) {
|
|
76
|
-
const src = join(templateManifold, file);
|
|
77
|
-
if (existsSync(src)) {
|
|
78
|
-
await copyFile(src, join(manifoldPath, file));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
await client.app.log({
|
|
83
|
-
body: {
|
|
84
|
-
service: "opencode-manifold",
|
|
85
|
-
level: "info",
|
|
86
|
-
message: "Manifold directory created"
|
|
83
|
+
level: "error",
|
|
84
|
+
message: `Bundled templates not found at ${bundledTemplatesDir}`
|
|
87
85
|
}
|
|
88
86
|
});
|
|
87
|
+
return;
|
|
89
88
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
level: "info",
|
|
96
|
-
message: "Setting up agent definitions..."
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
await mkdir(opencodeAgentsPath, { recursive: true });
|
|
100
|
-
const templateAgents = join(templateSourceDir, "agents");
|
|
101
|
-
if (existsSync(templateAgents)) {
|
|
102
|
-
const agents = [
|
|
103
|
-
"manifold.md",
|
|
104
|
-
"clerk.md",
|
|
105
|
-
"senior-dev.md",
|
|
106
|
-
"junior-dev.md",
|
|
107
|
-
"debug.md"
|
|
108
|
-
];
|
|
109
|
-
for (const agent of agents) {
|
|
110
|
-
const src = join(templateAgents, agent);
|
|
111
|
-
if (existsSync(src)) {
|
|
112
|
-
await copyFile(src, join(opencodeAgentsPath, agent));
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
await client.app.log({
|
|
117
|
-
body: {
|
|
118
|
-
service: "opencode-manifold",
|
|
119
|
-
level: "info",
|
|
120
|
-
message: "Agent definitions created"
|
|
121
|
-
}
|
|
122
|
-
});
|
|
89
|
+
await copyMissingFiles(bundledTemplatesDir, globalTemplatesDir);
|
|
90
|
+
const globalCommandsDir = join(homedir(), ".config", "opencode", "commands");
|
|
91
|
+
const bundledCommandsDir = join(bundledTemplatesDir, "commands");
|
|
92
|
+
if (existsSync(bundledCommandsDir)) {
|
|
93
|
+
await copyMissingFiles(bundledCommandsDir, globalCommandsDir);
|
|
123
94
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
level: "info",
|
|
130
|
-
message: "Setting up skills..."
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
await mkdir(opencodeSkillsPath, { recursive: true });
|
|
134
|
-
const templateSkills = join(templateSourceDir, "skills");
|
|
135
|
-
if (existsSync(templateSkills)) {
|
|
136
|
-
const skills = [
|
|
137
|
-
"clerk-orchestration",
|
|
138
|
-
"manifold-workflow",
|
|
139
|
-
"wiki-ingest",
|
|
140
|
-
"wiki-query"
|
|
141
|
-
];
|
|
142
|
-
for (const skill of skills) {
|
|
143
|
-
const skillDir = join(templateSkills, skill);
|
|
144
|
-
if (existsSync(skillDir)) {
|
|
145
|
-
await copyDirectory(skillDir, join(opencodeSkillsPath, skill));
|
|
146
|
-
}
|
|
147
|
-
}
|
|
95
|
+
await ctx.client.app.log({
|
|
96
|
+
body: {
|
|
97
|
+
service: "opencode-manifold",
|
|
98
|
+
level: "info",
|
|
99
|
+
message: "Global templates ready"
|
|
148
100
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (!opencodeJsonExists) {
|
|
159
|
-
await client.app.log({
|
|
160
|
-
body: {
|
|
161
|
-
service: "opencode-manifold",
|
|
162
|
-
level: "info",
|
|
163
|
-
message: "Creating opencode.json configuration..."
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
const templateConfig = join(templateSourceDir, "config", "opencode.json");
|
|
167
|
-
if (existsSync(templateConfig)) {
|
|
168
|
-
await copyFile(templateConfig, opencodeJsonPath);
|
|
169
|
-
} else {
|
|
170
|
-
const defaultConfig = {
|
|
171
|
-
$schema: "https://opencode.ai/config.json",
|
|
172
|
-
plugin: ["opencode-manifold", "opencode-codebase-index"],
|
|
173
|
-
agent: {
|
|
174
|
-
manifold: {
|
|
175
|
-
skill: ["manifold-workflow"]
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
await writeFile(opencodeJsonPath, JSON.stringify(defaultConfig, null, 2));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async function initProject(directory, client) {
|
|
104
|
+
const initialized = [];
|
|
105
|
+
await client.app.log({
|
|
106
|
+
body: {
|
|
107
|
+
service: "opencode-manifold",
|
|
108
|
+
level: "info",
|
|
109
|
+
message: `Running /manifold-init in ${directory}`
|
|
180
110
|
}
|
|
111
|
+
});
|
|
112
|
+
if (!await dirHasContent(globalTemplatesDir)) {
|
|
181
113
|
await client.app.log({
|
|
182
114
|
body: {
|
|
183
115
|
service: "opencode-manifold",
|
|
184
|
-
level: "
|
|
185
|
-
message:
|
|
116
|
+
level: "error",
|
|
117
|
+
message: `Global templates not found at ${globalTemplatesDir}. Plugin may not have loaded correctly.`
|
|
186
118
|
}
|
|
187
119
|
});
|
|
120
|
+
return initialized;
|
|
121
|
+
}
|
|
122
|
+
const agentsCopied = await copyMissingFiles(join(globalTemplatesDir, "agents"), join(directory, ".opencode", "agents"));
|
|
123
|
+
if (agentsCopied.length > 0) {
|
|
124
|
+
initialized.push(`agents (${agentsCopied.join(", ")})`);
|
|
125
|
+
}
|
|
126
|
+
const skillsCopied = await copyMissingFiles(join(globalTemplatesDir, "skills"), join(directory, ".opencode", "skills"));
|
|
127
|
+
if (skillsCopied.length > 0) {
|
|
128
|
+
initialized.push(`skills (${skillsCopied.join(", ")})`);
|
|
129
|
+
}
|
|
130
|
+
const manifoldCopied = await copyMissingFiles(join(globalTemplatesDir, "manifold"), join(directory, "Manifold"));
|
|
131
|
+
if (manifoldCopied.length > 0) {
|
|
132
|
+
initialized.push(`Manifold/ (${manifoldCopied.join(", ")})`);
|
|
133
|
+
}
|
|
134
|
+
const configPath = join(directory, "opencode.json");
|
|
135
|
+
if (!existsSync(configPath) || !JSON.parse(await readFile(configPath, "utf-8")).agent?.manifold) {
|
|
136
|
+
await mergeOpencodeConfig(directory);
|
|
137
|
+
initialized.push("opencode.json");
|
|
188
138
|
}
|
|
189
139
|
await client.app.log({
|
|
190
140
|
body: {
|
|
191
141
|
service: "opencode-manifold",
|
|
192
142
|
level: "info",
|
|
193
|
-
message:
|
|
143
|
+
message: `/manifold-init complete: ${initialized.join(", ") || "already initialized"}`
|
|
194
144
|
}
|
|
195
145
|
});
|
|
146
|
+
return initialized;
|
|
196
147
|
}
|
|
197
148
|
|
|
198
149
|
// src/tools/dispatch-task.ts
|
|
@@ -1341,7 +1292,7 @@ var dispatchTaskTool = tool({
|
|
|
1341
1292
|
description: tool.schema.string().describe("One-line task description"),
|
|
1342
1293
|
plan_file: tool.schema.string().describe("Path to the plan document")
|
|
1343
1294
|
},
|
|
1344
|
-
async execute(args) {
|
|
1295
|
+
async execute(args, context) {
|
|
1345
1296
|
const { task_number, description, plan_file } = args;
|
|
1346
1297
|
const client = getClient();
|
|
1347
1298
|
await client.app.log({
|
|
@@ -1351,7 +1302,7 @@ var dispatchTaskTool = tool({
|
|
|
1351
1302
|
message: `dispatchTask called: task ${task_number} - ${description}`
|
|
1352
1303
|
}
|
|
1353
1304
|
});
|
|
1354
|
-
const directory =
|
|
1305
|
+
const directory = context.directory;
|
|
1355
1306
|
const settings = await readSettings(directory);
|
|
1356
1307
|
await updatePlansRegistry(directory, plan_file);
|
|
1357
1308
|
await client.app.log({
|
|
@@ -1424,6 +1375,7 @@ ${testResult.result.output}`,
|
|
|
1424
1375
|
// src/index.ts
|
|
1425
1376
|
var ManifoldPlugin = async (ctx) => {
|
|
1426
1377
|
setPluginContext(ctx.client);
|
|
1378
|
+
await ensureGlobalTemplates(ctx);
|
|
1427
1379
|
await ctx.client.app.log({
|
|
1428
1380
|
body: {
|
|
1429
1381
|
service: "opencode-manifold",
|
|
@@ -1435,16 +1387,24 @@ var ManifoldPlugin = async (ctx) => {
|
|
|
1435
1387
|
tool: {
|
|
1436
1388
|
dispatchTask: dispatchTaskTool
|
|
1437
1389
|
},
|
|
1438
|
-
|
|
1439
|
-
if (
|
|
1440
|
-
await ctx.client
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1390
|
+
"command.execute.before": async (input, output) => {
|
|
1391
|
+
if (input.command === "manifold-init") {
|
|
1392
|
+
const initialized = await initProject(ctx.directory, ctx.client);
|
|
1393
|
+
if (initialized.length > 0) {
|
|
1394
|
+
output.parts = [
|
|
1395
|
+
{
|
|
1396
|
+
type: "text",
|
|
1397
|
+
text: `Manifold initialized: ${initialized.join(", ")}`
|
|
1398
|
+
}
|
|
1399
|
+
];
|
|
1400
|
+
} else {
|
|
1401
|
+
output.parts = [
|
|
1402
|
+
{
|
|
1403
|
+
type: "text",
|
|
1404
|
+
text: "All Manifold files already present. To reset a specific component, delete the corresponding file(s) from `.opencode/agents/`, `.opencode/skills/`, or `Manifold/`, then run `/manifold-init` again."
|
|
1405
|
+
}
|
|
1406
|
+
];
|
|
1407
|
+
}
|
|
1448
1408
|
}
|
|
1449
1409
|
}
|
|
1450
1410
|
};
|
package/package.json
CHANGED