Skip to content

feat(cli): Add dev/self build targets for local CLI dogfooding#41

Merged
thecodedrift merged 2 commits into
mainfrom
feat/dev-cli-build
Jun 15, 2026
Merged

feat(cli): Add dev/self build targets for local CLI dogfooding#41
thecodedrift merged 2 commits into
mainfrom
feat/dev-cli-build

Conversation

@thecodedrift

@thecodedrift thecodedrift commented Jun 15, 2026

Copy link
Copy Markdown
Member

Add two non-production build targets so a locally built CLI can be exercised without publishing, and make local dogfooding behave exactly like a real install.

What

  • Build targets via a Vite define (TASKLESS_BUILD_TARGET): the CLI invocation baked into emitted skill/command/recipe content is now build-target-specific.
    • pnpm build (prod, default) → npx @taskless/cli — byte-identical to today (no-op).
    • pnpm build:dev → an absolute path, for validating this build from another repo.
    • pnpm build:self → a repo-root-relative path, for dogfooding in this repo.
    • dev/self also prepend a one-time banner to canonical skill/command bodies telling the agent to rebuild (pnpm build:self) if the local CLI is missing.
  • Local install replaces the symlink hack. build:self now compiles and runs taskless init --no-interactive, so .claude gets real reference stubs that delegate to the canonical .taskless/ store — identical to any other install. The old scripts/link-skills.ts (which raw-symlinked skills/ into .claude/) is removed.
  • Installer hardening + regression test. The installer now refuses to write through a symlinked target directory. The previous unlinkIfSymlink guarded only the leaf file, so a leftover link-skills directory symlink (.claude/skills/taskless -> ../../skills/taskless) routed stub writes back into source and clobbered it. Removed the two relic committed symlinks and gitignored the generated self-install artifacts.

Why

We hit this validating earlier work: there was no way to run the locally built CLI against another checkout, and dogfooding relied on raw symlinks that diverged from a real install. Routing local setup through the install pipeline makes it consistent and reliable — and surfaced the symlink-clobber bug, which is now fixed and covered by a test.

Review notes

  • Prod output is unchanged by design: applyCliInvocation is a strict no-op when the define equals npx @taskless/cli (verified: prod rebuild is a FULL TURBO cache hit, 297 tests pass).
  • The dev/self invocations bake local paths and must never be published — only pnpm build / pnpm package produce a release artifact.
  • New regression test: apply-install-plan.test.ts › "does not write through a symlinked skill directory".

Bake a build-target-specific invocation into emitted skill/command/recipe
content via a Vite define: prod ships `npx @taskless/cli`, `build:dev` an
absolute path (validate from another repo), `build:self` a repo-relative
path (dogfood in place). dev/self also prepend a one-time banner telling
the agent to rebuild if the local CLI is missing.

Replace the raw `link-skills` symlink step with a real self-install so
local `.claude` matches any other install (stubs delegating to `.taskless`).

Harden the installer to never write through a symlinked target directory —
a prior link-skills relic could otherwise route stub writes back into
source and clobber it. Add a regression test and gitignore the generated
self-install artifacts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 15, 2026 03:02

Copilot AI 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.

Pull request overview

This PR adds non-production build targets for the Taskless CLI so locally built artifacts can be dogfooded (in-repo) or validated (from another repo) without publishing, while making local dogfooding follow the same “real install” path as an actual CLI install.

Changes:

  • Introduces TASKLESS_BUILD_TARGET-driven Vite defines to bake a build-target-specific CLI invocation string (and optional notice banner) into emitted canonical skill/command content.
  • Replaces the previous .claude symlink-based local workflow by making pnpm build:self build the CLI and run taskless init --no-interactive to install real reference stubs.
  • Hardens the installer against symlinked target directories (prevents writing stubs through a directory symlink) and adds a regression test for the skill-directory case.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
turbo.json Adds TASKLESS_BUILD_TARGET to the build task env inputs for correct caching.
scripts/link-skills.ts Removes the old symlink-based local dogfooding script.
README.md Documents the new local build targets and the self-install workflow.
packages/cli/vite.config.ts Defines build-target-specific invocation + optional notice banner via Vite define.
packages/cli/test/apply-install-plan.test.ts Adds regression coverage for “symlinked skill directory should not be clobbered”.
packages/cli/src/util/invocation.ts Implements invocation rewriting and build-notice insertion helpers.
packages/cli/src/install/install.ts Hardens stub writing by normalizing symlinked target directories before writing.
packages/cli/src/install/canonical.ts Applies invocation rewriting + notice insertion when writing canonical content.
packages/cli/src/globals.d.ts Declares new Vite-injected globals.
packages/cli/src/commands/help.ts Rewrites baked CLI invocation inside rendered help recipes.
packages/cli/package.json Adds build:dev / build:self scripts for the CLI package.
package.json Updates root build scripts; adds build:dev and build:self orchestration.
.gitignore Ignores generated self-install artifacts (canonical skills/commands + stubs).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/cli/src/install/canonical.ts
Comment thread packages/cli/src/install/canonical.ts
Comment thread packages/cli/src/install/install.ts
Update the writeCanonicalSkill/writeCanonicalCommand JSDoc: content is no
longer strictly verbatim — dev/self builds rewrite the CLI invocation and
prepend a build notice, while prod stays byte-identical.

Add a regression test for a symlinked command-namespace directory
(.claude/commands/tskl), mirroring the skill-directory case, so the
command-path symlink hardening can't regress.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thecodedrift thecodedrift merged commit 1e3fc90 into main Jun 15, 2026
3 checks passed
@thecodedrift thecodedrift deleted the feat/dev-cli-build branch June 15, 2026 03:17
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.

2 participants