create-claude-workspace 1.1.132 → 1.1.134

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.
@@ -2,7 +2,7 @@
2
2
  // ─── Autonomous development loop ───
3
3
  // Headless runner for Claude Code orchestrator using Agent SDK.
4
4
  import { resolve } from 'node:path';
5
- import { existsSync, writeFileSync, unlinkSync, readFileSync } from 'node:fs';
5
+ import { existsSync, writeFileSync, unlinkSync, readFileSync, readdirSync } from 'node:fs';
6
6
  import { execSync } from 'node:child_process';
7
7
  import { DEFAULTS } from './lib/types.mjs';
8
8
  import { emptyCheckpoint, readCheckpoint, writeCheckpoint } from './lib/state.mjs';
@@ -250,6 +250,33 @@ function isProjectComplete(memory, dir) {
250
250
  return false;
251
251
  }
252
252
  }
253
+ function loadAgents(dir) {
254
+ const agentsDir = resolve(dir, '.claude', 'agents');
255
+ const agents = {};
256
+ if (!existsSync(agentsDir))
257
+ return agents;
258
+ for (const file of readdirSync(agentsDir)) {
259
+ if (!file.endsWith('.md'))
260
+ continue;
261
+ const name = file.replace('.md', '');
262
+ const content = readFileSync(resolve(agentsDir, file), 'utf-8');
263
+ // Parse YAML frontmatter
264
+ let description = name;
265
+ let model;
266
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
267
+ if (fmMatch) {
268
+ const fm = fmMatch[1];
269
+ const descMatch = fm.match(/description:\s*["']?(.*?)["']?\s*$/m);
270
+ if (descMatch)
271
+ description = descMatch[1];
272
+ const modelMatch = fm.match(/model:\s*(\S+)/m);
273
+ if (modelMatch)
274
+ model = modelMatch[1];
275
+ }
276
+ agents[name] = { description, prompt: content, model };
277
+ }
278
+ return agents;
279
+ }
253
280
  function gitPull(dir) {
254
281
  try {
255
282
  execSync('git fetch --quiet && git pull --ff-only --quiet', { cwd: dir, timeout: 30_000, stdio: 'pipe' });
@@ -383,13 +410,26 @@ async function main() {
383
410
  resumeOpts.continue = true;
384
411
  opts.resume = false;
385
412
  }
413
+ const agents = loadAgents(opts.projectDir);
414
+ // Load project CLAUDE.md as system prompt context (don't use settingSources
415
+ // which adds built-in agents like general-purpose, Explore, Plan)
416
+ let claudeMd = '';
417
+ const claudeMdPath = resolve(opts.projectDir, 'CLAUDE.md');
418
+ const dotClaudeMdPath = resolve(opts.projectDir, '.claude', 'CLAUDE.md');
419
+ if (existsSync(claudeMdPath))
420
+ claudeMd = readFileSync(claudeMdPath, 'utf-8');
421
+ else if (existsSync(dotClaudeMdPath))
422
+ claudeMd = readFileSync(dotClaudeMdPath, 'utf-8');
386
423
  const queryOptions = {
387
- settingSources: ['project'],
424
+ agents,
388
425
  agent: 'orchestrator',
389
426
  model: 'claude-opus-4-6',
390
427
  maxTurns: opts.maxTurns,
391
428
  cwd: opts.projectDir,
392
429
  };
430
+ if (claudeMd) {
431
+ queryOptions.systemPrompt = { type: 'preset', preset: 'claude_code', append: claudeMd };
432
+ }
393
433
  if (opts.skipPermissions) {
394
434
  queryOptions.permissionMode = 'bypassPermissions';
395
435
  queryOptions.allowDangerouslySkipPermissions = true;
@@ -43,7 +43,6 @@ export class TUI {
43
43
  // Render state
44
44
  pendingLines = [];
45
45
  renderTimer = null;
46
- lastStatusLen = 0;
47
46
  // Stats
48
47
  loopStart = Date.now();
49
48
  iteration_ = 0;
@@ -61,26 +60,25 @@ export class TUI {
61
60
  this.interactive = interactive && process.stdin.isTTY === true;
62
61
  if (this.interactive) {
63
62
  this.setupInput();
64
- // 4 fps render loop
65
- this.renderTimer = setInterval(() => this.render(), 250);
63
+ // 60 fps render loop
64
+ this.renderTimer = setInterval(() => this.render(), 16);
66
65
  }
67
66
  }
68
67
  // ─── Render loop ───
69
68
  render() {
70
69
  const out = process.stdout;
71
- // Clear current status line
72
- if (this.lastStatusLen > 0) {
73
- out.write('\r\x1b[2K');
74
- }
75
- // Flush pending log lines
76
- for (const line of this.pendingLines) {
77
- out.write(line + '\n');
70
+ const hasPending = this.pendingLines.length > 0;
71
+ // Erase current status line
72
+ out.write('\r\x1b[2K');
73
+ // Flush pending log lines — each gets its own line
74
+ if (hasPending) {
75
+ for (const line of this.pendingLines) {
76
+ out.write(line + '\n');
77
+ }
78
+ this.pendingLines = [];
78
79
  }
79
- this.pendingLines = [];
80
- // Draw status bar (single line, no \n — stays overwritable)
81
- const status = this.buildStatus();
82
- out.write(status);
83
- this.lastStatusLen = strip(status).length;
80
+ // Redraw status bar (no \n — stays on current line, overwritable by next render)
81
+ out.write(this.buildStatus());
84
82
  }
85
83
  buildStatus() {
86
84
  const elapsed = fmtDur(Date.now() - this.loopStart);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.132",
3
+ "version": "1.1.134",
4
4
  "author": "",
5
5
  "repository": {
6
6
  "type": "git",