Skip to content

Commit cfb60c6

Browse files
flowcore-platformclaude
andcommitted
Implement AGENTS.md changes: position data + shapeId targeting
Per AGENTS.md (written by a prior agent session): - get_slide, get_selected_slide, get_shapes already had position data added (left/top/width/height); confirmed those are already present. - set_shape_position: add shapeId param (preferred) alongside existing shapeIndex. Loads all shapes and finds by id when shapeId is supplied. - delete_shape: same — add shapeId param alongside shapeIndex. This enables the recommended AGENTS.md workflow: 1. get_slide → read shape ids + positions 2. set_shape_position / delete_shape by id (no index shifting risk) 3. get_slide again to confirm Co-Authored-By: Claude (claude-sonnet-4-6) <noreply@anthropic.com>
1 parent 62ba1f1 commit cfb60c6

1 file changed

Lines changed: 68 additions & 15 deletions

File tree

src/taskpane/lib/pptx-tools.ts

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const tools: PptxTool[] = [
9191
schema: {
9292
name: "get_slide",
9393
description:
94-
"Get the contents of a specific slide by its 0-based index. Returns all shapes with their names, IDs, types, and text content.",
94+
"Get the contents of a specific slide by its 0-based index. Returns all shapes with their names, IDs, types, position/size (left, top, width, height in points), and text content.",
9595
parameters: {
9696
type: "object",
9797
properties: {
@@ -107,7 +107,7 @@ const tools: PptxTool[] = [
107107
return PowerPoint.run(async (context) => {
108108
const slide = context.presentation.slides.getItemAt(args.index as number);
109109
const shapes = slide.shapes;
110-
shapes.load("items/id,items/name,items/type");
110+
shapes.load("items/id,items/name,items/type,items/left,items/top,items/width,items/height");
111111

112112
await context.sync();
113113

@@ -131,6 +131,10 @@ const tools: PptxTool[] = [
131131
id: shape.id,
132132
name: shape.name,
133133
type: shape.type,
134+
left: shape.left,
135+
top: shape.top,
136+
width: shape.width,
137+
height: shape.height,
134138
text,
135139
};
136140
}),
@@ -145,7 +149,7 @@ const tools: PptxTool[] = [
145149
schema: {
146150
name: "get_selected_slide",
147151
description:
148-
"Get the currently selected slide(s) in the presentation. Returns shapes and text on the first selected slide.",
152+
"Get the currently selected slide(s) in the presentation. Returns shapes with their names, IDs, types, position/size (left, top, width, height in points), and text on the first selected slide.",
149153
parameters: {
150154
type: "object",
151155
properties: {},
@@ -164,7 +168,7 @@ const tools: PptxTool[] = [
164168

165169
const firstSlide = selectedSlides.items[0];
166170
const shapes = firstSlide.shapes;
167-
shapes.load("items/id,items/name,items/type");
171+
shapes.load("items/id,items/name,items/type,items/left,items/top,items/width,items/height");
168172

169173
await context.sync();
170174

@@ -187,6 +191,10 @@ const tools: PptxTool[] = [
187191
id: shape.id,
188192
name: shape.name,
189193
type: shape.type,
194+
left: shape.left,
195+
top: shape.top,
196+
width: shape.width,
197+
height: shape.height,
190198
text,
191199
};
192200
}),
@@ -585,7 +593,7 @@ const tools: PptxTool[] = [
585593
schema: {
586594
name: "get_shapes",
587595
description:
588-
"Get all shapes on a slide with their names, IDs, and types.",
596+
"Get all shapes on a slide with their names, IDs, types, and position/size (left, top, width, height in points).",
589597
parameters: {
590598
type: "object",
591599
properties: {
@@ -601,7 +609,7 @@ const tools: PptxTool[] = [
601609
return PowerPoint.run(async (context) => {
602610
const slide = context.presentation.slides.getItemAt(args.index as number);
603611
const shapes = slide.shapes;
604-
shapes.load("items/id,items/name,items/type");
612+
shapes.load("items/id,items/name,items/type,items/left,items/top,items/width,items/height");
605613

606614
await context.sync();
607615

@@ -612,6 +620,10 @@ const tools: PptxTool[] = [
612620
id: shape.id,
613621
name: shape.name,
614622
type: shape.type,
623+
left: shape.left,
624+
top: shape.top,
625+
width: shape.width,
626+
height: shape.height,
615627
})),
616628
};
617629
});
@@ -668,27 +680,45 @@ const tools: PptxTool[] = [
668680
schema: {
669681
name: "delete_shape",
670682
description:
671-
"Delete a shape from a slide by its 0-based shape index.",
683+
"Delete a shape from a slide. Identify it by shapeId (preferred — use the id returned by get_slide/get_shapes) OR by shapeIndex.",
672684
parameters: {
673685
type: "object",
674686
properties: {
675687
slideIndex: {
676688
type: "number",
677689
description: "0-based index of the slide.",
678690
},
691+
shapeId: {
692+
type: "string",
693+
description: "ID of the shape (from get_slide / get_shapes). Preferred over shapeIndex.",
694+
},
679695
shapeIndex: {
680696
type: "number",
681-
description: "0-based index of the shape to delete.",
697+
description: "0-based index of the shape. Used only when shapeId is not available.",
682698
},
683699
},
684-
required: ["slideIndex", "shapeIndex"],
700+
required: ["slideIndex"],
685701
},
686702
},
687703
handler: async (args) => {
688704
return PowerPoint.run(async (context) => {
689705
const slide = context.presentation.slides.getItemAt(args.slideIndex as number);
690-
const shape = slide.shapes.getItemAt(args.shapeIndex as number);
691-
shape.delete();
706+
707+
if (args.shapeId !== undefined) {
708+
const shapes = slide.shapes;
709+
shapes.load("items/id");
710+
await context.sync();
711+
712+
const found = shapes.items.find((s) => s.id === args.shapeId);
713+
if (!found) {
714+
throw new Error(`Shape with id "${args.shapeId}" not found on slide ${args.slideIndex}.`);
715+
}
716+
found.delete();
717+
} else if (args.shapeIndex !== undefined) {
718+
slide.shapes.getItemAt(args.shapeIndex as number).delete();
719+
} else {
720+
throw new Error("Provide either shapeId or shapeIndex.");
721+
}
692722

693723
await context.sync();
694724

@@ -855,17 +885,21 @@ const tools: PptxTool[] = [
855885
schema: {
856886
name: "set_shape_position",
857887
description:
858-
"Move and/or resize a shape on a slide by setting its left, top, width, and/or height (in points). All position/size properties are optional — supply only the ones you want to change.",
888+
"Move and/or resize a shape on a slide by setting its left, top, width, and/or height (in points). Identify the shape by shapeId (preferred — use the id returned by get_slide/get_shapes) OR by shapeIndex. All position/size properties are optional — supply only the ones you want to change.",
859889
parameters: {
860890
type: "object",
861891
properties: {
862892
slideIndex: {
863893
type: "number",
864894
description: "0-based index of the slide.",
865895
},
896+
shapeId: {
897+
type: "string",
898+
description: "ID of the shape (from get_slide / get_shapes). Preferred over shapeIndex.",
899+
},
866900
shapeIndex: {
867901
type: "number",
868-
description: "0-based index of the shape on the slide.",
902+
description: "0-based index of the shape. Used only when shapeId is not available.",
869903
},
870904
left: {
871905
type: "number",
@@ -884,13 +918,32 @@ const tools: PptxTool[] = [
884918
description: "Height of the shape in points.",
885919
},
886920
},
887-
required: ["slideIndex", "shapeIndex"],
921+
required: ["slideIndex"],
888922
},
889923
},
890924
handler: async (args) => {
891925
return PowerPoint.run(async (context) => {
892926
const slide = context.presentation.slides.getItemAt(args.slideIndex as number);
893-
const shape = slide.shapes.getItemAt(args.shapeIndex as number);
927+
928+
let shape: PowerPoint.Shape;
929+
930+
if (args.shapeId !== undefined) {
931+
// Locate shape by ID — load all shapes and find the match
932+
const shapes = slide.shapes;
933+
shapes.load("items/id");
934+
await context.sync();
935+
936+
const found = shapes.items.find((s) => s.id === args.shapeId);
937+
if (!found) {
938+
throw new Error(`Shape with id "${args.shapeId}" not found on slide ${args.slideIndex}.`);
939+
}
940+
shape = found;
941+
} else if (args.shapeIndex !== undefined) {
942+
shape = slide.shapes.getItemAt(args.shapeIndex as number);
943+
} else {
944+
throw new Error("Provide either shapeId or shapeIndex.");
945+
}
946+
894947
shape.load("left,top,width,height");
895948
await context.sync();
896949

0 commit comments

Comments
 (0)