ArtCraft: programu 14 huru za ubunifu, kama Photoshop, Premiere, Word au AutoCAD

🌐 Español · English · Português · Français · Italiano · Deutsch · Nederlands · Polski · Русский · Українська · Türkçe · Ελληνικά · العربية · فارسی · עברית · हिन्दी · বাংলা · தமிழ் · Bahasa Indonesia · Tiếng Việt · ไทย · 中文 · 日本語 · 한국어 · Kiswahili

Kisa: ada moja ya kusitisha iliyozidi

Kisa kinachozunguka wiki hizi kwenye majukwaa na mitandao ya kijamii ni kwamba ArtCraft ilizaliwa kutokana na hasira: mwandishi wake «alitapeliwa». Nyuma ya mradi yupo Brandon Thomas, mhandisi wa programu kutoka Atlanta (Marekani) mwenye uzoefu wa miaka kumi na tano, aliyekuwa akiandika Reddit kwa jina u/ai_art_is_art. Neno «utapeli» ni la watu; yeye mwenyewe anasema Adobe ilimtoza ada ya kusitisha usajili wake.

Aliandika Reddit: «Walinitoza ‘ada ya kusitisha’ mara kadhaa na tangu hapo nawachukia». Kwenye Hacker News alisema alinaswa mara nyingi mno na «mtindo huo wa giza»: faini inayotozwa unapoacha mapema mpango wa mwaka unaolipwa kila mwezi. Si lalamiko la mtu mmoja tu: mwezi Juni 2024 Wizara ya Sheria ya Marekani iliishtaki Adobe kwa kuficha ada hizo na kufanya kusitisha kuwe kugumu. Adobe inasisitiza kwamba masharti yake ni wazi.

Jibu lake lilikuwa kuunda upya programu hizo na kuzitoa bure. Kwa msaada wa Claude, akili bandia ya Anthropic, na lugha ya Rust, kati ya mwishoni mwa Septemba na mwanzoni mwa Oktoba 2026 alichapisha GitHub programu saba za kwanza — sawa na Photoshop, Illustrator, Premiere, Lightroom, After Effects, InDesign na Acrobat — na ndani ya wiki chache akaongeza zinazolingana na Word, PowerPoint, Excel, AutoCAD, Pro Tools na Figma. Anasema ni utekelezaji upya wa «chumba safi», uliotengenezwa kutokana na maelezo ya wazi ya miundo ya faili, bila msimbo wa mtu yeyote.

Kauli yake iliyojumlisha yote, «zama za programu zimekwisha», ilienea duniani kote: ikiwa mtu mmoja akiwa na AI anaweza kuunda upya kwa wiki chache kile kilichochukua miongo, programu za kulipia zitapata shida. Kuna wenye shaka: Profesa Andrés Guadamuz wa Chuo Kikuu cha Sussex anakumbusha kwamba bado haijulikani kama mchakato huo wa «chumba safi» utastahimili uchunguzi, wala ni kiasi gani cha msimbo aliandika yeye na kiasi gani AI. Thomas anasisitiza kuwa si «mwako wa mara moja utakaozimika», na kwa sasa kasi ya matoleo karibu kila siku inamthibitisha.

ArtCraft ni mradi wa chanzo huria (leseni MIT au Apache-2.0) wa timu ya storytold unaoandika upya kuanzia mwanzo, kwa Rust, zana tunazotumia kila siku kubuni. Ni programu asilia, nyepesi, bila usajili wa kulipia, zinazoiga jinsi programu za kibiashara maarufu zaidi zinavyofanya kazi bila kunakili msimbo wake. Zinafanya kazi kwenye Windows, macOS, Linux na FreeBSD, nyingi pia kwenye kivinjari, na matoleo mapya hutoka karibu kila wiki. Majina ya kibiashara yametajwa kama mwongozo tu: programu hizi hazihusiani na chapa hizo.

Zana, moja baada ya nyingine

ArtCraft Launcher v0.8.1

Anza hapa. Ndicho kisakinishi cha nyingine zote: kinaonyesha orodha kamili, kinasakinisha kila programu kwa kubofya mara moja kikichagua toleo sahihi kwa kompyuta yako, kinakagua kwamba faili haijaharibika na kinakujulisha masasisho yanapotoka. Hakuna kifurushi kimoja chenye kila kitu, lakini kizindua hiki ndicho kilicho karibu zaidi.

PhotoCraft v0.16.0

Kihariri cha picha kwa mtindo wa Photoshop: tabaka, uteuzi, brashi, marekebisho na urekebishaji. Ndiyo zana maarufu zaidi ya mradi kwenye GitHub.

LightCraft v0.14.0

Maktaba ya picha na uchakataji wa RAW usioharibu, kwa mtindo wa Lightroom: unapanga picha zako na kurekebisha mwanga, rangi na ukataji bila kugusa faili asili kamwe.

VectorCraft v0.17.0

Michoro ya vekta kama katika Illustrator: mikunjo, maumbo, mistari na maandishi yanayokuzwa bila kupoteza ubora. Kwa nembo, aikoni na mabango.

FilmCraft v0.13.0

Kihariri cha video kisicho cha mstari, kinachofanana na Premiere Pro: ratiba ya nyimbo nyingi, ukataji, urekebishaji wa rangi na sauti.

EffectCraft v0.17.0

Michoro inayosonga, uunganishaji na athari za kuona kwa mtindo wa After Effects: vichwa, uhuishaji kwa fremu muhimu na tabaka zinazochanganyika.

SoundCraft v0.13.1

Kituo cha sauti cha kurekodi, kuhariri na kuchanganya, kilichochochewa na Pro Tools: nyimbo nyingi, ukataji, athari na mchanganyiko wa mwisho.

DesignCraft v0.13.0

Upangaji wa kurasa na uchapishaji kwa mtindo wa InDesign: majarida, vipeperushi na vitabu vyenye kurasa, safu, mitindo ya maandishi na picha.

FigCraft v0.11.2

Usanifu wa violesura na mifano, kama Figma: skrini za programu na tovuti, vipengele vinavyotumika tena na michoro inayoonyesha jinsi kitu kitakavyofanya kazi kabla hakijajengwa.

PdfCraft v0.14.0

Kwa kusoma, kupanga na kulinda PDF, kwa mtindo wa Acrobat: kufungua, kuweka maelezo, kupanga upya kurasa na kuhifadhi nyaraka zilizolindwa.

WordCraft v0.11.0

Kichakataji maneno kinachofanana na Word, kwa barua, ripoti na nyaraka zenye mitindo, majedwali na picha.

DeckCraft v0.11.1

Mawasilisho na slaidi kwa mtindo wa PowerPoint: slaidi zenye maandishi, picha na maumbo za kuonyesha kwa skrini nzima.

GridCraft v0.12.1

Lahajedwali kama Excel: fomula, majedwali ya data, chati, na kupanga au kuchuja taarifa.

CADCraft v0.13.0

Usanifu kwa msaada wa kompyuta na uchoraji wa kiufundi kwa mtindo wa AutoCAD: michoro yenye vipimo kamili, tabaka na vipimo.

ArtCraft v0.41.0

Programu iliyoupa mradi jina lake, na ndiyo pekee iliyo tofauti na nyingine: studio ya kuunda picha na video kwa akili bandia, kwa wasanii, wabunifu na watengenezaji filamu. Kwa sasa ni kwa Windows na Mac tu.

Zihifadhi zote: msimbo chanzo na faili za kuendesha

Ukipenda kuwa na nakala ya kila kitu (endapo mradi utatoweka siku moja, au kusakinisha bila intaneti), skripti hii ya Linux inapakua msimbo chanzo wa kila zana na faili zote za kuendesha za toleo la karibuni, zikiwa zimepangwa kwenye folda kwa zana na kwa mfumo (Windows, macOS, Linux, FreeBSD na wavuti). Ifungue na uiendeshe; hoja ni folda ya kuhifadhi, na kwa PLATFORMS na EXCLUDE unachagua cha kupakua. (Maoni yaliyomo ndani yake ni kwa Kihispania.)

⬇ Pakua skripti (artcraft-mirror.zip)

chmod +x artcraft-mirror.sh
./artcraft-mirror.sh ~/artcraft

PLATFORMS="windows linux" EXCLUDE='riscv64|aarch64' ./artcraft-mirror.sh ~/artcraft
  • Inaweza kukatizwa: ikisimama, iendeshe tena na itaendelea pale ilipoachia.
  • Inapakua kipya tu: toleo jipya likitoka, inaunda folda yake bila kugusa za zamani.
  • Inakagua kila kitu kwa jumla za SHA-256 ambazo kila toleo huchapisha.
  • Inachukua nafasi kubwa: majukwaa yote kwa pamoja ni karibu GB 24 kwa kila toleo; ukihitaji baadhi tu, chuja.
Onyesha skripti nzima
#!/usr/bin/env bash
# artcraft-mirror.sh — espejo local de las Craft Apps de ArtCraft (github.com/storytold)
#
# Estructura que genera:
#   <DEST>/<herramienta>/code/<rama>-<herramienta>-AAAAMMDD.zip   (+ .sha con el commit)
#   <DEST>/<herramienta>/release-<versión>/{windows,macos,linux,freebsd,web,otros}/...
#   <DEST>/<herramienta>/release-<versión>/SHA256SUMS.txt
#
# - Reanudable: las descargas van a *.part y continúan con Range (curl -C -).
#   Una release se da por terminada sólo cuando todo se verificó contra SHA256SUMS
#   (queda el marcador .complete). Si se corta, se vuelve a ejecutar y sigue.
# - Incremental: sólo mira la última release de cada herramienta; las carpetas
#   release-* anteriores y los zip de código de días anteriores no se tocan.
# - El código fuente se baja sólo si el commit de la rama principal cambió.
#
# Uso:
#   ./artcraft-mirror.sh [DEST]           (DEST por defecto: carpeta del script)
# Variables opcionales:
#   GITHUB_TOKEN=ghp_...                  sube el límite de la API de 60 a 5000 llamadas/h
#   PLATFORMS="windows linux macos"       sólo estas plataformas (por defecto todas)
#   EXCLUDE='riscv64|aarch64|flatpak'     regex de nombres de archivo a omitir
#   TOOLS="photocraft cadcraft"           sólo estas herramientas
#   EXTRA_TOOLS="anicraft"                añadir repos de storytold no incluidos en el catálogo
#   SKIP_CODE=1 / SKIP_RELEASES=1

set -uo pipefail

OWNER=storytold
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
DEST=${1:-$SCRIPT_DIR}
PLATFORMS=${PLATFORMS:-"windows macos linux freebsd web otros"}
EXCLUDE=${EXCLUDE:-}
TODAY=$(date +%Y%m%d)

# Catálogo de respaldo por si no se puede leer el del launcher
FALLBACK_TOOLS="photocraft vectorcraft filmcraft lightcraft pdfcraft effectcraft designcraft
figcraft wordcraft soundcraft deckcraft cadcraft gridcraft"
# Fuera del catálogo del launcher pero con releases propias
ALWAYS_TOOLS="craft-launcher artcraft"

for bin in curl jq git sha256sum flock; do
    command -v "$bin" >/dev/null || { echo "Falta '$bin'" >&2; exit 1; }
done

mkdir -p "$DEST"
exec 9>"$DEST/.artcraft-mirror.lock"
flock -n 9 || { echo "Ya hay otra ejecución en curso en $DEST" >&2; exit 1; }

log()  { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"; }
warn() { printf '[%s] AVISO: %s\n' "$(date +%H:%M:%S)" "$*" >&2; }

api() {
    local auth=()
    [[ -n ${GITHUB_TOKEN:-} ]] && auth=(-H "Authorization: Bearer $GITHUB_TOKEN")
    curl -fsSL --retry 3 -H "Accept: application/vnd.github+json" "${auth[@]}" \
        "https://api.github.com/$1"
}

# Descarga: $1 url, $2 destino final, $3 tamaño esperado.
# Con tamaño conocido continúa el .part (Range); sin él (zip de código, generado
# al vuelo y sin Range) empieza de cero.
fetch() {
    local url=$1 out=$2 size=${3:-} part="$2.part" have resume=()
    mkdir -p "$(dirname "$out")"
    if [[ -n $size && -f $part ]]; then
        have=$(stat -c %s "$part")
        if (( have == size )); then mv -f "$part" "$out"; return 0; fi
        if (( have > size )); then rm -f "$part"; fi
        resume=(-C -)
    else
        rm -f "$part"
    fi
    curl -fL --retry 5 --retry-delay 5 --retry-all-errors "${resume[@]}" \
        --progress-bar -o "$part" "$url" || return 1
    mv -f "$part" "$out"
}

platform_of() {
    case $1 in
        SHA256SUMS*)                              echo . ;;
        *windows*|*.msi|*.exe)                    echo windows ;;
        *macos*|*.dmg|*.app.tar.gz|*universal*)   echo macos ;;
        *freebsd*)                                echo freebsd ;;
        *linux*|*.AppImage*|*.deb|*.rpm|*.flatpak) echo linux ;;
        *-web-*)                                  echo web ;;
        *)                                        echo otros ;;
    esac
}

wanted() {
    local name=$1 plat=$2
    [[ $plat == . ]] && return 0
    [[ " $PLATFORMS " == *" $plat "* ]] || return 1
    [[ -n $EXCLUDE && $name =~ $EXCLUDE ]] && return 1
    return 0
}

tool_list() {
    if [[ -n ${TOOLS:-} ]]; then echo $TOOLS; return; fi
    local cat
    cat=$(curl -fsSL "https://raw.githubusercontent.com/$OWNER/craft-launcher/main/crates/core/src/catalog.rs" 2>/dev/null \
          | grep -oE "\"$OWNER/[a-z0-9-]+\"" | tr -d '"' | cut -d/ -f2 | grep -v '^craft-launcher$' | sort -u)
    [[ -z $cat ]] && { warn "no pude leer el catálogo del launcher; uso la lista interna"; cat=$FALLBACK_TOOLS; }
    echo $cat $ALWAYS_TOOLS ${EXTRA_TOOLS:-} | tr ' ' '\n' | awk 'NF && !seen[$0]++'
}

mirror_code() {
    local tool=$1 dir="$DEST/$1/code" head branch sha last
    head=$(git ls-remote --symref "https://github.com/$OWNER/$tool" HEAD 2>/dev/null) \
        || { warn "$tool: no pude consultar el repositorio"; return 1; }
    branch=$(awk '/^ref:/ {sub("refs/heads/","",$2); print $2}' <<<"$head")
    sha=$(awk '$2=="HEAD" && $1!="ref:" {print $1}' <<<"$head")
    mkdir -p "$dir"

    last=$(ls -1 "$dir"/*.zip.sha 2>/dev/null | sort | tail -1)
    if [[ -n $last && $(<"$last") == "$sha" ]]; then
        log "$tool: código al día ($branch@${sha:0:8})"
        return 0
    fi
    local zip="$dir/$branch-$tool-$TODAY.zip"
    log "$tool: bajando código $branch@${sha:0:8} → $(basename "$zip")"
    # El zip por commit garantiza que el archivo corresponde al sha anotado
    fetch "https://github.com/$OWNER/$tool/archive/$sha.zip" "$zip" || { warn "$tool: falló el zip"; return 1; }
    echo "$sha" > "$zip.sha"
}

verify() { # $1 archivo, $2 SHA256SUMS → 0 ok / 1 mal / 2 sin suma publicada
    local file=$1 sums=$2 expected
    [[ -f $sums ]] || return 2
    expected=$(awk -v n="$(basename "$file")" '{f=$2; sub(/^\*/,"",f)} f==n {print $1}' "$sums")
    [[ -z $expected ]] && return 2
    [[ $(sha256sum "$file" | cut -d' ' -f1) == "$expected" ]]
}

mirror_release() {
    local tool=$1 json tag ver rdir
    json=$(api "repos/$OWNER/$tool/releases/latest") || { warn "$tool: sin releases o límite de API alcanzado"; return 1; }
    tag=$(jq -r .tag_name <<<"$json")
    ver=${tag#"$tool"-}; ver=${ver#v}
    rdir="$DEST/$tool/release-$ver"

    if [[ -f $rdir/.complete && $(<"$rdir/.complete") == "$PLATFORMS|$EXCLUDE" ]]; then
        log "$tool: release $ver ya completa"
        return 0
    fi
    log "$tool: release $ver"
    mkdir -p "$rdir"
    jq -c '{tag_name, name, published_at, html_url, body}' <<<"$json" > "$rdir/release.json"

    local ok=1 name url size plat out sums="$rdir/SHA256SUMS.txt"
    # SHA256SUMS primero para poder verificar el resto
    while IFS=$'\t' read -r name url size; do
        plat=$(platform_of "$name")
        wanted "$name" "$plat" || continue
        if [[ $plat == . ]]; then out="$rdir/$name"; else out="$rdir/$plat/$name"; fi

        if [[ -f $out ]]; then
            verify "$out" "$sums"; case $? in
                0) continue ;;
                2) [[ $(stat -c %s "$out") == "$size" ]] && continue ;;
            esac
            warn "$tool: $name no coincide, se vuelve a bajar"; rm -f "$out"
        fi
        log "  ↓ ${out#"$rdir"/} ($((size / 1048576)) MiB)"
        if ! fetch "$url" "$out" "$size"; then warn "  falló $name"; ok=0; continue; fi
        verify "$out" "$sums"; case $? in
            1) warn "  checksum INCORRECTO: $name (se borra)"; rm -f "$out"; ok=0 ;;
            2) [[ $name != SHA256SUMS* ]] && [[ $(stat -c %s "$out") != "$size" ]] && { warn "  tamaño incorrecto: $name"; rm -f "$out"; ok=0; } ;;
        esac
    done < <(jq -r '.assets | sort_by(.name | startswith("SHA256SUMS") | not)[]
                    | [.name, .browser_download_url, .size] | @tsv' <<<"$json")

    if (( ok )); then echo "$PLATFORMS|$EXCLUDE" > "$rdir/.complete"; log "$tool: release $ver completa ✔"
    else warn "$tool: release $ver incompleta; vuelve a ejecutar el script para continuar"; return 1; fi
}

fail=0
for tool in $(tool_list); do
    echo "──────── $tool"
    [[ -z ${SKIP_CODE:-} ]]     && { mirror_code "$tool"    || fail=1; }
    [[ -z ${SKIP_RELEASES:-} ]] && { mirror_release "$tool" || fail=1; }
done

(( fail )) && { warn "Hubo errores; ejecuta de nuevo para reintentar lo pendiente."; exit 1; }
log "Todo al día en $DEST"

Hizi ni programu changa sana, karibu zote zimewekwa alama ya alfa ya mapema: zinaahidi mengi, lakini bado haziwezi kuchukua nafasi ya zana za kitaalamu kwa kazi nzito. Zijaribu, weka nakala za faili zako na ukipata hitilafu iripoti kwenye GitHub yao.

Marejeo