schub 0.1.0 → 0.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.
Files changed (50) hide show
  1. package/README.md +68 -0
  2. package/dist/index.js +1573 -597
  3. package/package.json +3 -1
  4. package/skills/create-proposal/SKILL.md +33 -0
  5. package/skills/create-tasks/SKILL.md +40 -0
  6. package/skills/implement-task/SKILL.md +84 -0
  7. package/skills/review-proposal/SKILL.md +37 -0
  8. package/skills/setup-project/SKILL.md +29 -0
  9. package/src/App.test.tsx +93 -0
  10. package/src/App.tsx +62 -10
  11. package/src/changes.ts +86 -28
  12. package/src/clipboard.ts +5 -0
  13. package/src/commands/adr.test.ts +69 -0
  14. package/src/commands/adr.ts +107 -0
  15. package/src/commands/changes.test.ts +171 -0
  16. package/src/commands/changes.ts +163 -0
  17. package/src/commands/cookbook.test.ts +71 -0
  18. package/src/commands/cookbook.ts +95 -0
  19. package/src/commands/eject.test.ts +74 -0
  20. package/src/commands/eject.ts +100 -0
  21. package/src/commands/init.test.ts +78 -0
  22. package/src/commands/init.ts +144 -0
  23. package/src/commands/project.test.ts +113 -0
  24. package/src/commands/project.ts +75 -0
  25. package/src/commands/review.test.ts +100 -0
  26. package/src/commands/review.ts +231 -0
  27. package/src/commands/tasks-create.test.ts +172 -0
  28. package/src/commands/tasks-list.test.ts +177 -0
  29. package/src/commands/tasks.ts +172 -0
  30. package/src/components/PlanView.test.tsx +113 -0
  31. package/src/components/PlanView.tsx +95 -26
  32. package/src/components/StatusView.test.tsx +380 -0
  33. package/src/components/StatusView.tsx +233 -83
  34. package/src/features/tasks/constants.ts +2 -0
  35. package/src/features/tasks/create.ts +15 -7
  36. package/src/features/tasks/filesystem.test.ts +78 -0
  37. package/src/features/tasks/filesystem.ts +61 -7
  38. package/src/ide.ts +7 -0
  39. package/src/index.test.ts +23 -0
  40. package/src/index.ts +60 -383
  41. package/src/init.test.ts +43 -0
  42. package/src/init.ts +27 -0
  43. package/src/project.ts +5 -32
  44. package/src/schub-root.ts +33 -0
  45. package/src/templates.ts +18 -0
  46. package/src/terminal.test.ts +46 -0
  47. package/templates/create-proposal/cookbook-template.md +37 -0
  48. package/templates/review-proposal/q&a-template.md +5 -1
  49. package/templates/templates-parity.test.ts +45 -0
  50. package/templates/setup-project/review-me-template.md +0 -18
@@ -0,0 +1,46 @@
1
+ import { expect, test } from "bun:test";
2
+ import { applyTerminalPrelude, applyTerminalReset, terminalPrelude, terminalReset } from "./terminal";
3
+
4
+ test("terminal prelude clears scrollback and sets black background", () => {
5
+ expect(terminalPrelude).toBe("\u001b[3J\u001b[2J\u001b[H\u001b[40m");
6
+ });
7
+
8
+ test("terminal reset restores default colors", () => {
9
+ expect(terminalReset).toBe("\u001b[0m");
10
+ });
11
+
12
+ test("applyTerminalPrelude writes the prelude", () => {
13
+ const writes: string[] = [];
14
+ const originalWrite = process.stdout.write;
15
+
16
+ process.stdout.write = ((chunk: string | Uint8Array) => {
17
+ writes.push(String(chunk));
18
+ return true;
19
+ }) as typeof process.stdout.write;
20
+
21
+ try {
22
+ applyTerminalPrelude();
23
+ } finally {
24
+ process.stdout.write = originalWrite;
25
+ }
26
+
27
+ expect(writes.join("")).toBe(terminalPrelude);
28
+ });
29
+
30
+ test("applyTerminalReset writes the reset sequence", () => {
31
+ const writes: string[] = [];
32
+ const originalWrite = process.stdout.write;
33
+
34
+ process.stdout.write = ((chunk: string | Uint8Array) => {
35
+ writes.push(String(chunk));
36
+ return true;
37
+ }) as typeof process.stdout.write;
38
+
39
+ try {
40
+ applyTerminalReset();
41
+ } finally {
42
+ process.stdout.write = originalWrite;
43
+ }
44
+
45
+ expect(writes.join("")).toBe(terminalReset);
46
+ });
@@ -0,0 +1,37 @@
1
+ # Cookbook - {{CHANGE_TITLE}}
2
+
3
+ **Change ID**: `{{CHANGE_ID}}`
4
+ **Created**: {{DATE}}
5
+
6
+ ## Overview
7
+
8
+ [What this cookbook covers and who it is for.]
9
+
10
+ ## Prerequisites
11
+
12
+ - [Requirement or dependency]
13
+
14
+ ## Setup
15
+
16
+ 1. [Step]
17
+ 2. [Step]
18
+
19
+ ## Usage
20
+
21
+ ### Example 1 — [Title]
22
+
23
+ ```bash
24
+ [Command]
25
+ ```
26
+
27
+ ### Example 2 — [Title]
28
+
29
+ ```bash
30
+ [Command]
31
+ ```
32
+
33
+ ## Verification & Evidence
34
+
35
+ - **Commands to run**: [exact commands]
36
+ - **Expected evidence**: [logs, HTTP responses, screenshots/videos/traces, artifacts]
37
+ - **Where to find artifacts**: [paths, URLs, container/log sources]
@@ -10,4 +10,8 @@
10
10
  **Answer:** <answer>
11
11
 
12
12
  ### ❓ <Question 3>
13
- **Answer:** <answer>
13
+ **Answer:** <answer>
14
+
15
+ #--- TODO: copy into Q&A Template --
16
+ LLM: Move the content below into the Q&A sections above, then delete this block.
17
+ {{REVIEW_CONTENT}}
@@ -0,0 +1,45 @@
1
+ import { expect, test } from "bun:test";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const testDir = dirname(fileURLToPath(import.meta.url));
7
+ const cliDir = resolve(testDir, "..");
8
+ const repoRoot = resolve(cliDir, "..", "..");
9
+
10
+ const cliTemplates = [
11
+ join(cliDir, "templates", "create-proposal", "proposal-template.md"),
12
+ join(cliDir, "templates", "create-proposal", "adr-template.md"),
13
+ join(cliDir, "templates", "create-proposal", "cookbook-template.md"),
14
+ join(cliDir, "templates", "create-tasks", "task-template.md"),
15
+ join(cliDir, "templates", "setup-project", "project-overview-template.md"),
16
+ join(cliDir, "templates", "setup-project", "project-setup-template.md"),
17
+ join(cliDir, "templates", "setup-project", "project-wow-template.md"),
18
+ join(cliDir, "templates", "review-proposal", "review-me-template.md"),
19
+ join(cliDir, "templates", "review-proposal", "q&a-template.md"),
20
+ ];
21
+
22
+ const legacyTemplates = [
23
+ join(repoRoot, "skills", "create-proposal", "assets", "proposal-template.md"),
24
+ join(repoRoot, "skills", "create-proposal", "assets", "adr-template.md"),
25
+ join(repoRoot, "skills", "create-tasks", "assets", "task-template.md"),
26
+ join(repoRoot, "skills", "setup-project", "assets", "project-overview-template.md"),
27
+ join(repoRoot, "skills", "setup-project", "assets", "project-setup-template.md"),
28
+ join(repoRoot, "skills", "setup-project", "assets", "project-wow-template.md"),
29
+ join(repoRoot, "skills", "setup-project", "assets", "review-me-template.md"),
30
+ join(repoRoot, "skills", "review-proposal", "assets", "review-me-template.md"),
31
+ join(repoRoot, "skills", "review-proposal", "assets", "q&a-template.md"),
32
+ ];
33
+
34
+ test("cli templates exist and are non-empty", () => {
35
+ for (const templatePath of cliTemplates) {
36
+ const contents = readFileSync(templatePath, "utf8");
37
+ expect(contents.trim().length).toBeGreaterThan(0);
38
+ }
39
+ });
40
+
41
+ test("legacy skill template assets are removed", () => {
42
+ for (const legacyPath of legacyTemplates) {
43
+ expect(existsSync(legacyPath)).toBe(false);
44
+ }
45
+ });
@@ -1,18 +0,0 @@
1
- # REVIEW_ME: {{CHANGE_TITLE}}
2
-
3
- **Change ID**: `{{CHANGE_ID}}`
4
- **Created**: {{DATE}}
5
-
6
- **Purpose**: Open questions to review requirements with the user.
7
-
8
- ## Open Questions
9
-
10
- - [ ] Q1: [Question]
11
- - [ ] Q2: [Question]
12
-
13
- ## Notes
14
-
15
- - Check items off as completed: `[x]`
16
- - Add comments or findings inline
17
- - Link to relevant resources or documentation
18
- - Items are numbered sequentially for easy reference