prjct-cli 0.55.2 → 0.55.4
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 +39 -0
- package/core/__tests__/services/project-index.test.ts +3 -1
- package/core/infrastructure/command-installer.ts +33 -3
- package/core/infrastructure/setup.ts +55 -0
- package/core/integrations/jira/index.ts +0 -15
- package/core/services/sync-service.ts +6 -0
- package/dist/bin/prjct.mjs +61 -1
- package/dist/core/infrastructure/command-installer.js +24 -0
- package/dist/core/infrastructure/setup.js +57 -0
- package/package.json +1 -1
- package/templates/commands/bug.md +143 -18
- package/templates/commands/dash.md +74 -18
- package/templates/commands/done.md +125 -26
- package/templates/commands/idea.md +64 -9
- package/templates/commands/jira.md +0 -8
- package/templates/commands/linear.md +0 -8
- package/templates/commands/next.md +49 -11
- package/templates/commands/p.md +30 -183
- package/templates/commands/pause.md +115 -18
- package/templates/commands/resume.md +151 -14
- package/templates/commands/sync.md +0 -10
- package/templates/commands/task.md +86 -38
- package/templates/commands/test.md +60 -17
- package/templates/commands/workflow.md +70 -70
- package/templates/mcp-config.json +4 -32
- package/core/integrations/jira/mcp-adapter.ts +0 -446
- package/templates/_bases/tracker-base.md +0 -321
- package/templates/commands/github.md +0 -298
- package/templates/commands/monday.md +0 -243
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.55.4] - 2026-02-05
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- remove legacy p.*.md commands on sync
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [0.55.3] - 2026-02-05
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- ensure test isolation in IndexStorage tests
|
|
15
|
+
- remove MCP integrations, keep only Context7 (#87)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [0.56.0] - 2026-02-04
|
|
19
|
+
|
|
20
|
+
### Breaking Changes
|
|
21
|
+
|
|
22
|
+
- **Removed MCP-based integrations** (Monday.com, GitHub Issues)
|
|
23
|
+
- Only Context7 remains as the sole MCP server (for library docs)
|
|
24
|
+
- Linear and JIRA use SDK/REST API directly (4x faster)
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
- **Context7 auto-install**: Now automatically configured in `~/.claude/mcp.json` on `prjct init`
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Templates no longer reference non-existent CLI commands (`prjct context task`, etc.)
|
|
33
|
+
- All workflow templates (task, done, bug, pause, resume, next, dash) now use Read/Write directly
|
|
34
|
+
|
|
35
|
+
### Removed
|
|
36
|
+
|
|
37
|
+
- `templates/commands/monday.md` - MCP integration
|
|
38
|
+
- `templates/commands/github.md` - MCP integration
|
|
39
|
+
- `templates/_bases/tracker-base.md` - MCP base template
|
|
40
|
+
- `core/integrations/jira/mcp-adapter.ts` - Unused MCP adapter
|
|
41
|
+
|
|
3
42
|
## [0.55.2] - 2026-02-04
|
|
4
43
|
|
|
5
44
|
### Bug Fixes
|
|
@@ -184,9 +184,11 @@ describe('FileScorer', () => {
|
|
|
184
184
|
})
|
|
185
185
|
|
|
186
186
|
describe('IndexStorage', () => {
|
|
187
|
-
|
|
187
|
+
let testProjectId: string
|
|
188
188
|
|
|
189
189
|
beforeEach(async () => {
|
|
190
|
+
// Generate unique project ID for each test to ensure isolation
|
|
191
|
+
testProjectId = `test-project-${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
190
192
|
// Set up test directory
|
|
191
193
|
const testDir = path.join(os.tmpdir(), `prjct-test-${Date.now()}`)
|
|
192
194
|
pathManager.setGlobalBaseDir(testDir)
|
|
@@ -569,6 +569,36 @@ export class CommandInstaller {
|
|
|
569
569
|
}
|
|
570
570
|
}
|
|
571
571
|
|
|
572
|
+
/**
|
|
573
|
+
* Remove legacy p.*.md files from commands root directory
|
|
574
|
+
* These were replaced by the p/ subdirectory structure in v0.50+
|
|
575
|
+
*/
|
|
576
|
+
async removeLegacyCommands(): Promise<number> {
|
|
577
|
+
const aiProvider = require('./ai-provider')
|
|
578
|
+
const activeProvider = aiProvider.getActiveProvider()
|
|
579
|
+
const commandsRoot = path.join(activeProvider.configDir, 'commands')
|
|
580
|
+
|
|
581
|
+
let removed = 0
|
|
582
|
+
|
|
583
|
+
try {
|
|
584
|
+
const files = await fs.readdir(commandsRoot)
|
|
585
|
+
const legacyFiles = files.filter((f) => f.startsWith('p.') && f.endsWith('.md'))
|
|
586
|
+
|
|
587
|
+
for (const file of legacyFiles) {
|
|
588
|
+
try {
|
|
589
|
+
await fs.unlink(path.join(commandsRoot, file))
|
|
590
|
+
removed++
|
|
591
|
+
} catch {
|
|
592
|
+
// Ignore errors removing individual files
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
} catch {
|
|
596
|
+
// Ignore errors if directory doesn't exist
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return removed
|
|
600
|
+
}
|
|
601
|
+
|
|
572
602
|
/**
|
|
573
603
|
* Sync commands - intelligent update that detects and removes orphans
|
|
574
604
|
*/
|
|
@@ -639,9 +669,9 @@ export class CommandInstaller {
|
|
|
639
669
|
}
|
|
640
670
|
}
|
|
641
671
|
|
|
642
|
-
//
|
|
643
|
-
//
|
|
644
|
-
|
|
672
|
+
// Remove legacy p.*.md files from commands root (old naming convention)
|
|
673
|
+
// These were replaced by p/ subdirectory structure
|
|
674
|
+
await this.removeLegacyCommands()
|
|
645
675
|
|
|
646
676
|
return results
|
|
647
677
|
} catch (error) {
|
|
@@ -169,6 +169,9 @@ export async function run(): Promise<SetupResults> {
|
|
|
169
169
|
|
|
170
170
|
// Install status line (Claude only)
|
|
171
171
|
await installStatusLine()
|
|
172
|
+
|
|
173
|
+
// Install Context7 MCP (only MCP server prjct uses)
|
|
174
|
+
await installContext7MCP()
|
|
172
175
|
}
|
|
173
176
|
} else if (providerName === 'gemini') {
|
|
174
177
|
// Gemini provider - install router and global config
|
|
@@ -875,6 +878,58 @@ echo "prjct"
|
|
|
875
878
|
}
|
|
876
879
|
}
|
|
877
880
|
|
|
881
|
+
/**
|
|
882
|
+
* Install Context7 MCP server configuration
|
|
883
|
+
*
|
|
884
|
+
* Context7 is the ONLY MCP server prjct uses - for library documentation lookup.
|
|
885
|
+
* All issue tracker integrations (Linear, JIRA) use SDK/REST API directly.
|
|
886
|
+
*/
|
|
887
|
+
async function installContext7MCP(): Promise<void> {
|
|
888
|
+
try {
|
|
889
|
+
const claudeDir = path.join(os.homedir(), '.claude')
|
|
890
|
+
const mcpConfigPath = path.join(claudeDir, 'mcp.json')
|
|
891
|
+
|
|
892
|
+
// Ensure ~/.claude directory exists
|
|
893
|
+
if (!fs.existsSync(claudeDir)) {
|
|
894
|
+
fs.mkdirSync(claudeDir, { recursive: true })
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Context7 MCP configuration
|
|
898
|
+
const context7Config = {
|
|
899
|
+
mcpServers: {
|
|
900
|
+
context7: {
|
|
901
|
+
command: 'npx',
|
|
902
|
+
args: ['-y', '@upstash/context7-mcp@latest'],
|
|
903
|
+
},
|
|
904
|
+
},
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// Check if mcp.json exists
|
|
908
|
+
if (fs.existsSync(mcpConfigPath)) {
|
|
909
|
+
// Read existing config
|
|
910
|
+
const existingContent = fs.readFileSync(mcpConfigPath, 'utf-8')
|
|
911
|
+
const existingConfig = JSON.parse(existingContent)
|
|
912
|
+
|
|
913
|
+
// Check if context7 is already configured
|
|
914
|
+
if (existingConfig.mcpServers?.context7) {
|
|
915
|
+
// Already configured, skip
|
|
916
|
+
return
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// Add context7 to existing config
|
|
920
|
+
existingConfig.mcpServers = existingConfig.mcpServers || {}
|
|
921
|
+
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7
|
|
922
|
+
fs.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), 'utf-8')
|
|
923
|
+
} else {
|
|
924
|
+
// Create new mcp.json with context7
|
|
925
|
+
fs.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), 'utf-8')
|
|
926
|
+
}
|
|
927
|
+
} catch (error) {
|
|
928
|
+
// Non-fatal error, just log
|
|
929
|
+
console.error(`Context7 MCP setup warning: ${(error as Error).message}`)
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
878
933
|
/**
|
|
879
934
|
* Install statusline modules (lib/ or components/)
|
|
880
935
|
* Copies .sh files from source to destination, always overwriting for updates
|
|
@@ -19,20 +19,5 @@ export {
|
|
|
19
19
|
} from './cache'
|
|
20
20
|
// REST API client
|
|
21
21
|
export { type JiraAuthMode, JiraProvider, jiraProvider } from './client'
|
|
22
|
-
// MCP adapter (deprecated - will be removed)
|
|
23
|
-
export {
|
|
24
|
-
createCreateIssueInstruction,
|
|
25
|
-
createGetIssueInstruction,
|
|
26
|
-
// MCP instruction generators
|
|
27
|
-
createSearchInstruction,
|
|
28
|
-
createTransitionInstruction,
|
|
29
|
-
createUpdateInstruction,
|
|
30
|
-
getMCPSetupInstructions,
|
|
31
|
-
// Utilities
|
|
32
|
-
isMCPAvailable,
|
|
33
|
-
JiraMCPAdapter,
|
|
34
|
-
jiraMCPAdapter,
|
|
35
|
-
type MCPInstruction,
|
|
36
|
-
} from './mcp-adapter'
|
|
37
22
|
// Service layer with caching (preferred API)
|
|
38
23
|
export { JiraService, jiraService } from './service'
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type ProjectContext,
|
|
27
27
|
resolveToolIds,
|
|
28
28
|
} from '../ai-tools'
|
|
29
|
+
import commandInstaller from '../infrastructure/command-installer'
|
|
29
30
|
import configManager from '../infrastructure/config-manager'
|
|
30
31
|
import pathManager from '../infrastructure/path-manager'
|
|
31
32
|
import { metricsStorage } from '../storage/metrics-storage'
|
|
@@ -232,6 +233,11 @@ class SyncService {
|
|
|
232
233
|
const duration = Date.now() - startTime
|
|
233
234
|
const syncMetrics = await this.recordSyncMetrics(stats, contextFiles, agents, duration)
|
|
234
235
|
|
|
236
|
+
// 10. Update global config and commands (CLI does EVERYTHING)
|
|
237
|
+
// This ensures `prjct sync` from terminal updates global CLAUDE.md and commands
|
|
238
|
+
await commandInstaller.installGlobalConfig()
|
|
239
|
+
await commandInstaller.syncCommands()
|
|
240
|
+
|
|
235
241
|
return {
|
|
236
242
|
success: true,
|
|
237
243
|
projectId: this.projectId,
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -5952,6 +5952,29 @@ var init_command_installer = __esm({
|
|
|
5952
5952
|
throw error;
|
|
5953
5953
|
}
|
|
5954
5954
|
}
|
|
5955
|
+
/**
|
|
5956
|
+
* Remove legacy p.*.md files from commands root directory
|
|
5957
|
+
* These were replaced by the p/ subdirectory structure in v0.50+
|
|
5958
|
+
*/
|
|
5959
|
+
async removeLegacyCommands() {
|
|
5960
|
+
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
5961
|
+
const activeProvider = aiProvider.getActiveProvider();
|
|
5962
|
+
const commandsRoot = path16.join(activeProvider.configDir, "commands");
|
|
5963
|
+
let removed = 0;
|
|
5964
|
+
try {
|
|
5965
|
+
const files = await fs16.readdir(commandsRoot);
|
|
5966
|
+
const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
|
|
5967
|
+
for (const file of legacyFiles) {
|
|
5968
|
+
try {
|
|
5969
|
+
await fs16.unlink(path16.join(commandsRoot, file));
|
|
5970
|
+
removed++;
|
|
5971
|
+
} catch {
|
|
5972
|
+
}
|
|
5973
|
+
}
|
|
5974
|
+
} catch {
|
|
5975
|
+
}
|
|
5976
|
+
return removed;
|
|
5977
|
+
}
|
|
5955
5978
|
/**
|
|
5956
5979
|
* Sync commands - intelligent update that detects and removes orphans
|
|
5957
5980
|
*/
|
|
@@ -6004,6 +6027,7 @@ var init_command_installer = __esm({
|
|
|
6004
6027
|
results.errors.push({ file, error: error.message });
|
|
6005
6028
|
}
|
|
6006
6029
|
}
|
|
6030
|
+
await this.removeLegacyCommands();
|
|
6007
6031
|
return results;
|
|
6008
6032
|
} catch (error) {
|
|
6009
6033
|
return {
|
|
@@ -19105,6 +19129,7 @@ var init_sync_service = __esm({
|
|
|
19105
19129
|
"core/services/sync-service.ts"() {
|
|
19106
19130
|
"use strict";
|
|
19107
19131
|
init_ai_tools();
|
|
19132
|
+
init_command_installer();
|
|
19108
19133
|
init_config_manager();
|
|
19109
19134
|
init_path_manager();
|
|
19110
19135
|
init_metrics_storage();
|
|
@@ -19203,6 +19228,8 @@ var init_sync_service = __esm({
|
|
|
19203
19228
|
]);
|
|
19204
19229
|
const duration = Date.now() - startTime;
|
|
19205
19230
|
const syncMetrics = await this.recordSyncMetrics(stats, contextFiles, agents, duration);
|
|
19231
|
+
await command_installer_default.installGlobalConfig();
|
|
19232
|
+
await command_installer_default.syncCommands();
|
|
19206
19233
|
return {
|
|
19207
19234
|
success: true,
|
|
19208
19235
|
projectId: this.projectId,
|
|
@@ -21231,6 +21258,7 @@ async function run() {
|
|
|
21231
21258
|
}
|
|
21232
21259
|
await command_installer_default.installDocs();
|
|
21233
21260
|
await installStatusLine();
|
|
21261
|
+
await installContext7MCP();
|
|
21234
21262
|
}
|
|
21235
21263
|
} else if (providerName === "gemini") {
|
|
21236
21264
|
const geminiInstalled = await installGeminiRouter();
|
|
@@ -21681,6 +21709,37 @@ echo "prjct"
|
|
|
21681
21709
|
}
|
|
21682
21710
|
}
|
|
21683
21711
|
}
|
|
21712
|
+
async function installContext7MCP() {
|
|
21713
|
+
try {
|
|
21714
|
+
const claudeDir = path44.join(os13.homedir(), ".claude");
|
|
21715
|
+
const mcpConfigPath = path44.join(claudeDir, "mcp.json");
|
|
21716
|
+
if (!fs41.existsSync(claudeDir)) {
|
|
21717
|
+
fs41.mkdirSync(claudeDir, { recursive: true });
|
|
21718
|
+
}
|
|
21719
|
+
const context7Config = {
|
|
21720
|
+
mcpServers: {
|
|
21721
|
+
context7: {
|
|
21722
|
+
command: "npx",
|
|
21723
|
+
args: ["-y", "@upstash/context7-mcp@latest"]
|
|
21724
|
+
}
|
|
21725
|
+
}
|
|
21726
|
+
};
|
|
21727
|
+
if (fs41.existsSync(mcpConfigPath)) {
|
|
21728
|
+
const existingContent = fs41.readFileSync(mcpConfigPath, "utf-8");
|
|
21729
|
+
const existingConfig = JSON.parse(existingContent);
|
|
21730
|
+
if (existingConfig.mcpServers?.context7) {
|
|
21731
|
+
return;
|
|
21732
|
+
}
|
|
21733
|
+
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
21734
|
+
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
|
|
21735
|
+
fs41.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
21736
|
+
} else {
|
|
21737
|
+
fs41.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
21738
|
+
}
|
|
21739
|
+
} catch (error) {
|
|
21740
|
+
console.error(`Context7 MCP setup warning: ${error.message}`);
|
|
21741
|
+
}
|
|
21742
|
+
}
|
|
21684
21743
|
function installStatusLineModules(sourceDir, destDir) {
|
|
21685
21744
|
if (!fs41.existsSync(sourceDir)) {
|
|
21686
21745
|
return;
|
|
@@ -21777,6 +21836,7 @@ var init_setup = __esm({
|
|
|
21777
21836
|
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
21778
21837
|
__name(ensureStatusLineSettings, "ensureStatusLineSettings");
|
|
21779
21838
|
__name(installStatusLine, "installStatusLine");
|
|
21839
|
+
__name(installContext7MCP, "installContext7MCP");
|
|
21780
21840
|
__name(installStatusLineModules, "installStatusLineModules");
|
|
21781
21841
|
__name(ensureStatusLineSymlink, "ensureStatusLineSymlink");
|
|
21782
21842
|
__name(showResults, "showResults");
|
|
@@ -25161,7 +25221,7 @@ var require_package = __commonJS({
|
|
|
25161
25221
|
"package.json"(exports, module) {
|
|
25162
25222
|
module.exports = {
|
|
25163
25223
|
name: "prjct-cli",
|
|
25164
|
-
version: "0.55.
|
|
25224
|
+
version: "0.55.4",
|
|
25165
25225
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
25166
25226
|
main: "core/index.ts",
|
|
25167
25227
|
bin: {
|
|
@@ -873,6 +873,29 @@ var CommandInstaller = class {
|
|
|
873
873
|
throw error;
|
|
874
874
|
}
|
|
875
875
|
}
|
|
876
|
+
/**
|
|
877
|
+
* Remove legacy p.*.md files from commands root directory
|
|
878
|
+
* These were replaced by the p/ subdirectory structure in v0.50+
|
|
879
|
+
*/
|
|
880
|
+
async removeLegacyCommands() {
|
|
881
|
+
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
882
|
+
const activeProvider = aiProvider.getActiveProvider();
|
|
883
|
+
const commandsRoot = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
884
|
+
let removed = 0;
|
|
885
|
+
try {
|
|
886
|
+
const files = await import_promises.default.readdir(commandsRoot);
|
|
887
|
+
const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
|
|
888
|
+
for (const file of legacyFiles) {
|
|
889
|
+
try {
|
|
890
|
+
await import_promises.default.unlink(import_node_path3.default.join(commandsRoot, file));
|
|
891
|
+
removed++;
|
|
892
|
+
} catch {
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
} catch {
|
|
896
|
+
}
|
|
897
|
+
return removed;
|
|
898
|
+
}
|
|
876
899
|
/**
|
|
877
900
|
* Sync commands - intelligent update that detects and removes orphans
|
|
878
901
|
*/
|
|
@@ -925,6 +948,7 @@ var CommandInstaller = class {
|
|
|
925
948
|
results.errors.push({ file, error: error.message });
|
|
926
949
|
}
|
|
927
950
|
}
|
|
951
|
+
await this.removeLegacyCommands();
|
|
928
952
|
return results;
|
|
929
953
|
} catch (error) {
|
|
930
954
|
return {
|
|
@@ -876,6 +876,29 @@ var CommandInstaller = class {
|
|
|
876
876
|
throw error;
|
|
877
877
|
}
|
|
878
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* Remove legacy p.*.md files from commands root directory
|
|
881
|
+
* These were replaced by the p/ subdirectory structure in v0.50+
|
|
882
|
+
*/
|
|
883
|
+
async removeLegacyCommands() {
|
|
884
|
+
const aiProvider = (init_ai_provider(), __toCommonJS(ai_provider_exports));
|
|
885
|
+
const activeProvider = aiProvider.getActiveProvider();
|
|
886
|
+
const commandsRoot = import_node_path3.default.join(activeProvider.configDir, "commands");
|
|
887
|
+
let removed = 0;
|
|
888
|
+
try {
|
|
889
|
+
const files = await import_promises.default.readdir(commandsRoot);
|
|
890
|
+
const legacyFiles = files.filter((f) => f.startsWith("p.") && f.endsWith(".md"));
|
|
891
|
+
for (const file of legacyFiles) {
|
|
892
|
+
try {
|
|
893
|
+
await import_promises.default.unlink(import_node_path3.default.join(commandsRoot, file));
|
|
894
|
+
removed++;
|
|
895
|
+
} catch {
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
} catch {
|
|
899
|
+
}
|
|
900
|
+
return removed;
|
|
901
|
+
}
|
|
879
902
|
/**
|
|
880
903
|
* Sync commands - intelligent update that detects and removes orphans
|
|
881
904
|
*/
|
|
@@ -928,6 +951,7 @@ var CommandInstaller = class {
|
|
|
928
951
|
results.errors.push({ file, error: error.message });
|
|
929
952
|
}
|
|
930
953
|
}
|
|
954
|
+
await this.removeLegacyCommands();
|
|
931
955
|
return results;
|
|
932
956
|
} catch (error) {
|
|
933
957
|
return {
|
|
@@ -1168,6 +1192,7 @@ async function run() {
|
|
|
1168
1192
|
}
|
|
1169
1193
|
await command_installer_default.installDocs();
|
|
1170
1194
|
await installStatusLine();
|
|
1195
|
+
await installContext7MCP();
|
|
1171
1196
|
}
|
|
1172
1197
|
} else if (providerName === "gemini") {
|
|
1173
1198
|
const geminiInstalled = await installGeminiRouter();
|
|
@@ -1635,6 +1660,38 @@ echo "prjct"
|
|
|
1635
1660
|
}
|
|
1636
1661
|
}
|
|
1637
1662
|
__name(installStatusLine, "installStatusLine");
|
|
1663
|
+
async function installContext7MCP() {
|
|
1664
|
+
try {
|
|
1665
|
+
const claudeDir = import_node_path5.default.join(import_node_os4.default.homedir(), ".claude");
|
|
1666
|
+
const mcpConfigPath = import_node_path5.default.join(claudeDir, "mcp.json");
|
|
1667
|
+
if (!import_node_fs3.default.existsSync(claudeDir)) {
|
|
1668
|
+
import_node_fs3.default.mkdirSync(claudeDir, { recursive: true });
|
|
1669
|
+
}
|
|
1670
|
+
const context7Config = {
|
|
1671
|
+
mcpServers: {
|
|
1672
|
+
context7: {
|
|
1673
|
+
command: "npx",
|
|
1674
|
+
args: ["-y", "@upstash/context7-mcp@latest"]
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
if (import_node_fs3.default.existsSync(mcpConfigPath)) {
|
|
1679
|
+
const existingContent = import_node_fs3.default.readFileSync(mcpConfigPath, "utf-8");
|
|
1680
|
+
const existingConfig = JSON.parse(existingContent);
|
|
1681
|
+
if (existingConfig.mcpServers?.context7) {
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
existingConfig.mcpServers = existingConfig.mcpServers || {};
|
|
1685
|
+
existingConfig.mcpServers.context7 = context7Config.mcpServers.context7;
|
|
1686
|
+
import_node_fs3.default.writeFileSync(mcpConfigPath, JSON.stringify(existingConfig, null, 2), "utf-8");
|
|
1687
|
+
} else {
|
|
1688
|
+
import_node_fs3.default.writeFileSync(mcpConfigPath, JSON.stringify(context7Config, null, 2), "utf-8");
|
|
1689
|
+
}
|
|
1690
|
+
} catch (error) {
|
|
1691
|
+
console.error(`Context7 MCP setup warning: ${error.message}`);
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
__name(installContext7MCP, "installContext7MCP");
|
|
1638
1695
|
function installStatusLineModules(sourceDir, destDir) {
|
|
1639
1696
|
if (!import_node_fs3.default.existsSync(sourceDir)) {
|
|
1640
1697
|
return;
|
package/package.json
CHANGED
|
@@ -4,35 +4,160 @@ allowed-tools: [Read, Write, Bash, Task, AskUserQuestion]
|
|
|
4
4
|
|
|
5
5
|
# p. bug "$ARGUMENTS"
|
|
6
6
|
|
|
7
|
+
## Step 1: Validate Arguments
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
IF $ARGUMENTS is empty:
|
|
11
|
+
ASK: "What bug do you want to report?"
|
|
12
|
+
WAIT for response
|
|
13
|
+
DO NOT proceed with empty description
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Step 2: Resolve Project Paths
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Get projectId from local config
|
|
20
|
+
cat .prjct/prjct.config.json | grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Set `globalPath = ~/.prjct-cli/projects/{projectId}`
|
|
24
|
+
|
|
25
|
+
## Step 3: Parse Severity from Keywords
|
|
26
|
+
|
|
27
|
+
Analyze `$ARGUMENTS` for severity indicators:
|
|
28
|
+
- `crash`, `down`, `broken`, `production`, `critical` → **critical**
|
|
29
|
+
- `error`, `fail`, `exception`, `cannot` → **high**
|
|
30
|
+
- `bug`, `incorrect`, `wrong`, `issue` → **medium** (default)
|
|
31
|
+
- `minor`, `typo`, `cosmetic`, `ui` → **low**
|
|
32
|
+
|
|
33
|
+
## Step 4: Explore Codebase
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
USE Task(Explore) → find affected files, recent commits related to the bug
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Step 5: Check for Active Task
|
|
40
|
+
|
|
41
|
+
READ `{globalPath}/storage/state.json`
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
IF currentTask exists AND currentTask.status == "active":
|
|
45
|
+
AskUserQuestion:
|
|
46
|
+
question: "You have an active task. How should we handle this bug?"
|
|
47
|
+
header: "Bug"
|
|
48
|
+
options:
|
|
49
|
+
- label: "Pause current and fix bug (Recommended)"
|
|
50
|
+
description: "Save current task, start bug fix"
|
|
51
|
+
- label: "Queue bug for later"
|
|
52
|
+
description: "Add to queue, continue current task"
|
|
53
|
+
|
|
54
|
+
IF "Queue bug for later":
|
|
55
|
+
# Add to queue and stop
|
|
56
|
+
READ {globalPath}/storage/queue.json (or create empty array)
|
|
57
|
+
APPEND bug to queue:
|
|
58
|
+
{
|
|
59
|
+
"id": "{uuid}",
|
|
60
|
+
"type": "bug",
|
|
61
|
+
"description": "$ARGUMENTS",
|
|
62
|
+
"severity": "{severity}",
|
|
63
|
+
"createdAt": "{timestamp}",
|
|
64
|
+
"status": "queued"
|
|
65
|
+
}
|
|
66
|
+
WRITE {globalPath}/storage/queue.json
|
|
67
|
+
|
|
68
|
+
OUTPUT:
|
|
69
|
+
"""
|
|
70
|
+
🐛 Queued: $ARGUMENTS [{severity}]
|
|
71
|
+
|
|
72
|
+
Continue with: {currentTask.description}
|
|
73
|
+
|
|
74
|
+
Later: `p. task` to work on queued bug
|
|
75
|
+
"""
|
|
76
|
+
STOP
|
|
77
|
+
|
|
78
|
+
IF "Pause current and fix bug":
|
|
79
|
+
# Move current task to pausedTasks
|
|
80
|
+
# Will be handled in Step 6
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Step 6: Create Bug Branch
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
git branch --show-current
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
IF current branch == "main" OR "master":
|
|
91
|
+
# Create bug fix branch
|
|
92
|
+
slug = sanitize($ARGUMENTS) # lowercase, hyphens, max 50 chars
|
|
93
|
+
|
|
94
|
+
git checkout -b bug/{slug}
|
|
95
|
+
|
|
96
|
+
IF git command fails:
|
|
97
|
+
OUTPUT: "Failed to create branch. Check git status."
|
|
98
|
+
STOP
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Step 7: Write State
|
|
102
|
+
|
|
103
|
+
Generate UUID and timestamp:
|
|
7
104
|
```bash
|
|
8
|
-
|
|
105
|
+
node -e "console.log(require('crypto').randomUUID())"
|
|
106
|
+
node -e "console.log(new Date().toISOString())"
|
|
9
107
|
```
|
|
10
108
|
|
|
11
|
-
|
|
12
|
-
- crash/down/broken/production → critical
|
|
13
|
-
- error/fail → high
|
|
14
|
-
- bug/incorrect → medium (default)
|
|
15
|
-
- minor/typo → low
|
|
109
|
+
READ current state, then update:
|
|
16
110
|
|
|
17
|
-
|
|
111
|
+
```
|
|
112
|
+
# If there was an active task, move it to pausedTasks
|
|
113
|
+
IF state.currentTask exists:
|
|
114
|
+
interruptedTask = state.currentTask
|
|
115
|
+
interruptedTask.status = "interrupted"
|
|
116
|
+
interruptedTask.interruptedAt = "{timestamp}"
|
|
117
|
+
interruptedTask.interruptedBy = "{new bug task id}"
|
|
18
118
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
119
|
+
state.pausedTasks = state.pausedTasks || []
|
|
120
|
+
state.pausedTasks.push(interruptedTask)
|
|
121
|
+
```
|
|
22
122
|
|
|
23
|
-
|
|
123
|
+
WRITE `{globalPath}/storage/state.json`:
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"currentTask": {
|
|
127
|
+
"id": "{uuid}",
|
|
128
|
+
"description": "$ARGUMENTS",
|
|
129
|
+
"type": "bug",
|
|
130
|
+
"severity": "{severity}",
|
|
131
|
+
"status": "active",
|
|
132
|
+
"startedAt": "{timestamp}",
|
|
133
|
+
"branch": "bug/{slug}",
|
|
134
|
+
"affectedFiles": ["{files from exploration}"]
|
|
135
|
+
},
|
|
136
|
+
"pausedTasks": [{interruptedTask if any}]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
24
139
|
|
|
25
|
-
|
|
26
|
-
|
|
140
|
+
## Step 8: Log Event
|
|
141
|
+
|
|
142
|
+
APPEND to `{globalPath}/memory/events.jsonl`:
|
|
143
|
+
```json
|
|
144
|
+
{"type":"bug_reported","taskId":"{uuid}","description":"$ARGUMENTS","severity":"{severity}","timestamp":"{timestamp}","branch":"bug/{slug}"}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Output
|
|
27
150
|
|
|
28
|
-
**Output**:
|
|
29
151
|
```
|
|
30
152
|
🐛 [{severity}] $ARGUMENTS
|
|
31
153
|
|
|
32
|
-
Affected: {files}
|
|
33
|
-
Branch: {
|
|
154
|
+
Affected: {files from exploration}
|
|
155
|
+
Branch: bug/{slug}
|
|
156
|
+
|
|
157
|
+
{IF interruptedTask: "Paused: {interruptedTask.description}"}
|
|
34
158
|
|
|
35
159
|
Next:
|
|
36
|
-
- Fix the bug →
|
|
37
|
-
-
|
|
160
|
+
- Fix the bug → work on code
|
|
161
|
+
- When fixed → `p. done`
|
|
162
|
+
- Resume previous → `p. resume`
|
|
38
163
|
```
|