(
ctx: MemoryScopeContext,
virtualPath: string,
insertLine: number,
insertText: string,
actor: MemoryActor
)
| 772 | } |
| 773 | |
| 774 | async insert( |
| 775 | ctx: MemoryScopeContext, |
| 776 | virtualPath: string, |
| 777 | insertLine: number, |
| 778 | insertText: string, |
| 779 | actor: MemoryActor |
| 780 | ): Promise<MemoryCommandResult> { |
| 781 | return this.runCommand(async () => { |
| 782 | const parsed = parseMemoryPath(virtualPath); |
| 783 | const scope = this.requireFilePath(parsed, virtualPath); |
| 784 | const store = await this.resolveStore(ctx, scope, parsed.relPath); |
| 785 | return this.locks.withLock(store.physicalRoot, async () => { |
| 786 | const content = await this.readTextFileForEdit(store, parsed.relPath, virtualPath); |
| 787 | const lines = content === "" ? [] : content.split("\n"); |
| 788 | if (insertLine < 0 || insertLine > lines.length) { |
| 789 | throw new MemoryCommandError( |
| 790 | `insert_line must be between 0 and ${lines.length} (0 inserts at the top; N inserts after line N)` |
| 791 | ); |
| 792 | } |
| 793 | const insertedLines = insertText.split("\n"); |
| 794 | // Trailing newline in insert_text would otherwise produce a stray blank line. |
| 795 | if (insertedLines.at(-1) === "") insertedLines.pop(); |
| 796 | lines.splice(insertLine, 0, ...insertedLines); |
| 797 | const updated = lines.join("\n"); |
| 798 | assertWithinFileSizeCap(updated); |
| 799 | await store.writeFile(parsed.relPath, updated); |
| 800 | await this.recordUsage(ctx, scope, parsed.relPath, { write: true }); |
| 801 | this.emitChange(ctx, scope, parsed.relPath, actor); |
| 802 | return { |
| 803 | success: true as const, |
| 804 | output: `Inserted ${insertedLines.length} line(s) into ${toVirtualPath(scope, parsed.relPath)} after line ${insertLine}`, |
| 805 | }; |
| 806 | }); |
| 807 | }); |
| 808 | } |
| 809 | |
| 810 | async deletePath( |
| 811 | ctx: MemoryScopeContext, |
no test coverage detected