ماجرا: یک هزینهٔ لغو اضافه
ماجرایی که این هفتهها در انجمنها و شبکههای اجتماعی دستبهدست میشود این است که ArtCraft از دل خشم زاده شد: سازندهاش «سرش کلاه رفته بود». پشت این پروژه براندون توماس (Brandon Thomas) است، مهندس نرمافزاری از آتلانتا (آمریکا) با پانزده سال سابقه، که در Reddit با نام u/ai_art_is_art مینوشت. واژهٔ «کلاهبرداری» از مردم است؛ خودش میگوید Adobe از او هزینهٔ لغو اشتراک گرفته است.
در Reddit نوشت: «چند بار از من «هزینهٔ لغو» گرفتند و از آن موقع از آنها متنفرم». در Hacker News گفت بارها در دام این «الگوی تاریک» افتاده است: جریمهای که برای ترک زودهنگام یک طرح سالانهٔ ماهانهپرداخت گرفته میشود. این شکایتی تک نیست: در ژوئن ۲۰۲۴ وزارت دادگستری آمریکا از Adobe به خاطر پنهان کردن این هزینهها و دشوار کردن لغو شکایت کرد. Adobe میگوید شرایطش شفاف است.
پاسخ او این بود که برنامهها را دوباره بسازد و رایگان بدهد. با کمک Claude، هوش مصنوعی Anthropic، و زبان Rust، بین اواخر سپتامبر و اوایل اکتبر ۲۰۲۶ هفت برنامهٔ نخست را در GitHub منتشر کرد —همارز Photoshop، Illustrator، Premiere، Lightroom، After Effects، InDesign و Acrobat— و در چند هفته Word، PowerPoint، Excel، AutoCAD، Pro Tools و Figma را هم افزود. او میگوید اینها پیادهسازیهای «اتاق تمیز» هستند، بر پایهٔ مشخصات عمومی قالبهای فایل و بدون کد دیگران.
جملهای که همهچیز را با آن خلاصه کرد، «دوران نرمافزار تمام شد»، دنیا را گشت: اگر یک نفر با هوش مصنوعی بتواند در چند هفته چیزی را بسازد که دههها طول کشیده، نرمافزار پولی به دردسر میافتد. تردیدهایی هم هست: پروفسور آندرس گوادموس از دانشگاه ساسکس یادآوری میکند که هنوز معلوم نیست این فرایند «اتاق تمیز» از بررسی سربلند بیرون بیاید، و چه مقدار از کد را او نوشته و چه مقدار را هوش مصنوعی. توماس اصرار دارد که این «شعلهای زودگذر نیست که خاموش شود»، و فعلاً سرعت تقریباً روزانهٔ نسخهها حق را به او میدهد.
ArtCraft پروژهای متنباز (مجوز MIT یا Apache-2.0) از تیم storytold است که ابزارهای روزمرهٔ خلق کردن را از صفر و با Rust بازنویسی میکند. برنامههایی بومی و سبک، بیاشتراک، که شیوهٔ کار مشهورترین برنامههای تجاری را تقلید میکنند بیآنکه کدشان را کپی کنند. روی Windows، macOS، Linux و FreeBSD اجرا میشوند، بسیاریشان در مرورگر هم، و تقریباً هر هفته نسخهٔ تازه منتشر میشود. نامهای تجاری فقط برای راهنمایی آمدهاند: این برنامهها هیچ ربطی به آن نشانها ندارند.
ابزارها، یکییکی
ArtCraft Launcher v0.8.1
از اینجا شروع کنید. نصبکنندهٔ همهٔ بقیه است: کل فهرست را نشان میدهد، هر برنامه را با یک کلیک و با نسخهٔ مناسب رایانهٔ شما نصب میکند، سالم بودن فایل را بررسی میکند و از بهروزرسانیها خبر میدهد. بستهٔ واحدی با همهچیز وجود ندارد، اما این لانچر نزدیکترین گزینه است.
PhotoCraft v0.16.0
ویرایشگر تصویر به سبک Photoshop: لایهها، انتخابها، قلمموها، تنظیمات و روتوش. محبوبترین ابزار پروژه در GitHub است.
LightCraft v0.14.0
کتابخانهٔ عکس و ظهور غیرمخرب RAW به سبک Lightroom: عکسهایتان را مرتب میکنید و نوردهی، رنگ و برش را بدون دست زدن به فایل اصلی تنظیم میکنید.
VectorCraft v0.17.0
تصویرسازی برداری مثل Illustrator: منحنیها، شکلها، خطها و متنی که بدون افت کیفیت بزرگ میشوند. برای لوگو، آیکون و پوستر.
FilmCraft v0.13.0
ویرایشگر ویدیوی غیرخطی، شبیه Premiere Pro: خط زمان چندشیاره، برش، اصلاح رنگ و صدا.
EffectCraft v0.17.0
موشنگرافیک، ترکیببندی و جلوههای بصری در مسیر After Effects: عنوانها، انیمیشن با فریم کلیدی و لایههایی که با هم ترکیب میشوند.
SoundCraft v0.13.1
ایستگاه صوتی برای ضبط، ویرایش و میکس، با الهام از Pro Tools: چند شیار، برش، افکت و میکس نهایی.
DesignCraft v0.13.0
صفحهآرایی و نشر به سبک InDesign: مجله، بروشور و کتاب با صفحهها، ستونها، سبکهای متن و تصویر.
FigCraft v0.11.2
طراحی رابط کاربری و نمونهٔ اولیه، مثل Figma: صفحههای اپ و وب، اجزای قابل استفادهٔ دوباره و ماکتهایی که پیش از ساخت نشان میدهند چیزی چگونه کار خواهد کرد.
PdfCraft v0.14.0
برای خواندن، مرتب کردن و محافظت از PDF، در مسیر Acrobat: باز کردن، یادداشتگذاری، جابهجایی صفحهها و ذخیرهٔ سندهای محافظتشده.
WordCraft v0.11.0
واژهپردازی شبیه Word، برای نامه، گزارش و سند با سبکها، جدولها و تصویرها.
DeckCraft v0.11.1
ارائه و اسلاید به سبک PowerPoint: اسلایدهایی با متن، تصویر و شکل برای نمایش تمامصفحه.
GridCraft v0.12.1
صفحهگسترده مثل Excel: فرمولها، جدولهای داده، نمودارها و مرتبسازی یا پالایش اطلاعات.
CADCraft v0.13.0
طراحی به کمک رایانه و نقشهکشی فنی در مسیر AutoCAD: نقشههایی با اندازههای دقیق، لایهها و اندازهگذاری.
ArtCraft v0.41.0
برنامهای که نامش را به پروژه داده و تنها برنامهای که جدا از بقیه است: استودیویی برای ساخت تصویر و ویدیو با هوش مصنوعی، برای هنرمندان، طراحان و فیلمسازان. فعلاً فقط برای Windows و Mac.
همه را نگه دارید: کد منبع و فایلهای اجرایی
اگر دوست دارید از همهچیز نسخهای داشته باشید (اگر روزی پروژهای ناپدید شد، یا برای نصب بدون اینترنت)، این اسکریپت Linux کد منبع هر ابزار و همهٔ فایلهای اجرایی آخرین نسخه را دانلود میکند و در پوشههایی بر اساس ابزار و سیستم (Windows، macOS، Linux، FreeBSD و وب) مرتب میکند. آن را از حالت فشرده خارج و اجرا کنید؛ آرگومان پوشهٔ مقصد است و با PLATFORMS و EXCLUDE انتخاب میکنید چه چیزی دانلود شود. (توضیحات داخل آن به اسپانیایی است.)
⬇ دانلود اسکریپت (artcraft-mirror.zip)
chmod +x artcraft-mirror.sh
./artcraft-mirror.sh ~/artcraft
PLATFORMS="windows linux" EXCLUDE='riscv64|aarch64' ./artcraft-mirror.sh ~/artcraft
- میشود قطعش کرد: اگر متوقف شد، دوباره اجرایش کنید تا از همانجا ادامه دهد.
- فقط تازهها را میگیرد: وقتی نسخهای منتشر میشود پوشهاش را میسازد و به قبلیها دست نمیزند.
- همهچیز را بررسی میکند با جمعهای SHA-256 که هر نسخه منتشر میکند.
- جای زیادی میگیرد: همهٔ سکوها روی هم حدود ۲۴ گیگابایت برای هر نسخه است؛ اگر فقط برخی را لازم دارید، پالایش کنید.
نمایش کامل اسکریپت
#!/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"
اینها برنامههایی بسیار نوپا هستند و تقریباً همه با برچسب آلفای اولیه: نوید زیادی میدهند، اما هنوز جای ابزارهای حرفهای را برای کار جدی نمیگیرند. امتحانشان کنید، از فایلهایتان نسخهٔ پشتیبان بگیرید و اگر خطایی دیدید در GitHub آنها گزارش دهید.
منابع
- GitHub · storytold (todas las Crafting Apps)
- GitHub · ArtCraft Launcher
- GitHub · ArtCraft
- getartcraft.com
- Al Jazeera (14-10-2026) · How AI apps are offering free substitutes for Big Tech software
- Amateur Photographer (08-10-2026) · This home coder got so sick of Adobe he built free, open-source versions of Photoshop, Lightroom and Premiere
- PetaPixel (07-10-2026) · Someone Rebuilt Free, Open-Source Versions of Photoshop, Premiere, and Lightroom Using AI
- Creative Bloq · Someone just rebuilt Adobe Creative Cloud with AI – then gave it away for free
- CineD · ArtCraft Releases Free Open-Source Adobe Alternatives
- Korben · I tested the 12 free clones of Adobe and Microsoft