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.
- package/README.md +33 -1
- package/dist/index.js +29 -56
- package/dist/scheduler/agents/health-checker.mjs +98 -0
- package/dist/scheduler/agents/health-checker.spec.js +143 -0
- package/dist/scheduler/agents/orchestrator.mjs +149 -0
- package/dist/scheduler/agents/orchestrator.spec.js +87 -0
- package/dist/scheduler/agents/prompt-builder.mjs +204 -0
- package/dist/scheduler/agents/prompt-builder.spec.js +240 -0
- package/dist/scheduler/agents/worker-pool.mjs +137 -0
- package/dist/scheduler/agents/worker-pool.spec.js +45 -0
- package/dist/scheduler/git/ci-watcher.mjs +93 -0
- package/dist/scheduler/git/ci-watcher.spec.js +35 -0
- package/dist/scheduler/git/manager.mjs +228 -0
- package/dist/scheduler/git/manager.spec.js +198 -0
- package/dist/scheduler/git/release.mjs +117 -0
- package/dist/scheduler/git/release.spec.js +175 -0
- package/dist/scheduler/index.mjs +309 -0
- package/dist/scheduler/index.spec.js +72 -0
- package/dist/scheduler/integration.spec.js +289 -0
- package/dist/scheduler/loop.mjs +435 -0
- package/dist/scheduler/loop.spec.js +139 -0
- package/dist/scheduler/state/session.mjs +14 -0
- package/dist/scheduler/state/session.spec.js +36 -0
- package/dist/scheduler/state/state.mjs +102 -0
- package/dist/scheduler/state/state.spec.js +175 -0
- package/dist/scheduler/tasks/inbox.mjs +98 -0
- package/dist/scheduler/tasks/inbox.spec.js +168 -0
- package/dist/scheduler/tasks/parser.mjs +228 -0
- package/dist/scheduler/tasks/parser.spec.js +303 -0
- package/dist/scheduler/tasks/queue.mjs +152 -0
- package/dist/scheduler/tasks/queue.spec.js +223 -0
- package/dist/scheduler/types.mjs +20 -0
- package/dist/{scripts/lib → scheduler/ui}/tui.mjs +84 -41
- package/dist/{scripts/lib → scheduler/ui}/tui.spec.js +56 -0
- package/dist/scheduler/util/memory.mjs +126 -0
- package/dist/scheduler/util/memory.spec.js +165 -0
- package/dist/template/.claude/{profiles/angular.md → agents/angular-engineer.md} +9 -4
- package/dist/template/.claude/{profiles/react.md → agents/react-engineer.md} +9 -4
- package/dist/template/.claude/{profiles/svelte.md → agents/svelte-engineer.md} +9 -4
- package/dist/template/.claude/{profiles/vue.md → agents/vue-engineer.md} +9 -4
- package/package.json +3 -4
- package/dist/scripts/autonomous.mjs +0 -492
- package/dist/scripts/autonomous.spec.js +0 -46
- package/dist/scripts/docker-run.mjs +0 -462
- package/dist/scripts/integration.spec.js +0 -108
- package/dist/scripts/lib/formatter.mjs +0 -309
- package/dist/scripts/lib/formatter.spec.js +0 -262
- package/dist/scripts/lib/state.mjs +0 -44
- package/dist/scripts/lib/state.spec.js +0 -59
- package/dist/template/.claude/docker/.dockerignore +0 -8
- package/dist/template/.claude/docker/Dockerfile +0 -54
- package/dist/template/.claude/docker/docker-compose.yml +0 -22
- package/dist/template/.claude/docker/docker-entrypoint.sh +0 -101
- /package/dist/{scripts/lib/types.mjs → scheduler/shared-types.mjs} +0 -0
- /package/dist/{scripts/lib → scheduler/util}/idle-poll.mjs +0 -0
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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": "
|
|
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/
|
|
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/
|
|
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",
|