@siegesailor/terminal-sigma 1.0.0 → 1.1.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/README.md +84 -34
- package/build/app.js +308 -0
- package/build/app.js.map +1 -0
- package/build/command-line-interface.js +41 -4
- package/build/command-line-interface.js.map +1 -1
- package/build/components/character.js +16 -292
- package/build/components/character.js.map +1 -1
- package/build/components/entry-form.js +52 -0
- package/build/components/entry-form.js.map +1 -0
- package/build/components/footer.js +25 -0
- package/build/components/footer.js.map +1 -0
- package/build/components/logs-view.js +96 -0
- package/build/components/logs-view.js.map +1 -0
- package/build/components/menu-grid.js +26 -45
- package/build/components/menu-grid.js.map +1 -1
- package/build/components/today-panel.js +23 -0
- package/build/components/today-panel.js.map +1 -0
- package/build/content.js +176 -0
- package/build/content.js.map +1 -0
- package/build/i18n.js +254 -0
- package/build/i18n.js.map +1 -0
- package/build/pixel-art.js +402 -0
- package/build/pixel-art.js.map +1 -0
- package/build/progress.js +59 -33
- package/build/progress.js.map +1 -1
- package/build/quotes.js +52 -5
- package/build/quotes.js.map +1 -1
- package/build/theme.js +37 -0
- package/build/theme.js.map +1 -0
- package/package.json +1 -3
- package/build/commands/index.js +0 -274
- package/build/commands/index.js.map +0 -1
- package/build/components/status-panel.js +0 -19
- package/build/components/status-panel.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,34 +1,56 @@
|
|
|
1
1
|
# Terminal-Sigma
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@siegesailor/terminal-sigma)
|
|
4
|
+
[](https://github.com/SiegeSailor/Terminal-Sigma/releases/latest)
|
|
4
5
|
[](https://github.com/SiegeSailor/Terminal-Sigma/actions/workflows/push-verify.yml)
|
|
5
6
|
[](https://github.com/SiegeSailor/Terminal-Sigma/actions/workflows/main-release.yml)
|
|
7
|
+
[](https://github.com/SiegeSailor/Terminal-Sigma/actions/workflows/release-desktop.yml)
|
|
6
8
|
|
|
7
|
-
Terminal-Sigma is a terminal-based application that gives game-style feedback on your self-development journey. Though it is a CLI, it is meant to stay open: it updates in real time and is operated through
|
|
9
|
+
Terminal-Sigma is a terminal-based application that gives game-style feedback on your self-development journey. Though it is a CLI, it is meant to stay open: it fills the terminal, updates in real time, and is operated through menus rather than commands. It speaks English and Traditional Chinese, and it features 5 main components:
|
|
8
10
|
|
|
9
|
-
| Component | What It Does
|
|
10
|
-
| --------------------- |
|
|
11
|
-
| Character Progression |
|
|
12
|
-
| Diet Tracker | Logs
|
|
13
|
-
| Everyday Quotes | An inspiring quote that refreshes every 30 minutes, on restart, or on demand
|
|
14
|
-
| Tomato Timer | A Pomodoro timer: 25 minutes of focus, then a 5-minute break, against a daily goal of 4 focus sessions
|
|
15
|
-
| Workout Tracker | Logs
|
|
11
|
+
| Component | What It Does |
|
|
12
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| Character Progression | A pixel-art character that levels up with you, unlocks gear, and acts out what you are doing |
|
|
14
|
+
| Diet Tracker | Logs each meal step by step, with its calories and protein, against a daily goal of 3 meals |
|
|
15
|
+
| Everyday Quotes | An inspiring quote that refreshes every 30 minutes, on restart, or on demand |
|
|
16
|
+
| Tomato Timer | A Pomodoro timer: 25 minutes of focus, then a 5-minute break, against a daily goal of 4 focus sessions |
|
|
17
|
+
| Workout Tracker | Logs each workout step by step, with its activity, minutes, and intensity, against a daily goal of 30 minutes |
|
|
16
18
|
|
|
17
19
|
Underneath, your journey is written to the local file `~/.terminal-sigma/progress.json`. There is no plan to support logging at this point, and we chose JSON as a readable format, so that you can port it easily.
|
|
18
20
|
|
|
19
21
|
## Installation
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Terminal-Sigma comes as a CLI on NPM and as a desktop app on every GitHub release. Both read and write the same `progress.json`, so you can switch between them.
|
|
24
|
+
|
|
25
|
+
### CLI
|
|
26
|
+
|
|
27
|
+
Install it globally to get the command:
|
|
22
28
|
|
|
23
29
|
```shell
|
|
24
30
|
npm install --global @siegesailor/terminal-sigma
|
|
25
31
|
```
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
The CLI requires [Node.js](https://nodejs.org/) `>= 22`.
|
|
34
|
+
|
|
35
|
+
### Desktop
|
|
36
|
+
|
|
37
|
+
Download the file for your system from the [latest release](https://github.com/SiegeSailor/Terminal-Sigma/releases/latest). The desktop app needs no Node.js:
|
|
38
|
+
|
|
39
|
+
| System | File | First Launch |
|
|
40
|
+
| --------------------- | ------------------------------------------------ | ------------------------------------------------------------------- |
|
|
41
|
+
| Linux | `Terminal-Sigma-<version>-linux-x86_64.AppImage` | Run `chmod +x` on the file, then open it |
|
|
42
|
+
| macOS (Apple Silicon) | `Terminal-Sigma-<version>-mac-arm64.dmg` | Drag the app to Applications, then see the note below |
|
|
43
|
+
| macOS (Intel) | `Terminal-Sigma-<version>-mac-x64.dmg` | Drag the app to Applications, then see the note below |
|
|
44
|
+
| Windows | `Terminal-Sigma-<version>-win-x64.exe` | Choose **More info**, then **Run anyway** in the SmartScreen prompt |
|
|
28
45
|
|
|
29
|
-
|
|
46
|
+
> [!note]
|
|
47
|
+
> The apps are not signed by Apple or Microsoft yet. If macOS says the app "is damaged and can't be opened", it only means the download is quarantined; clear the flag once:
|
|
48
|
+
>
|
|
49
|
+
> ```shell
|
|
50
|
+
> xattr -dr com.apple.quarantine "/Applications/Terminal Sigma.app"
|
|
51
|
+
> ```
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
The desktop app opens the dashboard in its own window, sends a system notification when a focus or break ends, and uses the default options below.
|
|
32
54
|
|
|
33
55
|
## Usage
|
|
34
56
|
|
|
@@ -38,7 +60,7 @@ Start the dashboard and leave it open in a terminal tab:
|
|
|
38
60
|
siegesailor-terminal-sigma --name "Ken"
|
|
39
61
|
```
|
|
40
62
|
|
|
41
|
-
Every option has a default:
|
|
63
|
+
On the first run, it asks for your language and saves the answer in `progress.json`; change it at any time from **Language** in the menu. Every option has a default:
|
|
42
64
|
|
|
43
65
|
| Option | Default | Description |
|
|
44
66
|
| --------------- | ------------ | ---------------------------------- |
|
|
@@ -46,52 +68,80 @@ Every option has a default:
|
|
|
46
68
|
| `--focus <min>` | `25` | Minutes of each Tomato Timer focus |
|
|
47
69
|
| `--name <name>` | `Rook Sigma` | The name of your character |
|
|
48
70
|
|
|
71
|
+
### Menu
|
|
72
|
+
|
|
73
|
+
The menu at the bottom drives everything, and Enter opens an item:
|
|
74
|
+
|
|
75
|
+
| Item | Enter Does |
|
|
76
|
+
| --------------- | -------------------------------------------------------------------------- |
|
|
77
|
+
| Diet Tracker | Asks for the food, its calories, and its protein, one at a time |
|
|
78
|
+
| Everyday Quotes | Draws a new quote |
|
|
79
|
+
| Language | Switches between English and Traditional Chinese |
|
|
80
|
+
| Logs | Lists every focus, meal, and workout, newest first, with a filter per kind |
|
|
81
|
+
| Tomato Timer | Starts a focus, or pauses, resumes, or stops the running one |
|
|
82
|
+
| Workout Tracker | Asks for the activity, its minutes, and its intensity, one at a time |
|
|
83
|
+
|
|
84
|
+
A stopped focus earns nothing. While you log a meal or a workout, the character eats, runs, lifts, or stretches to match, and it celebrates when you level up.
|
|
85
|
+
|
|
49
86
|
### Keys
|
|
50
87
|
|
|
51
|
-
|
|
88
|
+
Every view shows its keys at the bottom right:
|
|
52
89
|
|
|
53
|
-
| Key | Action
|
|
54
|
-
| ------------------------- |
|
|
55
|
-
| `1` to `
|
|
56
|
-
| Arrows or `h` `j` `k` `l` | Move through the menu
|
|
57
|
-
| Enter |
|
|
58
|
-
| Esc |
|
|
59
|
-
| `q` or Ctrl+C | Quit
|
|
90
|
+
| Key | Action |
|
|
91
|
+
| ------------------------- | --------------------------------------------------------- |
|
|
92
|
+
| `1` to `6` | Jump to a menu item |
|
|
93
|
+
| Arrows or `h` `j` `k` `l` | Move through the menu, a list, or the log filters |
|
|
94
|
+
| Enter | Open the item, choose the option, or go to the next field |
|
|
95
|
+
| Esc | Go back to the menu without logging anything |
|
|
96
|
+
| `q` or Ctrl+C | Quit from the menu |
|
|
60
97
|
|
|
61
|
-
|
|
98
|
+
When a focus or break ends, the terminal rings its bell.
|
|
62
99
|
|
|
63
100
|
### Environment Variables
|
|
64
101
|
|
|
65
102
|
Both are optional:
|
|
66
103
|
|
|
67
|
-
| Variable | Effect
|
|
68
|
-
| --------------------- |
|
|
69
|
-
| `API_NINJAS_KEY` | Fetch quotes from [API Ninjas](https://api-ninjas.com/api/quotes) instead of the bundled list, falling back
|
|
70
|
-
| `TERMINAL_SIGMA_HOME` | The folder that holds `progress.json`, instead of `~/.terminal-sigma`, e.g. a synced folder
|
|
104
|
+
| Variable | Effect |
|
|
105
|
+
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `API_NINJAS_KEY` | Fetch quotes from [API Ninjas](https://api-ninjas.com/api/quotes) instead of the bundled list, in English only, falling back on any error |
|
|
107
|
+
| `TERMINAL_SIGMA_HOME` | The folder that holds `progress.json`, instead of `~/.terminal-sigma`, e.g. a synced folder |
|
|
71
108
|
|
|
72
109
|
## Progress File
|
|
73
110
|
|
|
74
|
-
`progress.json` holds
|
|
111
|
+
`progress.json` holds your language and what you logged. Your experience, level, and daily progress are worked out from it every time, so editing the file by hand can never put them out of sync:
|
|
75
112
|
|
|
76
113
|
```json
|
|
77
114
|
{
|
|
115
|
+
"language": "en",
|
|
78
116
|
"focus": [{ "at": "2026-10-03T09:00:00.000Z", "minutes": 25 }],
|
|
79
117
|
"meals": [
|
|
80
|
-
{
|
|
118
|
+
{
|
|
119
|
+
"at": "2026-10-03T08:00:00.000Z",
|
|
120
|
+
"food": "Oatmeal",
|
|
121
|
+
"calories": 350,
|
|
122
|
+
"protein": 12
|
|
123
|
+
}
|
|
81
124
|
],
|
|
82
125
|
"workouts": [
|
|
83
|
-
{
|
|
126
|
+
{
|
|
127
|
+
"at": "2026-10-03T07:00:00.000Z",
|
|
128
|
+
"activity": "running",
|
|
129
|
+
"minutes": 30,
|
|
130
|
+
"intensity": "moderate"
|
|
131
|
+
}
|
|
84
132
|
]
|
|
85
133
|
}
|
|
86
134
|
```
|
|
87
135
|
|
|
136
|
+
`language` is `en` or `zh-TW`. A workout's `activity` is one of `cycling`, `other`, `running`, `strength`, `swimming`, `walking`, or `yoga`, and its `intensity` is `light`, `moderate`, or `vigorous`. Files written by version 1 still load as they are.
|
|
137
|
+
|
|
88
138
|
Every 100 XP is a level, and every level from level 2 to level 9 upgrades 1 piece of your character's gear. Experience is earned as follows:
|
|
89
139
|
|
|
90
|
-
| Entry | Experience
|
|
91
|
-
| -------------- |
|
|
92
|
-
| Finished focus | 1 XP per minute
|
|
93
|
-
| Meal | 5 XP
|
|
94
|
-
| Workout | 1 XP
|
|
140
|
+
| Entry | Experience |
|
|
141
|
+
| -------------- | --------------------------------------------------------------------- |
|
|
142
|
+
| Finished focus | 1 XP per minute |
|
|
143
|
+
| Meal | 5 XP |
|
|
144
|
+
| Workout | Per minute: 1 XP when light, 1.5 XP when moderate, 2 XP when vigorous |
|
|
95
145
|
|
|
96
146
|
> [!important]
|
|
97
147
|
> If `progress.json` is not valid, Terminal-Sigma refuses to start rather than overwrite it. Fix or move the file, then start again.
|
package/build/app.js
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import zod from "zod";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { Select, ThemeProvider } from "@inkjs/ui";
|
|
5
|
+
import { Box, Text, useApp, useInput, useStdout, useWindowSize } from "ink";
|
|
6
|
+
import Character from "./components/character.js";
|
|
7
|
+
import EntryForm from "./components/entry-form.js";
|
|
8
|
+
import Footer from "./components/footer.js";
|
|
9
|
+
import LogsView from "./components/logs-view.js";
|
|
10
|
+
import MenuGrid from "./components/menu-grid.js";
|
|
11
|
+
import TodayPanel from "./components/today-panel.js";
|
|
12
|
+
import { characterWidth, dietFieldsOf, layoutOf, menuItemsOf, menuOrder, metricsOf, workoutFieldsOf, } from "./content.js";
|
|
13
|
+
import { intensities, languages, messagesOf, workoutActivities, } from "./i18n.js";
|
|
14
|
+
import { experienceOf, experiencePerMeal, levelOf, logsOf, saveProgress, todayOf, workoutExperience, } from "./progress.js";
|
|
15
|
+
import { fetchQuote, hasQuoteApi, localizedQuote, quoteRefreshMinutes, randomBundledQuote, } from "./quotes.js";
|
|
16
|
+
import { colors, uiTheme } from "./theme.js";
|
|
17
|
+
import { advanceTimer, formatClock, idleTimer, remainingOf, toggleTimer, } from "./timer.js";
|
|
18
|
+
export const optionsSchema = zod.object({
|
|
19
|
+
name: zod.string().min(1).default("Rook Sigma"),
|
|
20
|
+
focus: zod.number().int().positive().default(25),
|
|
21
|
+
break: zod.number().int().positive().default(5),
|
|
22
|
+
});
|
|
23
|
+
const flashMilliseconds = 6000;
|
|
24
|
+
const workoutAnimation = (activity) => {
|
|
25
|
+
if (activity === "strength") {
|
|
26
|
+
return "lift";
|
|
27
|
+
}
|
|
28
|
+
return activity === "yoga" ? "stretch" : "run";
|
|
29
|
+
};
|
|
30
|
+
const languageOptions = languages.map((language) => ({
|
|
31
|
+
label: messagesOf(language).languageName,
|
|
32
|
+
value: language,
|
|
33
|
+
}));
|
|
34
|
+
const asLanguage = (value) => value === "zh-TW" ? "zh-TW" : "en";
|
|
35
|
+
function Titled({ title, children, }) {
|
|
36
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
37
|
+
React.createElement(Text, { bold: true, color: colors.accent }, title),
|
|
38
|
+
children));
|
|
39
|
+
}
|
|
40
|
+
export default function App({ options, file, initialProgress }) {
|
|
41
|
+
const { exit } = useApp();
|
|
42
|
+
const { stdout } = useStdout();
|
|
43
|
+
const size = useWindowSize();
|
|
44
|
+
const [progress, setProgress] = React.useState(initialProgress);
|
|
45
|
+
const [now, setNow] = React.useState(Date.now);
|
|
46
|
+
const durations = React.useMemo(() => ({ focus: options.focus, break: options.break }), [options.focus, options.break]);
|
|
47
|
+
const [timer, setTimer] = React.useState(() => idleTimer(durations));
|
|
48
|
+
const [quote, setQuote] = React.useState(randomBundledQuote);
|
|
49
|
+
const [view, setView] = React.useState("menu");
|
|
50
|
+
const [flash, setFlash] = React.useState();
|
|
51
|
+
const [draftActivity, setDraftActivity] = React.useState();
|
|
52
|
+
const language = progress.language ?? "en";
|
|
53
|
+
const messages = messagesOf(language);
|
|
54
|
+
const [message, setMessage] = React.useState(() => ({
|
|
55
|
+
text: messages.savedTo(file.replace(homedir(), "~")),
|
|
56
|
+
tone: "info",
|
|
57
|
+
}));
|
|
58
|
+
const say = (text, tone = "info") => {
|
|
59
|
+
setMessage({ text, tone });
|
|
60
|
+
};
|
|
61
|
+
// Saves first and only then shows the change, so the screen never claims
|
|
62
|
+
// something the file does not hold.
|
|
63
|
+
const record = React.useCallback((update, text, activity) => {
|
|
64
|
+
const next = update(progress);
|
|
65
|
+
const { form, notSaved } = messagesOf(next.language ?? "en");
|
|
66
|
+
try {
|
|
67
|
+
saveProgress(file, next);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
setMessage({ text: notSaved(String(error)), tone: "error" });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const after = levelOf(experienceOf(next));
|
|
74
|
+
const leveledUp = after > levelOf(experienceOf(progress));
|
|
75
|
+
setProgress(next);
|
|
76
|
+
setMessage({
|
|
77
|
+
text: leveledUp ? `${text} ${form.levelUp(after)}` : text,
|
|
78
|
+
tone: "success",
|
|
79
|
+
});
|
|
80
|
+
setFlash({
|
|
81
|
+
activity: leveledUp ? "levelUp" : activity,
|
|
82
|
+
until: Date.now() + flashMilliseconds,
|
|
83
|
+
});
|
|
84
|
+
}, [file, progress]);
|
|
85
|
+
React.useEffect(() => {
|
|
86
|
+
const interval = setInterval(() => {
|
|
87
|
+
setNow(Date.now());
|
|
88
|
+
}, 1000);
|
|
89
|
+
return () => {
|
|
90
|
+
clearInterval(interval);
|
|
91
|
+
};
|
|
92
|
+
}, []);
|
|
93
|
+
React.useEffect(() => {
|
|
94
|
+
const { timer: next, finished } = advanceTimer(timer, now, durations);
|
|
95
|
+
if (!finished) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const { timer: words } = messagesOf(language);
|
|
99
|
+
setTimer(next);
|
|
100
|
+
stdout.write("\u0007");
|
|
101
|
+
if (finished === "break") {
|
|
102
|
+
setMessage({ text: words.breakOver, tone: "info" });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
record((current) => ({
|
|
106
|
+
...current,
|
|
107
|
+
focus: [
|
|
108
|
+
...current.focus,
|
|
109
|
+
{ at: new Date(now).toISOString(), minutes: durations.focus },
|
|
110
|
+
],
|
|
111
|
+
}), words.focusComplete(durations.focus, durations.break), "idle");
|
|
112
|
+
}, [now, timer, durations, record, stdout, language]);
|
|
113
|
+
React.useEffect(() => {
|
|
114
|
+
let isMounted = true;
|
|
115
|
+
const refresh = async () => {
|
|
116
|
+
const next = await fetchQuote();
|
|
117
|
+
if (isMounted) {
|
|
118
|
+
setQuote(next);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
// The bundled quote shown first is already fresh; only the API is worth a call.
|
|
122
|
+
if (hasQuoteApi()) {
|
|
123
|
+
void refresh();
|
|
124
|
+
}
|
|
125
|
+
const interval = setInterval(() => {
|
|
126
|
+
void refresh();
|
|
127
|
+
}, quoteRefreshMinutes * 60_000);
|
|
128
|
+
return () => {
|
|
129
|
+
isMounted = false;
|
|
130
|
+
clearInterval(interval);
|
|
131
|
+
};
|
|
132
|
+
}, []);
|
|
133
|
+
const backToMenu = (text) => {
|
|
134
|
+
setView("menu");
|
|
135
|
+
setDraftActivity(undefined);
|
|
136
|
+
if (text) {
|
|
137
|
+
say(text);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
useInput((input, key) => {
|
|
141
|
+
if (view === "menu" && input === "q") {
|
|
142
|
+
exit();
|
|
143
|
+
}
|
|
144
|
+
else if (view !== "menu" && key.escape) {
|
|
145
|
+
const isForm = view === "diet" || view === "workout";
|
|
146
|
+
backToMenu(isForm ? messages.form.cancelled : undefined);
|
|
147
|
+
}
|
|
148
|
+
}, { isActive: progress.language !== undefined });
|
|
149
|
+
const chooseLanguage = (next) => {
|
|
150
|
+
const updated = { ...progress, language: next };
|
|
151
|
+
try {
|
|
152
|
+
saveProgress(file, updated);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
say(messagesOf(next).notSaved(String(error)), "error");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
setProgress(updated);
|
|
159
|
+
backToMenu(messagesOf(next).languageChanged);
|
|
160
|
+
};
|
|
161
|
+
if (progress.language === undefined) {
|
|
162
|
+
return (React.createElement(ThemeProvider, { theme: uiTheme },
|
|
163
|
+
React.createElement(Box, { borderColor: colors.accent, borderStyle: "round", flexDirection: "column", paddingX: 2, paddingY: 1 },
|
|
164
|
+
React.createElement(Titled, { title: "\u273B Terminal Sigma" },
|
|
165
|
+
React.createElement(Text, { dimColor: true }, messages.chooseLanguage),
|
|
166
|
+
React.createElement(Box, { marginTop: 1 },
|
|
167
|
+
React.createElement(Select, { options: languageOptions, onChange: (value) => {
|
|
168
|
+
chooseLanguage(asLanguage(value));
|
|
169
|
+
} }))))));
|
|
170
|
+
}
|
|
171
|
+
const isRunning = timer.endsAt !== undefined;
|
|
172
|
+
const isIdle = !isRunning &&
|
|
173
|
+
timer.phase === "focus" &&
|
|
174
|
+
timer.remaining === durations.focus * 60_000;
|
|
175
|
+
const clock = formatClock(remainingOf(timer, now));
|
|
176
|
+
const phaseLabel = messages.timer[timer.phase];
|
|
177
|
+
const selectMenu = (index) => {
|
|
178
|
+
const item = menuOrder[index];
|
|
179
|
+
if (item === "timer" && isIdle) {
|
|
180
|
+
setTimer(toggleTimer(timer, Date.now()));
|
|
181
|
+
say(messages.timer.started);
|
|
182
|
+
}
|
|
183
|
+
else if (item === "quotes") {
|
|
184
|
+
void fetchQuote().then(setQuote);
|
|
185
|
+
say(messages.quoteDrawn);
|
|
186
|
+
}
|
|
187
|
+
else if (item) {
|
|
188
|
+
setView(item);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const chooseTimerAction = (action) => {
|
|
192
|
+
if (action === "toggle") {
|
|
193
|
+
setTimer(toggleTimer(timer, Date.now()));
|
|
194
|
+
backToMenu(isRunning ? messages.timer.paused : messages.timer.resumed);
|
|
195
|
+
}
|
|
196
|
+
else if (action === "stop") {
|
|
197
|
+
setTimer(idleTimer(durations));
|
|
198
|
+
backToMenu(messages.timer.stopped);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
backToMenu();
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const submitMeal = (values) => {
|
|
205
|
+
const food = values.food ?? "";
|
|
206
|
+
backToMenu();
|
|
207
|
+
record((current) => ({
|
|
208
|
+
...current,
|
|
209
|
+
meals: [
|
|
210
|
+
...current.meals,
|
|
211
|
+
{
|
|
212
|
+
at: new Date().toISOString(),
|
|
213
|
+
food,
|
|
214
|
+
calories: Number(values.calories),
|
|
215
|
+
protein: Number(values.protein),
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
}), messages.form.mealLogged(food, experiencePerMeal), "eat");
|
|
219
|
+
};
|
|
220
|
+
const submitWorkout = (values) => {
|
|
221
|
+
const workout = {
|
|
222
|
+
at: new Date().toISOString(),
|
|
223
|
+
activity: workoutActivities.find((option) => option === values.activity) ??
|
|
224
|
+
"other",
|
|
225
|
+
minutes: Number(values.minutes),
|
|
226
|
+
intensity: intensities.find((option) => option === values.intensity) ?? "moderate",
|
|
227
|
+
};
|
|
228
|
+
backToMenu();
|
|
229
|
+
record((current) => ({ ...current, workouts: [...current.workouts, workout] }), messages.form.workoutLogged(messages.workoutActivity[workout.activity], workout.minutes, workoutExperience(workout)), workoutAnimation(workout.activity));
|
|
230
|
+
};
|
|
231
|
+
const experience = experienceOf(progress);
|
|
232
|
+
const level = levelOf(experience);
|
|
233
|
+
const today = todayOf(progress, now);
|
|
234
|
+
const logs = logsOf(progress);
|
|
235
|
+
const columns = size.columns || 100;
|
|
236
|
+
const rows = size.rows || 40;
|
|
237
|
+
const layout = layoutOf(columns, rows);
|
|
238
|
+
const activity = flash && flash.until > now
|
|
239
|
+
? flash.activity
|
|
240
|
+
: view === "diet"
|
|
241
|
+
? "eat"
|
|
242
|
+
: view === "workout"
|
|
243
|
+
? workoutAnimation(draftActivity)
|
|
244
|
+
: isRunning
|
|
245
|
+
? { focus: "focus", break: "break" }[timer.phase]
|
|
246
|
+
: "idle";
|
|
247
|
+
let timerSignal = isRunning ? clock : messages.signal.paused;
|
|
248
|
+
if (isIdle) {
|
|
249
|
+
timerSignal = messages.signal.ready;
|
|
250
|
+
}
|
|
251
|
+
const hints = {
|
|
252
|
+
menu: messages.hints.menu,
|
|
253
|
+
logs: messages.hints.logs,
|
|
254
|
+
diet: messages.hints.form,
|
|
255
|
+
workout: messages.hints.form,
|
|
256
|
+
timer: messages.hints.select,
|
|
257
|
+
language: messages.hints.select,
|
|
258
|
+
};
|
|
259
|
+
const panels = {
|
|
260
|
+
menu: (React.createElement(MenuGrid, { columns: layout.menuColumns, isActive: view === "menu", items: menuItemsOf(messages, language, {
|
|
261
|
+
timerSignal,
|
|
262
|
+
meals: today.meals,
|
|
263
|
+
workoutMinutes: today.workoutMinutes,
|
|
264
|
+
logs: logs.length,
|
|
265
|
+
focus: durations.focus,
|
|
266
|
+
rest: durations.break,
|
|
267
|
+
}), onSelect: selectMenu })),
|
|
268
|
+
timer: (React.createElement(Titled, { title: messages.menu.timer },
|
|
269
|
+
React.createElement(Select, { options: [
|
|
270
|
+
{
|
|
271
|
+
label: isRunning ? messages.timer.pause : messages.timer.resume,
|
|
272
|
+
value: "toggle",
|
|
273
|
+
},
|
|
274
|
+
{ label: messages.timer.stop, value: "stop" },
|
|
275
|
+
{ label: messages.timer.back, value: "back" },
|
|
276
|
+
], onChange: chooseTimerAction }))),
|
|
277
|
+
diet: (React.createElement(EntryForm, { fields: dietFieldsOf(messages), messages: messages, title: messages.form.dietTitle, onSubmit: submitMeal })),
|
|
278
|
+
workout: (React.createElement(EntryForm, { fields: workoutFieldsOf(messages), messages: messages, title: messages.form.workoutTitle, onSubmit: submitWorkout, onValues: (values) => {
|
|
279
|
+
setDraftActivity(values.activity);
|
|
280
|
+
} })),
|
|
281
|
+
language: (React.createElement(Titled, { title: messages.menu.language },
|
|
282
|
+
React.createElement(Select, { options: languageOptions, onChange: (value) => {
|
|
283
|
+
chooseLanguage(asLanguage(value));
|
|
284
|
+
} }))),
|
|
285
|
+
};
|
|
286
|
+
const shownQuote = localizedQuote(quote, language);
|
|
287
|
+
const todayPanel = (React.createElement(TodayPanel, { metrics: metricsOf(messages, language, progress, now), title: messages.today.title, width: layout.todayWidth }));
|
|
288
|
+
return (React.createElement(ThemeProvider, { theme: uiTheme },
|
|
289
|
+
React.createElement(Box, { flexDirection: "column", height: size.rows ? rows : undefined, overflow: "hidden", width: columns },
|
|
290
|
+
React.createElement(Box, { borderColor: colors.accent, borderStyle: "round", flexDirection: "column", flexShrink: 0, paddingX: 1 },
|
|
291
|
+
React.createElement(Box, { justifyContent: "space-between" },
|
|
292
|
+
React.createElement(Text, { bold: true, color: colors.accent }, "\u273B Terminal Sigma"),
|
|
293
|
+
React.createElement(Text, { dimColor: true }, new Date(now).toLocaleTimeString(language, { hour12: false }))),
|
|
294
|
+
React.createElement(Text, { dimColor: true, italic: true, wrap: "truncate-end" }, `“${shownQuote.quote}” — ${shownQuote.author}`)),
|
|
295
|
+
view === "logs" ? (React.createElement(Box, { borderColor: colors.accent, borderStyle: "round", flexGrow: 1, paddingX: 1 },
|
|
296
|
+
React.createElement(LogsView, { height: rows - 7, language: language, logs: logs, messages: messages }))) : (React.createElement(React.Fragment, null,
|
|
297
|
+
React.createElement(Box, { flexDirection: layout.stacked ? "column-reverse" : "row", flexGrow: 1 },
|
|
298
|
+
layout.showCharacter ? (React.createElement(Character, { activity: activity, label: activity === "levelUp"
|
|
299
|
+
? `${messages.activity.levelUp} ${messages.level(level)}`
|
|
300
|
+
: messages.activity[activity], level: messages.level(level), levelNumber: level, name: options.name, width: characterWidth })) : null,
|
|
301
|
+
layout.showToday && layout.todayBeside ? todayPanel : null,
|
|
302
|
+
React.createElement(Box, { borderColor: view === "menu" ? colors.border : colors.accent, borderStyle: "round", flexDirection: "column", paddingX: 1, width: layout.panelWidth }, view === "menu" ? panels.menu : panels[view])),
|
|
303
|
+
layout.showToday && !layout.todayBeside ? todayPanel : null)),
|
|
304
|
+
React.createElement(Footer, { hint: hints[view], message: isIdle || isRunning
|
|
305
|
+
? message.text
|
|
306
|
+
: `${messages.timer.pausedAt(phaseLabel, clock)} · ${message.text}`, status: isRunning ? messages.timer.left(phaseLabel, clock) : undefined, tone: message.tone }))));
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=app.js.map
|
package/build/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../source/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,45 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { render } from "ink";
|
|
5
|
+
import meow from "meow";
|
|
6
|
+
import zod from "zod";
|
|
7
|
+
import App, { optionsSchema } from "./app.js";
|
|
8
|
+
import { loadProgress, progressFile } from "./progress.js";
|
|
9
|
+
const cli = meow(`
|
|
10
|
+
Usage
|
|
11
|
+
$ siegesailor-terminal-sigma [options]
|
|
12
|
+
|
|
13
|
+
Options
|
|
14
|
+
--name Your character's name (default: Rook Sigma)
|
|
15
|
+
--focus Minutes of each Tomato Timer focus (default: 25)
|
|
16
|
+
--break Minutes of each Tomato Timer break (default: 5)
|
|
17
|
+
`, {
|
|
4
18
|
importMeta: import.meta,
|
|
5
|
-
|
|
19
|
+
allowUnknownFlags: false,
|
|
20
|
+
flags: {
|
|
21
|
+
name: { type: "string" },
|
|
22
|
+
focus: { type: "number" },
|
|
23
|
+
break: { type: "number" },
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const options = optionsSchema.safeParse(cli.flags);
|
|
27
|
+
if (!options.success) {
|
|
28
|
+
console.error(zod.prettifyError(options.error));
|
|
29
|
+
process.exit(2);
|
|
30
|
+
}
|
|
31
|
+
// Load before entering the alternate screen, which would swallow the error.
|
|
32
|
+
const file = progressFile();
|
|
33
|
+
let initialProgress;
|
|
34
|
+
try {
|
|
35
|
+
initialProgress = loadProgress(file);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error(error instanceof Error ? error.message : error);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
render(React.createElement(App, { file: file, initialProgress: initialProgress, options: options.data }), {
|
|
42
|
+
alternateScreen: true,
|
|
43
|
+
incrementalRendering: true,
|
|
6
44
|
});
|
|
7
|
-
await app.run();
|
|
8
45
|
//# sourceMappingURL=command-line-interface.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-line-interface.js","sourceRoot":"","sources":["../source/command-line-interface.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"command-line-interface.js","sourceRoot":"","sources":["../source/command-line-interface.tsx"],"names":[],"mappings":";AACA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,GAAG,EAAE,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,GAAG,GAAG,IAAI,CACf;;;;;;;;CAQA,EACA;IACC,UAAU,EAAE,MAAM,CAAC,IAAI;IACvB,iBAAiB,EAAE,KAAK;IACxB,KAAK,EAAE;QACN,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACxB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACzB;CACD,CACD,CAAC;AAEF,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAEnD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;AAC5B,IAAI,eAAe,CAAC;AAEpB,IAAI,CAAC;IACJ,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,CACL,oBAAC,GAAG,IAAC,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,GAAI,EAC5E;IACC,eAAe,EAAE,IAAI;IACrB,oBAAoB,EAAE,IAAI;CAC1B,CACD,CAAC"}
|