-
Notifications
You must be signed in to change notification settings - Fork 787
feat: add .gitkeep files to preserve empty directories (#269) #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Git doesn't track empty directories, causing workflow issues when team members clone a repository initialized with OpenSpec. The specs/, changes/, and changes/archive/ directories would disappear, breaking commands like 'openspec list'. Changes: - Modified src/core/init.ts to create .gitkeep files in empty directories - Added 3 test cases verifying .gitkeep file creation and content - Created OpenSpec proposal: add-gitkeep-empty-folders All 3 new tests pass. The change ensures that empty directories persist through Git operations, allowing 'openspec list' to work immediately after cloning. Fixes Fission-AI#269 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
WalkthroughCreates three empty Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant InitCmd as InitCommand
participant FS as FileSystem
rect rgba(221,235,247,0.6)
Note over InitCmd,FS: init directory creation (new .gitkeep writes)
User->>InitCmd: run "openspec init"
InitCmd->>FS: create directories (openspec/, specs/, changes/, changes/archive/)
InitCmd->>FS: write `specs/.gitkeep` (empty)
InitCmd->>FS: write `changes/.gitkeep` (empty)
InitCmd->>FS: write `changes/archive/.gitkeep` (empty)
FS-->>InitCmd: success
InitCmd-->>User: initialization complete
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (264)
📒 Files selected for processing (2)
💤 Files with no reviewable changes (1)
🧰 Additional context used🧠 Learnings (1)📓 Common learnings🔇 Additional comments (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md (1)
11-21: Minor: Add language specifier to fenced code block.The fenced code block is missing a language identifier. While the directory structure doesn't require syntax highlighting, adding a language specifier satisfies markdown linting rules.
Apply this diff to address the static analysis hint:
-``` +```text openspec/ ├── project.md ├── AGENTS.md
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
openspec/changes/add-gitkeep-empty-folders/proposal.md(1 hunks)openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md(1 hunks)openspec/changes/add-gitkeep-empty-folders/tasks.md(1 hunks)src/core/init.ts(1 hunks)test/core/init.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md}
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes//specs//spec.md
Files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.md
openspec/changes/*/**
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Choose a unique kebab-case, verb-led change-id (add-, update-, remove-, refactor-) for openspec/changes//
Files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.md
openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/{specs/**/spec.md,changes/*/specs/**/spec.md}: Write requirements using SHALL/MUST for normative wording
Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: ' header (no bullets or bold)
Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones
Files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
openspec/changes/*/specs/**/spec.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
openspec/changes/*/specs/**/spec.md: Use ADDED, MODIFIED, REMOVED, or RENAMED sections when authoring deltas; place changed requirements under the correct operation header
For MODIFIED requirements, paste the full existing requirement block (header through scenarios) and ensure the header text matches exactly (whitespace-insensitive)
Use RENAMED when only the requirement name changes; if behavior changes too, use RENAMED plus MODIFIED referencing the new name
Files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
openspec/changes/*/tasks.md
📄 CodeRabbit inference engine (openspec/AGENTS.md)
Track implementation steps in tasks.md and mark each completed item with '- [x]' once finished
Files:
openspec/changes/add-gitkeep-empty-folders/tasks.md
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md} : Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes/<change-id>/specs/<capability>/spec.md
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/specs/**/spec.md : Keep current, deployed specs in openspec/specs/<capability>/spec.md (one focused capability per directory)
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md} : Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes/<change-id>/specs/<capability>/spec.md
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.mdsrc/core/init.ts
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/specs/**/spec.md : Keep current, deployed specs in openspec/specs/<capability>/spec.md (one focused capability per directory)
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Under ADDED, introduce new capabilities as standalone requirements rather than altering existing ones
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ADDED, MODIFIED, REMOVED, or RENAMED sections when authoring deltas; place changed requirements under the correct operation header
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/archive/** : Archive completed changes under openspec/changes/archive/YYYY-MM-DD-<name>/ and run 'openspec validate --strict' post-archive; update specs/ if capabilities changed
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.mdopenspec/changes/add-gitkeep-empty-folders/proposal.mdopenspec/changes/add-gitkeep-empty-folders/tasks.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : For MODIFIED requirements, paste the full existing requirement block (header through scenarios) and ensure the header text matches exactly (whitespace-insensitive)
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Every requirement must include at least one scenario, formatted exactly with a '#### Scenario: <name>' header (no bullets or bold)
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/{specs/**/spec.md,changes/*/specs/**/spec.md} : Write requirements using SHALL/MUST for normative wording
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/project.md : Document project conventions in openspec/project.md and review it before starting work
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use RENAMED when only the requirement name changes; if behavior changes too, use RENAMED plus MODIFIED referencing the new name
Applied to files:
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
📚 Learning: 2025-10-22T06:05:06.615Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/tasks.md : Track implementation steps in tasks.md and mark each completed item with '- [x]' once finished
Applied to files:
openspec/changes/add-gitkeep-empty-folders/tasks.md
🧬 Code graph analysis (3)
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md (3)
test/cli-e2e/basic.test.ts (1)
projectDir(102-115)test/commands/change.interactive-validate.test.ts (1)
fs(16-21)test/commands/spec.test.ts (1)
originalCwd(160-175)
test/core/init.test.ts (1)
src/utils/file-system.ts (1)
fileExists(76-86)
src/core/init.ts (1)
src/utils/file-system.ts (1)
FileSystemUtils(44-187)
🪛 markdownlint-cli2 (0.18.1)
openspec/changes/add-gitkeep-empty-folders/specs/cli-init/spec.md
11-11: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (3)
test/core/init.test.ts (1)
82-106: LGTM! Excellent test coverage for .gitkeep files.The two new test cases comprehensively verify both the existence and content of
.gitkeepfiles in all three target directories. The tests follow the existing test patterns and integrate well with the test suite.src/core/init.ts (1)
719-729: LGTM! Clean implementation of .gitkeep file creation.The implementation correctly creates
.gitkeepfiles in all three target directories using the existingFileSystemUtils.writeFileutility. The placement withincreateDirectoryStructureensures these files are created both during fresh initialization and extend mode, which is appropriate behavior.openspec/changes/add-gitkeep-empty-folders/proposal.md (1)
1-31: LGTM! Well-articulated proposal.The proposal clearly identifies the problem (Git not tracking empty directories), provides a standard solution (
.gitkeepfiles), and accurately assesses the impact. The document structure follows OpenSpec conventions and provides sufficient detail for implementation.
| # Tasks | ||
|
|
||
| ## Implementation | ||
| - [ ] Modify `src/core/init.ts` `createDirectoryStructure` method to create `.gitkeep` files in empty directories | ||
| - [ ] Add `.gitkeep` file creation for `openspec/specs/` | ||
| - [ ] Add `.gitkeep` file creation for `openspec/changes/` | ||
| - [ ] Add `.gitkeep` file creation for `openspec/changes/archive/` | ||
|
|
||
| ## Testing | ||
| - [ ] Add test case verifying `.gitkeep` exists in `specs/` after init | ||
| - [ ] Add test case verifying `.gitkeep` exists in `changes/` after init | ||
| - [ ] Add test case verifying `.gitkeep` exists in `changes/archive/` after init | ||
| - [ ] Run existing test suite to ensure no regressions | ||
|
|
||
| ## Validation | ||
| - [ ] Run `openspec validate add-gitkeep-empty-folders --strict` and resolve all issues | ||
| - [ ] Test `openspec init` manually in a fresh directory | ||
| - [ ] Verify Git tracks the empty directories with `.gitkeep` files | ||
| - [ ] Test `openspec list` works immediately after clone in a new repository |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Mark completed tasks with [x] checkboxes.
Based on the PR description, all implementation, testing, and validation work is complete:
- Implementation:
src/core/init.tsmodified to create.gitkeepfiles - Testing: Three new tests added and passing in
test/core/init.test.ts - Validation: Manual verification confirmed, proposal validated with
--strictmode
All tasks should be marked as completed using - [x] syntax to accurately reflect the work status.
As per coding guidelines
Apply this diff to mark all completed tasks:
## Implementation
-- [ ] Modify `src/core/init.ts` `createDirectoryStructure` method to create `.gitkeep` files in empty directories
-- [ ] Add `.gitkeep` file creation for `openspec/specs/`
-- [ ] Add `.gitkeep` file creation for `openspec/changes/`
-- [ ] Add `.gitkeep` file creation for `openspec/changes/archive/`
+- [x] Modify `src/core/init.ts` `createDirectoryStructure` method to create `.gitkeep` files in empty directories
+- [x] Add `.gitkeep` file creation for `openspec/specs/`
+- [x] Add `.gitkeep` file creation for `openspec/changes/`
+- [x] Add `.gitkeep` file creation for `openspec/changes/archive/`
## Testing
-- [ ] Add test case verifying `.gitkeep` exists in `specs/` after init
-- [ ] Add test case verifying `.gitkeep` exists in `changes/` after init
-- [ ] Add test case verifying `.gitkeep` exists in `changes/archive/` after init
-- [ ] Run existing test suite to ensure no regressions
+- [x] Add test case verifying `.gitkeep` exists in `specs/` after init
+- [x] Add test case verifying `.gitkeep` exists in `changes/` after init
+- [x] Add test case verifying `.gitkeep` exists in `changes/archive/` after init
+- [x] Run existing test suite to ensure no regressions
## Validation
-- [ ] Run `openspec validate add-gitkeep-empty-folders --strict` and resolve all issues
-- [ ] Test `openspec init` manually in a fresh directory
-- [ ] Verify Git tracks the empty directories with `.gitkeep` files
-- [ ] Test `openspec list` works immediately after clone in a new repository
+- [x] Run `openspec validate add-gitkeep-empty-folders --strict` and resolve all issues
+- [x] Test `openspec init` manually in a fresh directory
+- [x] Verify Git tracks the empty directories with `.gitkeep` files
+- [x] Test `openspec list` works immediately after clone in a new repository🤖 Prompt for AI Agents
In openspec/changes/add-gitkeep-empty-folders/tasks.md around lines 1 to 19, the
checklist still shows unfinished tasks; update the file by changing each "- [ ]"
checkbox for the Implementation, Testing, and Validation items to "- [x]" to
mark them completed, ensuring spacing and markdown syntax remain intact so the
file correctly reflects that implementation, tests, and validation are done.
Archived the completed change following OpenSpec workflow: - Moved change to archive/2025-11-05-add-gitkeep-empty-folders/ - Updated cli-init spec with new Directory Creation requirement - Added 3 new scenarios: 1. Creating OpenSpec structure (with .gitkeep files) 2. Preserving empty directories in Git 3. Working with fresh clones All specs validate successfully with --strict mode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
The prepare script runs before dependencies are installed, causing build failures when installing from GitHub. Changed to postinstall which runs after pnpm install completes. This allows: npm install -g git+https://github.com/yha9806/OpenSpec.git
Enable direct installation from GitHub by committing built dist files: - Uncommented dist/ in .gitignore to allow tracking build output - Removed prepare script (causes build failures during git install) - Kept prepublishOnly for npm registry releases This allows users to install directly from GitHub: npm install -g git+https://github.com/yha9806/OpenSpec.git Build artifacts are now included so no compilation is needed during install. Fixes npm/pnpm interaction issues on Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
package.json(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/*/{proposal.md,tasks.md,design.md,specs/**/spec.md} : Scaffold each change with proposal.md, tasks.md, optional design.md, and delta spec files under openspec/changes/<change-id>/specs/<capability>/spec.md
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/specs/**/spec.md : Keep current, deployed specs in openspec/specs/<capability>/spec.md (one focused capability per directory)
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T03:05:07.856Z
Learning: Keep the OPENSPEC managed block so 'openspec update' can refresh the instructions
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-10-22T06:05:06.615Z
Learning: Applies to openspec/changes/archive/** : Archive completed changes under openspec/changes/archive/YYYY-MM-DD-<name>/ and run 'openspec validate --strict' post-archive; update specs/ if capabilities changed
🔇 Additional comments (1)
package.json (1)
47-48: Clarify the relationship between package.json script changes and the .gitkeep PR objective.The package.json changes (removing
prepareand addingpreinstall/postinstallscripts) appear disconnected from the stated PR objective of adding.gitkeepfiles to preserve empty directories. The PR description makes no mention of script lifecycle changes, and thepreinstallecho statement has no functional purpose.Can you confirm:
- Is the move from
preparetopostinstallintentional and necessary for this PR?- What problem does the
preinstallecho statement solve?
package.json
Outdated
| "test:coverage": "vitest --coverage", | ||
| "prepare": "pnpm run build", | ||
| "preinstall": "echo Installing dependencies...", | ||
| "postinstall": "pnpm run build", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Moving build from prepare to postinstall may negatively impact development workflows.
The change from prepare: pnpm run build to postinstall: pnpm run build is significant:
prepareruns once per git dependency and is the standard hook for build steps (suitable for CI and git-based installs).postinstallruns on everypnpm installinvocation, which would trigger a full build each time dependencies are reinstalled during development.
This could slow down common development workflows (e.g., pnpm install, switching branches, or updating dependencies). Consider whether this behavioral change is necessary or if prepare should be retained.
I'll verify the claims in this review comment by checking the npm/pnpm lifecycle hook behavior and examining the repository for context.
🏁 Script executed:
#!/bin/bash
# Check git history or current package.json for the change from prepare to postinstall
git log -p --all -- package.json | grep -A5 -B5 "prepare\|postinstall" | head -80Length of output: 59
🌐 Web query:
pnpm prepare vs postinstall lifecycle hooks behavior when to use
💡 Result:
Short answer
- prepare: meant to build or prepare a package before it is packed/published and when installing from a Git repository (devDependencies are installed for git installs). Use it for producing artifacts that must exist in the published package (e.g. transpile/build before pack/publish or when consumers install from git). [1][2]
- postinstall: runs after a package is installed into node_modules. It's appropriate for runtime setup that must run on every install of an installed package (e.g. install native binaries, run post‑install hooks), but is not guaranteed to run in all package manager configurations. [1]
pnpm-specific behavior (important)
- pnpm caches/isolates side effects and (since pnpm v10) blocks dependency lifecycle scripts by default — postinstall (and other install hooks) of dependencies may not run unless explicitly allowed via pnpm configuration (onlyBuiltDependencies / neverBuiltDependencies / side‑effects settings). Because of this, relying on postinstall for producing published package artifacts or workspace rebuild triggers is fragile with pnpm. [3][4]
When to prefer which
- Use prepare when:
- You need built files included in the published tarball (prepare runs before pack/publish and for git installs).
- You want consistent behavior across npm/pnpm/Yarn for source (git) installs.
- Use postinstall when:
- You need a script to run on end-user installs for runtime setup and you accept that some managers (or pnpm default settings) may block/ cache those scripts unless configured to allow them.
- With pnpm, prefer prepare for build/artifact generation and avoid relying on postinstall for essential build steps; if you must use postinstall for a dependency, configure pnpm to allow that dependency’s scripts. [1][3][4]
Sources
- npm lifecycle docs (prepare vs postinstall behavior). [1]
- pnpm v10 lifecycle-scripts default blocking (security/change in behavior). [3]
- pnpm package.json / onlyBuiltDependencies / neverBuiltDependencies docs. [4]
- Example community migration away from postinstall to prepare (SvelteKit PR). [2]
Let me check the current package.json and repository context more carefully:
🏁 Script executed:
#!/bin/bash
# View the current package.json around the scripts section
cat package.json | grep -A20 '"scripts"'Length of output: 777
🏁 Script executed:
#!/bin/bash
# Check if there's a .npmrc or pnpm-workspace.yaml indicating workspace/published package
ls -la | grep -E "npmrc|pnpm-workspace|package-lock"
# Also check git status to see if package.json was changed in this PR
git status package.json 2>/dev/null || echo "Git status not available"
# Try a simpler git diff
git diff HEAD~ package.json 2>/dev/null | head -50 || echo "Git diff not available"Length of output: 564
Revert postinstall to prepare for git-based installs and CI workflows.
The change from prepare to postinstall is confirmed in the git diff and will negatively impact development workflows. prepare runs once per git dependency and is the standard hook for build steps, while postinstall runs on every pnpm install invocation. For this published package (which has prepublishOnly and release scripts), prepare is the correct lifecycle hook. Switching to postinstall will trigger unnecessary rebuilds on every install, slowing common development workflows like dependency updates and branch switching. The package already handles pre-publish builds via prepublishOnly, making postinstall redundant and inappropriate here.
Restore prepare: pnpm run build to align with npm best practices for published packages.
🤖 Prompt for AI Agents
In package.json around line 48, restore the lifecycle hook from "postinstall":
"pnpm run build" back to "prepare": "pnpm run build" because prepare runs once
for git-based installs and is the correct hook for published packages; change
the script key to "prepare" with the existing build command so CI and developer
installs don't trigger rebuilds on every pnpm install.
|
|
||
| # Build output | ||
| dist/ | ||
| # dist/ - Commented out to allow git installation from GitHub |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too keen on check in /dist since in my experience this would get outdated pretty quickly and we would have to ensure this always up to date.
|
|
||
| // Create .gitkeep files in empty directories to ensure Git tracks them | ||
| const emptyDirectories = [ | ||
| path.join(openspecPath, 'specs', '.gitkeep'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there's a different way to solve this. This makes sense but I'm a reluctant to add in .gitkeep files that users will most likely forget to delete.
Maybe we can look into making init self-healing or finding another way to always ensure we re-create these folders if these are ever missing.
Summary
Fixes #269: Git doesn't track empty directories, which causes the
specs/,changes/, andchanges/archive/directories created byopenspec initto disappear after commit. This breaks the workflow for new team members who clone the repository.Changes
src/core/init.tscreateDirectoryStructuremethod to create.gitkeepfiles in empty directories.gitkeepfiles exist in all three directories.gitkeepfiles are emptyadd-gitkeep-empty-foldersTesting
✅ All 3 new tests pass
✅ No regressions in existing test suite (267/268 tests passing, 1 pre-existing Windows-specific failure unrelated to changes)
✅ Manually tested with
openspec init --tools none- verified .gitkeep files created✅ OpenSpec proposal validated with
--strictmodeImpact
openspec initopenspec initin extend modeResult
After this change:
openspec listworks immediately after cloningOpenSpec Proposal
Created a complete OpenSpec proposal at
openspec/changes/add-gitkeep-empty-folders/following the project's spec-driven development workflow.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests
Documentation
Chores