Skip to content

Repository files navigation

Untwine

Untwine is a local-first Mac app, CLI, and JavaScript library for diagnosing and safely repairing Articulate Rise/Storyline XLIFF import failures.

Open the browser-local tool · Build Untwine for Mac · Run the demo repair

What it catches · Examples · Safe repairs

Untwine local Articulate XLIFF import diagnostics interface

Sample output:

Verdict: repairable
Critical issues: 1
Total issues: 2

Use it when you exported an original .xlf, translated it in a CAT tool, and Articulate refuses to import it back because the translated file no longer matches the course structure.

The tool is intentionally narrow: it does not translate files and it does not promise to fix every XLIFF. It compares the original and translated XLIFF 1.2 files, reports likely import blockers, and only rewrites metadata that can be repaired deterministically without changing translated text.

Quickstart

git clone https://github.com/KikuAI-Lab/untwine.git
cd untwine
npm test

Analyze a repairable demo file:

node bin/articulate-xliff-doctor.js analyze \
  demo-files/demo-articulate-original.xlf \
  demo-files/demo-articulate-translated-safe-repair.xlf

Expected result:

Verdict: repairable
Critical issues: 1
Total issues: 2

The analyzer exits non-zero when it finds critical issues. That is expected for this demo fixture.

Write the repaired file:

node bin/articulate-xliff-doctor.js repair \
  demo-files/demo-articulate-original.xlf \
  demo-files/demo-articulate-translated-safe-repair.xlf \
  --out demo-files/demo-articulate-translated-safe-repair.repaired.xlf

Expected result:

Wrote repaired XLIFF: demo-files/demo-articulate-translated-safe-repair.repaired.xlf
Critical issues after repair: 0

If you install or link the package locally, the same CLI is available as articulate-xliff-doctor.

npm link
articulate-xliff-doctor analyze original.xlf translated.xlf --json

Untwine for Mac

The macOS app puts the same conservative repair engine behind drag-and-drop file selection, a visual diagnosis, and native save panels. Course text stays inside the app; there is no account, telemetry, upload, or translation service.

Requirements: macOS 13 or later, Node.js 20 or later, and the Swift toolchain included with Xcode or Xcode Command Line Tools.

npm test
npm run build:macos
npm run verify:macos
open dist/Untwine.app

The default build is a universal arm64 + x86_64 app. It is sandboxed and ad-hoc signed with the hardened-runtime option for local development. The build writes Untwine.app, a versioned Untwine-<version>-macOS.zip, and its matching .sha256 receipt beside the app; verification checks version consistency, the runtime flag, archive integrity/checksum and app-payload parity, bundle resources, entitlements, remote-URL absence, and generated-engine parity. CI sets UNTWINE_MAC_ARCHS to its native runner architecture and verifies the resulting thin app through the same path.

This release-candidate slice explicitly defers icon/ICNS generation, a Developer ID identity, a trusted timestamp and notarization, store/Gumroad/payment setup, an updater, analytics, a new framework or runtime, and real Articulate re-import proof. These remain separate owner-controlled release gates.

See the maintained Mac architecture and privacy boundary.

What It Catches

  • wrong file extension for an XLIFF upload
  • malformed XML
  • invalid XML entities
  • non-XLIFF XML wrappers
  • unsupported XLIFF versions
  • namespace/version drift between original and translated files
  • missing, removed, changed, or mismatched trans-unit ids
  • missing translated target elements
  • source/target inline tag count drift
  • protected inline tag rewrites
  • UTF-8 BOM and XML encoding declaration issues
  • empty default namespace attributes introduced inside translated source/target content

Safe Repairs

The current repair engine is conservative. It can safely:

  • remove a UTF-8 BOM
  • normalize the XML declaration to UTF-8
  • restore missing or changed translated trans-unit ids when the original and translated unit order still matches
  • remove empty xmlns="" attributes only inside translated source or target subtrees

It blocks repairs when the file needs human review or when an automated edit could corrupt translated content.

Library Usage

import { analyze, repair } from "articulate-xliff-import-doctor";

const files = [
  {
    name: "original.xlf",
    async text() {
      return originalXlfText;
    }
  },
  {
    name: "translated.xlf",
    async text() {
      return translatedXlfText;
    }
  }
];

const preview = await analyze(files);
const repaired = await repair(files);

The file objects only need a name and either text() or arrayBuffer(). This makes the core usable in Node, browsers, workers, or local desktop wrappers.

Privacy Model

The core runs locally and does not upload file content anywhere. The hosted Untwine page keeps the same browser-local boundary. The sandboxed Mac shell uses WebKit's required network-client capability, but the shipped interface contains no remote URL, request, analytics, or upload code; the package verifier enforces that boundary.

Hosted tool: Untwine - Articulate XLIFF Import Repair

Limits

  • XLIFF 1.2 only.
  • Built for Articulate-style original/translated file pairs.
  • Not a CAT tool, TMS, translator, or generic XLIFF validator.
  • Manual review is still required when target text, inline tags, segmentation, or course structure were materially changed.
  • Storyline XLIFF 2.0 is detected and rejected with an explicit unsupported result.

Test Corpus

The repository includes a 22-case public proof corpus under test/articulate-xliff-corpus/ with clean, repairable, manual-review, unrepairable, and unsupported cases.

Run:

npm test

Release Readiness

The engine, universal Mac package, bundled demo, native save flow, and repaired-file roundtrip have automated or local-device proof. Untwine should not be sold as Articulate-compatible yet: the remaining product gate is one real or trial-generated Rise/Storyline export, repair, and successful re-import into the exact source course.

Commercial terms are also intentionally unset while the repository remains AGPL-3.0-only. See the existing license decision memo.

Research And Visibility Notes

The current product-validation packet lives under docs/:

  • docs/research/articulate-xliff-operator-zero-brief-2026-06-12.md maps the buyer workflow, website-vs-mobile decision, proof corpus coverage, and trial-account blocker.
  • docs/research/articulate-xliff-error-phrase-corpus-2026-06-12.csv maps public Articulate error phrases to current tool verdicts and detector backlog.
  • docs/marketing/articulate-xliff-import-doctor/ contains the visibility brief, error-page backlog, mention targets, tutorial briefs, outreach drafts, and measurement plan.

Follow the work

Project notes and new tools: Telegram · LinkedIn · KikuAI

License

AGPL-3.0-only. See LICENSE.

KikuAI website Telegram @kiku_ai GitHub @kiku-jw

Follow new projects and updates from @kiku-jw.

About

Local-first Articulate Rise and Storyline XLIFF import-error diagnosis and safe repair.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages