tsoft-cli 3.9.4 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to T-Soft CLI will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.10.0] - 2026-07-30
9
+
10
+ ### Added
11
+ - `tsoft theme create` now accepts the theme name as an argument: `tsoft theme create my-theme`. The name was previously only ever asked for interactively, so a name passed on the command line was silently discarded and the prompt appeared anyway. Every other theme command already took an optional name, and `create` was the exception. Running `tsoft theme create` with no argument still prompts exactly as before.
12
+
13
+ ### Fixed
14
+ - `tsoft theme init` is now also available as `tsoft theme fork`. The command has always forked an existing theme into a copy of your own, but the name `init` read like "start a blank project", so developers looked for a fork command and concluded forking was unavailable. Both names run the same command and `theme init` keeps working unchanged.
15
+ - The help screen lists the command as `theme fork`, and the JSON-mode usage hint points to `tsoft --json theme fork --from <slug>`.
16
+
17
+ ## [3.9.5] - 2026-07-20
18
+
19
+ ### Fixed
20
+ - `theme dev` no longer shows a red error when a theme has no marketplace organization. The server's raw guard message ("no marketplace organization...") looked like a crash, and some users opened support tickets over it. Organization guard responses (unconfigured, ownership mismatch, no active organization) now render as a clear info box with a next step, such as running `tsoft theme fork` to work on your own copy.
21
+ - The info box top border no longer breaks at the right corner. The `ℹ️` emoji in the "Bilgi"/"Info" title threw off boxen's width calculation, so the title emoji was dropped.
22
+
8
23
  ## [3.9.4] - 2026-06-25
9
24
 
10
25
  ### Fixed
package/locales/en.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "ui.label.warning": "⚠️ Warning",
6
6
  "ui.label.error": "❌ Error",
7
7
  "ui.label.success": "✅ Success",
8
- "ui.label.info": "ℹ️ Info",
8
+ "ui.label.info": "Info",
9
9
  "ui.label.theme_selection": "🎨 Theme Selection",
10
10
  "ui.label.loading": "⏳ Processing",
11
11
  "ui.prompt.continue": "Do you want to continue?",
@@ -26,6 +26,9 @@
26
26
  "error.http.401.hint": "Login again: tsoft login --org",
27
27
  "error.http.403.message": "You do not have permission for this operation.",
28
28
  "error.http.403.hint": "Check your organization permissions: tsoft org switch",
29
+ "error.org.ownership_mismatch": "This theme belongs to another organization.\n\nOptions:\n tsoft theme fork - Copy the theme into your own organization\n tsoft org switch - Switch to the organization that owns this theme",
30
+ "error.org.no_context": "No active organization selected.\n\nFix:\n tsoft org switch - Select the organization you want to work in",
31
+ "error.org.unconfigured": "This theme is not linked to an organization, so it cannot be developed directly.\n\nFix:\n tsoft theme fork - Create your own copy of the theme and develop on it\n\nIf the problem persists, contact support.",
29
32
  "error.http.404.message": "Theme not found.",
30
33
  "error.http.404.hint": "Check the theme name: tsoft theme list",
31
34
  "error.http.409.message": "Cannot push: theme is not in a valid state.",
@@ -211,7 +214,7 @@
211
214
  "init.location_label": "Location:",
212
215
  "init.dev_tip": "To start development: tsoft theme dev {{slug}}",
213
216
  "init.json_error.message": "--from parameter required (interactive selection not supported in JSON mode)",
214
- "init.json_error.hint": "Usage: tsoft --json theme init --from <slug>",
217
+ "init.json_error.hint": "Usage: tsoft --json theme fork --from <slug>",
215
218
  "init.theme_not_found": "Theme not found: {{slug}}",
216
219
  "section.list.no_active_theme": "No active theme found. Please run \"tsoft theme use <theme-name>\" first.",
217
220
  "section.list.starting": "Listing sections...",
@@ -313,7 +316,7 @@
313
316
  "help.cmd.theme_create": "Create a new theme",
314
317
  "help.cmd.theme_pull": "Download an existing theme",
315
318
  "help.cmd.theme_use": "Set the active theme",
316
- "help.cmd.theme_init": "Initialize a new theme by forking an existing one",
319
+ "help.cmd.theme_init": "Fork an existing theme into a new theme of your own (alias: theme init)",
317
320
  "help.cmd.login": "Authenticate with your tsoft360 store",
318
321
  "help.cmd.logout": "Sign out and clear local credentials",
319
322
  "help.cmd.whoami": "Show the logged-in user and store info",
package/locales/tr.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "ui.label.warning": "⚠️ Uyarı",
6
6
  "ui.label.error": "❌ Hata",
7
7
  "ui.label.success": "✅ Başarılı",
8
- "ui.label.info": "ℹ️ Bilgi",
8
+ "ui.label.info": "Bilgi",
9
9
  "ui.label.theme_selection": "🎨 Tema Seçimi",
10
10
  "ui.label.loading": "⏳ İşlem Devam Ediyor",
11
11
  "ui.prompt.continue": "Devam etmek istiyor musunuz?",
@@ -26,6 +26,9 @@
26
26
  "error.http.401.hint": "Tekrar giriş yapın: tsoft login --org",
27
27
  "error.http.403.message": "Bu işlem için yetkiniz yok.",
28
28
  "error.http.403.hint": "Organizasyon yetkinizi kontrol edin: tsoft org switch",
29
+ "error.org.ownership_mismatch": "Bu tema başka bir organizasyona ait.\n\nSeçenekler:\n tsoft theme fork - Temayı kendi organizasyonunuza kopyalayın\n tsoft org switch - Temanın ait olduğu organizasyona geçin",
30
+ "error.org.no_context": "Aktif organizasyon seçili değil.\n\nÇözüm:\n tsoft org switch - Çalışacağınız organizasyonu seçin",
31
+ "error.org.unconfigured": "Bu tema bir organizasyona bağlı olmadığı için doğrudan üzerinde çalışılamıyor.\n\nÇözüm:\n tsoft theme fork - Temanın kendi kopyanızı oluşturun ve onun üzerinde geliştirin\n\nSorun sürerse destek ekibiyle iletişime geçin.",
29
32
  "error.http.404.message": "Tema bulunamadı.",
30
33
  "error.http.404.hint": "Tema adini kontrol edin: tsoft theme list",
31
34
  "error.http.409.message": "Push yapılamaz: tema uygun durumda değil.",
@@ -211,7 +214,7 @@
211
214
  "init.location_label": "Konum:",
212
215
  "init.dev_tip": "Geliştirmeye başlamak için: tsoft theme dev {{slug}}",
213
216
  "init.json_error.message": "--from parametresi gerekli (JSON modda interaktif seçim desteklenmez)",
214
- "init.json_error.hint": "Kullanim: tsoft --json theme init --from <slug>",
217
+ "init.json_error.hint": "Kullanim: tsoft --json theme fork --from <slug>",
215
218
  "init.theme_not_found": "Tema bulunamadı: {{slug}}",
216
219
  "section.list.no_active_theme": "Aktif tema bulunamadı. Lütfen önce \"tsoft theme use <tema-adı>\" komutunu çalıştırın.",
217
220
  "section.list.starting": "Section'lar listeleniyor...",
@@ -313,7 +316,7 @@
313
316
  "help.cmd.theme_create": "Yeni bir tema oluşturun",
314
317
  "help.cmd.theme_pull": "Mevcut bir temayı indirin",
315
318
  "help.cmd.theme_use": "Aktif temayı ayarlayın",
316
- "help.cmd.theme_init": "Mevcut bir temayi fork ederek yeni tema başlatın",
319
+ "help.cmd.theme_init": "Mevcut bir temayi fork ederek kendi temanizi olusturun (eski adi: theme init)",
317
320
  "help.cmd.login": "tsoft360 mağazanızla kimlik doğrulayın",
318
321
  "help.cmd.logout": "Oturumu kapatın ve yerel kimlik bilgilerini temizleyin",
319
322
  "help.cmd.whoami": "Giriş yapan kullanıcı ve mağaza bilgilerini gösterin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsoft-cli",
3
- "version": "3.9.4",
3
+ "version": "3.10.0",
4
4
  "description": "Command-line tool for tsoft360 theme development and management",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/api-client.js CHANGED
@@ -1,6 +1,13 @@
1
1
  import axios from 'axios';
2
2
  import { loadTokens, ensureValidToken, refreshAccessToken, saveTokens, isRefreshTokenValid } from './storage.js';
3
3
  import { verboseLog } from './output-mode.js';
4
+ import { t } from './i18n.js';
5
+
6
+ const ORG_ERROR_MESSAGE_KEYS = {
7
+ 'ORG-OWNERSHIP-MISMATCH': 'error.org.ownership_mismatch',
8
+ 'ORG-NO-CONTEXT': 'error.org.no_context',
9
+ 'ORG-UNCONFIGURED': 'error.org.unconfigured',
10
+ };
4
11
 
5
12
  export class ApiClient {
6
13
  constructor(store) {
@@ -212,11 +219,17 @@ export class ApiClient {
212
219
  const status = error.response.status;
213
220
  const message = error.response.data?.message || error.message;
214
221
  const context = error.response.data?.context;
222
+ const errorCode = error.response.data?.error_code;
215
223
 
216
224
 
217
225
  if (status === 401) {
218
226
  throw new Error('Yetkilendirme hatası. Lütfen tekrar giriş yapın: tsoft login');
219
227
  } else if (status === 403) {
228
+ if (errorCode && ORG_ERROR_MESSAGE_KEYS[errorCode]) {
229
+ const guidanceError = new Error(t(ORG_ERROR_MESSAGE_KEYS[errorCode]));
230
+ guidanceError.isOrgGuidance = true;
231
+ throw guidanceError;
232
+ }
220
233
  throw new Error(message || 'Bu işlem için yetkiniz yok.');
221
234
  } else if (status === 404) {
222
235
  throw new Error('İstenen kaynak bulunamadı.');
@@ -543,6 +543,10 @@ export async function themeDevCommand(themeName) {
543
543
  setupGracefulShutdown(watcher, keepAliveInterval);
544
544
 
545
545
  } catch (error) {
546
+ if (error.isOrgGuidance) {
547
+ showInfo(error.message);
548
+ process.exit(1);
549
+ }
546
550
  console.error(chalk.red('\n❌ Hata: ') + error.message);
547
551
  process.exit(1);
548
552
  }
@@ -71,7 +71,7 @@ export async function themeListCommand() {
71
71
  }
72
72
  }
73
73
 
74
- export async function themeCreateCommand() {
74
+ export async function themeCreateCommand(themeName) {
75
75
  try {
76
76
  const store = await getActiveStore();
77
77
  if (!store) {
@@ -81,7 +81,9 @@ export async function themeCreateCommand() {
81
81
 
82
82
  console.log(chalk.cyan(t('theme.creating') + '\n'));
83
83
 
84
- const name = await input({
84
+ const providedName = typeof themeName === 'string' ? themeName.trim() : '';
85
+
86
+ const name = providedName || await input({
85
87
  message: t('theme.name_prompt'), validate: (value) => {
86
88
  if (!value.trim()) {
87
89
  return t('theme.name_required');
package/src/index.js CHANGED
@@ -93,10 +93,10 @@ theme
93
93
  });
94
94
 
95
95
  theme
96
- .command('create')
96
+ .command('create [theme-name]')
97
97
  .description('Create a new theme')
98
- .action(async () => {
99
- await themeCreateCommand();
98
+ .action(async (themeName) => {
99
+ await themeCreateCommand(themeName);
100
100
  });
101
101
 
102
102
  theme
@@ -146,7 +146,8 @@ submitCmd._hidden = true;
146
146
 
147
147
  theme
148
148
  .command('init')
149
- .description('Initialize a new theme by forking an existing one')
149
+ .alias('fork')
150
+ .description('Fork an existing theme into a new theme of your own')
150
151
  .option('--from [slug]', 'Slug or name of the theme to fork')
151
152
  .action(async (options) => {
152
153
  await themeInitCommand(options.from);
@@ -52,7 +52,7 @@ const COMMAND_GROUPS = [
52
52
  { display: 'theme create', descKey: 'help.cmd.theme_create' },
53
53
  { display: 'theme pull', descKey: 'help.cmd.theme_pull' },
54
54
  { display: 'theme use', descKey: 'help.cmd.theme_use' },
55
- { display: 'theme init', descKey: 'help.cmd.theme_init' },
55
+ { display: 'theme fork', descKey: 'help.cmd.theme_init' },
56
56
  ]
57
57
  },
58
58
  {