Skip to content

Releases: StephaneBerthoz/sandforge

SandForge 1.39.5

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 10:36

A cancel stops every write that has not gone out, and the command-line tools
read and delete everything they are asked to.

Fixed

  • A cancel stops every write that has not gone out: a write's first
    batch, a batch the target failed on, a Bulk API job not yet opened, and a
    Frozen object's rows once its relations were looked up.
  • A Forge object the cancel stops says what it wrote, and the updates that
    give invitees their flags stop with the run.
  • Forge's execution shows the API calls made so far; the plan, QuickSync
    and Autopilot say their counts are estimates.
  • Autopilot's review takes the keyboard back when a run is refused or its
    confirmation declined.
  • Forge says why each held-back row is not written, and rows read again
    under a late order keep only those its status needs.
  • The sync command reads every row of an object, not the first 200, and
    every command reads every page of a query.
  • The cleanup command deletes more than 200 records, and the clone command
    prints every group of errors.

SandForge 1.39.4

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 08:35

A wizard ignores a second Enter while it waits, and Forge follows a catalog
further.

Fixed

  • A second Enter never starts an unreviewed run: while a wizard's Next
    waits, the keyboard stays on it, then moves to the step that comes.
  • Autopilot announces its scan and its plan, and the keyboard moves to its
    run when it starts.
  • Forge's plan and preview card say their API calls are estimates.
  • Forge: a product sold only by held-back lines is held back with them.
  • Forge: records read before a parent that came late are read again under
    it
    , and a category brings its parents up the tree.
  • An invited contact keeps its flag when the target refuses only its
    answer, and the refused field is named.
  • The clone command counts its record-type lookup, and the frozen command
    prints the PersonContact links.

SandForge 1.39.3

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 06:13

The webview runs on React 19; every page renders as before.

Changed

  • The webview runs on React 19, with zustand 5, framer-motion 13 and React
    Flow's maintained package, @xyflow/react 12.
  • A few icons are redrawn by lucide's newer set, with the same meaning.

SandForge 1.39.2

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 04:45

The webview is built with Vite 8 and payloads are validated with zod 4; every
page renders as before.

Changed

  • The webview is built with Vite 8, its pages and styles unchanged.
  • Payloads are validated with zod 4, which parses without eval in the
    webview, as its content security policy requires.

SandForge 1.39.1

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 02:31

Seed Clone writes only where it previewed, and Production Guard is told what
a Forge run can really write.

Fixed

  • Seed Clone runs against the orgs it previewed. Selecting another org
    after the preview sets it aside, and the extension refuses a run that names
    no preview, one it no longer holds, or one made for other orgs.
  • Seed Clone warns before Execute when the target requires a lookup the
    source does not have, shows that its preview is being prepared, and keeps
    the wizard when an error is dismissed.
  • Seed Clone's Next runs the clone instead of opening an empty step, and
    the source is asked only for the fields it has.
  • Production Guard is told what a Forge run can write: the objects it
    writes, at most their capped counts, the related records it adds besides,
    and "unknown" when nothing counted them.
  • Forge counts the API calls a run makes; an estimate says it is one.
  • The Review plan tab stops showing zeros for a starter template, and a
    node card's count survives the progress throttle.
  • The clone command reads every page of a query, not the first 2 000
    records.

SandForge 1.39.0

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 25 Sep 01:08

A Frozen load can be taken back, a stopped Forge run can write the rest, and
every module says what it wrote, held back or could not write.

Added

  • Take back a Frozen load from the Frozen page or the command line: the
    records it created go, the ones it only linked stay, and earlier loads can
    be taken back one by one. Not yet run against a real org.
  • Write the rest of a failed or stopped Forge run over what the first run
    wrote.
  • The Load tab says why: failed records grouped by reason, what a
    reload's purge took and could not take, and the links a load left empty.

Fixed

  • Forge: a stopped run says what it wrote and offers a way out; its
    progress, log, clock and result survive leaving the screen, and it reads
    Stopped, not Completed.
  • Forge: an abort is never lost, even during Production Guard's
    confirmation, and a second run waits for the first to finish.
  • Forge: what you leave out stays out. Unchecked or excluded objects are
    held back with their cost shown in Review, and so is every row that needs
    one of them.
  • Forge: no lines lost at smaller caps, and a product clone brings only
    the categories its own assignments name.
  • Forge: activated orders at the default cap bring their items and are
    activated again.
  • Forge: the catalog is read again for what later records name, and a
    price book the clone leaves out brings no price.
  • Forge: starter templates say their counts come with discovery, and the
    clone command says what its graph numbers count.
  • Frozen: a reload purges only what earlier loads created, dated by the
    org's clock, and a load that fails part way keeps what it created named.
  • Frozen: a refused or cancelled reload purges nothing it should keep, and
    orders a stopped reload set to Draft get their status back.
  • Frozen: a load leaves out what the target refuses, carries the prices a
    pilot needs, and keeps matching the standard price book when price books
    are excluded.
  • Frozen: verify names a changed or moved dataset folder before anything
    else.
  • Rows the platform writes itself are left to it: an email's task and an
    event's or task's contact, in Forge, Frozen, Sync, Seed and Autopilot. An
    invited contact keeps their answer.
  • Seed Clone orders by what both orgs have in common, breaks cycles with a
    second pass, says when a clone was cancelled, and needs both orgs before its
    preview.
  • Updates send the duplicate-rule header in Sync, DataOps anonymization,
    compliance erasure and cleanup.
  • Live Operations and the Forge cards add up every write of an object.
  • A cancelled run that wrote nothing is recorded as stopped in Forge,
    Frozen and CSV import.

SandForge 1.38.2

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 24 Sep 17:53

Forge and Frozen clone what a record really holds, and report it in numbers
that add up. Checked on a real pair of sandboxes.

Fixed

  • An opportunity clone with product lines works at the default settings.
    Its prices, products, price books and selling models now come whatever the
    object cap; before, the lines were refused.
  • Results count the clone, not the tables it came from: a run of 272
    records reads "272 of 272", where it read "272 of 4315".
  • A read that fails is named, not counted as a whole table of failures,
    and the rate never looks complete when an object could not be read.
  • A feed item is written when its own parent is: one failed parent object
    no longer skips every feed item of the run.
  • Tracked changes are left to the platform by every module that copies
    feed items — Forge, Frozen, Autopilot, Sync and Seed's clone — and reported:
    the platform writes them itself and refuses a copy.
  • Order actions come with their orders.
  • The catalog is read after the records put off to the end, for the
    prices and products only they name.
  • A clone from a price book or a product brings the other books and
    products its lines name.
  • A line brings the prices of its own currency, not every currency's.
  • Full-table runs write required parents first.
  • The plan breaks each cycle where the run does, and says when one cannot
    be broken.
  • A run cancelled in the middle of an object counts what it wrote, and the
    rows still waiting for their key.
  • A removal cancelled part way no longer blocks the next one.
  • A dry run says what the target would refuse, as a real run does.
  • Reference data is matched by name even where the target refuses inserts.
  • Objects with nothing to clone are no longer listed as errors; the clone
    command says why each object was skipped and folds empty tables into one
    line.
  • A dry run with files says why the file lookup failed.
  • The Skipped card counts objects, and the Reports page counts the records
    a run read.
  • A polymorphic orphan's parent is looked for in its own object.
  • Frozen dossiers read their scope both ways: one opportunity's went from
    23 records to 249, its quotes, orders and prices included, at any cap.
  • A Frozen load links the selling model the target already holds, and
    carries the options its prices need.

SandForge 1.38.1

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 24 Sep 12:17

Opportunity clones and run removal, hardened on a real pair of sandboxes.

Fixed

  • Opportunity clones bring their products. Prices were refused and orders
    stayed unactivated.
  • Each currency keeps its own price in multi-currency orgs.
  • Large catalogs no longer overflow a request when standard prices are
    read.
  • Discovery keeps required lookups, whichever side of the relationship it
    reads first.
  • Full-table runs write past a failed optional parent, leaving that lookup
    empty and reported.
  • Records written before a failed call are kept, and the lookups they owe
    are filled in.
  • More orders get their status back: after an upsert, a failed call, or
    when fetched as a parent. Drafts left by a cancel or a failure are listed.
  • Second-pass counts report every lookup left empty.
  • File copy stops before writing when the files cannot be looked up; the
    size field keeps only what you finished typing.
  • Run results open one report at a time.
  • Removing a run leaves what a colleague adds meanwhile, gives the orders it
    set to Draft their status back, and dates the run by the org's clock.

SandForge 1.38.0

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 23 Sep 21:38

Forge can copy the files of what it clones, when you ask for it, and an
opportunity clone now brings the catalog its lines use rather than all of it.
Run against a real pair of sandboxes, that clone met the rest of what a Sales
Cloud org holds: selling models, activated orders, quotes the running user
cannot write. It now writes every price and line, restores each order's
status, and its removal goes in one pass.

Added

  • Forge copies files, on request. The Salesforce Files and attachments of
    the records a run clones are copied to the records it creates, each file in
    its own call, after the records it hangs on. Off by default; while a run
    anonymizes, refused unless you accept that files are copied as they are,
    since their content cannot be anonymized. Each file is capped (10 MB by
    default, 35 at most) and the total is checked against the target's file
    storage before anything is written. A dry run lists them; removing the run
    removes them too. sandforge-clone gains --files, --max-file-size and
    --files-as-is.

Fixed

  • A clone no longer writes a file's content as its address. Discovery
    left file objects in the graph, and a clone that met one wrote each file's
    body as the text of its URL. File objects are now left to the file copy, and
    every other field holding a file's content — a quote's generated document —
    is left empty and named in the summary.
  • An opportunity clone brings the catalog its lines use. Prices and
    products were read as children of every price book in scope, the standard
    one included: 171 prices and 146 products for an opportunity of three line
    items. The clone now
    brings the prices its opportunity, quote and order lines use, their
    products, the standard prices those need and their price books — and keeps
    the quote and order lines priced from other books, which it dropped.
  • Catalogs sold under selling models clone. Every price under a selling
    model was refused for want of the product's selling-model option: the
    options are now cloned, or linked, before the prices, and each price gets
    the standard price of its own selling model.
  • Prices are written before every line that uses them, and an opportunity
    after its account.
    The order no longer depends on which object discovery
    met first.
  • Activated orders clone. An order or contract past Draft is written as a
    draft and gets its status back once the run has written everything.
  • A record whose optional parent could not be written is written with that
    lookup empty
    , and the run says which lookups it left empty, all of them —
    it counted three at most. Orders whose quote was held back were skipped
    whole.
  • A large scoped clone no longer overflows the query URI: a parent's whole
    id list was repeated in every statement.
  • Removing a run goes in one pass. Records are deleted after whatever still
    points at them, the root included; a refusal for a dependency is retried; a
    record the removal itself causes — a feed item, a duplicate-rule entry, a
    file's link — no longer holds anything back; custom prices go before
    standard ones; activated orders go back to Draft first. Every date is read
    from the org's clock, not this machine's.
  • The Forge dependency graph works from the keyboard. A node was a button
    around its own checkbox, which a screen reader could not tell apart; its
    name now selects it.

Changed

  • jsforce stays at 3.10.14. Later releases send their requests through a
    transport of their own that skips the proxy VS Code applies to the
    extension; a gate now refuses a jsforce that does, until the proxy is wired
    to it.

SandForge 1.37.0

Choose a tag to compare

@StephaneBerthoz StephaneBerthoz released this 23 Sep 12:03

Forge can now take back what it cloned: a run's history entry removes, from
the target, the records that run created and nothing else — a failed or
cancelled run included. A record-scoped clone keeps every child: a lookup back
to the parent, or a child another user owns, dropped records without a word.
Cancel stops what it cancels, every write run shows in Live Operations, and a
cancelled large upload is aborted before Salesforce writes rows nobody counts.
Around it, a second window no longer undoes the first one's saves, a profile
import brings Forge templates to the project it was made in, and a native
reading of the six languages and a screen reader corrected the rest.

Added

  • Remove the records a Forge run created. Each run in the Forge history
    offers to remove, from its target, the records it created: children before
    their parents, only those still there. Records the run linked to rather than
    created are never touched, nor anything a later record still depends on;
    records changed since the run are kept unless you ask to include them. The
    Production Guard is consulted, the removal is audited, runs in Live
    Operations and can be cancelled, and the result says per object what was
    deleted, already gone, kept and refused, with Salesforce's reason. A run
    that failed or was cancelled after writing is kept in the history too, so
    its records can be removed the same way.
  • Every write run shows in Live Operations, and Cancel there stops it:
    Forge runs, record clones, CSV imports and Frozen loads join Sync and Seed.

Fixed

  • A record-scoped clone keeps every child. Two cases dropped records
    without a word: when the parent object has a lookup back to the child — an
    account's "key contact" made the clone keep that contact and leave the
    account's other contacts behind — and when a child was owned, created or
    last modified by a user no earlier record named. Frozen extraction had the
    second defect too.
  • Cancel stops what it cancels. A Sync or Seed run went on writing its
    remaining objects after a cancel and ended as a success or a failure; it now
    stops between objects and ends as cancelled with what it wrote. Record
    clone, CSV import and Frozen load stop the same way. A cancelled upload of
    more than 10,000 records aborted too late: the job was closed, and
    Salesforce wrote the rows already uploaded without anyone counting or
    auditing them; it is now aborted before Salesforce processes it, and an
    upload of 201 to 10,000 records too. A large object's write stops between
    its batches of 200 instead of after its last.
  • A cancelled operation says cancelled in the recent operations, on Home,
    in the side panel, in Sync history, in the schedule badge, on the results
    screens and in the native notification. A Forge run that fails or is
    cancelled, or a plan or comparison that fails, no longer stays "running".
  • Two windows no longer undo each other's saves. The settings store read
    a window's state once and wrote its whole copy back, so a save made in one
    window was lost at the next save of another.
  • A configuration profile carries what it names. Forge templates are
    exported from the project's own file and imported into the project the
    import was made in, adding what the project lacks, or replacing it when
    overwrite is chosen; no project receives another project's templates any
    more. The Settings category, which always exported nothing, is gone:
    SandForge's settings are VS Code settings, which Settings Sync carries.
  • Names count as personal data. First, last, middle and maiden names are
    flagged, so Forge anonymizes them, quick-start templates included. The GDPR
    template keeps the last four digits of a phone number.
  • A stored date that cannot be read no longer breaks a screen. The Sync
    history, the schedules, the triggers, the Monitor's panels and charts, the
    backups and the device sign-in threw or printed "Invalid Date"; they now say
    the date is unknown.
  • Schedules keep a date they can run on. A stored next run that cannot be
    read is planned again instead of run at once, and no longer blanks the
    schedule list; a schedule planned for 2054 is planned again.
  • Compare names a change one way. The diff views drew what a deployment
    creates in red, under a minus; they now draw it as an addition, as the risk
    card reads it. The Deploy tab says "Only in the source" and "Modified", as
    the diff views do; a group's counts say what they count to a screen reader;
    the risk level is written in the panel's language. A pipeline's Compare
    step names the org that holds each difference.
  • A wizard shows one step at a time. The step being left stayed on screen
    beside the next one while it faded out, so a click could land on it. Each
    field rule of Seed's Configure step is named after its field, each
    favourite star after its module, each status icon of the side panel after
    its status.
  • A hidden Monitor reads no org. VS Code keeps a hidden panel running, and
    the Monitor's auto-refresh went on reading the org every 30 seconds from a
    tab nobody was looking at; it now waits until the panel is shown again.
  • Errors stay until you dismiss them, including the ones the extension
    raises.
  • The command-line tools read a usable token where the Salesforce CLI now
    redacts it; sandforge-monitor no longer prints production's creation date
    as a sandbox's own; sandforge-clone --dry-run prints what each object
    would receive, and --upsert counts an updated record as updated, not
    created.
  • The translations read as native text. Japanese names an org 組織 and a
    field 項目, as Salesforce's Japanese interface does; French says "modèle",
    "vérification préalable" and "décomptes"; Spanish makes a sandbox
    masculine; Flow keeps its capital.