Skip to content

feat(project): show create progress like build and deploy - #2174

Merged
aidandaly24 merged 7 commits into
refactorfrom
feat/create-progress-ui
Sep 3, 2026
Merged

feat(project): show create progress like build and deploy#2174
aidandaly24 merged 7 commits into
refactorfrom
feat/create-progress-ui

Conversation

@aidandaly24

Copy link
Copy Markdown
Contributor

project create printed a plain line per step while build and deploy rendered a live
step list. This runs create under the same driver, so all three look the same.

✓ Creating project tree
⠋ Installing CDK dependencies with npm
  │ added 320 packages, and audited 341 packages in 6s
  Syncing Python dependencies with uv
  • create now goes through runWithProgress, the same driver build and deploy use.
  • The four subprocess steps (npm install, uv sync, lockfile generation) stream their output
    as output events, so the tail under the running step shows real progress instead of
    sitting empty.

Non-TTY and --json keep the previous plain line-per-step output, byte for byte.

Testing

  • bun test src — 2789 pass, 0 fail
  • bun run typecheck, bunx oxlint src, bunx prettier --check src clean
  • Drove a real project create in a TTY: spinner, ✓ marks, and the output tail all render;
    measured no event-loop stall over 150ms across the run
  • Verified --json and piped stderr produce output identical to before, and that a failing
    step renders with its tail preserved

`project create` printed a flat line per step while `build` and `deploy` render
the live step list #2163 introduced. It now uses the same `runWithProgress`
driver, so a TTY gets the spinner and per-step ✓, and the non-TTY and --json
paths keep the previous plain output byte for byte.

Every event the create generator yields is already a `step`, so nothing else
had to change. The bare interactive `project create` still opens the TUI wizard.
The step list create now runs under can show a live tail of the running step's
output, but create's subprocesses sent their chunks only to the debug log, so the
tail was always empty and create looked flatter than build and deploy.

`npm install` (CDK app and scaffolded runtime), `uv sync`, and container
lockfile generation now stream through withOutputEvents plus createLineSplitter,
the same bridge the CDK backend uses for synth. Chunks still reach the debug log
whole; the splitter reassembles them into lines for display and flushes an
unterminated trailing chunk when the process exits. `git init` stays plain since
it prints nothing worth tailing.

Draining the generator on a real create yields 3 step events and 133 output
events, including "added 320 packages, and audited 341 packages in 6s" and
"Creating virtual environment at: .venv". A cached npm install finishes in
milliseconds and flushes at the end, so the tail is only visible on a cold cache
or a slow step -- and on failure, where the driver keeps it in scrollback.
The rebase onto refactor picked up #2170, which renamed the hello-world-python
template shortcut, so the new streaming test referenced a constant that no
longer exists.
@github-actions github-actions Bot added the size/s PR size: S label Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed claude-security-reviewing Claude Code /security-review in progress agentcore-harness-reviewing AgentCore Harness review in progress labels Sep 2, 2026

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused change that brings project create in line with build/deploy by driving progress through runWithProgress, and factors a runStreaming helper so the three npm install / uv sync / lockfile-generation steps stream subprocess output as output events for the live tail.

  • The runStreaming helper in src/core/project/manager.tsx is a faithful factoring of the existing withOutputEvents(...) + createLineSplitter + finally(flush) pattern in src/core/project/backends/cdk.ts, including the .finally(() => lines.flush()) to drain unterminated trailing chunks.
  • interactive: ctx.require(JsonKey) ? false : undefined in src/handlers/project/create/index.ts matches the shape used by build/deploy and correctly forces the plain path only under --json, otherwise deferring to runWithProgress's TTY autodetection.
  • ProjectEvent = ProgressEvent, so passing the generator straight to runWithProgress is type-safe.
  • The other caller of projectManager.create — the wizard in screen.tsx — already filters on event.type === "step", so the new output events are silently ignored there. No regression.
  • The added test uses a real temp directory and mocks only at the runner boundary (the true I/O boundary), and covers the important edge case of flushing an unterminated trailing chunk on process exit.

No telemetry gap: the sibling build/deploy handlers don't instrument here either, so this isn't a new omission.

Nothing blocking — good to merge.

@codecov-commenter

codecov-commenter commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 62.22222% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.07%. Comparing base (d403f5d) to head (646fb74).
⚠️ Report is 1 commits behind head on refactor.

Files with missing lines Patch % Lines
src/core/project/manager.tsx 56.41% 17 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #2174      +/-   ##
============================================
- Coverage     97.12%   97.07%   -0.05%     
============================================
  Files           535      535              
  Lines         36844    36878      +34     
============================================
+ Hits          35783    35800      +17     
- Misses         1061     1078      +17     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

npm prints nothing at all while its stderr is piped, so the progress tail stayed
empty for the first ~5.8s of a ~6.5s install. Neither --progress=true nor a real
PTY helps: the flag is ignored when piped, and npm's TTY output is a textless
spinner. Its HTTP log is the only per-package progress it will emit, so
--loglevel=http is now parsed back into package names -- 'resolving aws-cdk-lib'
rather than 'npm http fetch GET 200 https://registry.npmjs.org/aws-cdk-lib 34ms'.

First readable line lands at 540ms instead of 5869ms, at no measurable cost.
uv sync needs none of this; it already prints for people.
@github-actions github-actions Bot added size/m PR size: M and removed size/s PR size: S labels Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
…g test

The four functions in npmProgress.ts were each used once, and tarballVersion parsed
a version out of a tarball name only to print it in a scrolling tail. Collapsed to a
single function beside the flag that makes npm talk, dropping the file: the version,
the URL parsing, and the decodeURIComponent guard all go away, since npm's only
encoding is %2f for a scope slash.

Also drops the create streaming test, which asserted that a mocked runner's chunks
reach the generator -- plumbing the type system already pins.
@github-actions github-actions Bot added size/s PR size: S and removed size/m PR size: M labels Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
runStreaming duplicated run rather than replacing it, leaving two methods doing one
job and one caller -- git init -- still on the old path because it prints little worth
tailing. That is not worth a duplicate method: run now streams, every caller yields it,
and git init's one line shows like any other.
@github-actions github-actions Bot added size/s PR size: S and removed size/s PR size: S labels Sep 2, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 2, 2026

@Hweinstock Hweinstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this!

return this.runner(command, {
cwd,
onOutput: (chunk) => {
this.logger.debug(chunk);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOS here since I think its existing behavior, but this is dumping raw output (with ANSI codes) into the logs which are not human readable.

Ex.

{
  "level": "debug",
  "msg": "\u001b[32m+\u001b[39m \u001b[1ms3transfer\u001b[0m\u001b[2m==0.19.2\u001b[0m\n \u001b[32m+\u001b[39m \u001b[1msix\u001b[0m\u001b[2m==1.17.0\u001b[0m\n \u001b[32m+",
  "time": 1788392133886,
  "cliSessionId": "cebc9a0c-9985-400f-b5e7-28c9221ce9cd",
  "version": "1.0.0",
  "module": "projectManager"
}
{
  "level": "debug",
  "msg": "\u001b[39m \u001b[1msse-starlette\u001b[0m\u001b[2m==3.4.8\u001b[0m",
  "time": 1788392133887,
  "cliSessionId": "cebc9a0c-9985-400f-b5e7-28c9221ce9cd",
  "version": "1.0.0",
  "module": "projectManager"
}
{
  "level": "debug",
  "msg": "\n ",
  "time": 1788392133887,
  "cliSessionId": "cebc9a0c-9985-400f-b5e7-28c9221ce9cd",
  "version": "1.0.0",
  "module": "projectManager"
}
{
  "level": "debug",
  "msg": "\u001b[32m",
  "time": 1788392133887,
  "cliSessionId": "cebc9a0c-9985-400f-b5e7-28c9221ce9cd",
  "version": "1.0.0",
  "module": "projectManager"
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhh this is a good call out. I can fix this in a follow up. I don't think that this was pre existing.

for await (const event of config.projectManager.create(createInput)) {
if (event.type === "step") config.io.stderr.write(`${event.message}\n`);
}
// Same driver as build and deploy: a live step list in a TTY, and the previous plain

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i don't feel like this comment is relevant.

@aidandaly24
aidandaly24 merged commit e44a533 into refactor Sep 3, 2026
22 checks passed
@aidandaly24
aidandaly24 deleted the feat/create-progress-ui branch September 3, 2026 01:20
This was referenced Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants