@ompo-design/mcp-server 0.1.2 → 0.1.4
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/dist/apply-plan.d.ts +2 -0
- package/dist/apply-plan.js +140 -5
- package/dist/cli.js +11 -8
- package/dist/edit-store.d.ts +5 -5
- package/dist/edit-store.js +20 -43
- package/dist/edits-path.d.ts +1 -0
- package/dist/edits-path.js +5 -0
- package/dist/index.js +23 -22
- package/package.json +1 -1
package/dist/apply-plan.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type ApplySuggestion = {
|
|
|
8
8
|
export type ApplyPlanFile = {
|
|
9
9
|
selector: string;
|
|
10
10
|
suggestions: ApplySuggestion[];
|
|
11
|
+
layoutIntent?: string;
|
|
11
12
|
};
|
|
12
13
|
export type DomStructurePlan = {
|
|
13
14
|
kind: 'dom.insert' | 'dom.move' | 'dom.delete' | 'dom.flexWrap';
|
|
@@ -24,6 +25,7 @@ export type ApplyPlan = {
|
|
|
24
25
|
domChanges: OmpoOperation[];
|
|
25
26
|
warnings: string[];
|
|
26
27
|
instructions: string[];
|
|
28
|
+
ompoGlossary: Record<string, string>;
|
|
27
29
|
};
|
|
28
30
|
export declare function buildApplyPlan(bundle: OmpoEditBundle): ApplyPlan;
|
|
29
31
|
export declare function explainEdit(bundle: OmpoEditBundle): string;
|
package/dist/apply-plan.js
CHANGED
|
@@ -1,10 +1,135 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const OMPO_GLOSSARY = {
|
|
2
|
+
gap: `Ompo "Gap" is the space between children inside a flex or grid container. Apply \`gap\` on the parent layout element (not on children). The parent needs \`display: flex\` or \`display: grid\`. Example: gap "16px" → CSS \`gap: 16px\` or Tailwind \`gap-4\`.`,
|
|
3
|
+
fill: `Ompo "Fill" means an element should expand to consume free space inside its parent. Fill is NOT a CSS property — read \`widthMode: fill\` / \`heightMode: fill\` together with \`ensureParentFlex\`, \`flexGrow\`, \`flexShrink\`, \`flexBasis\`, and \`alignSelf\` on the same selector. Parent must be \`display: flex\`. Main axis (direction of flex): use \`flex: 1 1 0\` (grow/shrink/basis). Cross axis: use \`align-self: stretch\` and remove fixed width/height on that axis. If \`ensureParentFlex\` is present, make the parent a flex container with that direction first.`,
|
|
4
|
+
fit: `Ompo "Fit" means size to content. Map \`widthMode: fit\` → \`width: fit-content\`, \`heightMode: fit\` → \`height: fit-content\` (or the project's equivalent).`
|
|
5
|
+
};
|
|
6
|
+
function formatChangedValue(property, value) {
|
|
7
|
+
const text = String(value);
|
|
8
|
+
if (text !== '')
|
|
9
|
+
return text;
|
|
10
|
+
if (property === 'width' || property === 'height') {
|
|
11
|
+
return '(remove fixed size — required for Fill)';
|
|
12
|
+
}
|
|
13
|
+
if (property === 'alignSelf' && text === '') {
|
|
14
|
+
return '(remove align-self override)';
|
|
15
|
+
}
|
|
16
|
+
return '(empty / remove)';
|
|
17
|
+
}
|
|
18
|
+
function styleSuggestionForProperty(property, value, changed) {
|
|
19
|
+
const parentFlex = changed.ensureParentFlex;
|
|
20
|
+
const parentFlexLabel = parentFlex === 'row' || parentFlex === 'column' ? parentFlex : 'row or column';
|
|
21
|
+
switch (property) {
|
|
22
|
+
case 'gap':
|
|
23
|
+
return {
|
|
24
|
+
property,
|
|
25
|
+
value: formatChangedValue(property, value),
|
|
26
|
+
strategy: 'css-rule',
|
|
27
|
+
notes: `${OMPO_GLOSSARY.gap} Apply on this selector if it is the flex/grid parent.`
|
|
28
|
+
};
|
|
29
|
+
case 'widthMode':
|
|
30
|
+
if (value === 'fill') {
|
|
31
|
+
return {
|
|
32
|
+
property,
|
|
33
|
+
value: 'fill',
|
|
34
|
+
strategy: 'css-rule',
|
|
35
|
+
notes: `${OMPO_GLOSSARY.fill} This selector has Fill width. If parent flex-direction is row, prefer flex-grow on this element; if column, prefer align-self: stretch for width.`
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (value === 'fit') {
|
|
39
|
+
return {
|
|
40
|
+
property,
|
|
41
|
+
value: 'fit',
|
|
42
|
+
strategy: 'css-rule',
|
|
43
|
+
notes: OMPO_GLOSSARY.fit
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case 'heightMode':
|
|
48
|
+
if (value === 'fill') {
|
|
49
|
+
return {
|
|
50
|
+
property,
|
|
51
|
+
value: 'fill',
|
|
52
|
+
strategy: 'css-rule',
|
|
53
|
+
notes: `${OMPO_GLOSSARY.fill} This selector has Fill height. If parent flex-direction is column, prefer flex-grow on this element; if row, prefer align-self: stretch for height.`
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (value === 'fit') {
|
|
57
|
+
return {
|
|
58
|
+
property,
|
|
59
|
+
value: 'fit',
|
|
60
|
+
strategy: 'css-rule',
|
|
61
|
+
notes: OMPO_GLOSSARY.fit
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case 'ensureParentFlex':
|
|
66
|
+
return {
|
|
67
|
+
property,
|
|
68
|
+
value: String(value),
|
|
69
|
+
strategy: 'css-rule',
|
|
70
|
+
notes: `Ompo auto-enabled flex on this element's parent so Fill sizing could work. In source, ensure the parent has display: flex and flex-direction: ${parentFlexLabel}. Apply on the parent element, not this child.`
|
|
71
|
+
};
|
|
72
|
+
case 'flexGrow':
|
|
73
|
+
case 'flexShrink':
|
|
74
|
+
case 'flexBasis':
|
|
75
|
+
return {
|
|
76
|
+
property,
|
|
77
|
+
value: formatChangedValue(property, value),
|
|
78
|
+
strategy: 'css-rule',
|
|
79
|
+
notes: `Part of Ompo Fill sizing on the main flex axis. Apply together with widthMode/heightMode fill and remove fixed width/height on the filled axis.`
|
|
80
|
+
};
|
|
81
|
+
case 'alignSelf':
|
|
82
|
+
return {
|
|
83
|
+
property,
|
|
84
|
+
value: formatChangedValue(property, value),
|
|
85
|
+
strategy: 'css-rule',
|
|
86
|
+
notes: value === 'stretch'
|
|
87
|
+
? 'Ompo Fill on the cross axis: stretch this flex child to fill the parent’s cross size. Remove any fixed width/height that blocks stretching.'
|
|
88
|
+
: 'Map to the matching align-self rule in source.'
|
|
89
|
+
};
|
|
90
|
+
case 'minWidth':
|
|
91
|
+
case 'minHeight':
|
|
92
|
+
return {
|
|
93
|
+
property,
|
|
94
|
+
value: formatChangedValue(property, value),
|
|
95
|
+
strategy: 'css-rule',
|
|
96
|
+
notes: 'Supporting constraint for Ompo Fill sizing. Often min-width: 0 or min-height: 0 so flex children can shrink.'
|
|
97
|
+
};
|
|
98
|
+
case 'maxWidth':
|
|
99
|
+
case 'maxHeight':
|
|
100
|
+
return {
|
|
101
|
+
property,
|
|
102
|
+
value: formatChangedValue(property, value),
|
|
103
|
+
strategy: 'css-rule',
|
|
104
|
+
notes: 'Supporting constraint for Ompo Fill sizing. max-width/max-height: none allows the element to grow.'
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
3
108
|
property,
|
|
4
|
-
value:
|
|
109
|
+
value: formatChangedValue(property, value),
|
|
5
110
|
strategy: 'inline-style',
|
|
6
111
|
notes: 'Map this changed property to the matching source stylesheet, class, or component prop. Do not modify unrelated styles.'
|
|
7
|
-
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function styleSuggestions(operation) {
|
|
115
|
+
const changed = operation.changed;
|
|
116
|
+
return Object.entries(changed).map(([property, value]) => styleSuggestionForProperty(property, value, changed));
|
|
117
|
+
}
|
|
118
|
+
function summarizeLayoutIntent(changed) {
|
|
119
|
+
const parts = [];
|
|
120
|
+
if (changed.gap !== undefined) {
|
|
121
|
+
parts.push(`Set container gap to ${changed.gap}`);
|
|
122
|
+
}
|
|
123
|
+
if (changed.widthMode === 'fill') {
|
|
124
|
+
parts.push('Width: Fill (expand on main or cross axis per parent flex-direction)');
|
|
125
|
+
}
|
|
126
|
+
if (changed.heightMode === 'fill') {
|
|
127
|
+
parts.push('Height: Fill (expand on main or cross axis per parent flex-direction)');
|
|
128
|
+
}
|
|
129
|
+
if (changed.ensureParentFlex) {
|
|
130
|
+
parts.push(`Parent needs display:flex with flex-direction:${changed.ensureParentFlex}`);
|
|
131
|
+
}
|
|
132
|
+
return parts.length > 0 ? parts.join('. ') : null;
|
|
8
133
|
}
|
|
9
134
|
function buildDomStructurePlan(operation) {
|
|
10
135
|
switch (operation.kind) {
|
|
@@ -92,6 +217,12 @@ export function buildApplyPlan(bundle) {
|
|
|
92
217
|
suggestions: []
|
|
93
218
|
};
|
|
94
219
|
existing.suggestions.push(...styleSuggestions(operation));
|
|
220
|
+
const layoutIntent = summarizeLayoutIntent(operation.changed);
|
|
221
|
+
if (layoutIntent) {
|
|
222
|
+
existing.layoutIntent = existing.layoutIntent
|
|
223
|
+
? `${existing.layoutIntent} ${layoutIntent}`
|
|
224
|
+
: layoutIntent;
|
|
225
|
+
}
|
|
95
226
|
files.set(operation.selector, existing);
|
|
96
227
|
if (operation.selector.includes('nth-of-type')) {
|
|
97
228
|
warnings.push(`Selector "${operation.selector}" may be unstable across builds. Prefer matching by component structure or stable attributes.`);
|
|
@@ -144,10 +275,14 @@ export function buildApplyPlan(bundle) {
|
|
|
144
275
|
instructions: [
|
|
145
276
|
'Only apply properties and operations listed in this plan.',
|
|
146
277
|
'Leave all untouched styling and markup unchanged.',
|
|
278
|
+
'Read ompoGlossary.fill and ompoGlossary.gap before applying layout changes — Ompo terms are not literal CSS properties.',
|
|
279
|
+
'When widthMode or heightMode is "fill", apply the grouped flex properties together (flexGrow, flexBasis, alignSelf, removed width/height) — do not set a fixed px width/height on the filled axis.',
|
|
280
|
+
'Gap belongs on the flex/grid parent. Fill belongs on the child inside a flex parent.',
|
|
147
281
|
'For dom.flexWrap: create a new wrapper, move matched children, then apply wrapperStyles.',
|
|
148
282
|
'Use child anchors (tag, id, class, textSnippet) to find elements in source when selectors are unstable.',
|
|
149
283
|
'Prefer the smallest possible diff for each file.'
|
|
150
|
-
]
|
|
284
|
+
],
|
|
285
|
+
ompoGlossary: OMPO_GLOSSARY
|
|
151
286
|
};
|
|
152
287
|
}
|
|
153
288
|
export function explainEdit(bundle) {
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,8 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { join, resolve } from 'path';
|
|
5
|
-
import {
|
|
5
|
+
import { editsStoreReady } from './edit-store.js';
|
|
6
|
+
import { getOmpoEditsStorePath } from './edits-path.js';
|
|
6
7
|
const PACKAGE_NAME = '@ompo-design/mcp-server';
|
|
7
8
|
const SERVER_NAME = 'ompo';
|
|
8
9
|
function resolveExecutable(name) {
|
|
@@ -120,21 +121,23 @@ function runGlobalSetup() {
|
|
|
120
121
|
console.log(' 3. Open any Code project and run /mcp');
|
|
121
122
|
console.log(' 4. Approve ompo if prompted');
|
|
122
123
|
console.log(' 5. In Ompo, click Send on an edit before using the tools');
|
|
124
|
+
console.log(` Edits are stored in ${getOmpoEditsStorePath()}`);
|
|
123
125
|
}
|
|
124
126
|
function runDoctor() {
|
|
125
127
|
const projectRoot = resolve(process.cwd());
|
|
126
128
|
const configPath = join(projectRoot, '.mcp.json');
|
|
127
129
|
const desktopPath = claudeDesktopConfigPath();
|
|
128
130
|
const claudeCodePath = claudeCodeUserConfigPath();
|
|
129
|
-
const
|
|
131
|
+
const storePath = getOmpoEditsStorePath();
|
|
130
132
|
console.log('Ompo MCP doctor');
|
|
131
133
|
console.log('');
|
|
132
|
-
console.log(`
|
|
134
|
+
console.log(`Current folder: ${projectRoot}`);
|
|
133
135
|
console.log(`Node: ${process.version}`);
|
|
134
136
|
console.log(`npx: ${resolveExecutable('npx')}`);
|
|
137
|
+
console.log(`Edits store: ${storePath}`);
|
|
135
138
|
console.log('');
|
|
136
139
|
for (const [label, path] of [
|
|
137
|
-
['Project config', configPath],
|
|
140
|
+
['Project MCP config', configPath],
|
|
138
141
|
['Claude Desktop', desktopPath],
|
|
139
142
|
['Claude Code user', claudeCodePath]
|
|
140
143
|
]) {
|
|
@@ -153,11 +156,11 @@ function runDoctor() {
|
|
|
153
156
|
}
|
|
154
157
|
}
|
|
155
158
|
console.log('');
|
|
156
|
-
if (
|
|
157
|
-
console.log(
|
|
159
|
+
if (editsStoreReady()) {
|
|
160
|
+
console.log('Edits: ready (Send from Ompo to add more)');
|
|
158
161
|
}
|
|
159
162
|
else {
|
|
160
|
-
console.log('Edits: none yet (
|
|
163
|
+
console.log('Edits: none yet (click Send in Ompo first)');
|
|
161
164
|
}
|
|
162
165
|
console.log('');
|
|
163
166
|
console.log('Global install: npx @ompo-design/mcp-server setup-global');
|
|
@@ -168,7 +171,7 @@ function printProjectNextSteps(projectRoot) {
|
|
|
168
171
|
console.log(` 1. cd ${projectRoot}`);
|
|
169
172
|
console.log(' 2. Start Claude Code in this folder');
|
|
170
173
|
console.log(' 3. Run /mcp and approve ompo if prompted');
|
|
171
|
-
console.log(' 4. In Ompo, click Send on an edit
|
|
174
|
+
console.log(' 4. In Ompo, click Send on an edit');
|
|
172
175
|
console.log('');
|
|
173
176
|
console.log('For all projects, run: npx @ompo-design/mcp-server setup-global');
|
|
174
177
|
}
|
package/dist/edit-store.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { EditIndex, OmpoEditBundle } from './types.js';
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function listEdits(
|
|
4
|
-
export declare function readEditBundle(
|
|
5
|
-
export declare function recordEditPull(
|
|
6
|
-
export declare function recordEditApplied(
|
|
2
|
+
export declare function editsStoreReady(): boolean;
|
|
3
|
+
export declare function listEdits(): EditIndex['edits'];
|
|
4
|
+
export declare function readEditBundle(editId: string): OmpoEditBundle;
|
|
5
|
+
export declare function recordEditPull(editId: string): void;
|
|
6
|
+
export declare function recordEditApplied(editId: string): void;
|
package/dist/edit-store.js
CHANGED
|
@@ -1,67 +1,44 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
process.env.OMPO_PROJECT_ROOT,
|
|
7
|
-
process.env.CLAUDE_PROJECT_DIR,
|
|
8
|
-
startDir
|
|
9
|
-
].filter((value) => Boolean(value?.trim()));
|
|
10
|
-
return [...new Set(candidates.map((value) => resolve(value)))];
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { getOmpoEditsStorePath } from './edits-path.js';
|
|
4
|
+
function editsDirectory() {
|
|
5
|
+
return getOmpoEditsStorePath();
|
|
11
6
|
}
|
|
12
|
-
export function
|
|
13
|
-
|
|
14
|
-
const found = findProjectRootFrom(candidate);
|
|
15
|
-
if (found)
|
|
16
|
-
return found;
|
|
17
|
-
}
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
function findProjectRootFrom(startDir) {
|
|
21
|
-
let current = resolve(startDir);
|
|
22
|
-
while (true) {
|
|
23
|
-
const editsDirectory = join(current, OMPo_EDITS_DIR);
|
|
24
|
-
if (existsSync(join(editsDirectory, 'index.json'))) {
|
|
25
|
-
return current;
|
|
26
|
-
}
|
|
27
|
-
const parent = dirname(current);
|
|
28
|
-
if (parent === current)
|
|
29
|
-
return null;
|
|
30
|
-
current = parent;
|
|
31
|
-
}
|
|
7
|
+
export function editsStoreReady() {
|
|
8
|
+
return existsSync(join(editsDirectory(), 'index.json'));
|
|
32
9
|
}
|
|
33
|
-
function readIndex(
|
|
34
|
-
const indexPath = join(
|
|
10
|
+
function readIndex() {
|
|
11
|
+
const indexPath = join(editsDirectory(), 'index.json');
|
|
35
12
|
return JSON.parse(readFileSync(indexPath, 'utf8'));
|
|
36
13
|
}
|
|
37
|
-
function writeIndex(
|
|
38
|
-
const indexPath = join(
|
|
14
|
+
function writeIndex(index) {
|
|
15
|
+
const indexPath = join(editsDirectory(), 'index.json');
|
|
39
16
|
writeFileSync(indexPath, `${JSON.stringify(index, null, 2)}\n`, 'utf8');
|
|
40
17
|
}
|
|
41
|
-
export function listEdits(
|
|
42
|
-
return readIndex(
|
|
18
|
+
export function listEdits() {
|
|
19
|
+
return readIndex().edits;
|
|
43
20
|
}
|
|
44
|
-
export function readEditBundle(
|
|
45
|
-
const bundlePath = join(
|
|
21
|
+
export function readEditBundle(editId) {
|
|
22
|
+
const bundlePath = join(editsDirectory(), `${editId}.json`);
|
|
46
23
|
if (!existsSync(bundlePath)) {
|
|
47
24
|
throw new Error(`Edit not found: ${editId}`);
|
|
48
25
|
}
|
|
49
26
|
return JSON.parse(readFileSync(bundlePath, 'utf8'));
|
|
50
27
|
}
|
|
51
|
-
export function recordEditPull(
|
|
52
|
-
const index = readIndex(
|
|
28
|
+
export function recordEditPull(editId) {
|
|
29
|
+
const index = readIndex();
|
|
53
30
|
const entry = index.edits.find((edit) => edit.id === editId);
|
|
54
31
|
if (!entry)
|
|
55
32
|
return;
|
|
56
33
|
entry.pulls += 1;
|
|
57
34
|
entry.lastPulledAt = new Date().toISOString();
|
|
58
|
-
writeIndex(
|
|
35
|
+
writeIndex(index);
|
|
59
36
|
}
|
|
60
|
-
export function recordEditApplied(
|
|
61
|
-
const index = readIndex(
|
|
37
|
+
export function recordEditApplied(editId) {
|
|
38
|
+
const index = readIndex();
|
|
62
39
|
const entry = index.edits.find((edit) => edit.id === editId);
|
|
63
40
|
if (!entry)
|
|
64
41
|
return;
|
|
65
42
|
entry.appliedAt = new Date().toISOString();
|
|
66
|
-
writeIndex(
|
|
43
|
+
writeIndex(index);
|
|
67
44
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getOmpoEditsStorePath(): string;
|
package/dist/index.js
CHANGED
|
@@ -4,26 +4,27 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { buildApplyPlan, explainEdit } from './apply-plan.js';
|
|
6
6
|
import { runCli } from './cli.js';
|
|
7
|
-
import {
|
|
7
|
+
import { editsStoreReady, listEdits, readEditBundle, recordEditApplied, recordEditPull } from './edit-store.js';
|
|
8
|
+
import { getOmpoEditsStorePath } from './edits-path.js';
|
|
8
9
|
const server = new McpServer({
|
|
9
10
|
name: 'ompo-mcp-server',
|
|
10
|
-
version: '0.1.
|
|
11
|
+
version: '0.1.4'
|
|
11
12
|
});
|
|
12
|
-
function
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
15
|
-
throw new Error('No Ompo edits found.
|
|
13
|
+
function requireEditsStore() {
|
|
14
|
+
const storePath = getOmpoEditsStorePath();
|
|
15
|
+
if (!editsStoreReady()) {
|
|
16
|
+
throw new Error('No Ompo edits found. Click Send in Ompo first to save an edit, then try again.');
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return storePath;
|
|
18
19
|
}
|
|
19
|
-
server.tool('list_edits', 'List Ompo edit bundles saved
|
|
20
|
-
const
|
|
21
|
-
const edits = listEdits(
|
|
20
|
+
server.tool('list_edits', 'List Ompo edit bundles saved on this machine', {}, async () => {
|
|
21
|
+
const storePath = requireEditsStore();
|
|
22
|
+
const edits = listEdits();
|
|
22
23
|
return {
|
|
23
24
|
content: [
|
|
24
25
|
{
|
|
25
26
|
type: 'text',
|
|
26
|
-
text: JSON.stringify({
|
|
27
|
+
text: JSON.stringify({ storePath, edits }, null, 2)
|
|
27
28
|
}
|
|
28
29
|
]
|
|
29
30
|
};
|
|
@@ -31,9 +32,9 @@ server.tool('list_edits', 'List Ompo edit bundles saved in the current project',
|
|
|
31
32
|
server.tool('get_edit', 'Load a specific Ompo edit bundle by id', {
|
|
32
33
|
id: z.string().describe('Edit id, e.g. ed_8K42P')
|
|
33
34
|
}, async ({ id }) => {
|
|
34
|
-
|
|
35
|
-
const bundle = readEditBundle(
|
|
36
|
-
recordEditPull(
|
|
35
|
+
requireEditsStore();
|
|
36
|
+
const bundle = readEditBundle(id);
|
|
37
|
+
recordEditPull(id);
|
|
37
38
|
return {
|
|
38
39
|
content: [
|
|
39
40
|
{
|
|
@@ -46,9 +47,9 @@ server.tool('get_edit', 'Load a specific Ompo edit bundle by id', {
|
|
|
46
47
|
server.tool('explain_edit', 'Summarize what an Ompo edit changes', {
|
|
47
48
|
id: z.string().describe('Edit id, e.g. ed_8K42P')
|
|
48
49
|
}, async ({ id }) => {
|
|
49
|
-
|
|
50
|
-
const bundle = readEditBundle(
|
|
51
|
-
recordEditPull(
|
|
50
|
+
requireEditsStore();
|
|
51
|
+
const bundle = readEditBundle(id);
|
|
52
|
+
recordEditPull(id);
|
|
52
53
|
return {
|
|
53
54
|
content: [
|
|
54
55
|
{
|
|
@@ -58,19 +59,19 @@ server.tool('explain_edit', 'Summarize what an Ompo edit changes', {
|
|
|
58
59
|
]
|
|
59
60
|
};
|
|
60
61
|
});
|
|
61
|
-
server.tool('apply_edit', 'Build an apply plan for an Ompo edit. The agent should execute the plan against source files and only change listed properties.', {
|
|
62
|
+
server.tool('apply_edit', 'Build an apply plan for an Ompo edit. The agent should execute the plan against source files in the open codebase and only change listed properties.', {
|
|
62
63
|
id: z.string().describe('Edit id, e.g. ed_8K42P'),
|
|
63
64
|
markApplied: z
|
|
64
65
|
.boolean()
|
|
65
66
|
.optional()
|
|
66
67
|
.describe('Set true after the agent successfully applies the edit')
|
|
67
68
|
}, async ({ id, markApplied }) => {
|
|
68
|
-
|
|
69
|
-
const bundle = readEditBundle(
|
|
70
|
-
recordEditPull(
|
|
69
|
+
requireEditsStore();
|
|
70
|
+
const bundle = readEditBundle(id);
|
|
71
|
+
recordEditPull(id);
|
|
71
72
|
const plan = buildApplyPlan(bundle);
|
|
72
73
|
if (markApplied) {
|
|
73
|
-
recordEditApplied(
|
|
74
|
+
recordEditApplied(id);
|
|
74
75
|
}
|
|
75
76
|
return {
|
|
76
77
|
content: [
|