tsoft-cli 3.13.0 → 3.13.2
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 +10 -0
- package/package.json +1 -1
- package/src/commands/theme-push.js +5 -4
- package/src/commands/theme-section.js +2 -2
- package/src/storage.js +26 -0
- package/src/ui/help-renderer.js +4 -2
- package/src/ui/theme-choice.js +9 -1
- package/src/ui/workspace-hint.js +6 -2
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.13.2] - 2026-09-10
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Commands no longer print a theme's folder id where its name belongs. `theme push`, `theme section list`, `theme section add` and the help screen showed whatever is recorded as the active theme, and for most themes that is the folder id — so a line meant to confirm what you are about to push read "Store: example.com - Theme: adf806ec-9ee6-4ce8-af40-cd1af10a4c04" and told you nothing. The commands that already talk to the store now show the theme's name; the help screen, which must not make a network call to draw its status line, leaves the theme out rather than printing an id.
|
|
12
|
+
|
|
13
|
+
## [3.13.1] - 2026-09-10
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- The directory warning added in 3.13.0 no longer fires inside the theme directory it is pointing at. Some commands record the active theme by its folder id and others by its name, while the directory on disk is always named after the theme — so for a theme recorded by id the two never matched, the warning appeared even in the right place, and the `cd` it offered named an id that no directory has. An id cannot be turned back into a directory name without asking the store, which this check deliberately avoids so it stays fast and works offline, so the warning is now skipped in that case. Themes recorded by name are unaffected and still get the warning outside their directory.
|
|
17
|
+
|
|
8
18
|
## [3.13.0] - 2026-09-10
|
|
9
19
|
|
|
10
20
|
### Added
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { createApiClient } from '../api-client.js';
|
|
4
|
-
import {
|
|
4
|
+
import { describeActiveTheme, getActiveStore } from '../storage.js';
|
|
5
5
|
import { mapPushError } from '../errors/error-mapper.js';
|
|
6
6
|
import { isJsonMode, jsonOut } from '../output-mode.js';
|
|
7
7
|
import { t } from '../i18n.js';
|
|
@@ -91,11 +91,12 @@ export async function themePushCommand(themeName, options = {}) {
|
|
|
91
91
|
if (themeName) {
|
|
92
92
|
themeUuid = themeName;
|
|
93
93
|
} else {
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
const active = await describeActiveTheme();
|
|
95
|
+
themeUuid = active?.uuid ?? null;
|
|
96
|
+
if (active && !isJsonMode()) {
|
|
96
97
|
const store = await getActiveStore();
|
|
97
98
|
if (store) {
|
|
98
|
-
console.log(chalk.gray(t('context.line', { store, theme:
|
|
99
|
+
console.log(chalk.gray(t('context.line', { store, theme: active.label })));
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
if (!themeUuid) {
|
|
@@ -35,10 +35,10 @@ export async function themeSectionListCommand() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
console.log(chalk.cyan(t('section.list.starting') + '\n'));
|
|
38
|
-
console.log(chalk.gray(t('section.list.active_theme', { theme: activeTheme }) + '\n'));
|
|
39
38
|
|
|
40
39
|
// Tema UUID'sini al
|
|
41
40
|
const themeInfo = await getThemeUuidBySlug(activeTheme);
|
|
41
|
+
console.log(chalk.gray(t('section.list.active_theme', { theme: themeInfo.name ?? activeTheme }) + '\n'));
|
|
42
42
|
|
|
43
43
|
// Section'ları çek
|
|
44
44
|
const apiClient = await createApiClient();
|
|
@@ -98,10 +98,10 @@ export async function themeSectionAddCommand() {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
console.log(chalk.cyan(t('section.add.starting') + '\n'));
|
|
101
|
-
console.log(chalk.gray(t('section.add.active_theme', { theme: activeTheme }) + '\n'));
|
|
102
101
|
|
|
103
102
|
// Tema UUID'sini al
|
|
104
103
|
const themeInfo = await getThemeUuidBySlug(activeTheme);
|
|
104
|
+
console.log(chalk.gray(t('section.add.active_theme', { theme: themeInfo.name ?? activeTheme }) + '\n'));
|
|
105
105
|
|
|
106
106
|
// Section'ları çek
|
|
107
107
|
const apiClient = await createApiClient();
|
package/src/storage.js
CHANGED
|
@@ -729,6 +729,32 @@ export async function resolveActiveThemeUuid() {
|
|
|
729
729
|
return uuid;
|
|
730
730
|
}
|
|
731
731
|
|
|
732
|
+
/**
|
|
733
|
+
* Aktif temayı hem kimliğiyle hem okunabilir adıyla döner.
|
|
734
|
+
*
|
|
735
|
+
* Kayıt UUID ise ad mağazadan çözülür; mağazaya ulaşılamazsa kayıtlı değer
|
|
736
|
+
* olduğu gibi etiket olur. Kullanıcıya UUID göstermemek için vardır.
|
|
737
|
+
*
|
|
738
|
+
* @returns {Promise<{uuid: string, label: string}|null>}
|
|
739
|
+
*/
|
|
740
|
+
export async function describeActiveTheme() {
|
|
741
|
+
const uuid = await resolveActiveThemeUuid();
|
|
742
|
+
|
|
743
|
+
if (!uuid) {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
try {
|
|
748
|
+
const { fetchAllThemes } = await import('./theme-list.js');
|
|
749
|
+
const { themes } = await fetchAllThemes();
|
|
750
|
+
const match = themes.find(theme => theme.theme_folder === uuid);
|
|
751
|
+
|
|
752
|
+
return { uuid, label: match?.name ?? uuid };
|
|
753
|
+
} catch {
|
|
754
|
+
return { uuid, label: uuid };
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
732
758
|
/**
|
|
733
759
|
* Tema slug'ından UUID/folder adını bulur
|
|
734
760
|
* @param {string} themeSlug - Tema slug (örn: 'my-theme')
|
package/src/ui/help-renderer.js
CHANGED
|
@@ -4,6 +4,7 @@ import { TSOFT_COLORS, createTSoftGradient } from './prompt-wrapper.js';
|
|
|
4
4
|
import { humanOut, isJsonMode, jsonOut } from '../output-mode.js';
|
|
5
5
|
import { t } from '../i18n.js';
|
|
6
6
|
import { loadTokens, getActiveStore, getActiveTheme } from '../storage.js';
|
|
7
|
+
import { themeStatusLabel } from './theme-choice.js';
|
|
7
8
|
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
9
10
|
|
|
@@ -150,8 +151,9 @@ function buildStatusLines(status) {
|
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
// Theme line
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
const themeLabel = themeStatusLabel(activeTheme);
|
|
155
|
+
if (themeLabel) {
|
|
156
|
+
const themeText = t('help.status.active_theme', { theme: themeLabel });
|
|
155
157
|
lines.push(' ' + orangeBullet + ' ' + themeText);
|
|
156
158
|
} else {
|
|
157
159
|
lines.push(' ' + chalk.dim('○ ' + t('help.status.no_theme')));
|
package/src/ui/theme-choice.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { slugify } from '../storage.js';
|
|
2
|
+
import { slugify, isThemeUuid } from '../storage.js';
|
|
3
3
|
import { t } from '../i18n.js';
|
|
4
4
|
|
|
5
5
|
export function themeLabels(theme, selectedTheme) {
|
|
@@ -31,3 +31,11 @@ export function decorateThemeName(theme, selectedTheme) {
|
|
|
31
31
|
|
|
32
32
|
return [name, chalk.gray(`v${theme.version}`), ...marks].join(' ');
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
export function themeStatusLabel(activeTheme) {
|
|
36
|
+
if (!activeTheme || isThemeUuid(activeTheme)) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return activeTheme;
|
|
41
|
+
}
|
package/src/ui/workspace-hint.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { normalizeStoreDomain } from '../storage.js';
|
|
3
|
+
import { normalizeStoreDomain, isThemeUuid } from '../storage.js';
|
|
4
4
|
import { t } from '../i18n.js';
|
|
5
5
|
|
|
6
6
|
const THEME_CONTEXT_COMMANDS = new Set([
|
|
@@ -37,6 +37,10 @@ export function buildWorkspaceHint({ context, activeStore, activeTheme, workspac
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
if (isThemeUuid(activeTheme)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
if (standingInTheme({ context, activeStore, activeTheme })) {
|
|
41
45
|
return null;
|
|
42
46
|
}
|
|
@@ -49,7 +53,7 @@ export function buildWorkspaceHint({ context, activeStore, activeTheme, workspac
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
export function buildThemeMissingHint({ context, activeStore, activeTheme, workspaceRoot = null }) {
|
|
52
|
-
if (standingInTheme({ context, activeStore, activeTheme })) {
|
|
56
|
+
if (isThemeUuid(activeTheme) || standingInTheme({ context, activeStore, activeTheme })) {
|
|
53
57
|
return { reason: 'not-downloaded', store: activeStore, theme: activeTheme, cd: null };
|
|
54
58
|
}
|
|
55
59
|
|