terminal-quest 1.0.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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/bin/terminal-quest.js +2 -0
  3. package/dist/App.d.ts +2 -0
  4. package/dist/App.js +33 -0
  5. package/dist/components/HintBar.d.ts +9 -0
  6. package/dist/components/HintBar.js +11 -0
  7. package/dist/components/MenuItem.d.ts +9 -0
  8. package/dist/components/MenuItem.js +9 -0
  9. package/dist/components/ObjectivePanel.d.ts +8 -0
  10. package/dist/components/ObjectivePanel.js +10 -0
  11. package/dist/components/ProgressBar.d.ts +8 -0
  12. package/dist/components/ProgressBar.js +10 -0
  13. package/dist/components/TerminalOutput.d.ts +11 -0
  14. package/dist/components/TerminalOutput.js +25 -0
  15. package/dist/components/TerminalPrompt.d.ts +10 -0
  16. package/dist/components/TerminalPrompt.js +46 -0
  17. package/dist/data/commands-meta.d.ts +17 -0
  18. package/dist/data/commands-meta.js +256 -0
  19. package/dist/data/stories/00-beginner-pc.d.ts +3 -0
  20. package/dist/data/stories/00-beginner-pc.js +841 -0
  21. package/dist/data/stories/01-first-server.d.ts +3 -0
  22. package/dist/data/stories/01-first-server.js +364 -0
  23. package/dist/data/stories/02-messy-project.d.ts +3 -0
  24. package/dist/data/stories/02-messy-project.js +433 -0
  25. package/dist/data/stories/03-log-detective.d.ts +3 -0
  26. package/dist/data/stories/03-log-detective.js +291 -0
  27. package/dist/data/stories/04-deploy-day.d.ts +3 -0
  28. package/dist/data/stories/04-deploy-day.js +337 -0
  29. package/dist/data/stories/05-git-incident.d.ts +3 -0
  30. package/dist/data/stories/05-git-incident.js +534 -0
  31. package/dist/data/stories/06-pipe-master.d.ts +3 -0
  32. package/dist/data/stories/06-pipe-master.js +377 -0
  33. package/dist/data/stories/07-dangerous-commands.d.ts +3 -0
  34. package/dist/data/stories/07-dangerous-commands.js +411 -0
  35. package/dist/data/stories/index.d.ts +4 -0
  36. package/dist/data/stories/index.js +14 -0
  37. package/dist/data/stories/k1-treasure-hunt.d.ts +3 -0
  38. package/dist/data/stories/k1-treasure-hunt.js +815 -0
  39. package/dist/data/types.d.ts +97 -0
  40. package/dist/data/types.js +2 -0
  41. package/dist/engine/Achievements.d.ts +5 -0
  42. package/dist/engine/Achievements.js +93 -0
  43. package/dist/engine/CommandHandler.d.ts +17 -0
  44. package/dist/engine/CommandHandler.js +177 -0
  45. package/dist/engine/HintEngine.d.ts +10 -0
  46. package/dist/engine/HintEngine.js +26 -0
  47. package/dist/engine/MissionEngine.d.ts +17 -0
  48. package/dist/engine/MissionEngine.js +84 -0
  49. package/dist/engine/TabCompletion.d.ts +14 -0
  50. package/dist/engine/TabCompletion.js +93 -0
  51. package/dist/engine/VirtualFS.d.ts +33 -0
  52. package/dist/engine/VirtualFS.js +276 -0
  53. package/dist/engine/commands/cat.d.ts +4 -0
  54. package/dist/engine/commands/cat.js +18 -0
  55. package/dist/engine/commands/cd.d.ts +4 -0
  56. package/dist/engine/commands/cd.js +12 -0
  57. package/dist/engine/commands/chmod.d.ts +4 -0
  58. package/dist/engine/commands/chmod.js +98 -0
  59. package/dist/engine/commands/clear.d.ts +4 -0
  60. package/dist/engine/commands/clear.js +4 -0
  61. package/dist/engine/commands/cp.d.ts +4 -0
  62. package/dist/engine/commands/cp.js +26 -0
  63. package/dist/engine/commands/cut.d.ts +4 -0
  64. package/dist/engine/commands/cut.js +76 -0
  65. package/dist/engine/commands/echo.d.ts +4 -0
  66. package/dist/engine/commands/echo.js +4 -0
  67. package/dist/engine/commands/find.d.ts +4 -0
  68. package/dist/engine/commands/find.js +60 -0
  69. package/dist/engine/commands/git.d.ts +4 -0
  70. package/dist/engine/commands/git.js +510 -0
  71. package/dist/engine/commands/grep.d.ts +4 -0
  72. package/dist/engine/commands/grep.js +127 -0
  73. package/dist/engine/commands/head.d.ts +4 -0
  74. package/dist/engine/commands/head.js +59 -0
  75. package/dist/engine/commands/help.d.ts +4 -0
  76. package/dist/engine/commands/help.js +32 -0
  77. package/dist/engine/commands/hint.d.ts +4 -0
  78. package/dist/engine/commands/hint.js +4 -0
  79. package/dist/engine/commands/index.d.ts +8 -0
  80. package/dist/engine/commands/index.js +51 -0
  81. package/dist/engine/commands/ls.d.ts +4 -0
  82. package/dist/engine/commands/ls.js +50 -0
  83. package/dist/engine/commands/man.d.ts +4 -0
  84. package/dist/engine/commands/man.js +51 -0
  85. package/dist/engine/commands/mkdir.d.ts +4 -0
  86. package/dist/engine/commands/mkdir.js +31 -0
  87. package/dist/engine/commands/mv.d.ts +4 -0
  88. package/dist/engine/commands/mv.js +15 -0
  89. package/dist/engine/commands/pwd.d.ts +4 -0
  90. package/dist/engine/commands/pwd.js +4 -0
  91. package/dist/engine/commands/rm.d.ts +4 -0
  92. package/dist/engine/commands/rm.js +49 -0
  93. package/dist/engine/commands/sort.d.ts +4 -0
  94. package/dist/engine/commands/sort.js +100 -0
  95. package/dist/engine/commands/tail.d.ts +4 -0
  96. package/dist/engine/commands/tail.js +59 -0
  97. package/dist/engine/commands/touch.d.ts +4 -0
  98. package/dist/engine/commands/touch.js +18 -0
  99. package/dist/engine/commands/uniq.d.ts +4 -0
  100. package/dist/engine/commands/uniq.js +61 -0
  101. package/dist/engine/commands/wc.d.ts +4 -0
  102. package/dist/engine/commands/wc.js +67 -0
  103. package/dist/index.d.ts +3 -0
  104. package/dist/index.js +6 -0
  105. package/dist/screens/MissionBriefScreen.d.ts +9 -0
  106. package/dist/screens/MissionBriefScreen.js +27 -0
  107. package/dist/screens/MissionCompleteScreen.d.ts +9 -0
  108. package/dist/screens/MissionCompleteScreen.js +30 -0
  109. package/dist/screens/ProgressScreen.d.ts +8 -0
  110. package/dist/screens/ProgressScreen.js +24 -0
  111. package/dist/screens/SettingsScreen.d.ts +8 -0
  112. package/dist/screens/SettingsScreen.js +45 -0
  113. package/dist/screens/StorySelectScreen.d.ts +8 -0
  114. package/dist/screens/StorySelectScreen.js +81 -0
  115. package/dist/screens/TerminalScreen.d.ts +12 -0
  116. package/dist/screens/TerminalScreen.js +150 -0
  117. package/dist/screens/TitleScreen.d.ts +7 -0
  118. package/dist/screens/TitleScreen.js +27 -0
  119. package/dist/state/GameState.d.ts +8 -0
  120. package/dist/state/GameState.js +12 -0
  121. package/dist/state/ProgressStore.d.ts +9 -0
  122. package/dist/state/ProgressStore.js +45 -0
  123. package/dist/state/useGameState.d.ts +11 -0
  124. package/dist/state/useGameState.js +92 -0
  125. package/dist/utils/ascii-art.d.ts +4 -0
  126. package/dist/utils/ascii-art.js +22 -0
  127. package/dist/utils/colors.d.ts +17 -0
  128. package/dist/utils/colors.js +17 -0
  129. package/dist/utils/text.d.ts +4 -0
  130. package/dist/utils/text.js +28 -0
  131. package/package.json +58 -0
@@ -0,0 +1,433 @@
1
+ const mission1FS = {
2
+ type: 'directory',
3
+ children: {
4
+ home: {
5
+ type: 'directory',
6
+ children: {
7
+ dev: {
8
+ type: 'directory',
9
+ children: {
10
+ project: {
11
+ type: 'directory',
12
+ children: {
13
+ 'app.js': {
14
+ type: 'file',
15
+ content: 'const express = require("express");\nconst app = express();\napp.listen(3000);\n',
16
+ },
17
+ 'readme.md': {
18
+ type: 'file',
19
+ content: '# My Project\n\nThis is a sample project.\n',
20
+ },
21
+ 'test.js': {
22
+ type: 'file',
23
+ content: 'const assert = require("assert");\nassert.ok(true);\nconsole.log("tests passed");\n',
24
+ },
25
+ 'style.css': {
26
+ type: 'file',
27
+ content: 'body { margin: 0; padding: 0; }\nh1 { color: #333; }\n',
28
+ },
29
+ 'data.json': {
30
+ type: 'file',
31
+ content: '{"name": "my-project", "version": "1.0.0"}\n',
32
+ },
33
+ },
34
+ },
35
+ },
36
+ },
37
+ },
38
+ },
39
+ },
40
+ };
41
+ const mission2FS = {
42
+ type: 'directory',
43
+ children: {
44
+ home: {
45
+ type: 'directory',
46
+ children: {
47
+ dev: {
48
+ type: 'directory',
49
+ children: {
50
+ project: {
51
+ type: 'directory',
52
+ children: {
53
+ 'app.js': {
54
+ type: 'file',
55
+ content: 'const express = require("express");\nconst app = express();\napp.listen(3000);\n',
56
+ },
57
+ 'style.css': {
58
+ type: 'file',
59
+ content: 'body { margin: 0; padding: 0; }\nh1 { color: #333; }\n',
60
+ },
61
+ 'readme.md': {
62
+ type: 'file',
63
+ content: '# My Project\n\nThis is a sample project.\n',
64
+ },
65
+ 'test.js': {
66
+ type: 'file',
67
+ content: 'const assert = require("assert");\nassert.ok(true);\nconsole.log("tests passed");\n',
68
+ },
69
+ src: {
70
+ type: 'directory',
71
+ children: {},
72
+ },
73
+ docs: {
74
+ type: 'directory',
75
+ children: {},
76
+ },
77
+ tests: {
78
+ type: 'directory',
79
+ children: {},
80
+ },
81
+ },
82
+ },
83
+ },
84
+ },
85
+ },
86
+ },
87
+ },
88
+ };
89
+ const mission3FS = {
90
+ type: 'directory',
91
+ children: {
92
+ home: {
93
+ type: 'directory',
94
+ children: {
95
+ dev: {
96
+ type: 'directory',
97
+ children: {
98
+ project: {
99
+ type: 'directory',
100
+ children: {
101
+ src: {
102
+ type: 'directory',
103
+ children: {
104
+ 'app.js': {
105
+ type: 'file',
106
+ content: 'const express = require("express");\nconst app = express();\napp.listen(3000);\n',
107
+ },
108
+ 'old.tmp': {
109
+ type: 'file',
110
+ content: 'temporary file - safe to delete\n',
111
+ },
112
+ },
113
+ },
114
+ docs: {
115
+ type: 'directory',
116
+ children: {
117
+ 'readme.md': {
118
+ type: 'file',
119
+ content: '# My Project\n\nThis is a sample project.\n',
120
+ },
121
+ 'backup.bak': {
122
+ type: 'file',
123
+ content: 'old backup data\n',
124
+ },
125
+ },
126
+ },
127
+ tests: {
128
+ type: 'directory',
129
+ children: {
130
+ 'test.js': {
131
+ type: 'file',
132
+ content: 'const assert = require("assert");\nassert.ok(true);\nconsole.log("tests passed");\n',
133
+ },
134
+ },
135
+ },
136
+ 'cache.tmp': {
137
+ type: 'file',
138
+ content: 'cached data - safe to delete\n',
139
+ },
140
+ },
141
+ },
142
+ },
143
+ },
144
+ },
145
+ },
146
+ },
147
+ };
148
+ const appJsContent = [
149
+ 'const express = require("express");',
150
+ 'const app = express();',
151
+ '',
152
+ 'app.get("/", (req, res) => {',
153
+ ' res.send("Hello World");',
154
+ '});',
155
+ '',
156
+ 'app.get("/api/users", (req, res) => {',
157
+ ' res.json([]);',
158
+ '});',
159
+ '',
160
+ 'app.get("/api/status", (req, res) => {',
161
+ ' res.json({ status: "ok" });',
162
+ '});',
163
+ '',
164
+ 'app.post("/api/data", (req, res) => {',
165
+ ' res.json({ success: true });',
166
+ '});',
167
+ '',
168
+ 'app.use((err, req, res, next) => {',
169
+ ' console.error(err.stack);',
170
+ ' res.status(500).send("Server Error");',
171
+ '});',
172
+ '',
173
+ 'const PORT = process.env.PORT || 3000;',
174
+ 'app.listen(PORT, () => {',
175
+ ' console.log(`Server running on port ${PORT}`);',
176
+ '});',
177
+ '',
178
+ '// End of file',
179
+ ].join('\n');
180
+ const readmeContent = [
181
+ '# My Project',
182
+ '',
183
+ '## Overview',
184
+ 'A sample web application.',
185
+ '',
186
+ '## Installation',
187
+ 'npm install',
188
+ '',
189
+ '## Usage',
190
+ 'npm start',
191
+ ].join('\n');
192
+ const testJsContent = [
193
+ 'const assert = require("assert");',
194
+ '',
195
+ 'describe("App", () => {',
196
+ ' it("should return 200", () => {',
197
+ ' assert.ok(true);',
198
+ ' });',
199
+ '',
200
+ ' it("should return users", () => {',
201
+ ' assert.deepEqual([], []);',
202
+ ' });',
203
+ '',
204
+ ' it("should return status", () => {',
205
+ ' assert.equal("ok", "ok");',
206
+ ' });',
207
+ '',
208
+ ' it("should handle errors", () => {',
209
+ ' assert.ok(true);',
210
+ ' });',
211
+ '});',
212
+ ].join('\n');
213
+ const mission4FS = {
214
+ type: 'directory',
215
+ children: {
216
+ home: {
217
+ type: 'directory',
218
+ children: {
219
+ dev: {
220
+ type: 'directory',
221
+ children: {
222
+ project: {
223
+ type: 'directory',
224
+ children: {
225
+ src: {
226
+ type: 'directory',
227
+ children: {
228
+ 'app.js': {
229
+ type: 'file',
230
+ content: appJsContent,
231
+ },
232
+ },
233
+ },
234
+ docs: {
235
+ type: 'directory',
236
+ children: {
237
+ 'readme.md': {
238
+ type: 'file',
239
+ content: readmeContent,
240
+ },
241
+ },
242
+ },
243
+ tests: {
244
+ type: 'directory',
245
+ children: {
246
+ 'test.js': {
247
+ type: 'file',
248
+ content: testJsContent,
249
+ },
250
+ },
251
+ },
252
+ },
253
+ },
254
+ },
255
+ },
256
+ },
257
+ },
258
+ },
259
+ };
260
+ export const story02 = {
261
+ id: 'story-02',
262
+ title: '散らかったプロジェクト',
263
+ description: 'プロジェクトのディレクトリがぐちゃぐちゃ。整理整頓してプロジェクト構造を立て直そう。',
264
+ emoji: '\u{1F4C1}',
265
+ missions: [
266
+ {
267
+ id: 'mission-02-01',
268
+ title: 'ディレクトリを作ろう',
269
+ description: 'mkdir コマンドでディレクトリを作成して、プロジェクト構造を整理しよう。',
270
+ narrative: 'プロジェクトにはソースコード、ドキュメント、テストが混在している。まずはディレクトリを整理しよう。',
271
+ initialCwd: '/home/dev/project',
272
+ newCommands: ['mkdir'],
273
+ initialFS: mission1FS,
274
+ objectives: [
275
+ {
276
+ id: 'obj-02-01-01',
277
+ description: 'src ディレクトリを作成する',
278
+ checks: [{ type: 'file_exists', path: '/home/dev/project/src' }],
279
+ hints: [
280
+ { level: 1, text: 'ディレクトリを作成するコマンドがあります。' },
281
+ { level: 2, text: '"Make Directory" の略で、mkdir コマンドを使います。' },
282
+ { level: 3, text: '「mkdir src」と入力してEnterを押してください。' },
283
+ ],
284
+ },
285
+ {
286
+ id: 'obj-02-01-02',
287
+ description: 'docs ディレクトリを作成する',
288
+ checks: [{ type: 'file_exists', path: '/home/dev/project/docs' }],
289
+ hints: [
290
+ { level: 1, text: '同じコマンドでもう1つディレクトリを作りましょう。' },
291
+ { level: 2, text: 'mkdir コマンドに別の名前を指定します。' },
292
+ { level: 3, text: '「mkdir docs」と入力してEnterを押してください。' },
293
+ ],
294
+ },
295
+ {
296
+ id: 'obj-02-01-03',
297
+ description: 'tests ディレクトリを作成する',
298
+ checks: [{ type: 'file_exists', path: '/home/dev/project/tests' }],
299
+ hints: [
300
+ { level: 1, text: 'テスト用のディレクトリも同様に作りましょう。' },
301
+ { level: 2, text: 'mkdir コマンドを使って tests という名前で作成します。' },
302
+ { level: 3, text: '「mkdir tests」と入力してEnterを押してください。' },
303
+ ],
304
+ },
305
+ ],
306
+ },
307
+ {
308
+ id: 'mission-02-02',
309
+ title: 'ファイルを移動せよ',
310
+ description: 'mv コマンドでファイルを適切なディレクトリに移動しよう。',
311
+ narrative: 'ディレクトリができた。次はファイルを適切な場所に移動しよう。',
312
+ initialCwd: '/home/dev/project',
313
+ newCommands: ['mv'],
314
+ initialFS: mission2FS,
315
+ objectives: [
316
+ {
317
+ id: 'obj-02-02-01',
318
+ description: 'app.js を src/ ディレクトリに移動する',
319
+ checks: [
320
+ { type: 'file_exists', path: '/home/dev/project/src/app.js' },
321
+ { type: 'file_not_exists', path: '/home/dev/project/app.js' },
322
+ ],
323
+ hints: [
324
+ { level: 1, text: 'ファイルを移動するコマンドがあります。' },
325
+ { level: 2, text: '"Move" の略で、mv コマンドを使います。mv 元 先 の形式です。' },
326
+ { level: 3, text: '「mv app.js src/」と入力してEnterを押してください。' },
327
+ ],
328
+ },
329
+ {
330
+ id: 'obj-02-02-02',
331
+ description: 'readme.md を docs/ ディレクトリに移動する',
332
+ checks: [{ type: 'file_exists', path: '/home/dev/project/docs/readme.md' }],
333
+ hints: [
334
+ { level: 1, text: 'ドキュメントファイルも適切な場所に移動しましょう。' },
335
+ { level: 2, text: 'mv コマンドで readme.md を docs/ に移動します。' },
336
+ { level: 3, text: '「mv readme.md docs/」と入力してEnterを押してください。' },
337
+ ],
338
+ },
339
+ {
340
+ id: 'obj-02-02-03',
341
+ description: 'test.js を tests/ ディレクトリに移動する',
342
+ checks: [{ type: 'file_exists', path: '/home/dev/project/tests/test.js' }],
343
+ hints: [
344
+ { level: 1, text: 'テストファイルも適切な場所に移動しましょう。' },
345
+ { level: 2, text: 'mv コマンドで test.js を tests/ に移動します。' },
346
+ { level: 3, text: '「mv test.js tests/」と入力してEnterを押してください。' },
347
+ ],
348
+ },
349
+ ],
350
+ },
351
+ {
352
+ id: 'mission-02-03',
353
+ title: '不要なファイルを削除',
354
+ description: '.tmp ファイルや .bak ファイルを見つけて削除しよう。',
355
+ narrative: 'プロジェクト内に .tmp ファイルや .bak ファイルが大量にある。不要ファイルを見つけて削除しよう。',
356
+ initialCwd: '/home/dev/project',
357
+ newCommands: ['rm', 'find'],
358
+ initialFS: mission3FS,
359
+ objectives: [
360
+ {
361
+ id: 'obj-02-03-01',
362
+ description: '.tmp ファイルを見つける',
363
+ checks: [
364
+ { type: 'command_executed', command: 'find' },
365
+ { type: 'output_contains', pattern: '.tmp' },
366
+ ],
367
+ hints: [
368
+ { level: 1, text: 'ファイルを検索するコマンドがあります。' },
369
+ { level: 2, text: 'find コマンドで名前パターンを指定して検索できます。' },
370
+ { level: 3, text: '「find . -name "*.tmp"」と入力してEnterを押してください。' },
371
+ ],
372
+ },
373
+ {
374
+ id: 'obj-02-03-02',
375
+ description: 'cache.tmp を削除する',
376
+ checks: [{ type: 'file_not_exists', path: '/home/dev/project/cache.tmp' }],
377
+ hints: [
378
+ { level: 1, text: 'ファイルを削除するコマンドがあります。' },
379
+ { level: 2, text: '"Remove" の略で、rm コマンドを使います。' },
380
+ { level: 3, text: '「rm cache.tmp」と入力してEnterを押してください。' },
381
+ ],
382
+ },
383
+ {
384
+ id: 'obj-02-03-03',
385
+ description: 'src/old.tmp を削除する',
386
+ checks: [{ type: 'file_not_exists', path: '/home/dev/project/src/old.tmp' }],
387
+ hints: [
388
+ { level: 1, text: 'サブディレクトリ内のファイルも削除しましょう。' },
389
+ { level: 2, text: 'rm コマンドにパスを指定します。' },
390
+ { level: 3, text: '「rm src/old.tmp」と入力してEnterを押してください。' },
391
+ ],
392
+ },
393
+ ],
394
+ },
395
+ {
396
+ id: 'mission-02-04',
397
+ title: '新しいファイルを作成',
398
+ description: '新しいファイルを作成して、プロジェクトの状態を確認しよう。',
399
+ narrative: 'プロジェクト構造が整った。新しいファイルを作成して、プロジェクトの状態を確認しよう。',
400
+ initialCwd: '/home/dev/project',
401
+ newCommands: ['touch', 'wc'],
402
+ initialFS: mission4FS,
403
+ objectives: [
404
+ {
405
+ id: 'obj-02-04-01',
406
+ description: 'CHANGELOG.md を作成する',
407
+ checks: [{ type: 'file_exists', path: '/home/dev/project/CHANGELOG.md' }],
408
+ hints: [
409
+ { level: 1, text: '空のファイルを作成するコマンドがあります。' },
410
+ { level: 2, text: 'touch コマンドでファイルを作成できます。' },
411
+ { level: 3, text: '「touch CHANGELOG.md」と入力してEnterを押してください。' },
412
+ ],
413
+ },
414
+ {
415
+ id: 'obj-02-04-02',
416
+ description: 'app.js の行数を確認する',
417
+ checks: [
418
+ { type: 'command_executed', command: 'wc' },
419
+ { type: 'output_contains', pattern: '30' },
420
+ ],
421
+ hints: [
422
+ { level: 1, text: 'ファイルの行数を数えるコマンドがあります。' },
423
+ { level: 2, text: '"Word Count" の略の wc コマンドに -l オプションをつけると行数を表示します。' },
424
+ { level: 3, text: '「wc -l src/app.js」と入力してEnterを押してください。' },
425
+ ],
426
+ },
427
+ ],
428
+ },
429
+ ],
430
+ unlockRequires: ['story-01'],
431
+ course: 'engineer',
432
+ };
433
+ //# sourceMappingURL=02-messy-project.js.map
@@ -0,0 +1,3 @@
1
+ import type { Story } from '../types.js';
2
+ export declare const story03: Story;
3
+ //# sourceMappingURL=03-log-detective.d.ts.map