create-claude-workspace 1.1.103 → 1.1.105
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/dist/scripts/autonomous.mjs +1 -1
- package/dist/scripts/lib/errors.mjs +8 -7
- package/dist/scripts/lib/errors.spec.js +7 -1
- package/dist/scripts/lib/loop-integration.spec.js +2 -2
- package/dist/scripts/lib/types.mjs +1 -1
- package/dist/template/.claude/agents/backend-ts-architect.md +3 -1
- package/dist/template/.claude/agents/orchestrator.md +7 -0
- package/dist/template/.claude/templates/claude-md.md +1 -1
- package/package.json +1 -1
|
@@ -148,7 +148,7 @@ Options:
|
|
|
148
148
|
--max-turns <n> Max turns per Claude invocation (default: 50)
|
|
149
149
|
--delay <ms> Pause between tasks (default: 5000)
|
|
150
150
|
--cooldown <ms> Wait after error (default: 60000)
|
|
151
|
-
--process-timeout <ms> Max wall-clock time per invocation (default:
|
|
151
|
+
--process-timeout <ms> Max wall-clock time per invocation (default: 14400000 = 4h)
|
|
152
152
|
--activity-timeout <ms> Max silence before kill (default: 900000 = 15min)
|
|
153
153
|
--post-result-timeout <ms> Max wait after result (default: 30000 = 30s)
|
|
154
154
|
--project-dir <path> Project directory (default: cwd)
|
|
@@ -21,21 +21,22 @@ export function classifyError(signals) {
|
|
|
21
21
|
return 'auth_expired';
|
|
22
22
|
if (signals.isAuthServerError)
|
|
23
23
|
return 'auth_server_error';
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (signals.isRateLimit)
|
|
28
|
-
return 'rate_limited';
|
|
24
|
+
// Timeouts take priority over rate limit — timeout is the actual kill reason,
|
|
25
|
+
// rate limit is just a transient event that may have occurred during a 2h+ run.
|
|
26
|
+
// Without this, a normal process_timeout gets misclassified as rate_limited.
|
|
29
27
|
if (signals.timedOut) {
|
|
30
|
-
// Double-check stderr for auth errors (may not have been caught by stream events)
|
|
31
28
|
if (/authentication_error|failed to authenticate|api error: 401|oauth token has expired/i.test(signals.stderr)) {
|
|
32
29
|
return 'auth_expired';
|
|
33
30
|
}
|
|
34
31
|
return 'process_timeout';
|
|
35
32
|
}
|
|
36
|
-
// Activity timeout after result = success (process just hung after finishing)
|
|
37
33
|
if (signals.activityTimedOut)
|
|
38
34
|
return signals.hasResult ? 'none' : 'activity_timeout';
|
|
35
|
+
// Usage limit (account quota) takes priority over rate limit — it's hours, not seconds
|
|
36
|
+
if (signals.isUsageLimit)
|
|
37
|
+
return 'usage_limit';
|
|
38
|
+
if (signals.isRateLimit)
|
|
39
|
+
return 'rate_limited';
|
|
39
40
|
// Clean exit
|
|
40
41
|
if (signals.code === 0)
|
|
41
42
|
return 'none';
|
|
@@ -78,9 +78,15 @@ describe('classifyError', () => {
|
|
|
78
78
|
it('flag priority: auth flag wins over stderr patterns', () => {
|
|
79
79
|
expect(classifyError({ ...base, isAuthError: true, stderr: 'rate limit' })).toBe('auth_expired');
|
|
80
80
|
});
|
|
81
|
-
it('flag priority: rate limit flag
|
|
81
|
+
it('flag priority: rate limit flag detected when not timed out', () => {
|
|
82
82
|
expect(classifyError({ ...base, isRateLimit: true, timedOut: false })).toBe('rate_limited');
|
|
83
83
|
});
|
|
84
|
+
it('flag priority: timeout wins over rate limit (rate limit is transient during long run)', () => {
|
|
85
|
+
expect(classifyError({ ...base, isRateLimit: true, timedOut: true })).toBe('process_timeout');
|
|
86
|
+
});
|
|
87
|
+
it('flag priority: activity timeout wins over rate limit', () => {
|
|
88
|
+
expect(classifyError({ ...base, isRateLimit: true, activityTimedOut: true })).toBe('activity_timeout');
|
|
89
|
+
});
|
|
84
90
|
it('returns none when clean exit with result despite transient rate limit', () => {
|
|
85
91
|
expect(classifyError({ ...base, code: 0, hasResult: true, isRateLimit: true })).toBe('none');
|
|
86
92
|
});
|
|
@@ -659,8 +659,8 @@ describe('Loop integration: classifyError → getErrorAction → checkpoint', ()
|
|
|
659
659
|
it('auth error beats auth server error', () => {
|
|
660
660
|
expect(classifyError({ ...base, isAuthError: true, isAuthServerError: true })).toBe('auth_expired');
|
|
661
661
|
});
|
|
662
|
-
it('
|
|
663
|
-
expect(classifyError({ ...base, code: 1, isRateLimit: true, timedOut: true })).toBe('
|
|
662
|
+
it('process timeout beats rate limit (timeout is actual kill reason, rate limit is transient)', () => {
|
|
663
|
+
expect(classifyError({ ...base, code: 1, isRateLimit: true, timedOut: true })).toBe('process_timeout');
|
|
664
664
|
});
|
|
665
665
|
it('process timeout beats activity timeout', () => {
|
|
666
666
|
expect(classifyError({ ...base, timedOut: true, activityTimedOut: true })).toBe('process_timeout');
|
|
@@ -7,7 +7,7 @@ export const DEFAULTS = {
|
|
|
7
7
|
projectDir: process.cwd(),
|
|
8
8
|
skipPermissions: false,
|
|
9
9
|
resumeSession: null,
|
|
10
|
-
processTimeout:
|
|
10
|
+
processTimeout: 4 * 60 * 60_000,
|
|
11
11
|
activityTimeout: 15 * 60_000,
|
|
12
12
|
postResultTimeout: 30_000,
|
|
13
13
|
logFile: '.claude/autonomous.log',
|
|
@@ -69,6 +69,7 @@ Always prefer `@cibule/*` packages over custom implementations:
|
|
|
69
69
|
- Worker entry: exports `default { fetch }` with Hono app + D1 bindings → imports `infrastructure-d1`
|
|
70
70
|
- Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings → imports `infrastructure-sqlite`
|
|
71
71
|
- When planning, always structure FILES to keep platform-specific code in separate libraries per platform
|
|
72
|
+
- **Local development ALWAYS via Node.js entry point (STRICT):** `wrangler dev` is NOT used for local development — Nx `serve` target uses `@nx/js:node` executor pointing at the Node.js entry point (`main.ts`). Wrangler is deployment-only (handled by deployment-engineer). NEVER put `wrangler` commands in project.json targets.
|
|
72
73
|
|
|
73
74
|
## Task Approach
|
|
74
75
|
|
|
@@ -122,11 +123,12 @@ List of all files to create/modify, with full paths.
|
|
|
122
123
|
- **Publishable libs** (npm packages): use `--bundler=tsc` (or `--bundler=esbuild`/`--bundler=rollup` if needed) + `--publishable --importPath=@scope/name`. The generator creates the build target.
|
|
123
124
|
- **NEVER manually configure build tools** (tsup, esbuild, rollup, webpack). Do NOT create `tsup.config.ts`, `esbuild.config.js`, `rollup.config.js`, or similar files — Nx generators handle build configuration. Use `nx build [lib]` to build.
|
|
124
125
|
- **NEVER use `nx:run-commands` executor** in project.json targets. Always use the proper built-in Nx executor for each target type:
|
|
125
|
-
- serve: `@nx/js:node` (Node.js backend)
|
|
126
|
+
- serve: `@nx/js:node` (Node.js backend) — points at Node.js entry point, NOT wrangler
|
|
126
127
|
- build: `@nx/js:tsc`, `@nx/vite:build`, `@nx/esbuild:esbuild`
|
|
127
128
|
- test: `@nx/vitest:test` (Vitest), `@nx/jest:jest`
|
|
128
129
|
- lint: `@nx/eslint:lint`
|
|
129
130
|
- `nx:run-commands` is an escape hatch, not a default. Built-in executors handle watch mode, HMR, process management, and Nx dependency graph integration.
|
|
131
|
+
- **NEVER wrap `wrangler` in Nx targets** — wrangler is for deployment only (deployment-engineer handles it). Local dev always uses Node.js.
|
|
130
132
|
|
|
131
133
|
### IMPLEMENTATION ORDER
|
|
132
134
|
Numbered steps in the exact order the orchestrator should implement them.
|
|
@@ -78,6 +78,13 @@ At the beginning of EVERY session (including every Ralph Loop iteration):
|
|
|
78
78
|
### 1. Read state
|
|
79
79
|
- Read MEMORY.md — find where you left off, what is done, what is next, what phase you're in
|
|
80
80
|
- **Load `.env`**: If `.env` exists in the project root, source it to load tokens (`GITLAB_TOKEN`, `GH_TOKEN`, `CLICKUP_API_TOKEN`, etc.): `set -a && [ -f .env ] && . ./.env && set +a`
|
|
81
|
+
- **Refresh CLI auth from `.env`**: Each Bash tool call is an isolated shell session — env vars loaded above don't persist. To ensure CLI tools use the latest tokens from `.env`, re-authenticate in a single command:
|
|
82
|
+
```bash
|
|
83
|
+
set -a && [ -f .env ] && . ./.env && set +a && \
|
|
84
|
+
if [ -n "$GITLAB_TOKEN" ]; then glab auth login --hostname gitlab.com --token "$GITLAB_TOKEN" 2>/dev/null && echo "glab: re-authenticated from .env"; fi && \
|
|
85
|
+
if [ -n "$GH_TOKEN" ]; then echo "$GH_TOKEN" | gh auth login --with-token 2>/dev/null && echo "gh: re-authenticated from .env"; fi
|
|
86
|
+
```
|
|
87
|
+
This overwrites any stale tokens stored in CLI config files (e.g., from Docker entrypoint at container creation).
|
|
81
88
|
|
|
82
89
|
### 1b. Detect resumed development on completed project
|
|
83
90
|
If MEMORY.md indicates "Project complete" (Current Phase contains "PROJECT COMPLETE" or Next says "project complete"):
|
|
@@ -349,7 +349,7 @@ Key rules enforced (do NOT weaken):
|
|
|
349
349
|
- Entry points handle platform wiring:
|
|
350
350
|
- `apps/api/src/main.ts` — Node.js entry (optional, for local dev)
|
|
351
351
|
- `apps/api/src/index.ts` — Cloudflare Worker entry (production)
|
|
352
|
-
- Default deployment: **Cloudflare Workers** (production), **Node.js** (local development via `
|
|
352
|
+
- Default deployment: **Cloudflare Workers** (production), **Node.js** (local development via `@nx/js:node` executor + Node.js entry point). Wrangler is deployment-only — NEVER used for local dev or in Nx targets.
|
|
353
353
|
|
|
354
354
|
### Project-Specific Details
|
|
355
355
|
|