create-claude-workspace 1.1.151 → 2.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 (56) hide show
  1. package/README.md +33 -1
  2. package/dist/index.js +29 -56
  3. package/dist/scheduler/agents/health-checker.mjs +98 -0
  4. package/dist/scheduler/agents/health-checker.spec.js +143 -0
  5. package/dist/scheduler/agents/orchestrator.mjs +149 -0
  6. package/dist/scheduler/agents/orchestrator.spec.js +87 -0
  7. package/dist/scheduler/agents/prompt-builder.mjs +204 -0
  8. package/dist/scheduler/agents/prompt-builder.spec.js +240 -0
  9. package/dist/scheduler/agents/worker-pool.mjs +137 -0
  10. package/dist/scheduler/agents/worker-pool.spec.js +45 -0
  11. package/dist/scheduler/git/ci-watcher.mjs +93 -0
  12. package/dist/scheduler/git/ci-watcher.spec.js +35 -0
  13. package/dist/scheduler/git/manager.mjs +228 -0
  14. package/dist/scheduler/git/manager.spec.js +198 -0
  15. package/dist/scheduler/git/release.mjs +117 -0
  16. package/dist/scheduler/git/release.spec.js +175 -0
  17. package/dist/scheduler/index.mjs +309 -0
  18. package/dist/scheduler/index.spec.js +72 -0
  19. package/dist/scheduler/integration.spec.js +289 -0
  20. package/dist/scheduler/loop.mjs +435 -0
  21. package/dist/scheduler/loop.spec.js +139 -0
  22. package/dist/scheduler/state/session.mjs +14 -0
  23. package/dist/scheduler/state/session.spec.js +36 -0
  24. package/dist/scheduler/state/state.mjs +102 -0
  25. package/dist/scheduler/state/state.spec.js +175 -0
  26. package/dist/scheduler/tasks/inbox.mjs +98 -0
  27. package/dist/scheduler/tasks/inbox.spec.js +168 -0
  28. package/dist/scheduler/tasks/parser.mjs +228 -0
  29. package/dist/scheduler/tasks/parser.spec.js +303 -0
  30. package/dist/scheduler/tasks/queue.mjs +152 -0
  31. package/dist/scheduler/tasks/queue.spec.js +223 -0
  32. package/dist/scheduler/types.mjs +20 -0
  33. package/dist/{scripts/lib → scheduler/ui}/tui.mjs +84 -41
  34. package/dist/{scripts/lib → scheduler/ui}/tui.spec.js +56 -0
  35. package/dist/scheduler/util/memory.mjs +126 -0
  36. package/dist/scheduler/util/memory.spec.js +165 -0
  37. package/dist/template/.claude/{profiles/angular.md → agents/angular-engineer.md} +9 -4
  38. package/dist/template/.claude/{profiles/react.md → agents/react-engineer.md} +9 -4
  39. package/dist/template/.claude/{profiles/svelte.md → agents/svelte-engineer.md} +9 -4
  40. package/dist/template/.claude/{profiles/vue.md → agents/vue-engineer.md} +9 -4
  41. package/package.json +3 -4
  42. package/dist/scripts/autonomous.mjs +0 -492
  43. package/dist/scripts/autonomous.spec.js +0 -46
  44. package/dist/scripts/docker-run.mjs +0 -462
  45. package/dist/scripts/integration.spec.js +0 -108
  46. package/dist/scripts/lib/formatter.mjs +0 -309
  47. package/dist/scripts/lib/formatter.spec.js +0 -262
  48. package/dist/scripts/lib/state.mjs +0 -44
  49. package/dist/scripts/lib/state.spec.js +0 -59
  50. package/dist/template/.claude/docker/.dockerignore +0 -8
  51. package/dist/template/.claude/docker/Dockerfile +0 -54
  52. package/dist/template/.claude/docker/docker-compose.yml +0 -22
  53. package/dist/template/.claude/docker/docker-entrypoint.sh +0 -101
  54. /package/dist/{scripts/lib/types.mjs → scheduler/shared-types.mjs} +0 -0
  55. /package/dist/{scripts/lib → scheduler/util}/idle-poll.mjs +0 -0
  56. /package/dist/{scripts/lib → scheduler/util}/idle-poll.spec.js +0 -0
@@ -0,0 +1,165 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { readField, writeField, addDoneItem, setNextItem, readSessionConfig, isProjectComplete, readIterationCount, incrementIterations, } from './memory.mjs';
3
+ const SAMPLE_MEMORY = `# MEMORY.md
4
+
5
+ ## Current Phase
6
+ Phase 1: User Authentication
7
+
8
+ ## Current Task
9
+ Create auth domain types
10
+
11
+ ## Current Step
12
+ 3 — IMPLEMENT
13
+
14
+ ## Current Worktree
15
+ .worktrees/feat/5-auth-types
16
+
17
+ ## Iterations This Session
18
+ 7
19
+
20
+ ## Complexity This Session
21
+ 12
22
+
23
+ ## Session Config
24
+ - FRONTEND_APP: my-app
25
+ - BACKEND_APP: api-server
26
+ - Workflow: solo
27
+
28
+ ## Done
29
+ - Set up Nx workspace (2026-03-15)
30
+ - Configure ESLint (2026-03-15)
31
+
32
+ ## Next
33
+ - Create auth domain types
34
+
35
+ ## Decisions
36
+ (none yet)
37
+
38
+ ## Blockers
39
+ (none)
40
+
41
+ ## Notes
42
+ - Project initialized on 2026-03-14
43
+ `;
44
+ // ─── readField ───
45
+ describe('readField', () => {
46
+ it('reads a simple field', () => {
47
+ expect(readField(SAMPLE_MEMORY, 'Current Task')).toBe('Create auth domain types');
48
+ });
49
+ it('reads a multi-line field', () => {
50
+ const done = readField(SAMPLE_MEMORY, 'Done');
51
+ expect(done).toContain('Set up Nx workspace');
52
+ expect(done).toContain('Configure ESLint');
53
+ });
54
+ it('reads a field with structured content', () => {
55
+ const config = readField(SAMPLE_MEMORY, 'Session Config');
56
+ expect(config).toContain('FRONTEND_APP: my-app');
57
+ });
58
+ it('returns null for non-existent field', () => {
59
+ expect(readField(SAMPLE_MEMORY, 'Non Existent')).toBeNull();
60
+ });
61
+ it('returns null for a field with empty value', () => {
62
+ const empty = `## Empty Field\n\n## Next Field\nvalue`;
63
+ expect(readField(empty, 'Empty Field')).toBeNull();
64
+ });
65
+ it('reads the last field (no trailing heading)', () => {
66
+ const notes = readField(SAMPLE_MEMORY, 'Notes');
67
+ expect(notes).toContain('Project initialized on 2026-03-14');
68
+ });
69
+ });
70
+ // ─── writeField ───
71
+ describe('writeField', () => {
72
+ it('updates an existing field', () => {
73
+ const updated = writeField(SAMPLE_MEMORY, 'Current Task', 'Implement login flow');
74
+ expect(readField(updated, 'Current Task')).toBe('Implement login flow');
75
+ });
76
+ it('preserves other fields when updating', () => {
77
+ const updated = writeField(SAMPLE_MEMORY, 'Current Task', 'New task');
78
+ expect(readField(updated, 'Current Phase')).toBe('Phase 1: User Authentication');
79
+ expect(readField(updated, 'Current Step')).toBe('3 — IMPLEMENT');
80
+ });
81
+ it('creates a new field when it does not exist', () => {
82
+ const updated = writeField(SAMPLE_MEMORY, 'Kit_Version', '1.2.3');
83
+ expect(readField(updated, 'Kit_Version')).toBe('1.2.3');
84
+ });
85
+ it('replaces multi-line content', () => {
86
+ const updated = writeField(SAMPLE_MEMORY, 'Done', '- Only this item');
87
+ expect(readField(updated, 'Done')).toBe('- Only this item');
88
+ });
89
+ });
90
+ // ─── addDoneItem ───
91
+ describe('addDoneItem', () => {
92
+ it('appends to existing done list', () => {
93
+ const updated = addDoneItem(SAMPLE_MEMORY, 'Auth types done', '2026-03-20');
94
+ const done = readField(updated, 'Done');
95
+ expect(done).toContain('Set up Nx workspace');
96
+ expect(done).toContain('Auth types done (2026-03-20)');
97
+ });
98
+ it('replaces placeholder when Done is empty', () => {
99
+ const empty = `## Done\n(nothing yet)\n\n## Next\nfoo`;
100
+ const updated = addDoneItem(empty, 'First task', '2026-03-20');
101
+ expect(readField(updated, 'Done')).toBe('- First task (2026-03-20)');
102
+ });
103
+ });
104
+ // ─── setNextItem ───
105
+ describe('setNextItem', () => {
106
+ it('sets the next item', () => {
107
+ const updated = setNextItem(SAMPLE_MEMORY, 'Implement login');
108
+ expect(readField(updated, 'Next')).toBe('- Implement login');
109
+ });
110
+ });
111
+ // ─── readSessionConfig ───
112
+ describe('readSessionConfig', () => {
113
+ it('parses session config into key-value pairs', () => {
114
+ const config = readSessionConfig(SAMPLE_MEMORY);
115
+ expect(config).toEqual({
116
+ FRONTEND_APP: 'my-app',
117
+ BACKEND_APP: 'api-server',
118
+ Workflow: 'solo',
119
+ });
120
+ });
121
+ it('returns empty object when no config section', () => {
122
+ expect(readSessionConfig('# Just a heading')).toEqual({});
123
+ });
124
+ });
125
+ // ─── isProjectComplete ───
126
+ describe('isProjectComplete', () => {
127
+ it('detects "PROJECT COMPLETE" in Current Phase heading style', () => {
128
+ const complete = writeField(SAMPLE_MEMORY, 'Current Phase', 'Phase 3: Done — PROJECT COMPLETE');
129
+ expect(isProjectComplete(complete)).toBe(true);
130
+ });
131
+ it('detects Project_Status: complete', () => {
132
+ const complete = `Project_Status: complete\n`;
133
+ expect(isProjectComplete(complete)).toBe(true);
134
+ });
135
+ it('returns false for in-progress project', () => {
136
+ expect(isProjectComplete(SAMPLE_MEMORY)).toBe(false);
137
+ });
138
+ it('returns false for empty content', () => {
139
+ expect(isProjectComplete('')).toBe(false);
140
+ });
141
+ });
142
+ // ─── readIterationCount / incrementIterations ───
143
+ describe('readIterationCount', () => {
144
+ it('reads iteration count', () => {
145
+ expect(readIterationCount(SAMPLE_MEMORY)).toBe(7);
146
+ });
147
+ it('returns 0 when no iterations field', () => {
148
+ expect(readIterationCount('# Nothing here')).toBe(0);
149
+ });
150
+ it('returns 0 for non-numeric value', () => {
151
+ const bad = `## Iterations This Session\nnot a number\n`;
152
+ expect(readIterationCount(bad)).toBe(0);
153
+ });
154
+ });
155
+ describe('incrementIterations', () => {
156
+ it('increments from current value', () => {
157
+ const updated = incrementIterations(SAMPLE_MEMORY);
158
+ expect(readIterationCount(updated)).toBe(8);
159
+ });
160
+ it('increments from 0 when field missing', () => {
161
+ const noIter = `# MEMORY.md\n## Current Phase\nPhase 0\n`;
162
+ const updated = incrementIterations(noIter);
163
+ expect(readIterationCount(updated)).toBe(1);
164
+ });
165
+ });
@@ -1,8 +1,13 @@
1
- # Angular Frontend Profile
1
+ ---
2
+ name: angular-engineer
3
+ description: Angular frontend specialist — components, signals, RxJS, SSR, testing
4
+ model: opus
5
+ steps: plan, implement, rework
6
+ ---
7
+
8
+ You are an Angular frontend engineer. You plan, implement, and fix Angular applications.
9
+ Read the codebase before making changes. Follow the conventions below strictly.
2
10
 
3
- > This profile is copied to `.claude/profiles/frontend.md` in the target project by the project-initializer.
4
- > It is read by: `ui-engineer`, `senior-code-reviewer`, `test-engineer`.
5
- > It is NOT read by: `orchestrator`, `backend-ts-architect`, `devops-integrator`, `deployment-engineer`, `product-owner`, `technical-planner`.
6
11
 
7
12
  ## Framework
8
13
 
@@ -1,8 +1,13 @@
1
- # React Frontend Profile
1
+ ---
2
+ name: react-engineer
3
+ description: React frontend specialist — components, hooks, SSR, Next.js, testing
4
+ model: opus
5
+ steps: plan, implement, rework
6
+ ---
7
+
8
+ You are a React frontend engineer. You plan, implement, and fix React applications.
9
+ Read the codebase before making changes. Follow the conventions below strictly.
2
10
 
3
- > This profile is copied to `.claude/profiles/frontend.md` in the target project by the project-initializer.
4
- > It is read by: `ui-engineer`, `senior-code-reviewer`, `test-engineer`.
5
- > It is NOT read by: `orchestrator`, `backend-ts-architect`, `devops-integrator`, `deployment-engineer`, `product-owner`, `technical-planner`.
6
11
 
7
12
  ## Framework
8
13
 
@@ -1,8 +1,13 @@
1
- # Svelte Frontend Profile
1
+ ---
2
+ name: svelte-engineer
3
+ description: Svelte frontend specialist — runes, SvelteKit, SSR, testing
4
+ model: opus
5
+ steps: plan, implement, rework
6
+ ---
7
+
8
+ You are a Svelte frontend engineer. You plan, implement, and fix Svelte/SvelteKit applications.
9
+ Read the codebase before making changes. Follow the conventions below strictly.
2
10
 
3
- > This profile is copied to `.claude/profiles/frontend.md` in the target project by the project-initializer.
4
- > It is read by: `ui-engineer`, `senior-code-reviewer`, `test-engineer`.
5
- > It is NOT read by: `orchestrator`, `backend-ts-architect`, `devops-integrator`, `deployment-engineer`, `product-owner`, `technical-planner`.
6
11
 
7
12
  ## Framework
8
13
 
@@ -1,8 +1,13 @@
1
- # Vue Frontend Profile
1
+ ---
2
+ name: vue-engineer
3
+ description: Vue frontend specialist — Composition API, Pinia, Nuxt, SSR, testing
4
+ model: opus
5
+ steps: plan, implement, rework
6
+ ---
7
+
8
+ You are a Vue frontend engineer. You plan, implement, and fix Vue applications.
9
+ Read the codebase before making changes. Follow the conventions below strictly.
2
10
 
3
- > This profile is copied to `.claude/profiles/frontend.md` in the target project by the project-initializer.
4
- > It is read by: `ui-engineer`, `senior-code-reviewer`, `test-engineer`.
5
- > It is NOT read by: `orchestrator`, `backend-ts-architect`, `devops-integrator`, `deployment-engineer`, `product-owner`, `technical-planner`.
6
11
 
7
12
  ## Framework
8
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.151",
3
+ "version": "2.0.0",
4
4
  "author": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "files": [
21
21
  "dist/index.js",
22
- "dist/scripts",
22
+ "dist/scheduler",
23
23
  "dist/template"
24
24
  ],
25
25
  "keywords": [
@@ -35,8 +35,7 @@
35
35
  "scripts": {
36
36
  "build": "tsc && node scripts/copy-templates.mjs",
37
37
  "test": "vitest run",
38
- "test:integration": "vitest run src/scripts/integration.spec.ts",
39
- "test:all": "vitest run --config vitest.integration.config.ts",
38
+ "test:integration": "vitest run src/scheduler/integration.spec.ts",
40
39
  "prepublishOnly": "npm run build"
41
40
  },
42
41
  "type": "module",