this repo has no description

refacto: move extension to remanso package

+6 -95
+2 -1
package.json
··· 17 17 "deploy:docs": "cd docs && bun run deploy", 18 18 "deploy:cli": "cd packages/cli && bun run deploy", 19 19 "deploy:remanso": "cd packages/remanso && bun run deploy", 20 - "test:cli": "cd packages/cli && bun test" 20 + "test:cli": "cd packages/cli && bun test", 21 + "test:remanso": "cd packages/remanso && bun test" 21 22 }, 22 23 "devDependencies": { 23 24 "@types/bun": "latest",
-90
packages/cli/src/commands/publish.ts
··· 28 28 } from "../lib/markdown"; 29 29 import type { BlogPost, BlobObject, StrongRef } from "../lib/types"; 30 30 import { exitOnCancel } from "../lib/prompts"; 31 - import { 32 - createNote, 33 - updateNote, 34 - deleteNote, 35 - findPostsWithStaleLinks, 36 - type NoteOptions, 37 - } from "../extensions/remanso"; 38 31 import { fileExists } from "../lib/utils"; 39 32 40 33 export const publishCommand = command({ ··· 379 372 let errorCount = 0; 380 373 let bskyPostCount = 0; 381 374 382 - const context: NoteOptions = { 383 - contentDir, 384 - imagesDir, 385 - allPosts: posts, 386 - }; 387 - 388 - // Pass 1: Create/update document records and collect note queue 389 - const noteQueue: Array<{ 390 - post: BlogPost; 391 - action: "create" | "update"; 392 - atUri: string; 393 - }> = []; 394 - 395 375 for (const { post, action } of postsToPublish) { 396 376 const trimmedContent = post.content.trim(); 397 377 const titleMatch = trimmedContent.match(/^# (.+)$/m); ··· 511 491 bskyPostRef, 512 492 }; 513 493 514 - noteQueue.push({ post, action, atUri }); 515 494 } catch (error) { 516 495 const errorMessage = 517 496 error instanceof Error ? error.message : String(error); ··· 521 500 } 522 501 } 523 502 524 - // Pass 2: Create/update Remanso notes (atUris are now available for link resolution) 525 - for (const { post, action, atUri } of noteQueue) { 526 - try { 527 - if (action === "create") { 528 - await createNote(agent, post, atUri, context); 529 - } else { 530 - await updateNote(agent, post, atUri, context); 531 - } 532 - } catch (error) { 533 - log.warn( 534 - `Failed to create note for "${post.frontmatter.title}": ${error instanceof Error ? error.message : String(error)}`, 535 - ); 536 - } 537 - } 538 - 539 - // Re-process already-published posts with stale links to newly created posts 540 - const newlyCreatedSlugs = noteQueue 541 - .filter((r) => r.action === "create") 542 - .map((r) => r.post.slug); 543 - 544 - if (newlyCreatedSlugs.length > 0) { 545 - const batchFilePaths = new Set(noteQueue.map((r) => r.post.filePath)); 546 - const stalePosts = findPostsWithStaleLinks( 547 - posts, 548 - newlyCreatedSlugs, 549 - batchFilePaths, 550 - ); 551 - 552 - for (const stalePost of stalePosts) { 553 - try { 554 - s.start(`Updating links in: ${stalePost.frontmatter.title}`); 555 - await updateNote( 556 - agent, 557 - stalePost, 558 - stalePost.frontmatter.atUri!, 559 - context, 560 - ); 561 - s.stop(`Updated links: ${stalePost.frontmatter.title}`); 562 - } catch (error) { 563 - s.stop(`Failed to update links: ${stalePost.frontmatter.title}`); 564 - log.warn( 565 - ` ${error instanceof Error ? error.message : String(error)}`, 566 - ); 567 - } 568 - } 569 - } 570 - 571 503 // Delete records for removed files 572 504 let deletedCount = 0; 573 505 for (const { filePath, atUri } of deletedEntries) { ··· 576 508 s.start(`Deleting: ${filePath}`); 577 509 await deleteRecord(ag, atUri); 578 510 579 - // Try to delete the corresponding Remanso note 580 - try { 581 - const noteAtUri = atUri.replace( 582 - "site.standard.document", 583 - "space.remanso.note", 584 - ); 585 - await deleteNote(ag, noteAtUri); 586 - } catch { 587 - // Note may not exist, ignore 588 - } 589 - 590 511 delete state.posts[filePath]; 591 512 s.stop(`Deleted: ${filePath}`); 592 513 deletedCount++; ··· 603 524 const ag = await getAgent(); 604 525 s.start(`Deleting unmatched: ${title}`); 605 526 await deleteRecord(ag, atUri); 606 - 607 - // Try to delete the corresponding Remanso note 608 - try { 609 - const noteAtUri = atUri.replace( 610 - "site.standard.document", 611 - "space.remanso.note", 612 - ); 613 - await deleteNote(ag, noteAtUri); 614 - } catch { 615 - // Note may not exist, ignore 616 - } 617 527 618 528 s.stop(`Deleted unmatched: ${title}`); 619 529 unmatchedDeletedCount++;
+2 -2
packages/cli/src/extensions/remanso.test.ts packages/remanso/src/lib/note.test.ts
··· 1 1 import { describe, expect, test } from "bun:test"; 2 - import { resolveInternalLinks, findPostsWithStaleLinks } from "./remanso"; 3 - import type { BlogPost } from "../lib/types"; 2 + import { resolveInternalLinks, findPostsWithStaleLinks } from "./note"; 3 + import type { BlogPost } from "../../../cli/src/lib/types"; 4 4 5 5 function makePost( 6 6 slug: string,
+1 -1
packages/cli/src/extensions/remanso.ts packages/remanso/src/lib/note.ts
··· 2 2 import * as fs from "node:fs/promises"; 3 3 import * as path from "node:path"; 4 4 import mimeTypes from "mime-types"; 5 - import type { BlogPost, BlobObject } from "../lib/types"; 5 + import type { BlogPost, BlobObject } from "../../../cli/src/lib/types"; 6 6 7 7 const LEXICON = "space.remanso.note"; 8 8 const MAX_CONTENT = 10000;
+1 -1
packages/remanso/src/commands/publish.ts
··· 35 35 deleteNote, 36 36 findPostsWithStaleLinks, 37 37 type NoteOptions, 38 - } from "../../../cli/src/extensions/remanso"; 38 + } from "../lib/note"; 39 39 40 40 async function fileExists(filePath: string): Promise<boolean> { 41 41 try {