Skip to content

feat!: release 4.0.0 — git worktree support & rich help overview - #12

Merged
graphicfox merged 19 commits into
masterfrom
release-4.0.0-worktree-support
Jul 17, 2026
Merged

feat!: release 4.0.0 — git worktree support & rich help overview#12
graphicfox merged 19 commits into
masterfrom
release-4.0.0-worktree-support

Conversation

@graphicfox

Copy link
Copy Markdown
Contributor

4.0.0 major release

Cuts the 4.0.0 major release. Merges the dev overhaul into a release branch and adds git-worktree support, a rich help/overview command, and a full README.

Breaking changes (from dev)

  • Dependency & runtime migration: @labor-digital/helferleinradashi, Node 22, TypeScript 5, commander 14, dockerode 4, inquirer 13, chalk 5, glob 13.
  • factory:* commands extracted to the Factory pipeline-app.
  • Added a Jest test suite (npm test).

New in this branch

  • Git worktree support — running lab inside a linked worktree spins up an isolated instance (own compose project / domain / IP / hosts entry / DB names) so a feature branch runs alongside the main checkout. DOPPLER_PROJECT stays shared with main; .env.template is never rewritten inside a worktree; the main checkout is unaffected. Detection is fail-safe (git --git-dir vs --git-common-dir).
  • lab help — grouped overview of every command for newcomers, plus lab help --json for scripts & AI agents (commands, aliases, options, platforms).
  • README — rewritten with requirements, quick start, per-command deep dive, worktree guide, config reference, and troubleshooting.

Fixes made while preparing the release

  • Fixed a release-breaking CI typo carried in from dev: uses: u@masterlabor-digital/conventional-release-action@master (kept the new "Run tests" step and @v6 actions).
  • Made npm, restart-engine, stop-engine cross-platform (they defaulted to Windows-only).
  • Hardened the build so lib/index.js keeps its executable bit on every rebuild (postbuild chmod).
  • Corrected stale .nvmrc (10 → 22).

Versioning

The feat! (factory extraction) is in the v3.16.7..HEAD range, so conventional-release-action will compute 4.0.0 on merge to master. The PR title also carries feat!: so a squash-merge still triggers the major bump.

Verification

  • npm run build ✅   npm test ✅ (24 suites / 37 tests)
  • Worktree behaviour and both lab help modes verified against the built CLI; unit tests added for detection, suffixing, idempotency and the .env.template skip.

🤖 Generated with Claude Code

Kim Martini and others added 19 commits February 27, 2026 13:43
…issing

Previously fell back to a hardcoded `{news, hero}` manifest when
`../factory-core/manifest.json` didn't exist or couldn't be parsed.
That swap was silent: downstream `factory:add` for any other
component then failed with "Component not found in factory manifest"
even though the real cause was a wrong cwd (lab-cli looks one level
up from cwd; the operator likely wasn't in a scaffolded
backend/app/src or frontend/app/src).

Replace with explicit UserError raises that tell the operator
exactly where lab-cli looked and what cwd it expects. Surface the
same error for "file present but not valid JSON" and "JSON but not
an object" — both indistinguishable from "missing" before.

Verified locally by rebuilding (npm run build) and running the
binary from /Users/kim/Work/Labor/Factory (no factory-core sibling):
previously returned the misleading fallback; now raises the
actionable UserError.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
getManifest() was wrapping every error — including the actionable
UserErrors we just added to fetchComponentManifest — with the
generic "Failed to fetch factory manifest." Operators saw that
flat message instead of the path + cwd context that would actually
help them fix the problem.

Pass UserErrors through unchanged. Other Error types (unexpected
ones — disk I/O surprises, etc.) still get wrapped with the
generic message because we don't trust their wording for
end-user display.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…line-app

- Add `factory:create` to scaffold new client projects from factory-core templates with Doppler project + secrets setup
- Add `factory:upgrade` to upgrade factory-core deps in backend/frontend and run TYPO3 migrations
- Extend Doppler API client with project/environment lifecycle helpers (create, exists, delete, createEnvironment, setSecrets)
- Add `-y/--yes` and `-i/--import` flags to docker compose up; `-y/--yes` to restart
- Polish wizards (DockerComposeServiceSelectWizard, ProjectNameInputWizard) and command registry plumbing
- Add design logs and tests covering the new commands
- README: document `add-component` and `upgrade`, flag deprecation — factory:* commands will move to the Factory pipeline-app and be removed from lab-cli in a future major release

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes `factory:create`, `factory:add` (was `add-component`), and
`factory:upgrade` (was `upgrade`) — these commands have been ported into
the Factory pipeline-app as in-process TypeScript modules. lab-cli's
scope returns to docker/dev orchestration; project scaffolding and
component injection live with the Factory tooling that consumes them.

- Delete `FactoryCreateCommand`, `FactoryAddCommand`, `FactoryUpgradeCommand` and their tests
- Delete `Core/Factory/ComponentManifest.ts` (only consumer was the factory commands)
- Drop the `factory:*` and `upgrade`/`add-component` registrations from `DefaultCommands`
- Strip the factory sections from the README
- Add a `prepare` script so `npm install <repo>#<branch>` builds `lib/` automatically

`Doppler.ts` still has the factory-only methods (createProject, deleteProject,
createEnvironment, setSecrets, projectExists) since they're general-purpose
primitives — left in place rather than coupled to a removed feature.

BREAKING CHANGE: `lab factory:create`, `lab factory:add`, `lab factory:upgrade`,
`lab upgrade`, and `lab add-component` no longer exist. Use the Factory
pipeline-app's `factory` CLI (or its web UI) instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…out prepare

The previous attempt added a `prepare` script so `npm install <repo>#factory-extracted`
would build lib/ on install. That fails on `-g` installs because npm's prepare flow
runs `npm run build` in an environment where node_modules/.bin/tsc isn't on PATH,
so tsc isn't found.

Workaround for this dev branch: drop the prepare script and check in the
compiled lib/ directly. Installing the branch now just unpacks the prebuilt
binary — no build step required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without a `files` field (and no `.npmignore`), `npm pack` falls back to
.gitignore — which excludes `lib/`. That meant the previous commit's
prebuilt `lib/` was committed to the branch but stripped out at install
time, leaving a broken global install with only `bin/` (the elevate +
unison helpers) and no `lib/index.js` for the `lab` bin to resolve.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
npm's git fetcher applies .gitignore-derived filters somewhere in its
clone-pack-install pipeline that strips top-level files under
gitignored directories — even when the `files` field in package.json
includes lib/ and the files are committed. Locally-built tarballs
include lib/index.js correctly; the git-source install does not.

Removing `lib` from .gitignore on this branch is the simplest fix: it
means lib/ becomes tracked normally so the gitignore-derived filter
never excludes it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The compiled lib/index.js was committed without the execute bit, which
left the global `lab` binary unrunnable after install (the bin symlink
worked but resolved to a non-executable file). Set the mode in the
git index so any install path preserves it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/main.yml
When lab is run inside a linked git worktree it now gives the app its own
isolated identity so a feature branch can be spun up alongside the main
checkout without clashing:

- COMPOSE_PROJECT_NAME is suffixed with the worktree directory name, which
  isolates all containers, networks and volumes.
- APP_DOMAIN, APP_IP, the /etc/hosts entry and the MySQL db/user names are
  derived per worktree.
- DOPPLER_PROJECT intentionally stays on the base name, so the worktree shares
  its secrets with the main checkout.
- The committed .env.template is never rewritten from within a worktree.

Detection is based on git's --git-dir vs --git-common-dir and fails safe: when
git is unavailable, the directory is not a repository, or we are in the main
working tree, behaviour is byte-for-byte identical to before. The result is
resolved once and cached on the AppContext.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a dedicated "lab help" command that prints a grouped, self-contained
overview of every command available on the current platform, together with the
prerequisites and a short explanation of the git-worktree behaviour - so a
newcomer can orient themselves without prior knowledge of the CLI.

"lab help --json" outputs the same information as JSON (commands, aliases,
options, supported platforms) so scripts and AI agents can discover the CLI
without scraping formatted text. The command list is read from the command
registry, so the overview always matches what is actually registered.

Commander's built-in help command is disabled in favour of this richer one, and
the default help output now points users and agents at "lab help".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restructure the README so someone who has never used the CLI can install and
use it. Adds a requirements section, a quick start, a deep-dive command
reference (every command with its alias, options, examples and platform
support), a "getting help" section covering "lab help" / "lab help --json", a
dedicated git-worktree guide for 4.0.0, a configuration reference with the merge
precedence, and a troubleshooting section. Fixes the stale "windows only" note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regenerate the shipped lib/ output for the worktree and help features (this
branch commits lib/ so "npm install" from git works without a build step) and
align package-lock.json to the merged 3.16.7 version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These three commands lacked a "platforms" block and therefore defaulted to
Windows-only, even though the tool is otherwise cross-platform. Enable them on
macOS, Linux and Windows (matching start-engine and stop-all) and update the
README platform notes accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tsc drops the executable bit on the compiled entry point, which breaks the npm
"bin" symlink when installing directly from git (previously fixed by a one-off
chmod commit that any rebuild silently reverted). Add a postbuild step that
restores mode 0755 on lib/index.js on every build (a no-op on Windows), so it
can never be lost again.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The release workflow only runs on push to master, so pull requests had no
checks. Add a CI workflow that installs, builds and runs the Jest suite on
every pull request (and on manual dispatch), so tests gate changes before they
reach master. Publishing stays exclusive to the release workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@graphicfox
graphicfox merged commit e14b180 into master Jul 17, 2026
1 check passed
graphicfox pushed a commit that referenced this pull request Jul 17, 2026
The 4.0.0 breaking changes (radashi + Node 22 migration, factory:* extraction,
worktree-aware docker app identity) landed via PR #12, but merging with a merge
commit hid the individual conventional commits from the release action, so they
were mistakenly published as 3.16.8. This commit carries a proper breaking-change
footer so the release action bumps the major version to 4.0.0.

BREAKING CHANGE: migrated the utility library from @labor-digital/helferlein to
radashi and the runtime to Node 22, extracted the factory:* commands into the
Factory pipeline-app, and changed how the docker app identity is derived when
running inside a git worktree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant