terminal-quest 1.0.2 → 1.1.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/README.md +43 -4
- package/dist/App.js +1 -1
- package/dist/data/stories/00-beginner-pc.js +70 -0
- package/dist/data/stories/01-first-server.js +77 -0
- package/dist/data/stories/02-messy-project.js +24 -0
- package/dist/data/stories/03-log-detective.js +4 -0
- package/dist/data/stories/04-deploy-day.js +4 -0
- package/dist/data/stories/05-git-incident.js +5 -0
- package/dist/data/stories/06-pipe-master.js +4 -0
- package/dist/data/stories/07-dangerous-commands.js +4 -0
- package/dist/data/stories/k1-treasure-hunt.js +181 -0
- package/dist/data/types.d.ts +14 -0
- package/dist/engine/CommandFeedback.d.ts +14 -0
- package/dist/engine/CommandFeedback.js +55 -0
- package/dist/engine/commands/grep.js +42 -17
- package/dist/engine/commands/wc.js +50 -21
- package/dist/screens/MissionBriefScreen.js +3 -3
- package/dist/screens/MissionCompleteScreen.d.ts +2 -1
- package/dist/screens/MissionCompleteScreen.js +37 -12
- package/dist/screens/TerminalScreen.d.ts +1 -1
- package/dist/screens/TerminalScreen.js +47 -7
- package/dist/state/useGameState.d.ts +1 -1
- package/dist/state/useGameState.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,12 +26,24 @@ npm install -g terminal-quest
|
|
|
26
26
|
terminal-quest
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
### 動作環境
|
|
30
|
+
|
|
31
|
+
- **macOS** / **Linux** / **Windows(WSL)**
|
|
32
|
+
- Node.js v18 以上
|
|
33
|
+
- 外部依存なし(Docker不要、GUI不要、ネットワーク不要)
|
|
34
|
+
|
|
35
|
+
純粋なnpmパッケージとして動作する**TUIアプリ**です。Ink(React for CLI)で構築されており、ターミナルさえあればどこでも動きます。
|
|
36
|
+
|
|
29
37
|
## 特徴
|
|
30
38
|
|
|
31
|
-
-
|
|
39
|
+
- **安全な仮想環境** - すべてのコマンドはインメモリの仮想ファイルシステム上で動作。実際のファイルには一切触れません
|
|
32
40
|
- **ストーリー駆動** - 物語を進めながら自然にコマンドを習得
|
|
33
|
-
- **3つのコース** -
|
|
34
|
-
-
|
|
41
|
+
- **3つのコース** - 小学生向け・はじめて・エンジニアの3コースで、レベルに合わせた学習体験
|
|
42
|
+
- **結果ベースの判定** - コマンドの文字列ではなく実行結果で目標達成を判定。`grep foo file` でも `cat file | grep foo` でも正解になります
|
|
43
|
+
- **到達目標** - 各ミッションに「何ができるようになるか」を明示
|
|
44
|
+
- **段階的ヒント** - 困ったら3段階(方向性→コマンド候補→ほぼ答え)のヒントで学習をサポート
|
|
45
|
+
- **間違いフィードバック** - タイプミスには類似コマンドを提案、間違ったコマンドにはミッション固有のガイダンスを表示
|
|
46
|
+
- **ふりかえり問題** - ミッション完了後に4択クイズで理解度チェック
|
|
35
47
|
- **Tab補完** - コマンド名やファイルパスをTabキーで補完
|
|
36
48
|
- **達成バッジ** - 学習の進捗に応じてバッジを獲得
|
|
37
49
|
|
|
@@ -88,6 +100,27 @@ objectives 現在の目標を確認
|
|
|
88
100
|
man <cmd> コマンドのマニュアル
|
|
89
101
|
```
|
|
90
102
|
|
|
103
|
+
## アーキテクチャ
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
src/
|
|
107
|
+
├── engine/ コアエンジン(UI非依存)
|
|
108
|
+
│ ├── VirtualFS インメモリ仮想ファイルシステム
|
|
109
|
+
│ ├── CommandHandler 23コマンド実装(パイプ・リダイレクト対応)
|
|
110
|
+
│ ├── MissionEngine 結果ベースの目標判定
|
|
111
|
+
│ ├── HintEngine 3段階ヒント管理
|
|
112
|
+
│ ├── CommandFeedback タイプミス検出・ミッション固有フィードバック
|
|
113
|
+
│ └── TabCompletion コマンド名・パス補完
|
|
114
|
+
├── data/stories/ ストーリーデータ(コース別、全9ストーリー)
|
|
115
|
+
├── screens/ 7画面コンポーネント(Ink/React)
|
|
116
|
+
├── components/ 再利用UIコンポーネント
|
|
117
|
+
└── state/ ゲーム状態管理(~/.terminal-quest/progress.json に永続化)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- **仮想FS上で完結** — 実際のファイルシステムやシェルは一切使用しません
|
|
121
|
+
- **結果ベースの判定** — ObjectiveCheck がコマンドの出力・FS状態を検査し、解法の自由度を確保
|
|
122
|
+
- **コース別UX** — kids コースはひらがな中心のガイダンスとエラーメッセージ、engineer コースは実務寄りの表現
|
|
123
|
+
|
|
91
124
|
## 開発
|
|
92
125
|
|
|
93
126
|
```bash
|
|
@@ -95,10 +128,16 @@ git clone https://github.com/nasuda/terminal-quest.git
|
|
|
95
128
|
cd terminal-quest
|
|
96
129
|
npm install
|
|
97
130
|
npm run dev # 開発実行
|
|
98
|
-
npm test #
|
|
131
|
+
npm test # テスト実行(183件)
|
|
99
132
|
npm run build # ビルド
|
|
100
133
|
```
|
|
101
134
|
|
|
135
|
+
### 技術スタック
|
|
136
|
+
|
|
137
|
+
- TypeScript (ESM) + [Ink 5](https://github.com/vadimdemedes/ink) (React for CLI)
|
|
138
|
+
- Vitest(テスト)
|
|
139
|
+
- npm配布(`bin/terminal-quest.js` → `dist/index.js` 直接import、tsx不要)
|
|
140
|
+
|
|
102
141
|
## ライセンス
|
|
103
142
|
|
|
104
143
|
MIT
|
package/dist/App.js
CHANGED
|
@@ -21,7 +21,7 @@ export function App() {
|
|
|
21
21
|
case 'terminal':
|
|
22
22
|
return (_jsx(TerminalScreen, { storyId: screen.storyId, missionIndex: screen.missionIndex, onNavigate: navigateTo, onMissionComplete: completeMission, onStoryComplete: completeStory, onCommandExecuted: incrementCommands }));
|
|
23
23
|
case 'missionComplete':
|
|
24
|
-
return (_jsx(MissionCompleteScreen, { storyId: screen.storyId, missionIndex: screen.missionIndex, onNavigate: navigateTo }));
|
|
24
|
+
return (_jsx(MissionCompleteScreen, { storyId: screen.storyId, missionIndex: screen.missionIndex, commandCount: screen.commandCount, onNavigate: navigateTo }));
|
|
25
25
|
case 'progress':
|
|
26
26
|
return _jsx(ProgressScreen, { progress: progress, onNavigate: navigateTo });
|
|
27
27
|
case 'settings':
|
|
@@ -449,6 +449,13 @@ export const story00 = {
|
|
|
449
449
|
id: 'mission-00-01',
|
|
450
450
|
title: 'ここはどこ?',
|
|
451
451
|
description: '新しいパソコンを開いたら、まずは今いる場所を確認して、どんなファイルがあるか見てみよう。',
|
|
452
|
+
goal: 'pwd と ls を使って、今いる場所とファイル構成を把握できるようになる',
|
|
453
|
+
review: {
|
|
454
|
+
question: '今いるフォルダの場所を表示するコマンドはどれですか?',
|
|
455
|
+
choices: ['ls', 'cd', 'pwd', 'cat'],
|
|
456
|
+
correctIndex: 2,
|
|
457
|
+
explanation: 'pwd (Print Working Directory) は、今いるフォルダのパスを画面に表示するコマンドです。',
|
|
458
|
+
},
|
|
452
459
|
narrative: 'やったー!新しいパソコンが届いた!さっそくターミナルを開いてみたけど、真っ黒な画面が出てきた。ここはどこだろう?まずは自分がどこにいるのか確認して、周りに何があるのか見てみよう。',
|
|
453
460
|
initialCwd: '/home/watashi',
|
|
454
461
|
initialFS: mission1FS,
|
|
@@ -481,6 +488,13 @@ export const story00 = {
|
|
|
481
488
|
id: 'mission-00-02',
|
|
482
489
|
title: 'フォルダの中を見て回ろう',
|
|
483
490
|
description: 'フォルダを移動して、中にあるファイルを読んでみよう。',
|
|
491
|
+
goal: 'cd でフォルダを移動し、cat でファイルの中身を読めるようになる',
|
|
492
|
+
review: {
|
|
493
|
+
question: 'フォルダを移動するコマンドはどれですか?',
|
|
494
|
+
choices: ['ls', 'cd', 'cat', 'pwd'],
|
|
495
|
+
correctIndex: 1,
|
|
496
|
+
explanation: 'cd (Change Directory) は、別のフォルダに移動するコマンドです。',
|
|
497
|
+
},
|
|
484
498
|
narrative: 'パソコンの中には「写真」「音楽」「レシピ」などのフォルダがあるみたい。フォルダの中に移動して、どんなファイルがあるか見てみよう!',
|
|
485
499
|
initialCwd: '/home/watashi',
|
|
486
500
|
initialFS: mission2FS,
|
|
@@ -523,6 +537,13 @@ export const story00 = {
|
|
|
523
537
|
id: 'mission-00-03',
|
|
524
538
|
title: '写真アルバムを作ろう',
|
|
525
539
|
description: '写真を整理するために、新しいフォルダやファイルを作ってみよう。',
|
|
540
|
+
goal: 'mkdir でフォルダを作り、touch で空のファイルを作れるようになる',
|
|
541
|
+
review: {
|
|
542
|
+
question: '新しいフォルダを作るコマンドはどれですか?',
|
|
543
|
+
choices: ['touch', 'mkdir', 'cp', 'mv'],
|
|
544
|
+
correctIndex: 1,
|
|
545
|
+
explanation: 'mkdir (Make Directory) は、新しいフォルダ(ディレクトリ)を作成するコマンドです。',
|
|
546
|
+
},
|
|
526
547
|
narrative: '写真フォルダの中がごちゃごちゃしてきた。「旅行」や「ペット」のフォルダを作って、写真を整理しよう!',
|
|
527
548
|
initialCwd: '/home/watashi/写真',
|
|
528
549
|
initialFS: mission3FS,
|
|
@@ -565,6 +586,13 @@ export const story00 = {
|
|
|
565
586
|
id: 'mission-00-04',
|
|
566
587
|
title: 'ファイルを整理しよう',
|
|
567
588
|
description: '間違った場所にあるファイルをコピーしたり、移動したりして整理しよう。',
|
|
589
|
+
goal: 'cp でファイルをコピーし、mv や rm で整理できるようになる',
|
|
590
|
+
review: {
|
|
591
|
+
question: 'ファイルをコピーするコマンドはどれですか?',
|
|
592
|
+
choices: ['mv', 'cp', 'rm', 'cat'],
|
|
593
|
+
correctIndex: 1,
|
|
594
|
+
explanation: 'cp (Copy) は、ファイルやフォルダをコピーするコマンドです。mv は移動、rm は削除です。',
|
|
595
|
+
},
|
|
568
596
|
narrative: 'あれ?「大事なメモ.txt」がホームフォルダに置きっぱなしだ。これは「メモ」フォルダに入れるべきだよね。ファイルをコピーしたり移動したりして、きちんと整理しよう。',
|
|
569
597
|
initialCwd: '/home/watashi',
|
|
570
598
|
initialFS: mission4FS,
|
|
@@ -597,6 +625,13 @@ export const story00 = {
|
|
|
597
625
|
id: 'mission-00-05',
|
|
598
626
|
title: 'いらないファイルを片付けよう',
|
|
599
627
|
description: '不要な一時ファイルを探し出して、削除しよう。',
|
|
628
|
+
goal: 'find でファイルを検索し、rm で不要ファイルを削除できるようになる',
|
|
629
|
+
review: {
|
|
630
|
+
question: 'ファイルを名前で検索するコマンドはどれですか?',
|
|
631
|
+
choices: ['grep', 'find', 'ls', 'cat'],
|
|
632
|
+
correctIndex: 1,
|
|
633
|
+
explanation: 'find は、ファイルやフォルダを名前やタイプで検索するコマンドです。grep はファイルの中身を検索します。',
|
|
634
|
+
},
|
|
600
635
|
narrative: 'パソコンの中に「.tmp」という拡張子の一時ファイルがたまっている。これは不要なファイルなので、探し出して片付けよう!',
|
|
601
636
|
initialCwd: '/home/watashi',
|
|
602
637
|
initialFS: mission5FS,
|
|
@@ -649,6 +684,13 @@ export const story00 = {
|
|
|
649
684
|
id: 'mission-00-06',
|
|
650
685
|
title: '日記を書こう',
|
|
651
686
|
description: '新しい日記を書いて、過去の日記から特定の言葉を探してみよう。',
|
|
687
|
+
goal: 'echo でファイルに書き込み、grep で特定の言葉を検索できるようになる',
|
|
688
|
+
review: {
|
|
689
|
+
question: 'ファイルの中から特定の文字列を検索するコマンドはどれですか?',
|
|
690
|
+
choices: ['find', 'cat', 'grep', 'echo'],
|
|
691
|
+
correctIndex: 2,
|
|
692
|
+
explanation: 'grep は、ファイルの中身から指定した文字列を含む行を検索するコマンドです。find はファイル名で検索します。',
|
|
693
|
+
},
|
|
652
694
|
narrative: '日記フォルダに過去の日記がある。今日の日記を書いて、それから過去の日記から気になる言葉を探してみよう!',
|
|
653
695
|
initialCwd: '/home/watashi/日記',
|
|
654
696
|
initialFS: mission6FS,
|
|
@@ -681,6 +723,13 @@ export const story00 = {
|
|
|
681
723
|
id: 'mission-00-07',
|
|
682
724
|
title: '長いレポートを確認しよう',
|
|
683
725
|
description: '長いレポートの最初と最後だけを見たり、行数を数えたりしてみよう。',
|
|
726
|
+
goal: 'head と tail でファイルの一部を確認し、wc で行数を数えられるようになる',
|
|
727
|
+
review: {
|
|
728
|
+
question: 'ファイルの最後の数行だけを表示するコマンドはどれですか?',
|
|
729
|
+
choices: ['head', 'tail', 'cat', 'wc'],
|
|
730
|
+
correctIndex: 1,
|
|
731
|
+
explanation: 'tail はファイルの末尾(最後の部分)を表示するコマンドです。head は最初の部分を表示します。',
|
|
732
|
+
},
|
|
684
733
|
narrative: '旅行のレポートが長くて全部読むのは大変。最初の部分と最後の部分だけ確認して、全体の行数も数えてみよう。',
|
|
685
734
|
initialCwd: '/home/watashi',
|
|
686
735
|
initialFS: mission7FS,
|
|
@@ -725,6 +774,13 @@ export const story00 = {
|
|
|
725
774
|
id: 'mission-00-08',
|
|
726
775
|
title: '連絡先を整理しよう',
|
|
727
776
|
description: '連絡先データを並べ替えたり、重複を取り除いたりしてみよう。',
|
|
777
|
+
goal: 'sort、uniq、cut を使ってデータを加工・整理できるようになる',
|
|
778
|
+
review: {
|
|
779
|
+
question: '重複した行を取り除くために sort と組み合わせて使うコマンドはどれですか?',
|
|
780
|
+
choices: ['grep', 'cut', 'uniq', 'wc'],
|
|
781
|
+
correctIndex: 2,
|
|
782
|
+
explanation: 'uniq は、隣接する重複行を取り除くコマンドです。sort で並べ替えてから使うのがポイントです。',
|
|
783
|
+
},
|
|
728
784
|
narrative: '連絡先のファイルがぐちゃぐちゃで、同じ人が何回も登録されている。きれいに並べ替えて、重複を取り除こう!',
|
|
729
785
|
initialCwd: '/home/watashi',
|
|
730
786
|
initialFS: mission8FS,
|
|
@@ -770,6 +826,13 @@ export const story00 = {
|
|
|
770
826
|
id: 'mission-00-09',
|
|
771
827
|
title: '共有ファイルの設定',
|
|
772
828
|
description: 'ファイルの権限を設定して、スクリプトを実行できるようにしよう。',
|
|
829
|
+
goal: 'chmod で権限を変更し、パイプでコマンドを連携できるようになる',
|
|
830
|
+
review: {
|
|
831
|
+
question: 'ファイルに実行権限を追加するコマンドはどれですか?',
|
|
832
|
+
choices: ['chown +x', 'chmod +x', 'cp +x', 'mv +x'],
|
|
833
|
+
correctIndex: 1,
|
|
834
|
+
explanation: 'chmod (Change Mode) はファイルの権限を変更するコマンドです。+x で実行権限を追加します。',
|
|
835
|
+
},
|
|
773
836
|
narrative: '共有フォルダにある集計スクリプトを実行したいけど、実行する権限がない。権限を設定して使えるようにしよう!',
|
|
774
837
|
initialCwd: '/home/watashi',
|
|
775
838
|
initialFS: mission9FS,
|
|
@@ -802,6 +865,13 @@ export const story00 = {
|
|
|
802
865
|
id: 'mission-00-10',
|
|
803
866
|
title: '変更履歴を管理しよう',
|
|
804
867
|
description: 'git を使ってレポートの変更履歴を確認してみよう。',
|
|
868
|
+
goal: 'git status と git log で変更の状態と履歴を確認できるようになる',
|
|
869
|
+
review: {
|
|
870
|
+
question: 'ファイルの変更状態を確認する git コマンドはどれですか?',
|
|
871
|
+
choices: ['git log', 'git status', 'git diff', 'git add'],
|
|
872
|
+
correctIndex: 1,
|
|
873
|
+
explanation: 'git status は、どのファイルが変更されたか、ステージされているかなどの現在の状態を表示します。',
|
|
874
|
+
},
|
|
805
875
|
narrative: 'レポートフォルダでは git を使って変更履歴を管理している。どんな変更が行われたか確認してみよう!',
|
|
806
876
|
initialCwd: '/home/watashi/レポート',
|
|
807
877
|
initialFS: mission10FS,
|
|
@@ -196,6 +196,13 @@ export const story01 = {
|
|
|
196
196
|
id: 'mission-01-01',
|
|
197
197
|
title: '現在地を確認しよう',
|
|
198
198
|
description: '基本中の基本、現在のディレクトリを確認し、ファイルの一覧を表示してみよう。',
|
|
199
|
+
goal: 'pwd と ls を使って、今いる場所とファイル構成を把握できるようになる',
|
|
200
|
+
review: {
|
|
201
|
+
question: '現在のディレクトリを表示するコマンドはどれですか?',
|
|
202
|
+
choices: ['ls', 'cd', 'pwd', 'cat'],
|
|
203
|
+
correctIndex: 2,
|
|
204
|
+
explanation: 'pwd (Print Working Directory) は現在いるディレクトリのパスを表示するコマンドです。',
|
|
205
|
+
},
|
|
199
206
|
narrative: '先輩からの引き継ぎメモには「まずは現在いるディレクトリを確認」と書いてある。ターミナルを開いたら、まず自分がどこにいるのか把握しよう。',
|
|
200
207
|
initialCwd: '/home/admin',
|
|
201
208
|
newCommands: ['pwd', 'ls'],
|
|
@@ -210,6 +217,11 @@ export const story01 = {
|
|
|
210
217
|
{ level: 2, text: '"Print Working Directory" の略で、3文字のコマンドです。' },
|
|
211
218
|
{ level: 3, text: '「pwd」と入力してEnterを押してください。' },
|
|
212
219
|
],
|
|
220
|
+
feedbacks: [
|
|
221
|
+
{ pattern: 'ls', message: 'ls はディレクトリの中身を一覧表示するコマンドです。現在の場所を確認するには、別のコマンドを使います。' },
|
|
222
|
+
{ pattern: 'cd', message: 'cd はディレクトリを移動するコマンドです。現在の場所を確認するには、別のコマンドを使います。' },
|
|
223
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。現在の場所を確認するには、別のコマンドを使います。' },
|
|
224
|
+
],
|
|
213
225
|
},
|
|
214
226
|
{
|
|
215
227
|
id: 'obj-01-01-02',
|
|
@@ -220,6 +232,11 @@ export const story01 = {
|
|
|
220
232
|
{ level: 2, text: '"List" の略で、2文字のコマンドです。' },
|
|
221
233
|
{ level: 3, text: '「ls」と入力してEnterを押してください。' },
|
|
222
234
|
],
|
|
235
|
+
feedbacks: [
|
|
236
|
+
{ pattern: 'pwd', message: 'pwd は現在のディレクトリを表示するコマンドです。ファイル一覧を表示するには、別のコマンドを使います。' },
|
|
237
|
+
{ pattern: 'cd', message: 'cd はディレクトリを移動するコマンドです。ファイル一覧を表示するには、別のコマンドを使います。' },
|
|
238
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。ファイル一覧を表示するには、別のコマンドを使います。' },
|
|
239
|
+
],
|
|
223
240
|
},
|
|
224
241
|
],
|
|
225
242
|
},
|
|
@@ -227,6 +244,13 @@ export const story01 = {
|
|
|
227
244
|
id: 'mission-01-02',
|
|
228
245
|
title: '設定ファイルを探せ',
|
|
229
246
|
description: 'サーバーの設定ファイルを見つけて内容を確認しよう。',
|
|
247
|
+
goal: 'cd でディレクトリを移動し、cat でファイル内容を確認できるようになる',
|
|
248
|
+
review: {
|
|
249
|
+
question: 'ディレクトリを移動するコマンドはどれですか?',
|
|
250
|
+
choices: ['ls', 'cd', 'cat', 'pwd'],
|
|
251
|
+
correctIndex: 1,
|
|
252
|
+
explanation: 'cd (Change Directory) はディレクトリを移動するコマンドです。',
|
|
253
|
+
},
|
|
230
254
|
narrative: 'サーバーの設定ファイルを確認する必要がある。設定ファイルは /etc に保管されている。ディレクトリを移動して、設定内容を確認しよう。',
|
|
231
255
|
initialCwd: '/home/admin',
|
|
232
256
|
newCommands: ['cd', 'cat'],
|
|
@@ -241,6 +265,11 @@ export const story01 = {
|
|
|
241
265
|
{ level: 2, text: '"Change Directory" の略のコマンドに、移動先のパスを指定します。' },
|
|
242
266
|
{ level: 3, text: '「cd /etc」と入力してEnterを押してください。' },
|
|
243
267
|
],
|
|
268
|
+
feedbacks: [
|
|
269
|
+
{ pattern: 'pwd', message: 'pwd は現在の場所を表示するコマンドです。ディレクトリを移動するには、別のコマンドを使います。' },
|
|
270
|
+
{ pattern: 'ls', message: 'ls はファイル一覧を表示するコマンドです。ディレクトリを移動するには、別のコマンドを使います。' },
|
|
271
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。ディレクトリを移動するには、別のコマンドを使います。' },
|
|
272
|
+
],
|
|
244
273
|
},
|
|
245
274
|
{
|
|
246
275
|
id: 'obj-01-02-02',
|
|
@@ -251,6 +280,11 @@ export const story01 = {
|
|
|
251
280
|
{ level: 2, text: '2文字のコマンドで、ディレクトリの中身を表示できます。' },
|
|
252
281
|
{ level: 3, text: '「ls」と入力してEnterを押してください。' },
|
|
253
282
|
],
|
|
283
|
+
feedbacks: [
|
|
284
|
+
{ pattern: 'pwd', message: 'pwd は現在の場所を表示するコマンドです。ファイル一覧を確認するには、別のコマンドを使います。' },
|
|
285
|
+
{ pattern: 'cd', message: 'cd はディレクトリ移動のコマンドです。今いる場所の中身を見るには、別のコマンドを使います。' },
|
|
286
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。ディレクトリの中身一覧を見るには、別のコマンドを使います。' },
|
|
287
|
+
],
|
|
254
288
|
},
|
|
255
289
|
{
|
|
256
290
|
id: 'obj-01-02-03',
|
|
@@ -261,6 +295,11 @@ export const story01 = {
|
|
|
261
295
|
{ level: 2, text: '猫の鳴き声に似た3文字のコマンドです。パスを指定しましょう。' },
|
|
262
296
|
{ level: 3, text: '「cat app/config.json」と入力してください。' },
|
|
263
297
|
],
|
|
298
|
+
feedbacks: [
|
|
299
|
+
{ pattern: 'pwd', message: 'pwd は現在の場所を表示するコマンドです。ファイルの内容を読むには、別のコマンドを使います。' },
|
|
300
|
+
{ pattern: 'ls', message: 'ls はファイル一覧を表示するコマンドです。ファイルの中身を読むには、別のコマンドを使います。' },
|
|
301
|
+
{ pattern: 'cd', message: 'cd はディレクトリ移動のコマンドです。ファイルの内容を読むには、別のコマンドを使います。' },
|
|
302
|
+
],
|
|
264
303
|
},
|
|
265
304
|
],
|
|
266
305
|
},
|
|
@@ -268,6 +307,13 @@ export const story01 = {
|
|
|
268
307
|
id: 'mission-01-03',
|
|
269
308
|
title: 'ログからエラーを探せ',
|
|
270
309
|
description: 'ログファイルからエラーメッセージを見つけ出そう。',
|
|
310
|
+
goal: 'grep を使ってログから特定のパターンを抽出できるようになる',
|
|
311
|
+
review: {
|
|
312
|
+
question: 'ファイルの内容を表示するコマンドはどれですか?',
|
|
313
|
+
choices: ['ls', 'pwd', 'cat', 'cd'],
|
|
314
|
+
correctIndex: 2,
|
|
315
|
+
explanation: 'cat はファイルの内容を表示するコマンドです。concatenate(連結)が語源です。',
|
|
316
|
+
},
|
|
271
317
|
narrative: 'ユーザーから「エラーが出てる」と報告が。ログファイルを調べて、何が起きているか確認しよう。',
|
|
272
318
|
initialCwd: '/home/admin',
|
|
273
319
|
newCommands: ['grep'],
|
|
@@ -285,6 +331,10 @@ export const story01 = {
|
|
|
285
331
|
{ level: 2, text: 'ログファイルは /var/log/app.log にあります。' },
|
|
286
332
|
{ level: 3, text: '「cat /var/log/app.log」と入力してください。' },
|
|
287
333
|
],
|
|
334
|
+
feedbacks: [
|
|
335
|
+
{ pattern: 'grep', message: 'grep は検索コマンドです。まずは cat でログ全体を確認しましょう。' },
|
|
336
|
+
{ pattern: 'ls', message: 'ls はファイル一覧を表示するコマンドです。ファイルの内容を読むには、別のコマンドを使います。' },
|
|
337
|
+
],
|
|
288
338
|
},
|
|
289
339
|
{
|
|
290
340
|
id: 'obj-01-03-02',
|
|
@@ -298,6 +348,10 @@ export const story01 = {
|
|
|
298
348
|
{ level: 2, text: 'grep コマンドに検索パターンとファイル名を指定します。' },
|
|
299
349
|
{ level: 3, text: '「grep ERROR /var/log/app.log」と入力してください。' },
|
|
300
350
|
],
|
|
351
|
+
feedbacks: [
|
|
352
|
+
{ pattern: 'cat', message: 'cat はファイル全体を表示します。特定の文字列を含む行だけを抽出するには、検索コマンドを使いましょう。' },
|
|
353
|
+
{ pattern: 'find', message: 'find はファイル名を検索するコマンドです。ファイルの中身を検索するには、別のコマンドを使います。' },
|
|
354
|
+
],
|
|
301
355
|
},
|
|
302
356
|
],
|
|
303
357
|
},
|
|
@@ -305,6 +359,13 @@ export const story01 = {
|
|
|
305
359
|
id: 'mission-01-04',
|
|
306
360
|
title: '設定ファイルのバックアップ',
|
|
307
361
|
description: '設定を変更する前に、安全のためバックアップを取ろう。',
|
|
362
|
+
goal: 'cp でファイルのバックアップを作成する習慣を身につける',
|
|
363
|
+
review: {
|
|
364
|
+
question: '特定の文字列を含む行を検索するコマンドはどれですか?',
|
|
365
|
+
choices: ['cat', 'find', 'grep', 'ls'],
|
|
366
|
+
correctIndex: 2,
|
|
367
|
+
explanation: 'grep はファイル内のテキストをパターンで検索するコマンドです。',
|
|
368
|
+
},
|
|
308
369
|
narrative: '設定を変更する前に、バックアップを取る習慣をつけよう。何かあったときに元に戻せるように、コピーを作成する。',
|
|
309
370
|
initialCwd: '/etc/app',
|
|
310
371
|
newCommands: ['cp'],
|
|
@@ -324,6 +385,11 @@ export const story01 = {
|
|
|
324
385
|
{ level: 2, text: 'cp コマンドで「元ファイル」「コピー先」を指定します。.bak 拡張子をつけるのが慣例です。' },
|
|
325
386
|
{ level: 3, text: '「cp config.json config.json.bak」と入力してください。' },
|
|
326
387
|
],
|
|
388
|
+
feedbacks: [
|
|
389
|
+
{ pattern: 'mv', message: 'mv はファイルを移動するコマンドです。バックアップを作るには、元のファイルを残したままコピーするコマンドを使いましょう。' },
|
|
390
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。ファイルをコピーするには、別のコマンドを使います。' },
|
|
391
|
+
{ pattern: 'echo', message: 'echo はテキストを出力するコマンドです。ファイルをそのままコピーするには、別のコマンドを使います。' },
|
|
392
|
+
],
|
|
327
393
|
},
|
|
328
394
|
],
|
|
329
395
|
},
|
|
@@ -331,6 +397,13 @@ export const story01 = {
|
|
|
331
397
|
id: 'mission-01-05',
|
|
332
398
|
title: '設定を修正せよ',
|
|
333
399
|
description: 'デバッグモードを有効にして、問題を調査しやすくしよう。',
|
|
400
|
+
goal: 'echo とリダイレクト(>)を使ってファイルを書き換えられるようになる',
|
|
401
|
+
review: {
|
|
402
|
+
question: 'ファイルをコピーするコマンドはどれですか?',
|
|
403
|
+
choices: ['mv', 'cp', 'rm', 'cat'],
|
|
404
|
+
correctIndex: 1,
|
|
405
|
+
explanation: 'cp (copy) はファイルやディレクトリをコピーするコマンドです。',
|
|
406
|
+
},
|
|
334
407
|
narrative: 'デバッグモードが無効になっている。config.json の debug を true に変更しよう。echo とリダイレクトを使ってファイルを書き換える。',
|
|
335
408
|
initialCwd: '/etc/app',
|
|
336
409
|
newCommands: ['echo'],
|
|
@@ -354,6 +427,10 @@ export const story01 = {
|
|
|
354
427
|
text: '「echo \'{"port": 3000, "debug": true}\' > config.json」と入力してください。',
|
|
355
428
|
},
|
|
356
429
|
],
|
|
430
|
+
feedbacks: [
|
|
431
|
+
{ pattern: 'cat', message: 'cat はファイルの内容を表示するコマンドです。ファイルに書き込むには、別のコマンドとリダイレクト(>)を使います。' },
|
|
432
|
+
{ pattern: 'cp', message: 'cp はファイルをコピーするコマンドです。ファイルの内容を書き換えるには、echo とリダイレクト(>)を使いましょう。' },
|
|
433
|
+
],
|
|
357
434
|
},
|
|
358
435
|
],
|
|
359
436
|
},
|
|
@@ -267,6 +267,7 @@ export const story02 = {
|
|
|
267
267
|
id: 'mission-02-01',
|
|
268
268
|
title: 'ディレクトリを作ろう',
|
|
269
269
|
description: 'mkdir コマンドでディレクトリを作成して、プロジェクト構造を整理しよう。',
|
|
270
|
+
goal: 'mkdir でプロジェクトのディレクトリ構造を設計・作成できるようになる',
|
|
270
271
|
narrative: 'プロジェクトにはソースコード、ドキュメント、テストが混在している。まずはディレクトリを整理しよう。',
|
|
271
272
|
initialCwd: '/home/dev/project',
|
|
272
273
|
newCommands: ['mkdir'],
|
|
@@ -281,6 +282,10 @@ export const story02 = {
|
|
|
281
282
|
{ level: 2, text: '"Make Directory" の略で、mkdir コマンドを使います。' },
|
|
282
283
|
{ level: 3, text: '「mkdir src」と入力してEnterを押してください。' },
|
|
283
284
|
],
|
|
285
|
+
feedbacks: [
|
|
286
|
+
{ pattern: 'touch', message: 'touch は空のファイルを作成するコマンドです。ディレクトリを作成するには、別のコマンドを使います。' },
|
|
287
|
+
{ pattern: 'cd', message: 'cd はディレクトリを移動するコマンドです。新しいディレクトリを作成するには、別のコマンドを使います。' },
|
|
288
|
+
],
|
|
284
289
|
},
|
|
285
290
|
{
|
|
286
291
|
id: 'obj-02-01-02',
|
|
@@ -308,6 +313,7 @@ export const story02 = {
|
|
|
308
313
|
id: 'mission-02-02',
|
|
309
314
|
title: 'ファイルを移動せよ',
|
|
310
315
|
description: 'mv コマンドでファイルを適切なディレクトリに移動しよう。',
|
|
316
|
+
goal: 'mv でファイルを適切な場所に移動・整理できるようになる',
|
|
311
317
|
narrative: 'ディレクトリができた。次はファイルを適切な場所に移動しよう。',
|
|
312
318
|
initialCwd: '/home/dev/project',
|
|
313
319
|
newCommands: ['mv'],
|
|
@@ -325,6 +331,10 @@ export const story02 = {
|
|
|
325
331
|
{ level: 2, text: '"Move" の略で、mv コマンドを使います。mv 元 先 の形式です。' },
|
|
326
332
|
{ level: 3, text: '「mv app.js src/」と入力してEnterを押してください。' },
|
|
327
333
|
],
|
|
334
|
+
feedbacks: [
|
|
335
|
+
{ pattern: 'cp', message: 'cp はファイルをコピーするコマンドです。元のファイルを残さず移動するには、別のコマンドを使います。' },
|
|
336
|
+
{ pattern: 'rm', message: 'rm はファイルを削除するコマンドです。ファイルを別の場所に移動するには、別のコマンドを使います。' },
|
|
337
|
+
],
|
|
328
338
|
},
|
|
329
339
|
{
|
|
330
340
|
id: 'obj-02-02-02',
|
|
@@ -352,6 +362,7 @@ export const story02 = {
|
|
|
352
362
|
id: 'mission-02-03',
|
|
353
363
|
title: '不要なファイルを削除',
|
|
354
364
|
description: '.tmp ファイルや .bak ファイルを見つけて削除しよう。',
|
|
365
|
+
goal: 'find で不要ファイルを検索し、rm で安全に削除できるようになる',
|
|
355
366
|
narrative: 'プロジェクト内に .tmp ファイルや .bak ファイルが大量にある。不要ファイルを見つけて削除しよう。',
|
|
356
367
|
initialCwd: '/home/dev/project',
|
|
357
368
|
newCommands: ['rm', 'find'],
|
|
@@ -369,6 +380,10 @@ export const story02 = {
|
|
|
369
380
|
{ level: 2, text: 'find コマンドで名前パターンを指定して検索できます。' },
|
|
370
381
|
{ level: 3, text: '「find . -name "*.tmp"」と入力してEnterを押してください。' },
|
|
371
382
|
],
|
|
383
|
+
feedbacks: [
|
|
384
|
+
{ pattern: 'ls', message: 'ls は現在のディレクトリの中身を表示するコマンドです。サブディレクトリも含めてファイルを検索するには、別のコマンドを使います。' },
|
|
385
|
+
{ pattern: 'grep', message: 'grep はファイルの中身を検索するコマンドです。ファイル名で検索するには、別のコマンドを使います。' },
|
|
386
|
+
],
|
|
372
387
|
},
|
|
373
388
|
{
|
|
374
389
|
id: 'obj-02-03-02',
|
|
@@ -379,6 +394,10 @@ export const story02 = {
|
|
|
379
394
|
{ level: 2, text: '"Remove" の略で、rm コマンドを使います。' },
|
|
380
395
|
{ level: 3, text: '「rm cache.tmp」と入力してEnterを押してください。' },
|
|
381
396
|
],
|
|
397
|
+
feedbacks: [
|
|
398
|
+
{ pattern: 'mv', message: 'mv はファイルを移動するコマンドです。ファイルを削除するには、別のコマンドを使います。' },
|
|
399
|
+
{ pattern: 'find', message: 'find はファイルを検索するコマンドです。すでに見つけたファイルを削除するには、別のコマンドを使います。' },
|
|
400
|
+
],
|
|
382
401
|
},
|
|
383
402
|
{
|
|
384
403
|
id: 'obj-02-03-03',
|
|
@@ -396,6 +415,7 @@ export const story02 = {
|
|
|
396
415
|
id: 'mission-02-04',
|
|
397
416
|
title: '新しいファイルを作成',
|
|
398
417
|
description: '新しいファイルを作成して、プロジェクトの状態を確認しよう。',
|
|
418
|
+
goal: 'touch でファイルを作成し、wc でコードの行数を確認できるようになる',
|
|
399
419
|
narrative: 'プロジェクト構造が整った。新しいファイルを作成して、プロジェクトの状態を確認しよう。',
|
|
400
420
|
initialCwd: '/home/dev/project',
|
|
401
421
|
newCommands: ['touch', 'wc'],
|
|
@@ -410,6 +430,10 @@ export const story02 = {
|
|
|
410
430
|
{ level: 2, text: 'touch コマンドでファイルを作成できます。' },
|
|
411
431
|
{ level: 3, text: '「touch CHANGELOG.md」と入力してEnterを押してください。' },
|
|
412
432
|
],
|
|
433
|
+
feedbacks: [
|
|
434
|
+
{ pattern: 'mkdir', message: 'mkdir はディレクトリを作成するコマンドです。空のファイルを作成するには、別のコマンドを使います。' },
|
|
435
|
+
{ pattern: 'echo', message: 'echo はテキストを出力するコマンドです。空のファイルを作成するだけなら、もっと簡単なコマンドがあります。' },
|
|
436
|
+
],
|
|
413
437
|
},
|
|
414
438
|
{
|
|
415
439
|
id: 'obj-02-04-02',
|
|
@@ -167,6 +167,7 @@ export const story03 = {
|
|
|
167
167
|
id: 'mission-03-01',
|
|
168
168
|
title: 'ログファイルの調査',
|
|
169
169
|
description: 'head と tail コマンドでログファイルの最初と最後を確認しよう。',
|
|
170
|
+
goal: 'head と tail で大きなログファイルの概要を素早く把握できるようになる',
|
|
170
171
|
narrative: '大量のログがある。まずはファイルの最初と最後を確認しよう。',
|
|
171
172
|
initialCwd: '/var/log',
|
|
172
173
|
newCommands: ['head', 'tail'],
|
|
@@ -201,6 +202,7 @@ export const story03 = {
|
|
|
201
202
|
id: 'mission-03-02',
|
|
202
203
|
title: 'エラーの分析',
|
|
203
204
|
description: 'grep と wc コマンドで 500 エラーの件数を数えよう。',
|
|
205
|
+
goal: 'grep でエラーを抽出し、パイプで wc -l に渡して件数を数えられるようになる',
|
|
204
206
|
narrative: '500エラーが出ている。何件あるか数えよう。',
|
|
205
207
|
initialCwd: '/var/log',
|
|
206
208
|
initialFS: mission2FS,
|
|
@@ -234,6 +236,7 @@ export const story03 = {
|
|
|
234
236
|
id: 'mission-03-03',
|
|
235
237
|
title: 'アクセスパターンの分析',
|
|
236
238
|
description: 'sort と uniq コマンドでIPアドレスのアクセス頻度を調べよう。',
|
|
239
|
+
goal: 'sort | uniq -c でデータの出現頻度を集計できるようになる',
|
|
237
240
|
narrative: 'どのIPアドレスからアクセスが多いか調べよう。',
|
|
238
241
|
initialCwd: '/var/log',
|
|
239
242
|
newCommands: ['sort', 'uniq'],
|
|
@@ -265,6 +268,7 @@ export const story03 = {
|
|
|
265
268
|
id: 'mission-03-04',
|
|
266
269
|
title: 'レポート作成',
|
|
267
270
|
description: 'grep とリダイレクトを使って、調査結果をファイルに保存しよう。',
|
|
271
|
+
goal: 'コマンドの出力をリダイレクト(>)でファイルに保存できるようになる',
|
|
268
272
|
narrative: '調査結果をレポートファイルにまとめよう。',
|
|
269
273
|
initialCwd: '/var/log',
|
|
270
274
|
initialFS: mission4FS,
|
|
@@ -223,6 +223,7 @@ export const story04 = {
|
|
|
223
223
|
id: 'mission-04-01',
|
|
224
224
|
title: 'デプロイ先の準備',
|
|
225
225
|
description: 'mkdir -p と cp -r でデプロイ先を準備しよう。',
|
|
226
|
+
goal: 'mkdir -p と cp -r で本番環境のディレクトリ構成を構築できるようになる',
|
|
226
227
|
narrative: 'デプロイ先のディレクトリを作成して、ソースをコピーしよう。',
|
|
227
228
|
initialCwd: '/home/deploy',
|
|
228
229
|
initialFS: mission1FS,
|
|
@@ -253,6 +254,7 @@ export const story04 = {
|
|
|
253
254
|
id: 'mission-04-02',
|
|
254
255
|
title: '権限の設定',
|
|
255
256
|
description: 'chmod コマンドでファイルの実行権限を設定しよう。',
|
|
257
|
+
goal: 'chmod でスクリプトに実行権限を付与できるようになる',
|
|
256
258
|
narrative: 'デプロイしたファイルの実行権限を設定しよう。',
|
|
257
259
|
initialCwd: '/var/www/app',
|
|
258
260
|
newCommands: ['chmod'],
|
|
@@ -274,6 +276,7 @@ export const story04 = {
|
|
|
274
276
|
id: 'mission-04-03',
|
|
275
277
|
title: 'バックアップ作成',
|
|
276
278
|
description: '古いバックアップを削除して、新しいバックアップを作ろう。',
|
|
279
|
+
goal: 'rm -rf で古いディレクトリを削除し、cp -r で新しいバックアップを作れるようになる',
|
|
277
280
|
narrative: '古いバックアップを削除して、新しいバックアップを作ろう。',
|
|
278
281
|
initialCwd: '/var/www',
|
|
279
282
|
initialFS: mission3FS,
|
|
@@ -304,6 +307,7 @@ export const story04 = {
|
|
|
304
307
|
id: 'mission-04-04',
|
|
305
308
|
title: '最終確認',
|
|
306
309
|
description: 'デプロイが完了したか最終確認しよう。',
|
|
310
|
+
goal: 'find と cat でデプロイ結果を検証できるようになる',
|
|
307
311
|
narrative: 'デプロイが完了した。最終確認をしよう。',
|
|
308
312
|
initialCwd: '/var/www/app',
|
|
309
313
|
initialFS: mission4FS,
|
|
@@ -379,6 +379,7 @@ export const story05 = {
|
|
|
379
379
|
id: 'mission-05-01',
|
|
380
380
|
title: '状況確認',
|
|
381
381
|
description: 'git status と git log で現在のリポジトリの状態を把握しよう。',
|
|
382
|
+
goal: 'git status と git log でリポジトリの状態と履歴を把握できるようになる',
|
|
382
383
|
narrative: '先輩が「リポジトリがおかしい」と焦っている。まずは状況を確認しよう。',
|
|
383
384
|
initialCwd: '/home/dev/repo',
|
|
384
385
|
newCommands: ['git'],
|
|
@@ -416,6 +417,7 @@ export const story05 = {
|
|
|
416
417
|
id: 'mission-05-02',
|
|
417
418
|
title: '変更の退避',
|
|
418
419
|
description: 'git stash で作業中の変更を一旦退避しよう。',
|
|
420
|
+
goal: 'git stash で作業中の変更を安全に退避できるようになる',
|
|
419
421
|
narrative: '作業中の変更を一旦退避して、安全な状態に戻そう。',
|
|
420
422
|
initialCwd: '/home/dev/repo',
|
|
421
423
|
initialFS: mission2FS,
|
|
@@ -439,6 +441,7 @@ export const story05 = {
|
|
|
439
441
|
id: 'mission-05-03',
|
|
440
442
|
title: 'ブランチ操作',
|
|
441
443
|
description: 'git branch と git checkout でブランチを操作しよう。',
|
|
444
|
+
goal: 'git branch でブランチ確認、git checkout -b で新しいブランチを作れるようになる',
|
|
442
445
|
narrative: '修正用のブランチを作って切り替えよう。',
|
|
443
446
|
initialCwd: '/home/dev/repo',
|
|
444
447
|
initialFS: mission3FS,
|
|
@@ -475,6 +478,7 @@ export const story05 = {
|
|
|
475
478
|
id: 'mission-05-04',
|
|
476
479
|
title: '変更の確認',
|
|
477
480
|
description: 'git diff で変更内容を確認して問題箇所を特定しよう。',
|
|
481
|
+
goal: 'git diff でコードの変更差分を確認し問題を特定できるようになる',
|
|
478
482
|
narrative: '変更内容を確認して、問題の箇所を特定しよう。',
|
|
479
483
|
initialCwd: '/home/dev/repo',
|
|
480
484
|
initialFS: mission4FS,
|
|
@@ -498,6 +502,7 @@ export const story05 = {
|
|
|
498
502
|
id: 'mission-05-05',
|
|
499
503
|
title: 'マージ',
|
|
500
504
|
description: '修正をメインブランチに統合しよう。',
|
|
505
|
+
goal: 'git checkout と git merge でブランチを統合できるようになる',
|
|
501
506
|
narrative: '修正が完了した。メインブランチに統合しよう。',
|
|
502
507
|
initialCwd: '/home/dev/repo',
|
|
503
508
|
initialFS: mission5FS,
|
|
@@ -224,6 +224,7 @@ export const story06 = {
|
|
|
224
224
|
id: 'mission-06-01',
|
|
225
225
|
title: 'パイプ入門',
|
|
226
226
|
description: 'パイプ(|)を使ってコマンドの出力を次のコマンドに渡そう。',
|
|
227
|
+
goal: 'パイプ(|)でコマンドの出力を別のコマンドに渡せるようになる',
|
|
227
228
|
narrative: 'パイプ(|)を使うと、コマンドの出力を次のコマンドの入力にできる。',
|
|
228
229
|
initialCwd: '/home/data',
|
|
229
230
|
initialFS: mission1FS,
|
|
@@ -257,6 +258,7 @@ export const story06 = {
|
|
|
257
258
|
id: 'mission-06-02',
|
|
258
259
|
title: 'データ加工',
|
|
259
260
|
description: 'sort と uniq、grep と wc をパイプで組み合わせてデータを分析しよう。',
|
|
261
|
+
goal: 'パイプで複数コマンドを連携させてデータ集計・分析ができるようになる',
|
|
260
262
|
narrative: 'データの集計と分析にパイプを活用しよう。',
|
|
261
263
|
initialCwd: '/home/data',
|
|
262
264
|
initialFS: mission2FS,
|
|
@@ -290,6 +292,7 @@ export const story06 = {
|
|
|
290
292
|
id: 'mission-06-03',
|
|
291
293
|
title: 'フィールド抽出',
|
|
292
294
|
description: 'cut コマンドでCSVから特定のフィールドを抽出しよう。',
|
|
295
|
+
goal: 'cut でCSVの特定列を抽出し、sort でフィールド指定ソートができるようになる',
|
|
293
296
|
narrative: 'CSVデータから特定のフィールドを抽出して分析しよう。',
|
|
294
297
|
initialCwd: '/home/data',
|
|
295
298
|
newCommands: ['cut'],
|
|
@@ -324,6 +327,7 @@ export const story06 = {
|
|
|
324
327
|
id: 'mission-06-04',
|
|
325
328
|
title: '総合演習',
|
|
326
329
|
description: '複数のコマンドをパイプで繋いで、データを抽出してファイルに保存しよう。',
|
|
330
|
+
goal: '6段パイプで抽出・加工・集計・ソートを一括実行できるようになる',
|
|
327
331
|
narrative: '最終課題。複数のコマンドをパイプで繋いで、データから必要な情報を抽出し、ファイルに保存しよう。',
|
|
328
332
|
initialCwd: '/home/data',
|
|
329
333
|
initialFS: mission4FS,
|