create-claude-workspace 1.1.76 → 1.1.78
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 +9 -6
- package/dist/scripts/lib/claude-runner.mjs +11 -0
- package/dist/scripts/lib/utils.mjs +5 -4
- package/dist/scripts/lib/utils.spec.js +9 -2
- package/dist/template/.claude/agents/backend-ts-architect.md +5 -4
- package/dist/template/.claude/templates/claude-md.md +12 -3
- package/package.json +1 -1
|
@@ -390,13 +390,16 @@ async function main() {
|
|
|
390
390
|
i--; // Retry this iteration
|
|
391
391
|
continue;
|
|
392
392
|
}
|
|
393
|
-
// Can't parse reset time —
|
|
394
|
-
|
|
395
|
-
log.
|
|
396
|
-
|
|
397
|
-
notify(opts.notifyCommand, 'stopped', 'Account usage limit (unknown reset time)', i);
|
|
393
|
+
// Can't parse reset time — poll every 5 minutes instead of stopping
|
|
394
|
+
const USAGE_POLL_MS = 5 * 60_000;
|
|
395
|
+
log.warn(`Account usage limit reached. Could not parse reset time — polling every ${formatDuration(USAGE_POLL_MS)}.`);
|
|
396
|
+
notify(opts.notifyCommand, 'error', `Usage limit — polling every ${formatDuration(USAGE_POLL_MS)}`, i);
|
|
398
397
|
writeCheckpoint(opts.projectDir, checkpoint, log);
|
|
399
|
-
|
|
398
|
+
await sleep(USAGE_POLL_MS, stoppingRef);
|
|
399
|
+
if (stopping)
|
|
400
|
+
break;
|
|
401
|
+
i--; // Retry this iteration
|
|
402
|
+
continue;
|
|
400
403
|
}
|
|
401
404
|
// Handle stop — try OAuth refresh for auth errors before giving up
|
|
402
405
|
if (action.type === 'stop') {
|
|
@@ -344,6 +344,17 @@ export function runClaude(opts, log, runOpts = {}) {
|
|
|
344
344
|
if (event.type === 'rate_limit_event')
|
|
345
345
|
isRateLimit = true;
|
|
346
346
|
detectErrorSignals(event);
|
|
347
|
+
// Detect error signals in assistant text content (e.g. "You've hit your limit" as text, not error event)
|
|
348
|
+
if (event.type === 'assistant') {
|
|
349
|
+
const blocks = getContentBlocks(event);
|
|
350
|
+
if (blocks) {
|
|
351
|
+
for (const block of blocks) {
|
|
352
|
+
if (block.type === 'text' && block.text) {
|
|
353
|
+
detectTextSignals(block.text.toLowerCase());
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
347
358
|
// Display
|
|
348
359
|
const formatted = formatStreamEvent(event);
|
|
349
360
|
if (formatted)
|
|
@@ -7,11 +7,12 @@ import { createInterface } from 'node:readline';
|
|
|
7
7
|
// Node.js runtime accepts `true` for shell but @types expects string
|
|
8
8
|
const SHELL = process.platform === 'win32' ? 'cmd.exe' : '/bin/sh';
|
|
9
9
|
// ─── Usage limit reset time parser ───
|
|
10
|
-
/** Parse "resets Xpm (UTC)" / "resets X:XX AM
|
|
11
|
-
* Returns milliseconds to wait, or null if unparseable.
|
|
10
|
+
/** Parse "resets Xpm (UTC)" / "resets X:XX AM" / "resets 3am" from stderr text.
|
|
11
|
+
* Returns milliseconds to wait, or null if unparseable.
|
|
12
|
+
* Accepts with or without (UTC) — assumes UTC when timezone not specified. */
|
|
12
13
|
export function parseUsageLimitResetMs(text) {
|
|
13
|
-
// Match patterns: "resets 6pm (UTC)", "resets 6:30pm
|
|
14
|
-
const match = text.match(/resets\s+(\d{1,2})(?::(\d{2}))?\s*(am|pm)
|
|
14
|
+
// Match patterns: "resets 6pm (UTC)", "resets 6:30pm", "resets 18:00 (UTC)", "resets 6 PM", "resets 3am"
|
|
15
|
+
const match = text.match(/resets\s+(\d{1,2})(?::(\d{2}))?\s*(am|pm)?(?:\s*\(UTC\))?/i);
|
|
15
16
|
if (!match)
|
|
16
17
|
return null;
|
|
17
18
|
let hours = parseInt(match[1], 10);
|
|
@@ -129,8 +129,15 @@ describe('parseUsageLimitResetMs', () => {
|
|
|
129
129
|
it('returns null for invalid minutes', () => {
|
|
130
130
|
expect(parseUsageLimitResetMs('resets 6:99pm (UTC)')).toBeNull();
|
|
131
131
|
});
|
|
132
|
-
it('
|
|
133
|
-
|
|
132
|
+
it('parses "resets 6pm" without UTC marker (assumes UTC)', () => {
|
|
133
|
+
const ms = parseUsageLimitResetMs('resets 6pm');
|
|
134
|
+
expect(ms).toBeTypeOf('number');
|
|
135
|
+
expect(ms).toBeGreaterThan(0);
|
|
136
|
+
});
|
|
137
|
+
it('parses "resets 3am" bare format', () => {
|
|
138
|
+
const ms = parseUsageLimitResetMs("You've hit your limit · resets 3am");
|
|
139
|
+
expect(ms).toBeTypeOf('number');
|
|
140
|
+
expect(ms).toBeGreaterThan(0);
|
|
134
141
|
});
|
|
135
142
|
it('result is always positive (wraps to next day if time passed)', () => {
|
|
136
143
|
// Use a time that's definitely in the past today (1am UTC if test runs after 1am)
|
|
@@ -61,13 +61,14 @@ Always prefer `@cibule/*` packages over custom implementations:
|
|
|
61
61
|
- NEVER use Node.js-specific APIs (`fs`, `path`, `process`, `Buffer`) in business/domain/api layers
|
|
62
62
|
- NEVER use Cloudflare-specific APIs (`env.DB`, `ctx.waitUntil()`) in business/domain layers
|
|
63
63
|
- Platform-specific code lives ONLY in `infrastructure/` layer behind abstract repository interfaces
|
|
64
|
+
- **Platform-specific code MUST be in separate libraries** — NEVER mix Node.js and Cloudflare implementations in the same library. Barrel exports pull both platforms into the bundle, causing compilation errors (e.g. `better-sqlite3` in Cloudflare). Split into: `infrastructure-d1/` (Cloudflare) and `infrastructure-sqlite/` (Node.js). Same applies to shared providers: `shared/infrastructure-d1/` vs `shared/infrastructure-sqlite/`.
|
|
64
65
|
- Use Web Standard APIs: `fetch`, `Request`, `Response`, `URL`, `crypto`, `TextEncoder`/`TextDecoder`
|
|
65
66
|
- Hono is inherently platform-agnostic — inject platform bindings via DI, not `c.env` in routes
|
|
66
67
|
- **OpenAPI-first**: All API routes MUST use `hono-openapi` with `openAPIRouteHandler` — generates OpenAPI spec from TypeBox schemas. Serve API docs via `@scalar/hono-api-reference` at `/reference`. Never define routes without OpenAPI metadata.
|
|
67
|
-
- Entry points handle platform wiring:
|
|
68
|
-
- Worker entry: exports `default { fetch }` with Hono app + D1 bindings
|
|
69
|
-
- Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings
|
|
70
|
-
- When planning, always structure FILES to keep platform-specific code
|
|
68
|
+
- Entry points handle platform wiring (each imports ONLY its platform's infrastructure library):
|
|
69
|
+
- Worker entry: exports `default { fetch }` with Hono app + D1 bindings → imports `infrastructure-d1`
|
|
70
|
+
- Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings → imports `infrastructure-sqlite`
|
|
71
|
+
- When planning, always structure FILES to keep platform-specific code in separate libraries per platform
|
|
71
72
|
|
|
72
73
|
## Task Approach
|
|
73
74
|
|
|
@@ -323,9 +323,18 @@ Key rules enforced (do NOT weaken):
|
|
|
323
323
|
- NEVER use Cloudflare-specific APIs (`env.DB`, `ctx.waitUntil()`) in business/domain layers
|
|
324
324
|
- Platform-specific code lives ONLY in `infrastructure/` layer behind abstract interfaces
|
|
325
325
|
- Use Web Standard APIs where possible: `fetch`, `Request`, `Response`, `URL`, `crypto`, `TextEncoder`/`TextDecoder`, `Headers`, `FormData`, `ReadableStream`
|
|
326
|
-
-
|
|
327
|
-
|
|
328
|
-
|
|
326
|
+
- **Platform-specific code MUST be in separate libraries (STRICT)** — NEVER mix Node.js and Cloudflare code in the same library. Barrel exports (`index.ts`) would pull both platforms into the bundle, causing compilation errors (e.g. `better-sqlite3` in Cloudflare, or D1 bindings in Node.js):
|
|
327
|
+
```
|
|
328
|
+
libs/[domain]/
|
|
329
|
+
infrastructure-d1/ # Cloudflare D1 implementation ONLY
|
|
330
|
+
infrastructure-sqlite/ # Node.js SQLite implementation ONLY
|
|
331
|
+
libs/shared/
|
|
332
|
+
infrastructure-d1/ # shared D1 providers (provideD1Database)
|
|
333
|
+
infrastructure-sqlite/ # shared SQLite providers (provideSqliteDatabase)
|
|
334
|
+
```
|
|
335
|
+
Each entry point imports ONLY its platform's library:
|
|
336
|
+
- Worker entry → `@[PREFIX]/shared-infrastructure-d1`
|
|
337
|
+
- Node entry → `@[PREFIX]/shared-infrastructure-sqlite`
|
|
329
338
|
- Hono is inherently platform-agnostic — use its standard APIs, avoid `c.env` directly in routes (inject via DI)
|
|
330
339
|
- Entry points handle platform wiring:
|
|
331
340
|
- `apps/api/src/main.ts` — Node.js entry (optional, for local dev)
|