lemming-cli 0.1.0__py3-none-any.whl

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 (94) hide show
  1. lemming/__init__.py +1 -0
  2. lemming/api/__init__.py +5 -0
  3. lemming/api/auth.py +34 -0
  4. lemming/api/auth_test.py +40 -0
  5. lemming/api/config.py +85 -0
  6. lemming/api/config_test.py +84 -0
  7. lemming/api/conftest.py +204 -0
  8. lemming/api/context.py +39 -0
  9. lemming/api/context_test.py +62 -0
  10. lemming/api/directories.py +57 -0
  11. lemming/api/directories_test.py +94 -0
  12. lemming/api/files.py +116 -0
  13. lemming/api/files_test.py +163 -0
  14. lemming/api/hooks.py +15 -0
  15. lemming/api/hooks_test.py +33 -0
  16. lemming/api/logging.py +16 -0
  17. lemming/api/logging_test.py +59 -0
  18. lemming/api/loop.py +45 -0
  19. lemming/api/loop_test.py +58 -0
  20. lemming/api/main.py +53 -0
  21. lemming/api/main_test.py +30 -0
  22. lemming/api/tasks.py +170 -0
  23. lemming/api/tasks_test.py +426 -0
  24. lemming/api.py +5 -0
  25. lemming/api_test.py +7 -0
  26. lemming/cli/__init__.py +12 -0
  27. lemming/cli/config.py +67 -0
  28. lemming/cli/config_test.py +50 -0
  29. lemming/cli/context.py +40 -0
  30. lemming/cli/context_test.py +49 -0
  31. lemming/cli/hooks.py +147 -0
  32. lemming/cli/hooks_test.py +50 -0
  33. lemming/cli/main.py +42 -0
  34. lemming/cli/main_test.py +21 -0
  35. lemming/cli/operations.py +226 -0
  36. lemming/cli/operations_test.py +44 -0
  37. lemming/cli/progress.py +54 -0
  38. lemming/cli/progress_test.py +40 -0
  39. lemming/cli/readability_cli.py +28 -0
  40. lemming/cli/readability_cli_test.py +57 -0
  41. lemming/cli/tasks.py +529 -0
  42. lemming/cli/tasks_test.py +168 -0
  43. lemming/cli.py +5 -0
  44. lemming/cli_test.py +22 -0
  45. lemming/conftest.py +13 -0
  46. lemming/hooks.py +145 -0
  47. lemming/hooks_test.py +180 -0
  48. lemming/integration_test.py +299 -0
  49. lemming/main.py +6 -0
  50. lemming/main_test.py +44 -0
  51. lemming/models.py +88 -0
  52. lemming/models_test.py +91 -0
  53. lemming/orchestrator.py +407 -0
  54. lemming/orchestrator_test.py +468 -0
  55. lemming/paths.py +245 -0
  56. lemming/paths_test.py +186 -0
  57. lemming/persistence.py +179 -0
  58. lemming/persistence_test.py +150 -0
  59. lemming/prompts/hooks/readability.md +42 -0
  60. lemming/prompts/hooks/roadmap.md +61 -0
  61. lemming/prompts/hooks/testing.md +44 -0
  62. lemming/prompts/taskrunner.md +69 -0
  63. lemming/prompts.py +354 -0
  64. lemming/prompts_test.py +421 -0
  65. lemming/providers.py +190 -0
  66. lemming/providers_test.py +73 -0
  67. lemming/runner.py +327 -0
  68. lemming/runner_test.py +378 -0
  69. lemming/tasks/__init__.py +75 -0
  70. lemming/tasks/lifecycle.py +331 -0
  71. lemming/tasks/lifecycle_test.py +312 -0
  72. lemming/tasks/operations.py +258 -0
  73. lemming/tasks/operations_test.py +172 -0
  74. lemming/tasks/progress.py +29 -0
  75. lemming/tasks/progress_test.py +22 -0
  76. lemming/tasks/queries.py +128 -0
  77. lemming/tasks/queries_test.py +233 -0
  78. lemming/web/dashboard.spec.js +350 -0
  79. lemming/web/dashboard.test.js +998 -0
  80. lemming/web/favicon.js +40 -0
  81. lemming/web/favicon.spec.js +242 -0
  82. lemming/web/files.html +375 -0
  83. lemming/web/files.spec.js +97 -0
  84. lemming/web/index.html +983 -0
  85. lemming/web/index.js +753 -0
  86. lemming/web/logs.html +358 -0
  87. lemming/web/logs.test.js +195 -0
  88. lemming/web/mancha.js +58 -0
  89. lemming/web/screenshots.spec.js +328 -0
  90. lemming_cli-0.1.0.dist-info/METADATA +314 -0
  91. lemming_cli-0.1.0.dist-info/RECORD +94 -0
  92. lemming_cli-0.1.0.dist-info/WHEEL +4 -0
  93. lemming_cli-0.1.0.dist-info/entry_points.txt +2 -0
  94. lemming_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,97 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { expect, test } from '@playwright/test';
4
+
5
+ const filesHtmlPath = path.resolve(process.cwd(), 'src/lemming/web/files.html');
6
+ const manchaJsPath = path.resolve(process.cwd(), 'src/lemming/web/mancha.js');
7
+
8
+ test.describe('Files Browser UI', () => {
9
+ test.beforeEach(async ({ page }) => {
10
+ // Serve files over mocked HTTP
11
+ await page.route('http://localhost:8000/', async (route) => {
12
+ await route.fulfill({
13
+ contentType: 'text/html',
14
+ body: fs.readFileSync(filesHtmlPath, 'utf8'),
15
+ });
16
+ });
17
+ await page.route(
18
+ 'http://localhost:8000/static/mancha.js',
19
+ async (route) => {
20
+ await route.fulfill({
21
+ contentType: 'application/javascript',
22
+ body: fs.readFileSync(manchaJsPath, 'utf8'),
23
+ });
24
+ },
25
+ );
26
+
27
+ // Mock API
28
+ await page.route('**/api/files/**', async (route) => {
29
+ await route.fulfill({
30
+ contentType: 'application/json',
31
+ json: {
32
+ path: 'test/dir',
33
+ contents: [
34
+ {
35
+ name: 'file1.txt',
36
+ is_dir: false,
37
+ size: 1500,
38
+ modified: 1715000000,
39
+ path: 'test/dir/file1.txt',
40
+ },
41
+ {
42
+ name: 'subdir',
43
+ is_dir: true,
44
+ size: 4096,
45
+ modified: 1715001000,
46
+ path: 'test/dir/subdir',
47
+ },
48
+ ],
49
+ },
50
+ });
51
+ });
52
+
53
+ await page.route('**/api/data**', async (route) => {
54
+ await route.fulfill({
55
+ contentType: 'application/json',
56
+ json: {
57
+ loop_running: false,
58
+ tasks: [],
59
+ },
60
+ });
61
+ });
62
+
63
+ await page.goto('http://localhost:8000/');
64
+ // Wait for ManchaApp to be ready
65
+ await page.evaluate(async () => {
66
+ while (!window.ManchaApp) await new Promise((r) => setTimeout(r, 50));
67
+ await window.ManchaApp;
68
+ });
69
+ });
70
+
71
+ test('renders file list correctly', async ({ page }) => {
72
+ const headerPath = page.locator('header div.text-sm');
73
+ await expect(headerPath).toContainText('/test/dir');
74
+
75
+ const rows = page.locator('tbody tr');
76
+ // Row 0: Parent directory
77
+ // Row 1: file1.txt
78
+ // Row 2: subdir
79
+ await expect(rows).toHaveCount(3);
80
+
81
+ const file1Link = page.getByText('file1.txt');
82
+ await expect(file1Link).toBeVisible();
83
+ await expect(file1Link).toHaveAttribute(
84
+ 'href',
85
+ '/files/test/dir/file1.txt',
86
+ );
87
+
88
+ const subdirLink = page.getByText('subdir');
89
+ await expect(subdirLink).toBeVisible();
90
+ await expect(subdirLink).toHaveAttribute('href', '/files/test/dir/subdir');
91
+ });
92
+
93
+ test('formats file sizes', async ({ page }) => {
94
+ const sizeCell = page.getByText('1.46 KB');
95
+ await expect(sizeCell).toBeVisible();
96
+ });
97
+ });