tsoft-cli 3.13.2 → 3.14.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,16 @@ 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.14.0] - 2026-09-15
9
+
10
+ ### Added
11
+ - `theme dev` can open the panel's theme editor with `E`, and now prints both addresses as text. The status line only ever offered `P` for the preview and named no address at all, so reaching the editor meant leaving the terminal and finding the theme in the panel by hand, and the preview address could not be copied into another browser or pasted to a colleague. The editor address is asked of the store when the watcher starts; if the store does not answer or has no address for the theme, the `E` hint and the editor line are left out and `theme dev` carries on as before.
12
+
13
+ ## [3.13.3] - 2026-09-10
14
+
15
+ ### Fixed
16
+ - `theme dev` no longer crashes after you sign out. With no active store it read the store name as text anyway and died with "Cannot read properties of null (reading 'replace')", which says nothing about what went wrong or how to recover. It now reports that there is no active store, points at `tsoft login`, and exits non-zero like `theme list` and `theme init` already did in the same situation.
17
+
8
18
  ## [3.13.2] - 2026-09-10
9
19
 
10
20
  ### Fixed
package/locales/en.json CHANGED
@@ -330,8 +330,10 @@
330
330
  "submit.step3": "3. Submit from the partner panel",
331
331
  "dev.status_watching": "Watching",
332
332
  "dev.status_preview": "preview",
333
+ "dev.status_editor": "editor",
333
334
  "dev.status_exit": "exit",
334
335
  "dev.preview_open_failed": "Couldn't open browser: {{error}}",
336
+ "dev.editor_open_failed": "Couldn't open browser: {{error}}",
335
337
  "dev.section_synced": "🧩 section updated: {{folder}}",
336
338
  "dev.status_section": "section",
337
339
  "dev.section_menu_opening": "Opening section menu...",
@@ -395,5 +397,6 @@
395
397
  "config.autoupgrade.off": "Version checking is off.",
396
398
  "config.autoupgrade.status_on": "Version checking: on",
397
399
  "config.autoupgrade.status_off": "Version checking: off",
398
- "config.autoupgrade.usage": "Usage: tsoft config autoupgrade on | off | status"
400
+ "config.autoupgrade.usage": "Usage: tsoft config autoupgrade on | off | status",
401
+ "dev.no_active_store": "No active store.\n\nTo sign in: tsoft login"
399
402
  }
package/locales/tr.json CHANGED
@@ -330,8 +330,10 @@
330
330
  "submit.step3": "3. Partner panelden submit edin",
331
331
  "dev.status_watching": "İzleniyor",
332
332
  "dev.status_preview": "önizleme",
333
+ "dev.status_editor": "editör",
333
334
  "dev.status_exit": "çıkış",
334
335
  "dev.preview_open_failed": "Tarayıcı açılamadı: {{error}}",
336
+ "dev.editor_open_failed": "Tarayıcı açılamadı: {{error}}",
335
337
  "dev.section_synced": "🧩 section güncellendi: {{folder}}",
336
338
  "dev.status_section": "section",
337
339
  "dev.section_menu_opening": "Section menüsü açılıyor...",
@@ -395,5 +397,6 @@
395
397
  "config.autoupgrade.off": "Sürüm kontrolü kapatıldı.",
396
398
  "config.autoupgrade.status_on": "Sürüm kontrolü: açık",
397
399
  "config.autoupgrade.status_off": "Sürüm kontrolü: kapalı",
398
- "config.autoupgrade.usage": "Kullanım: tsoft config autoupgrade on | off | status"
400
+ "config.autoupgrade.usage": "Kullanım: tsoft config autoupgrade on | off | status",
401
+ "dev.no_active_store": "Aktif mağaza bulunamadı.\n\nGiriş yapmak için: tsoft login"
399
402
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsoft-cli",
3
- "version": "3.13.2",
3
+ "version": "3.14.0",
4
4
  "description": "Command-line tool for tsoft360 theme development and management",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -181,13 +181,35 @@ async function handleFileDelete(themeUuid, themePath, filePath) {
181
181
  }
182
182
  }
183
183
 
184
- function printWatchStatus(previewUrl) {
184
+ export function printWatchStatus(previewUrl, editorUrl) {
185
185
  const sep = chalk.dim(' · ');
186
186
  const parts = [chalk.cyan('👀 ' + t('dev.status_watching'))];
187
187
  if (previewUrl) parts.push(chalk.bold.green('P') + chalk.gray(' ' + t('dev.status_preview')));
188
+ if (editorUrl) parts.push(chalk.bold.green('E') + chalk.gray(' ' + t('dev.status_editor')));
188
189
  parts.push(chalk.bold.green('S') + chalk.gray(' ' + t('dev.status_section')));
189
190
  parts.push(chalk.gray('Ctrl+C ' + t('dev.status_exit')));
190
191
  console.log('\n' + parts.join(sep) + '\n');
192
+
193
+ if (previewUrl) console.log(` ${chalk.cyan.underline(previewUrl)}`);
194
+ if (editorUrl) console.log(` ${chalk.cyan.underline(editorUrl)}`);
195
+ if (previewUrl || editorUrl) console.log('');
196
+ }
197
+
198
+ export async function handleWatchKey(key, { previewUrl, editorUrl }) {
199
+ if (previewUrl && (key === 'p' || key === 'P')) {
200
+ try {
201
+ await open(previewUrl);
202
+ } catch (e) {
203
+ console.log(chalk.red(' ' + t('dev.preview_open_failed', { error: e.message })));
204
+ }
205
+ }
206
+ if (editorUrl && (key === 'e' || key === 'E')) {
207
+ try {
208
+ await open(editorUrl);
209
+ } catch (e) {
210
+ console.log(chalk.red(' ' + t('dev.editor_open_failed', { error: e.message })));
211
+ }
212
+ }
191
213
  }
192
214
 
193
215
  async function startFileWatcher(themeUuid, themePath) {
@@ -201,7 +223,15 @@ async function startFileWatcher(themeUuid, themePath) {
201
223
  // sessiz — preview opsiyonel
202
224
  }
203
225
 
204
- printWatchStatus(previewUrl);
226
+ let editorUrl = null;
227
+ try {
228
+ const apiClient = await createApiClient();
229
+ const editorRes = await apiClient.get(`/theme/${themeUuid}/editor-url`);
230
+ editorUrl = editorRes?.data?.editor_url || null;
231
+ } catch {
232
+ }
233
+
234
+ printWatchStatus(previewUrl, editorUrl);
205
235
 
206
236
  // Menu acikken hem watcher event'leri hem keypress dinleyici askiya alinir
207
237
  // (inquirer ile stdin cakismasini onler).
@@ -230,13 +260,7 @@ async function startFileWatcher(themeUuid, themePath) {
230
260
  if (paused) {
231
261
  return;
232
262
  }
233
- if (previewUrl && (key === 'p' || key === 'P')) {
234
- try {
235
- await open(previewUrl);
236
- } catch (e) {
237
- console.log(chalk.red(' ' + t('dev.preview_open_failed', { error: e.message })));
238
- }
239
- }
263
+ await handleWatchKey(key, { previewUrl, editorUrl });
240
264
  if (key === 's' || key === 'S') {
241
265
  await openSectionMenu();
242
266
  }
@@ -297,7 +321,7 @@ async function startFileWatcher(themeUuid, themePath) {
297
321
  setRawMode(true);
298
322
  process.stdin.resume();
299
323
  console.log(chalk.green('\n' + t('dev.section_menu_resumed')));
300
- printWatchStatus(previewUrl);
324
+ printWatchStatus(previewUrl, editorUrl);
301
325
  paused = false;
302
326
  }
303
327
 
@@ -332,6 +356,12 @@ export async function themeDevCommand(themeName) {
332
356
  console.log(chalk.cyan(t('dev.starting') + '\n'));
333
357
 
334
358
  const store = await getActiveStore();
359
+
360
+ if (!store) {
361
+ showError(t('dev.no_active_store'));
362
+ process.exit(1);
363
+ }
364
+
335
365
  const storeSlug = normalizeStoreDomain(store);
336
366
 
337
367
  let themeSlug = themeName;