prjct-cli 0.64.0 → 1.0.0
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.
- package/CHANGELOG.md +298 -0
- package/core/__tests__/ai-tools/formatters.test.ts +358 -0
- package/core/ai-tools/formatters.ts +76 -57
- package/core/ai-tools/registry.ts +2 -2
- package/core/services/sync-service.ts +6 -1
- package/dist/bin/prjct.mjs +72 -58
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,303 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0] - 2026-02-05
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- add input source tagging for context items (PRJ-102) (#106)
|
|
8
|
+
- add timeout management with configurable limits (PRJ-111) (#104)
|
|
9
|
+
- implement graceful degradation for missing dependencies (PRJ-114) (#103)
|
|
10
|
+
- add .prjct-state.md local state file for persistence (PRJ-112) (#102)
|
|
11
|
+
- hierarchical AGENTS.md resolution and template improvements (PRJ-101) (#99)
|
|
12
|
+
- add staleness detection for CLAUDE.md context (PRJ-120) (#97)
|
|
13
|
+
- complete Linear/JIRA workflow integration (#95)
|
|
14
|
+
- monorepo support with nested PRJCT.md inheritance (PRJ-118) (#94)
|
|
15
|
+
- implement output tiers for cleaner CLI output (#88)
|
|
16
|
+
- modular CLAUDE.md for reduced token usage - PRJ-94 (#86)
|
|
17
|
+
- Add showMetrics config option - PRJ-70 (#82)
|
|
18
|
+
- Selective memory retrieval based on task relevance - PRJ-107 (#81)
|
|
19
|
+
- Add session stats to p. stats command - PRJ-89 (#80)
|
|
20
|
+
- Lazy template loading with TTL cache - PRJ-76 (#79)
|
|
21
|
+
- Add confidence scores to all stored preferences - PRJ-104 (#78)
|
|
22
|
+
- Context diff preview before sync applies - PRJ-125 (#77)
|
|
23
|
+
- Unified output system with new methods - PRJ-130 (#76)
|
|
24
|
+
- Error messages with context and recovery hints - PRJ-131 (#75)
|
|
25
|
+
- Read-before-write enforcement for templates - PRJ-108 (#74)
|
|
26
|
+
- Complete and improve help text documentation - PRJ-133 (#73)
|
|
27
|
+
- Workflow hooks via natural language - PRJ-137 (#72)
|
|
28
|
+
- Subtask progress dashboard with domain colors - PRJ-138 (#71)
|
|
29
|
+
- preserve user customizations during sync - PRJ-115 (#70)
|
|
30
|
+
- automated release pipeline - PRJ-147 (#68)
|
|
31
|
+
- add project indexing and analysis services (PRJ-85, PRJ-87) (#66)
|
|
32
|
+
- metrics display in output (PRJ-68, PRJ-69) (#54)
|
|
33
|
+
- add prjct uninstall command (PRJ-146) (#65)
|
|
34
|
+
- add prjct doctor command (PRJ-117) (#62)
|
|
35
|
+
- smart watch mode - auto-sync on file changes (PRJ-123) (#61)
|
|
36
|
+
- add --quiet flag for silent output (PRJ-97) (#60)
|
|
37
|
+
- interactive onboarding wizard (PRJ-124) (#58)
|
|
38
|
+
- smart context filtering tools for AI agents (PRJ-127) (#57)
|
|
39
|
+
- workflow state machine + bidirectional Linear sync (#55)
|
|
40
|
+
- progress indicators for long-running operations (PRJ-129) (#52)
|
|
41
|
+
- agent activity stream for real-time visibility (PRJ-135) (#51)
|
|
42
|
+
- show explicit next steps after each command (PRJ-136) (#50)
|
|
43
|
+
- multi-agent output Phase 3 - Auto-detect + Continue.dev (PRJ-126) (#49)
|
|
44
|
+
- multi-agent output Phase 2 - Copilot + Windsurf (PRJ-126) (#48)
|
|
45
|
+
- multi-agent context output - Phase 1 (PRJ-126) (#47)
|
|
46
|
+
- bidirectional sync Linear ↔ prjct (PRJ-142) (#46)
|
|
47
|
+
- migrate Linear and JIRA from MCP to native SDK (PRJ-141) (#45)
|
|
48
|
+
- enhance skill system with remote installation and lock file (#44)
|
|
49
|
+
- Windsurf IDE support (PRJ-66) (#43)
|
|
50
|
+
- Google Antigravity support via Skills (PRJ-64) (#42)
|
|
51
|
+
- add mandatory plan-before-action rule to all agents
|
|
52
|
+
- Cursor IDE support (PRJ-63) (#40)
|
|
53
|
+
- Cursor IDE support (PRJ-63)
|
|
54
|
+
- dual platform support - Claude + Gemini (PRJ-62) (#39)
|
|
55
|
+
- 100% agentic task routing with subtask fragmentation
|
|
56
|
+
- add agent/skill orchestrator + agentskills.io integration
|
|
57
|
+
- auto-install MCP servers + individual command skills
|
|
58
|
+
- AI-powered ticket enrichment + 4 tracker integrations v0.33.0
|
|
59
|
+
- JIRA MCP integration for corporate SSO v0.32.0
|
|
60
|
+
- JIRA Integration v0.31.0 (#30)
|
|
61
|
+
- PM Expert auto-enrichment + statusline fixes v0.30.2
|
|
62
|
+
- add p. update command for manual sync
|
|
63
|
+
- modular statusline with Linear integration v0.29.0 (#29)
|
|
64
|
+
- redesign build and release flow for npm
|
|
65
|
+
- modular statusline with Linear integration v0.29.0
|
|
66
|
+
- integrate issue tracker and AI enrichment for project management
|
|
67
|
+
- per-project task filtering for status bar v0.28.0
|
|
68
|
+
- Skill integration system v0.27.0 (#24)
|
|
69
|
+
- Claude Code Skill Integration (Agentic) v0.27.0
|
|
70
|
+
- Complete development cycle with workflow integrity v0.26.0
|
|
71
|
+
- Unified /p:task command + auto-sync notification v0.24.0
|
|
72
|
+
- Branch + PR workflow v0.23.0
|
|
73
|
+
- Notion per-project databases + skill registration v0.22.0
|
|
74
|
+
- add optional Notion integration v0.21.0
|
|
75
|
+
- enhance error handling and permissions management
|
|
76
|
+
- UX/UI Design Agent Integration v0.20.0
|
|
77
|
+
- prompt-builder fix + web removal v0.19.0
|
|
78
|
+
- add TestSprite integration for AI-powered testing
|
|
79
|
+
- CLI-API sync bridge + /p:auth command v0.18.0
|
|
80
|
+
- Claude Code sub-agents integration v0.17.0
|
|
81
|
+
- Security, performance, and architecture improvements v0.16.1
|
|
82
|
+
- Dead code cleanup - remove ~6,600 lines v0.16.0
|
|
83
|
+
- Add MCP server configuration for Context7
|
|
84
|
+
- Template optimization - reduce 39 to 27 commands v0.15.0
|
|
85
|
+
- Refactor Project Management with UUID Migration and Enhanced Context Handling
|
|
86
|
+
- Enhance Project Management with Terminal Dock and UI Improvements
|
|
87
|
+
- Actionable Dashboard + Session Recovery v0.14.0
|
|
88
|
+
- Add MomentumWidget + Code workspace + Weekly reports
|
|
89
|
+
- Ship Deep Sync + Cleanup migrations v0.13.0
|
|
90
|
+
- MigrationGate + bug fixes
|
|
91
|
+
- JSON-First Architecture (Zero Data Loss)
|
|
92
|
+
- Implement project stats API and enhance UI components
|
|
93
|
+
- Enhance project management and terminal functionality in web application
|
|
94
|
+
- Revamp web application with Next.js and enhanced features
|
|
95
|
+
- Introduce new server and web components for prjct
|
|
96
|
+
- Release 0.10.14 with 100% agentic delegation and task tool integration
|
|
97
|
+
- Add ⚡ prjct branding with animated spinner
|
|
98
|
+
- 100% agentic agent assignment - JS=orchestrator, Claude=decisions
|
|
99
|
+
- 100% agentic system - eliminate all procedural keyword-based logic
|
|
100
|
+
- Release 0.10.10 with executable templates and context reduction
|
|
101
|
+
- Release 0.10.8 with minimal output system and reduced CLI verbosity
|
|
102
|
+
- Release 0.10.7 with critical improvements and enhanced context handling
|
|
103
|
+
- Enhanced global CLAUDE.md template for better prjct usage
|
|
104
|
+
- Rich project context for Claude
|
|
105
|
+
- Dynamic project context for Claude
|
|
106
|
+
- Intelligent Agent System & Performance Optimization (v0.10.0)
|
|
107
|
+
- add November 22, 2025 release notes for version 0.9.1
|
|
108
|
+
- context optimization and prompt conciseness
|
|
109
|
+
- add legacy installation detector and cleanup system for pre-v0.8.2 curl installations
|
|
110
|
+
- add system timestamp tools and optimize top 7 templates
|
|
111
|
+
- memory-efficient file operations for large JSONL files
|
|
112
|
+
- simplify installation to npm-only with automatic post-install setup
|
|
113
|
+
- v0.8.0 - conversational interface with zero memorization
|
|
114
|
+
- add comprehensive testing documentation
|
|
115
|
+
- add website component tests and configure vitest workspace
|
|
116
|
+
- migrate test suite to Vitest with coverage reporting
|
|
117
|
+
- add isSupported flag to agent detection for Claude and Terminal agents
|
|
118
|
+
- add setup, migrate-all commands and mark roadmap/status/build as implemented
|
|
119
|
+
- redesign footer layout and add AI policy page with updated navigation
|
|
120
|
+
- add Vercel Analytics and Speed Insights tracking to website
|
|
121
|
+
- simplify workflow to 5 essential commands
|
|
122
|
+
- rebrand from project management to developer momentum tool with streamlined templates and workflows
|
|
123
|
+
- add editor uninstallation and smart project data fusion to prjct init
|
|
124
|
+
- add first-time setup flow and auto-initialization for all commands
|
|
125
|
+
- add auto-migration from v0.1.0 projects during post-install hook
|
|
126
|
+
- add auto-install and clean uninstall functionality with editor tracking
|
|
127
|
+
- add GitHub Packages support and track installed editors in config
|
|
128
|
+
- add Windows compatibility feature card to changelog
|
|
129
|
+
- add automatic npm publication and update detection system
|
|
130
|
+
- publish prjct-cli to npm registry
|
|
131
|
+
- remove bun and homebrew installation methods
|
|
132
|
+
- add natural language interface with English and Spanish support
|
|
133
|
+
- add interactive workflow system with capability detection and installation
|
|
134
|
+
- release v0.3.0 with interactive editor selection and codebase analysis
|
|
135
|
+
- add project management workflows for analyzing, tracking, and fixing tasks
|
|
136
|
+
- update CNAME handling and add 404 page for better routing
|
|
137
|
+
- add cleanup and design commands with advanced options
|
|
138
|
+
- initialize project structure with core files and documentation
|
|
139
|
+
|
|
140
|
+
### Bug Fixes
|
|
141
|
+
|
|
142
|
+
- generate IDE context files with correct paths and formats (PRJ-122) (#107)
|
|
143
|
+
- improve sync output with summary-first format (PRJ-100) (#100)
|
|
144
|
+
- correct template paths and agent loading in CLAUDE.md (#93)
|
|
145
|
+
- make lefthook hooks portable (no bun required) (#92)
|
|
146
|
+
- skip lefthook in CI environments (#91)
|
|
147
|
+
- use npm instead of bun in lefthook hooks (#90)
|
|
148
|
+
- add pre-commit hooks to prevent commits with lint errors (#89)
|
|
149
|
+
- remove legacy p.*.md commands on sync
|
|
150
|
+
- ensure test isolation in IndexStorage tests
|
|
151
|
+
- remove MCP integrations, keep only Context7 (#87)
|
|
152
|
+
- make Linear/JIRA templates explicitly ignore MCP tools
|
|
153
|
+
- remove MCP inheritance from Linear/JIRA templates
|
|
154
|
+
- standardize confirmation pattern across all commands (#85)
|
|
155
|
+
- LLM debe manejar los prompts, no el CLI - PRJ-149 (#84)
|
|
156
|
+
- Claude over-plans simple commands like p. sync - PRJ-148 (#83)
|
|
157
|
+
- implement silent memory application - PRJ-103 (#69)
|
|
158
|
+
- ignore tar warning in release workflow - PRJ-147
|
|
159
|
+
- remove --provenance (requires public repo) - PRJ-147
|
|
160
|
+
- use Production environment for npm secrets - PRJ-147
|
|
161
|
+
- use semver-sorted tags for version detection - PRJ-147
|
|
162
|
+
- npm auth configuration for CI publish - PRJ-147
|
|
163
|
+
- add Bun setup for test runner in CI - PRJ-147
|
|
164
|
+
- use npm instead of bun for CI tests - PRJ-147
|
|
165
|
+
- remove IDE files from repo - PRJ-144, PRJ-145
|
|
166
|
+
- add --help handler in CLI entry point for CI compatibility
|
|
167
|
+
- update tests for CI compatibility
|
|
168
|
+
- CI workflow - remove unsupported bun reporter flag and fix verification
|
|
169
|
+
- enforce workflow steps in templates (PRJ-143) (#56)
|
|
170
|
+
- add $PRJCT_CLI prefix to relative paths in templates (PRJ-143)
|
|
171
|
+
- use stderr for Linear connection log to not break JSON output
|
|
172
|
+
- show Cursor in same format as other providers in --version
|
|
173
|
+
- Cursor command syntax (PRJ-65) (#41)
|
|
174
|
+
- reduce permission prompts from 50+ to 1 (#38)
|
|
175
|
+
- cleanup legacy files and fix TS error (#37)
|
|
176
|
+
- chore: release v0.35.2
|
|
177
|
+
- connect CLI workflow to CommandExecutor
|
|
178
|
+
- execute orchestration in TypeScript, not just paths (#36)
|
|
179
|
+
- execute orchestration in TypeScript, not just paths
|
|
180
|
+
- remove unsafe 'as unknown' casts (PRJ-54)
|
|
181
|
+
- complete error differentiation (Phase 3) (#35)
|
|
182
|
+
- enable enrichment by default in statusline config
|
|
183
|
+
- self-healing setup in bin/prjct v0.30.1
|
|
184
|
+
- distribution system overhaul - remove fallback, always read from npm root v0.30.0
|
|
185
|
+
- setup.ts auto-execute when run directly
|
|
186
|
+
- remove duplicate statusline version check
|
|
187
|
+
- dynamic path resolution for compiled dist/
|
|
188
|
+
- ALWAYS run postinstall setup, remove global detection
|
|
189
|
+
- detect /opt/homebrew for M1/M2 Macs in postinstall
|
|
190
|
+
- handle bun test warnings in release script
|
|
191
|
+
- include assets/ in npm package + add linear to router
|
|
192
|
+
- add cliVersion to project.json on postinstall
|
|
193
|
+
- resolve symlinks in bin/prjct for npm install
|
|
194
|
+
- agents only write to global storage v0.18.2
|
|
195
|
+
- agents only in global storage + auto-migrate legacy v0.18.1
|
|
196
|
+
- serve.js use start instead of start:prod
|
|
197
|
+
- Remove migration gate from production
|
|
198
|
+
- Restore sidebar collapse + fix server OOM crash
|
|
199
|
+
- Prevent terminal session loss on navigation
|
|
200
|
+
- Terminal responsive & performance issues
|
|
201
|
+
- Server runs in production mode, port 9472
|
|
202
|
+
- Export commands as singleton for direct invocation
|
|
203
|
+
- Update global CLAUDE.md on sync, analyze, and init
|
|
204
|
+
- Add glob dependency and update to modern API
|
|
205
|
+
- critical memory leaks - LRU cache, HTTP cleanup, session expiration
|
|
206
|
+
- ensure command templates always update by removing mtime checks and forcing overwrites
|
|
207
|
+
- resolve critical installation bugs and add auto-update functionality with visual feedback
|
|
208
|
+
- resolve TypeScript errors in website tests
|
|
209
|
+
- remove unused variables to pass lint
|
|
210
|
+
- update vercel build and install commands to use npm prefix syntax
|
|
211
|
+
- remove unused Globe import from Privacy.tsx
|
|
212
|
+
- resolve TypeScript errors in website build
|
|
213
|
+
- remove vercel.json, configure Root Directory in Vercel UI
|
|
214
|
+
- set rootDirectory to website for Vercel
|
|
215
|
+
- use npm --prefix for Vercel build command
|
|
216
|
+
- correct Vercel install command path
|
|
217
|
+
- configure Vercel deployment output directory
|
|
218
|
+
- restore Catppuccin-inspired ASCII art and fix undefined editor names in prjct start command
|
|
219
|
+
- update Badge import path to use correct casing
|
|
220
|
+
- return success exit code for help command
|
|
221
|
+
- remove install script tests from workflow
|
|
222
|
+
- add TERM environment variable to workflow steps
|
|
223
|
+
- add missing WorkflowsGuide.tsx to repository
|
|
224
|
+
- deploy install.sh and setup.sh to website
|
|
225
|
+
- replace inquirer with prompts for better CommonJS compatibility in interactive editor selection
|
|
226
|
+
- resolve installation path errors in setup scripts and add verification tests
|
|
227
|
+
- update init command to use global architecture and fix installer version display
|
|
228
|
+
- update install command URL to use www.prjct.app
|
|
229
|
+
- build(deps-dev): bump vite from 4.5.14 to 7.1.7 in /docs (#1)
|
|
230
|
+
|
|
231
|
+
### Performance
|
|
232
|
+
|
|
233
|
+
- parallelize agent/skill loading with Promise.all (PRJ-110) (#101)
|
|
234
|
+
- parallelize sync operations for 30-50% speedup (PRJ-116) (#59)
|
|
235
|
+
|
|
236
|
+
### Refactoring
|
|
237
|
+
|
|
238
|
+
- migrate from ESLint + Prettier to Biome
|
|
239
|
+
- consolidate and optimize CI workflows
|
|
240
|
+
- extract StackDetector from sync-service (PRJ-86) (#64)
|
|
241
|
+
- extract ContextFileGenerator from sync-service (PRJ-88) (#63)
|
|
242
|
+
- differentiate error types in catch blocks - Phase 2 (PRJ-60) (#34)
|
|
243
|
+
- differentiate error types in catch blocks (PRJ-51) (#33)
|
|
244
|
+
- simplify logger level detection logic (#32)
|
|
245
|
+
- consolidate hardcoded paths to use pathManager singleton (#31)
|
|
246
|
+
- type consolidation in core/types/ v0.20.1
|
|
247
|
+
- centralize types in core/types/ following DRY principles
|
|
248
|
+
- restructure command and agent modules for improved organization
|
|
249
|
+
- consolidate command and storage modules for improved structure
|
|
250
|
+
- migrate testing setup to Bun and enhance documentation
|
|
251
|
+
- Update project structure and enhance component functionality
|
|
252
|
+
- update command registry structure and remove unused imports
|
|
253
|
+
- remove open source references and GitHub links
|
|
254
|
+
- move Changelog link from header to footer
|
|
255
|
+
- use centralized helper utilities in commands
|
|
256
|
+
- migrate from GitHub Pages to Vercel deployment
|
|
257
|
+
- remove redundant title from changelog technical details section
|
|
258
|
+
- extract reusable components from Changelog.tsx
|
|
259
|
+
- sync install.sh from scripts directory to website/public and docs
|
|
260
|
+
- remove unnecessary comments from prjct.sh script
|
|
261
|
+
- remove unnecessary comments from command line parsing logic
|
|
262
|
+
- remove comments and unnecessary whitespace across core modules
|
|
263
|
+
- move author data and system fields from local to global config
|
|
264
|
+
- migrate legacy project files to new global structure with auto-migration
|
|
265
|
+
- rename landing directory to website and update deploy workflow paths
|
|
266
|
+
- update build paths from docs to lp directory in deploy workflow
|
|
267
|
+
- improve GitHub Pages deployment workflow with better file handling and directory structure
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
## [0.64.1] - 2026-02-05
|
|
271
|
+
|
|
272
|
+
### Bug Fixes
|
|
273
|
+
|
|
274
|
+
- **IDE context file generation (PRJ-122)**: Fixed Cursor and Windsurf context file paths and formats
|
|
275
|
+
|
|
276
|
+
### Implementation Details
|
|
277
|
+
|
|
278
|
+
Fixed misalignment between `ai-provider.ts` (correct paths) and `ai-tools/registry.ts` (incorrect paths). Updated Cursor output to `.cursor/rules/prjct.mdc` with MDC format and `alwaysApply: true` frontmatter. Updated Windsurf output to `.windsurf/rules/prjct.md` with `trigger: always_on` frontmatter. Modified sync-service default behavior to auto-detect IDE tools when `.cursor/` or `.windsurf/` directories exist.
|
|
279
|
+
|
|
280
|
+
### Learnings
|
|
281
|
+
|
|
282
|
+
- Two separate implementations existed (ai-provider vs ai-tools) that needed synchronization
|
|
283
|
+
- IDE formats differ: Cursor uses `alwaysApply: true`, Windsurf uses `trigger: always_on`
|
|
284
|
+
- Auto-detection pattern: check for directory existence to enable optional features
|
|
285
|
+
|
|
286
|
+
### Test Plan
|
|
287
|
+
|
|
288
|
+
#### For QA
|
|
289
|
+
1. Run `prjct sync` in project with `.cursor/` dir - verify `.cursor/rules/prjct.mdc` generated
|
|
290
|
+
2. Run `prjct sync` in project with `.windsurf/` dir - verify `.windsurf/rules/prjct.md` generated
|
|
291
|
+
3. Verify Cursor file has `alwaysApply: true` in frontmatter
|
|
292
|
+
4. Verify Windsurf file has `trigger: always_on` in frontmatter
|
|
293
|
+
5. Run `bun test` - all 405 tests pass
|
|
294
|
+
|
|
295
|
+
#### For Users
|
|
296
|
+
- `prjct sync` now auto-generates IDE context files when `.cursor/` or `.windsurf/` directories exist
|
|
297
|
+
- No manual flags needed - detection is automatic
|
|
298
|
+
- No breaking changes
|
|
299
|
+
|
|
300
|
+
|
|
3
301
|
## [0.64.0] - 2026-02-05
|
|
4
302
|
|
|
5
303
|
### Features
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for AI Tools Formatters
|
|
3
|
+
*
|
|
4
|
+
* @see PRJ-122
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, expect, test } from 'bun:test'
|
|
8
|
+
import {
|
|
9
|
+
formatForClaude,
|
|
10
|
+
formatForContinue,
|
|
11
|
+
formatForCopilot,
|
|
12
|
+
formatForCursor,
|
|
13
|
+
formatForWindsurf,
|
|
14
|
+
getFormatter,
|
|
15
|
+
type ProjectContext,
|
|
16
|
+
} from '../../ai-tools/formatters'
|
|
17
|
+
import { AI_TOOLS, getAIToolConfig } from '../../ai-tools/registry'
|
|
18
|
+
|
|
19
|
+
// =============================================================================
|
|
20
|
+
// Test Fixtures
|
|
21
|
+
// =============================================================================
|
|
22
|
+
|
|
23
|
+
const mockContext: ProjectContext = {
|
|
24
|
+
projectId: 'test-project-id',
|
|
25
|
+
name: 'test-project',
|
|
26
|
+
version: '1.0.0',
|
|
27
|
+
ecosystem: 'Node.js',
|
|
28
|
+
projectType: 'library',
|
|
29
|
+
languages: ['TypeScript'],
|
|
30
|
+
frameworks: ['Hono'],
|
|
31
|
+
repoPath: '/Users/test/project',
|
|
32
|
+
branch: 'main',
|
|
33
|
+
fileCount: 100,
|
|
34
|
+
commits: 50,
|
|
35
|
+
hasChanges: false,
|
|
36
|
+
commands: {
|
|
37
|
+
install: 'bun install',
|
|
38
|
+
dev: 'bun run dev',
|
|
39
|
+
test: 'bun test',
|
|
40
|
+
build: 'bun run build',
|
|
41
|
+
lint: 'bun run lint',
|
|
42
|
+
format: 'bun run format',
|
|
43
|
+
},
|
|
44
|
+
agents: {
|
|
45
|
+
workflow: ['prjct-planner', 'prjct-shipper'],
|
|
46
|
+
domain: ['backend'],
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// Registry Tests
|
|
52
|
+
// =============================================================================
|
|
53
|
+
|
|
54
|
+
describe('AI Tools Registry', () => {
|
|
55
|
+
test('cursor uses correct output file path', () => {
|
|
56
|
+
expect(AI_TOOLS.cursor.outputFile).toBe('.cursor/rules/prjct.mdc')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('windsurf uses correct output file path', () => {
|
|
60
|
+
expect(AI_TOOLS.windsurf.outputFile).toBe('.windsurf/rules/prjct.md')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('copilot uses correct output file path', () => {
|
|
64
|
+
expect(AI_TOOLS.copilot.outputFile).toBe('.github/copilot-instructions.md')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('claude uses correct output file path', () => {
|
|
68
|
+
expect(AI_TOOLS.claude.outputFile).toBe('CLAUDE.md')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('continue uses correct output file path', () => {
|
|
72
|
+
expect(AI_TOOLS.continue.outputFile).toBe('.continue/config.json')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('getAIToolConfig returns config for valid tool', () => {
|
|
76
|
+
const config = getAIToolConfig('cursor')
|
|
77
|
+
expect(config).not.toBeNull()
|
|
78
|
+
expect(config?.id).toBe('cursor')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('getAIToolConfig returns null for invalid tool', () => {
|
|
82
|
+
const config = getAIToolConfig('invalid-tool')
|
|
83
|
+
expect(config).toBeNull()
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// =============================================================================
|
|
88
|
+
// Formatter Tests
|
|
89
|
+
// =============================================================================
|
|
90
|
+
|
|
91
|
+
describe('formatForCursor', () => {
|
|
92
|
+
const config = AI_TOOLS.cursor
|
|
93
|
+
|
|
94
|
+
test('generates MDC format with YAML frontmatter', () => {
|
|
95
|
+
const result = formatForCursor(mockContext, config)
|
|
96
|
+
|
|
97
|
+
// Should start with YAML frontmatter
|
|
98
|
+
expect(result.startsWith('---\n')).toBe(true)
|
|
99
|
+
expect(result).toContain('description: prjct context for test-project')
|
|
100
|
+
expect(result).toContain('alwaysApply: true')
|
|
101
|
+
expect(result).toContain('---')
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('includes project info', () => {
|
|
105
|
+
const result = formatForCursor(mockContext, config)
|
|
106
|
+
|
|
107
|
+
expect(result).toContain('test-project')
|
|
108
|
+
expect(result).toContain('library')
|
|
109
|
+
expect(result).toContain('Node.js')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('includes tech stack', () => {
|
|
113
|
+
const result = formatForCursor(mockContext, config)
|
|
114
|
+
|
|
115
|
+
expect(result).toContain('TypeScript')
|
|
116
|
+
expect(result).toContain('Hono')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
test('includes commands', () => {
|
|
120
|
+
const result = formatForCursor(mockContext, config)
|
|
121
|
+
|
|
122
|
+
expect(result).toContain('bun install')
|
|
123
|
+
expect(result).toContain('bun run dev')
|
|
124
|
+
expect(result).toContain('bun test')
|
|
125
|
+
expect(result).toContain('bun run build')
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
describe('formatForWindsurf', () => {
|
|
130
|
+
const config = AI_TOOLS.windsurf
|
|
131
|
+
|
|
132
|
+
test('generates MD format with YAML frontmatter', () => {
|
|
133
|
+
const result = formatForWindsurf(mockContext, config)
|
|
134
|
+
|
|
135
|
+
// Should start with YAML frontmatter
|
|
136
|
+
expect(result.startsWith('---\n')).toBe(true)
|
|
137
|
+
expect(result).toContain('description: prjct context for test-project')
|
|
138
|
+
expect(result).toContain('trigger: always_on')
|
|
139
|
+
expect(result).toContain('---')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('uses trigger: always_on (not alwaysApply)', () => {
|
|
143
|
+
const result = formatForWindsurf(mockContext, config)
|
|
144
|
+
|
|
145
|
+
expect(result).toContain('trigger: always_on')
|
|
146
|
+
expect(result).not.toContain('alwaysApply')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
test('includes project info', () => {
|
|
150
|
+
const result = formatForWindsurf(mockContext, config)
|
|
151
|
+
|
|
152
|
+
expect(result).toContain('test-project')
|
|
153
|
+
expect(result).toContain('library')
|
|
154
|
+
expect(result).toContain('Node.js')
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
test('includes commands in bash block', () => {
|
|
158
|
+
const result = formatForWindsurf(mockContext, config)
|
|
159
|
+
|
|
160
|
+
expect(result).toContain('```bash')
|
|
161
|
+
expect(result).toContain('bun install')
|
|
162
|
+
expect(result).toContain('bun run dev')
|
|
163
|
+
expect(result).toContain('bun test')
|
|
164
|
+
expect(result).toContain('bun run build')
|
|
165
|
+
expect(result).toContain('```')
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
describe('formatForCopilot', () => {
|
|
170
|
+
const config = AI_TOOLS.copilot
|
|
171
|
+
|
|
172
|
+
test('generates minimal format without frontmatter', () => {
|
|
173
|
+
const result = formatForCopilot(mockContext, config)
|
|
174
|
+
|
|
175
|
+
// Copilot uses plain markdown, no YAML frontmatter
|
|
176
|
+
expect(result.startsWith('# Copilot Instructions')).toBe(true)
|
|
177
|
+
expect(result).not.toContain('---')
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
test('includes project info', () => {
|
|
181
|
+
const result = formatForCopilot(mockContext, config)
|
|
182
|
+
|
|
183
|
+
expect(result).toContain('test-project')
|
|
184
|
+
expect(result).toContain('library')
|
|
185
|
+
expect(result).toContain('Node.js')
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
test('includes essential commands only', () => {
|
|
189
|
+
const result = formatForCopilot(mockContext, config)
|
|
190
|
+
|
|
191
|
+
expect(result).toContain('bun test')
|
|
192
|
+
expect(result).toContain('bun run build')
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
describe('formatForClaude', () => {
|
|
197
|
+
const config = AI_TOOLS.claude
|
|
198
|
+
|
|
199
|
+
test('generates detailed markdown format', () => {
|
|
200
|
+
const result = formatForClaude(mockContext, config)
|
|
201
|
+
|
|
202
|
+
expect(result).toContain('# test-project - Project Rules')
|
|
203
|
+
expect(result).toContain('<!-- projectId: test-project-id -->')
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
test('includes prjct workflow reference', () => {
|
|
207
|
+
const result = formatForClaude(mockContext, config)
|
|
208
|
+
|
|
209
|
+
expect(result).toContain('## PRJCT RULES')
|
|
210
|
+
expect(result).toContain('p. sync')
|
|
211
|
+
expect(result).toContain('p. task')
|
|
212
|
+
expect(result).toContain('p. done')
|
|
213
|
+
expect(result).toContain('p. ship')
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
test('includes commands table', () => {
|
|
217
|
+
const result = formatForClaude(mockContext, config)
|
|
218
|
+
|
|
219
|
+
expect(result).toContain('| Action | Command |')
|
|
220
|
+
expect(result).toContain('bun install')
|
|
221
|
+
expect(result).toContain('bun run dev')
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
test('includes agent references', () => {
|
|
225
|
+
const result = formatForClaude(mockContext, config)
|
|
226
|
+
|
|
227
|
+
expect(result).toContain('prjct-planner')
|
|
228
|
+
expect(result).toContain('prjct-shipper')
|
|
229
|
+
expect(result).toContain('backend')
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
describe('formatForContinue', () => {
|
|
234
|
+
const config = AI_TOOLS.continue
|
|
235
|
+
|
|
236
|
+
test('generates valid JSON format', () => {
|
|
237
|
+
const result = formatForContinue(mockContext, config)
|
|
238
|
+
|
|
239
|
+
const parsed = JSON.parse(result)
|
|
240
|
+
expect(parsed).toBeDefined()
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
test('includes system message with project info', () => {
|
|
244
|
+
const result = formatForContinue(mockContext, config)
|
|
245
|
+
const parsed = JSON.parse(result)
|
|
246
|
+
|
|
247
|
+
expect(parsed.systemMessage).toContain('test-project')
|
|
248
|
+
expect(parsed.systemMessage).toContain('library')
|
|
249
|
+
expect(parsed.systemMessage).toContain('Node.js')
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
test('includes context providers', () => {
|
|
253
|
+
const result = formatForContinue(mockContext, config)
|
|
254
|
+
const parsed = JSON.parse(result)
|
|
255
|
+
|
|
256
|
+
expect(parsed.contextProviders).toBeArray()
|
|
257
|
+
expect(parsed.contextProviders.length).toBeGreaterThan(0)
|
|
258
|
+
expect(parsed.contextProviders).toContainEqual({ name: 'code' })
|
|
259
|
+
expect(parsed.contextProviders).toContainEqual({ name: 'diff' })
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
test('includes slash commands', () => {
|
|
263
|
+
const result = formatForContinue(mockContext, config)
|
|
264
|
+
const parsed = JSON.parse(result)
|
|
265
|
+
|
|
266
|
+
expect(parsed.slashCommands).toBeArray()
|
|
267
|
+
expect(parsed.slashCommands.length).toBeGreaterThan(0)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
test('includes custom test command with project test command', () => {
|
|
271
|
+
const result = formatForContinue(mockContext, config)
|
|
272
|
+
const parsed = JSON.parse(result)
|
|
273
|
+
|
|
274
|
+
expect(parsed.customCommands).toBeArray()
|
|
275
|
+
const testCmd = parsed.customCommands.find((c: { name: string }) => c.name === 'test')
|
|
276
|
+
expect(testCmd).toBeDefined()
|
|
277
|
+
expect(testCmd.prompt).toContain('bun test')
|
|
278
|
+
})
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
// =============================================================================
|
|
282
|
+
// getFormatter Tests
|
|
283
|
+
// =============================================================================
|
|
284
|
+
|
|
285
|
+
describe('getFormatter', () => {
|
|
286
|
+
test('returns formatter for claude', () => {
|
|
287
|
+
const formatter = getFormatter('claude')
|
|
288
|
+
expect(formatter).toBe(formatForClaude)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
test('returns formatter for cursor', () => {
|
|
292
|
+
const formatter = getFormatter('cursor')
|
|
293
|
+
expect(formatter).toBe(formatForCursor)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
test('returns formatter for windsurf', () => {
|
|
297
|
+
const formatter = getFormatter('windsurf')
|
|
298
|
+
expect(formatter).toBe(formatForWindsurf)
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
test('returns formatter for copilot', () => {
|
|
302
|
+
const formatter = getFormatter('copilot')
|
|
303
|
+
expect(formatter).toBe(formatForCopilot)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
test('returns formatter for continue', () => {
|
|
307
|
+
const formatter = getFormatter('continue')
|
|
308
|
+
expect(formatter).toBe(formatForContinue)
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
test('returns null for unknown tool', () => {
|
|
312
|
+
const formatter = getFormatter('unknown-tool')
|
|
313
|
+
expect(formatter).toBeNull()
|
|
314
|
+
})
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
// =============================================================================
|
|
318
|
+
// Edge Cases
|
|
319
|
+
// =============================================================================
|
|
320
|
+
|
|
321
|
+
describe('Formatter Edge Cases', () => {
|
|
322
|
+
test('handles empty languages array', () => {
|
|
323
|
+
const ctx = { ...mockContext, languages: [] }
|
|
324
|
+
|
|
325
|
+
const cursorResult = formatForCursor(ctx, AI_TOOLS.cursor)
|
|
326
|
+
expect(cursorResult).not.toContain('Languages:')
|
|
327
|
+
|
|
328
|
+
const windsurfResult = formatForWindsurf(ctx, AI_TOOLS.windsurf)
|
|
329
|
+
expect(windsurfResult).toContain('## Stack')
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
test('handles empty frameworks array', () => {
|
|
333
|
+
const ctx = { ...mockContext, frameworks: [] }
|
|
334
|
+
|
|
335
|
+
const cursorResult = formatForCursor(ctx, AI_TOOLS.cursor)
|
|
336
|
+
expect(cursorResult).not.toContain('Frameworks:')
|
|
337
|
+
|
|
338
|
+
const windsurfResult = formatForWindsurf(ctx, AI_TOOLS.windsurf)
|
|
339
|
+
expect(windsurfResult).toContain('## Stack')
|
|
340
|
+
})
|
|
341
|
+
|
|
342
|
+
test('handles empty agents', () => {
|
|
343
|
+
const ctx = { ...mockContext, agents: { workflow: [], domain: [] } }
|
|
344
|
+
|
|
345
|
+
const claudeResult = formatForClaude(ctx, AI_TOOLS.claude)
|
|
346
|
+
expect(claudeResult).toContain('**Domain**: none')
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
test('handles special characters in project name', () => {
|
|
350
|
+
const ctx = { ...mockContext, name: '@scope/my-project' }
|
|
351
|
+
|
|
352
|
+
const cursorResult = formatForCursor(ctx, AI_TOOLS.cursor)
|
|
353
|
+
expect(cursorResult).toContain('@scope/my-project')
|
|
354
|
+
|
|
355
|
+
const claudeResult = formatForClaude(ctx, AI_TOOLS.claude)
|
|
356
|
+
expect(claudeResult).toContain('@scope/my-project')
|
|
357
|
+
})
|
|
358
|
+
})
|
|
@@ -114,50 +114,60 @@ Load from \`~/.prjct-cli/projects/${ctx.projectId}/agents/\`:
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
* Format context for Cursor (.
|
|
118
|
-
*
|
|
117
|
+
* Format context for Cursor (.cursor/rules/prjct.mdc)
|
|
118
|
+
* MDC format with YAML frontmatter, optimized for inline suggestions
|
|
119
|
+
*
|
|
120
|
+
* @see https://cursor.com/docs/context/rules
|
|
119
121
|
*/
|
|
120
122
|
export function formatForCursor(ctx: ProjectContext, _config: AIToolConfig): string {
|
|
121
|
-
const
|
|
123
|
+
const lines: string[] = []
|
|
124
|
+
|
|
125
|
+
// MDC format with YAML frontmatter
|
|
126
|
+
lines.push('---')
|
|
127
|
+
lines.push(`description: prjct context for ${ctx.name}`)
|
|
128
|
+
lines.push('globs:')
|
|
129
|
+
lines.push('alwaysApply: true')
|
|
130
|
+
lines.push('---')
|
|
131
|
+
lines.push('')
|
|
122
132
|
|
|
123
133
|
// Project identity
|
|
124
|
-
|
|
125
|
-
|
|
134
|
+
lines.push(`You are working on ${ctx.name}, a ${ctx.projectType} ${ctx.ecosystem} project.`)
|
|
135
|
+
lines.push('')
|
|
126
136
|
|
|
127
137
|
// Tech stack
|
|
128
|
-
|
|
138
|
+
lines.push('## Tech Stack')
|
|
129
139
|
if (ctx.languages.length > 0) {
|
|
130
|
-
|
|
140
|
+
lines.push(`- Languages: ${ctx.languages.join(', ')}`)
|
|
131
141
|
}
|
|
132
142
|
if (ctx.frameworks.length > 0) {
|
|
133
|
-
|
|
143
|
+
lines.push(`- Frameworks: ${ctx.frameworks.join(', ')}`)
|
|
134
144
|
}
|
|
135
|
-
|
|
145
|
+
lines.push('')
|
|
136
146
|
|
|
137
147
|
// Commands
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
148
|
+
lines.push('## Commands')
|
|
149
|
+
lines.push(`- Install: \`${ctx.commands.install}\``)
|
|
150
|
+
lines.push(`- Dev: \`${ctx.commands.dev}\``)
|
|
151
|
+
lines.push(`- Test: \`${ctx.commands.test}\``)
|
|
152
|
+
lines.push(`- Build: \`${ctx.commands.build}\``)
|
|
153
|
+
lines.push('')
|
|
144
154
|
|
|
145
155
|
// Code style - language agnostic
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
lines.push('## Code Style')
|
|
157
|
+
lines.push(`- Follow ${ctx.ecosystem} conventions`)
|
|
158
|
+
lines.push('- Match existing code patterns in this project')
|
|
159
|
+
lines.push('- Use idiomatic constructs for the language')
|
|
160
|
+
lines.push('')
|
|
151
161
|
|
|
152
162
|
// Best practices
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return
|
|
163
|
+
lines.push('## Best Practices')
|
|
164
|
+
lines.push('- Write clean, readable code')
|
|
165
|
+
lines.push('- Add comments only for complex logic')
|
|
166
|
+
lines.push('- Keep functions small and focused')
|
|
167
|
+
lines.push('- Handle errors appropriately')
|
|
168
|
+
lines.push('- Write tests for new functionality')
|
|
169
|
+
|
|
170
|
+
return lines.join('\n')
|
|
161
171
|
}
|
|
162
172
|
|
|
163
173
|
/**
|
|
@@ -194,48 +204,57 @@ export function formatForCopilot(ctx: ProjectContext, _config: AIToolConfig): st
|
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
/**
|
|
197
|
-
* Format context for Windsurf (.
|
|
198
|
-
*
|
|
207
|
+
* Format context for Windsurf (.windsurf/rules/prjct.md)
|
|
208
|
+
* MD format with YAML frontmatter, optimized for Cascade AI
|
|
209
|
+
*
|
|
210
|
+
* @see https://docs.windsurf.com/windsurf/cascade/memories
|
|
199
211
|
*/
|
|
200
212
|
export function formatForWindsurf(ctx: ProjectContext, _config: AIToolConfig): string {
|
|
201
|
-
const
|
|
213
|
+
const lines: string[] = []
|
|
214
|
+
|
|
215
|
+
// YAML frontmatter (Windsurf uses trigger: always_on instead of alwaysApply)
|
|
216
|
+
lines.push('---')
|
|
217
|
+
lines.push(`description: prjct context for ${ctx.name}`)
|
|
218
|
+
lines.push('trigger: always_on')
|
|
219
|
+
lines.push('---')
|
|
220
|
+
lines.push('')
|
|
202
221
|
|
|
203
222
|
// Project identity
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
223
|
+
lines.push(`# ${ctx.name}`)
|
|
224
|
+
lines.push('')
|
|
225
|
+
lines.push(`${ctx.projectType} project using ${ctx.ecosystem}.`)
|
|
226
|
+
lines.push('')
|
|
208
227
|
|
|
209
228
|
// Tech stack (concise)
|
|
210
|
-
|
|
211
|
-
|
|
229
|
+
lines.push('## Stack')
|
|
230
|
+
lines.push(`- ${ctx.languages.join(', ')}`)
|
|
212
231
|
if (ctx.frameworks.length > 0) {
|
|
213
|
-
|
|
232
|
+
lines.push(`- ${ctx.frameworks.join(', ')}`)
|
|
214
233
|
}
|
|
215
|
-
|
|
234
|
+
lines.push('')
|
|
216
235
|
|
|
217
236
|
// Commands (essential only)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
lines.push('## Commands')
|
|
238
|
+
lines.push('```bash')
|
|
239
|
+
lines.push(`# Install`)
|
|
240
|
+
lines.push(ctx.commands.install)
|
|
241
|
+
lines.push(`# Dev`)
|
|
242
|
+
lines.push(ctx.commands.dev)
|
|
243
|
+
lines.push(`# Test`)
|
|
244
|
+
lines.push(ctx.commands.test)
|
|
245
|
+
lines.push(`# Build`)
|
|
246
|
+
lines.push(ctx.commands.build)
|
|
247
|
+
lines.push('```')
|
|
248
|
+
lines.push('')
|
|
230
249
|
|
|
231
250
|
// Code style - language agnostic
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
251
|
+
lines.push('## Rules')
|
|
252
|
+
lines.push(`- Follow ${ctx.ecosystem} conventions`)
|
|
253
|
+
lines.push('- Match existing project patterns')
|
|
254
|
+
lines.push('- Clean code, minimal comments')
|
|
255
|
+
lines.push('- Test new functionality')
|
|
237
256
|
|
|
238
|
-
return
|
|
257
|
+
return lines.join('\n')
|
|
239
258
|
}
|
|
240
259
|
|
|
241
260
|
/**
|
|
@@ -40,7 +40,7 @@ export const AI_TOOLS: Record<string, AIToolConfig> = {
|
|
|
40
40
|
cursor: {
|
|
41
41
|
id: 'cursor',
|
|
42
42
|
name: 'Cursor',
|
|
43
|
-
outputFile: '.
|
|
43
|
+
outputFile: '.cursor/rules/prjct.mdc',
|
|
44
44
|
outputPath: 'repo',
|
|
45
45
|
maxTokens: 2000,
|
|
46
46
|
format: 'concise',
|
|
@@ -58,7 +58,7 @@ export const AI_TOOLS: Record<string, AIToolConfig> = {
|
|
|
58
58
|
windsurf: {
|
|
59
59
|
id: 'windsurf',
|
|
60
60
|
name: 'Windsurf',
|
|
61
|
-
outputFile: '.
|
|
61
|
+
outputFile: '.windsurf/rules/prjct.md',
|
|
62
62
|
outputPath: 'repo',
|
|
63
63
|
maxTokens: 2000,
|
|
64
64
|
format: 'concise',
|
|
@@ -142,9 +142,14 @@ class SyncService {
|
|
|
142
142
|
const startTime = Date.now()
|
|
143
143
|
|
|
144
144
|
// Resolve AI tools: supports 'auto', 'all', or specific list
|
|
145
|
+
// Default behavior: claude + any detected IDE tools (.cursor/, .windsurf/)
|
|
145
146
|
let aiToolIds: string[]
|
|
146
147
|
if (!options.aiTools || options.aiTools.length === 0) {
|
|
147
|
-
|
|
148
|
+
// Start with default CLI tools and add detected IDE tools
|
|
149
|
+
const detectedIdeTools = detectInstalledTools(projectPath).filter(
|
|
150
|
+
(id) => !DEFAULT_AI_TOOLS.includes(id)
|
|
151
|
+
)
|
|
152
|
+
aiToolIds = [...DEFAULT_AI_TOOLS, ...detectedIdeTools]
|
|
148
153
|
} else if (options.aiTools[0] === 'auto') {
|
|
149
154
|
aiToolIds = detectInstalledTools(projectPath)
|
|
150
155
|
if (aiToolIds.length === 0) aiToolIds = ['claude'] // fallback
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -19701,35 +19701,41 @@ Load from \`~/.prjct-cli/projects/${ctx.projectId}/agents/\`:
|
|
|
19701
19701
|
`;
|
|
19702
19702
|
}
|
|
19703
19703
|
function formatForCursor(ctx, _config) {
|
|
19704
|
-
const
|
|
19705
|
-
|
|
19706
|
-
|
|
19707
|
-
|
|
19704
|
+
const lines = [];
|
|
19705
|
+
lines.push("---");
|
|
19706
|
+
lines.push(`description: prjct context for ${ctx.name}`);
|
|
19707
|
+
lines.push("globs:");
|
|
19708
|
+
lines.push("alwaysApply: true");
|
|
19709
|
+
lines.push("---");
|
|
19710
|
+
lines.push("");
|
|
19711
|
+
lines.push(`You are working on ${ctx.name}, a ${ctx.projectType} ${ctx.ecosystem} project.`);
|
|
19712
|
+
lines.push("");
|
|
19713
|
+
lines.push("## Tech Stack");
|
|
19708
19714
|
if (ctx.languages.length > 0) {
|
|
19709
|
-
|
|
19715
|
+
lines.push(`- Languages: ${ctx.languages.join(", ")}`);
|
|
19710
19716
|
}
|
|
19711
19717
|
if (ctx.frameworks.length > 0) {
|
|
19712
|
-
|
|
19713
|
-
}
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
19722
|
-
|
|
19723
|
-
|
|
19724
|
-
|
|
19725
|
-
|
|
19726
|
-
|
|
19727
|
-
|
|
19728
|
-
|
|
19729
|
-
|
|
19730
|
-
|
|
19731
|
-
|
|
19732
|
-
return
|
|
19718
|
+
lines.push(`- Frameworks: ${ctx.frameworks.join(", ")}`);
|
|
19719
|
+
}
|
|
19720
|
+
lines.push("");
|
|
19721
|
+
lines.push("## Commands");
|
|
19722
|
+
lines.push(`- Install: \`${ctx.commands.install}\``);
|
|
19723
|
+
lines.push(`- Dev: \`${ctx.commands.dev}\``);
|
|
19724
|
+
lines.push(`- Test: \`${ctx.commands.test}\``);
|
|
19725
|
+
lines.push(`- Build: \`${ctx.commands.build}\``);
|
|
19726
|
+
lines.push("");
|
|
19727
|
+
lines.push("## Code Style");
|
|
19728
|
+
lines.push(`- Follow ${ctx.ecosystem} conventions`);
|
|
19729
|
+
lines.push("- Match existing code patterns in this project");
|
|
19730
|
+
lines.push("- Use idiomatic constructs for the language");
|
|
19731
|
+
lines.push("");
|
|
19732
|
+
lines.push("## Best Practices");
|
|
19733
|
+
lines.push("- Write clean, readable code");
|
|
19734
|
+
lines.push("- Add comments only for complex logic");
|
|
19735
|
+
lines.push("- Keep functions small and focused");
|
|
19736
|
+
lines.push("- Handle errors appropriately");
|
|
19737
|
+
lines.push("- Write tests for new functionality");
|
|
19738
|
+
return lines.join("\n");
|
|
19733
19739
|
}
|
|
19734
19740
|
function formatForCopilot(ctx, _config) {
|
|
19735
19741
|
const lines = [];
|
|
@@ -19752,35 +19758,40 @@ function formatForCopilot(ctx, _config) {
|
|
|
19752
19758
|
return lines.join("\n");
|
|
19753
19759
|
}
|
|
19754
19760
|
function formatForWindsurf(ctx, _config) {
|
|
19755
|
-
const
|
|
19756
|
-
|
|
19757
|
-
|
|
19758
|
-
|
|
19759
|
-
|
|
19760
|
-
|
|
19761
|
-
|
|
19761
|
+
const lines = [];
|
|
19762
|
+
lines.push("---");
|
|
19763
|
+
lines.push(`description: prjct context for ${ctx.name}`);
|
|
19764
|
+
lines.push("trigger: always_on");
|
|
19765
|
+
lines.push("---");
|
|
19766
|
+
lines.push("");
|
|
19767
|
+
lines.push(`# ${ctx.name}`);
|
|
19768
|
+
lines.push("");
|
|
19769
|
+
lines.push(`${ctx.projectType} project using ${ctx.ecosystem}.`);
|
|
19770
|
+
lines.push("");
|
|
19771
|
+
lines.push("## Stack");
|
|
19772
|
+
lines.push(`- ${ctx.languages.join(", ")}`);
|
|
19762
19773
|
if (ctx.frameworks.length > 0) {
|
|
19763
|
-
|
|
19764
|
-
}
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
|
|
19768
|
-
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
|
|
19780
|
-
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
return
|
|
19774
|
+
lines.push(`- ${ctx.frameworks.join(", ")}`);
|
|
19775
|
+
}
|
|
19776
|
+
lines.push("");
|
|
19777
|
+
lines.push("## Commands");
|
|
19778
|
+
lines.push("```bash");
|
|
19779
|
+
lines.push(`# Install`);
|
|
19780
|
+
lines.push(ctx.commands.install);
|
|
19781
|
+
lines.push(`# Dev`);
|
|
19782
|
+
lines.push(ctx.commands.dev);
|
|
19783
|
+
lines.push(`# Test`);
|
|
19784
|
+
lines.push(ctx.commands.test);
|
|
19785
|
+
lines.push(`# Build`);
|
|
19786
|
+
lines.push(ctx.commands.build);
|
|
19787
|
+
lines.push("```");
|
|
19788
|
+
lines.push("");
|
|
19789
|
+
lines.push("## Rules");
|
|
19790
|
+
lines.push(`- Follow ${ctx.ecosystem} conventions`);
|
|
19791
|
+
lines.push("- Match existing project patterns");
|
|
19792
|
+
lines.push("- Clean code, minimal comments");
|
|
19793
|
+
lines.push("- Test new functionality");
|
|
19794
|
+
return lines.join("\n");
|
|
19784
19795
|
}
|
|
19785
19796
|
function formatForContinue(ctx, _config) {
|
|
19786
19797
|
const systemMessage = [
|
|
@@ -19907,7 +19918,7 @@ var init_registry = __esm({
|
|
|
19907
19918
|
cursor: {
|
|
19908
19919
|
id: "cursor",
|
|
19909
19920
|
name: "Cursor",
|
|
19910
|
-
outputFile: ".
|
|
19921
|
+
outputFile: ".cursor/rules/prjct.mdc",
|
|
19911
19922
|
outputPath: "repo",
|
|
19912
19923
|
maxTokens: 2e3,
|
|
19913
19924
|
format: "concise",
|
|
@@ -19925,7 +19936,7 @@ var init_registry = __esm({
|
|
|
19925
19936
|
windsurf: {
|
|
19926
19937
|
id: "windsurf",
|
|
19927
19938
|
name: "Windsurf",
|
|
19928
|
-
outputFile: ".
|
|
19939
|
+
outputFile: ".windsurf/rules/prjct.md",
|
|
19929
19940
|
outputPath: "repo",
|
|
19930
19941
|
maxTokens: 2e3,
|
|
19931
19942
|
format: "concise",
|
|
@@ -20704,7 +20715,10 @@ var init_sync_service = __esm({
|
|
|
20704
20715
|
const startTime = Date.now();
|
|
20705
20716
|
let aiToolIds;
|
|
20706
20717
|
if (!options.aiTools || options.aiTools.length === 0) {
|
|
20707
|
-
|
|
20718
|
+
const detectedIdeTools = detectInstalledTools(projectPath).filter(
|
|
20719
|
+
(id) => !DEFAULT_AI_TOOLS.includes(id)
|
|
20720
|
+
);
|
|
20721
|
+
aiToolIds = [...DEFAULT_AI_TOOLS, ...detectedIdeTools];
|
|
20708
20722
|
} else if (options.aiTools[0] === "auto") {
|
|
20709
20723
|
aiToolIds = detectInstalledTools(projectPath);
|
|
20710
20724
|
if (aiToolIds.length === 0) aiToolIds = ["claude"];
|
|
@@ -26845,7 +26859,7 @@ var require_package = __commonJS({
|
|
|
26845
26859
|
"package.json"(exports, module) {
|
|
26846
26860
|
module.exports = {
|
|
26847
26861
|
name: "prjct-cli",
|
|
26848
|
-
version: "0.
|
|
26862
|
+
version: "1.0.0",
|
|
26849
26863
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
26850
26864
|
main: "core/index.ts",
|
|
26851
26865
|
bin: {
|