prjct-cli 0.20.0 → 0.20.1
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 +24 -6
- package/CLAUDE.md +56 -15
- package/README.md +5 -6
- package/bin/prjct +59 -42
- package/bin/prjct.ts +60 -0
- package/core/__tests__/agentic/memory-system.test.ts +18 -3
- package/core/__tests__/agentic/plan-mode.test.ts +55 -26
- package/core/__tests__/agentic/prompt-builder.test.ts +6 -6
- package/core/__tests__/utils/project-commands.test.ts +72 -0
- package/core/agentic/agent-router.ts +3 -12
- package/core/agentic/command-executor.ts +372 -3
- package/core/agentic/context-builder.ts +7 -27
- package/core/agentic/ground-truth.ts +604 -5
- package/core/agentic/index.ts +180 -0
- package/core/agentic/loop-detector.ts +418 -4
- package/core/agentic/memory-system.ts +857 -3
- package/core/agentic/plan-mode.ts +491 -4
- package/core/agentic/prompt-builder.ts +44 -65
- package/core/agentic/services.ts +13 -5
- package/core/agentic/skill-loader.ts +112 -0
- package/core/agentic/smart-context.ts +37 -122
- package/core/agentic/template-loader.ts +79 -122
- package/core/agentic/tool-registry.ts +5 -11
- package/core/agents/index.ts +1 -1
- package/core/agents/performance.ts +4 -2
- package/core/bus/bus.ts +262 -0
- package/core/bus/index.ts +3 -313
- package/core/commands/analysis.ts +5 -5
- package/core/commands/analytics.ts +11 -11
- package/core/commands/base.ts +33 -209
- package/core/commands/cleanup.ts +148 -0
- package/core/commands/command-data.ts +346 -0
- package/core/commands/commands.ts +216 -0
- package/core/commands/design.ts +83 -0
- package/core/commands/index.ts +13 -207
- package/core/commands/maintenance.ts +52 -473
- package/core/commands/planning.ts +3 -3
- package/core/commands/register.ts +104 -0
- package/core/commands/registry.ts +441 -0
- package/core/commands/setup.ts +25 -9
- package/core/commands/shipping.ts +48 -11
- package/core/commands/snapshots.ts +299 -0
- package/core/commands/workflow.ts +2 -2
- package/core/constants/index.ts +254 -4
- package/core/domain/agent-loader.ts +5 -6
- package/core/domain/task-stack.ts +555 -4
- package/core/errors.ts +127 -1
- package/core/events/events.ts +87 -0
- package/core/events/index.ts +4 -138
- package/core/index.ts +15 -23
- package/core/infrastructure/agent-detector.ts +126 -201
- package/core/infrastructure/author-detector.ts +99 -171
- package/core/infrastructure/command-installer.ts +476 -4
- package/core/infrastructure/config-manager.ts +41 -37
- package/core/infrastructure/path-manager.ts +59 -9
- package/core/infrastructure/permission-manager.ts +286 -0
- package/core/outcomes/analyzer.ts +7 -41
- package/core/outcomes/index.ts +1 -1
- package/core/outcomes/recorder.ts +1 -1
- package/core/{plugins → plugin/builtin}/webhook.ts +6 -22
- package/core/plugin/loader.ts +5 -5
- package/core/plugin/registry.ts +2 -2
- package/core/schemas/ideas.ts +85 -54
- package/core/schemas/index.ts +14 -33
- package/core/schemas/permissions.ts +177 -0
- package/core/schemas/project.ts +39 -12
- package/core/schemas/roadmap.ts +94 -59
- package/core/schemas/schemas.ts +39 -0
- package/core/schemas/shipped.ts +87 -60
- package/core/schemas/state.ts +110 -70
- package/core/server/index.ts +21 -0
- package/core/server/routes.ts +165 -0
- package/core/server/server.ts +136 -0
- package/core/server/sse.ts +135 -0
- package/core/services/agent-service.ts +170 -0
- package/core/services/breakdown-service.ts +126 -0
- package/core/services/index.ts +21 -0
- package/core/services/memory-service.ts +108 -0
- package/core/services/project-service.ts +146 -0
- package/core/services/skill-service.ts +253 -0
- package/core/session/compaction.ts +257 -0
- package/core/session/index.ts +20 -8
- package/core/{infrastructure/session-manager/migration.ts → session/log-migration.ts} +9 -9
- package/core/{infrastructure/session-manager/session-manager.ts → session/session-log-manager.ts} +27 -26
- package/core/session/{session-manager.ts → task-session-manager.ts} +7 -4
- package/core/session/utils.ts +1 -1
- package/core/storage/ideas-storage.ts +10 -26
- package/core/storage/index.ts +14 -162
- package/core/storage/queue-storage.ts +13 -11
- package/core/storage/shipped-storage.ts +4 -17
- package/core/storage/state-storage.ts +35 -43
- package/core/storage/storage-manager.ts +42 -52
- package/core/storage/storage.ts +160 -0
- package/core/sync/auth-config.ts +1 -8
- package/core/sync/index.ts +17 -10
- package/core/sync/oauth-handler.ts +1 -6
- package/core/sync/sync-client.ts +6 -34
- package/core/sync/sync-manager.ts +11 -40
- package/core/types/agentic.ts +577 -0
- package/core/types/agents.ts +145 -0
- package/core/types/bus.ts +82 -0
- package/core/types/commands.ts +366 -0
- package/core/types/config.ts +66 -0
- package/core/types/core.ts +96 -0
- package/core/types/domain.ts +71 -0
- package/core/types/events.ts +42 -0
- package/core/types/fs.ts +56 -0
- package/core/types/index.ts +387 -500
- package/core/types/infrastructure.ts +196 -0
- package/core/{agentic/memory-system/types.ts → types/memory.ts} +33 -8
- package/core/{outcomes/types.ts → types/outcomes.ts} +53 -8
- package/core/types/plugin.ts +25 -0
- package/core/types/server.ts +54 -0
- package/core/types/services.ts +65 -0
- package/core/types/session.ts +135 -0
- package/core/types/storage.ts +148 -0
- package/core/types/sync.ts +121 -0
- package/core/types/task.ts +72 -0
- package/core/types/template.ts +24 -0
- package/core/types/utils.ts +90 -0
- package/core/utils/cache.ts +195 -0
- package/core/utils/collection-filters.ts +245 -0
- package/core/utils/date-helper.ts +1 -5
- package/core/utils/file-helper.ts +20 -10
- package/core/utils/jsonl-helper.ts +5 -8
- package/core/utils/markdown-builder.ts +277 -0
- package/core/utils/project-commands.ts +132 -0
- package/core/utils/runtime.ts +119 -0
- package/dist/bin/prjct.mjs +12568 -0
- package/package.json +13 -8
- package/scripts/build.js +106 -0
- package/scripts/postinstall.js +50 -8
- package/templates/agentic/subagent-generation.md +1 -1
- package/templates/commands/serve.md +118 -0
- package/templates/commands/ship.md +13 -2
- package/templates/commands/skill.md +110 -0
- package/templates/commands/sync.md +1 -1
- package/templates/commands/test.md +23 -4
- package/templates/permissions/default.jsonc +60 -0
- package/templates/permissions/permissive.jsonc +49 -0
- package/templates/permissions/strict.jsonc +62 -0
- package/templates/skills/code-review.md +47 -0
- package/templates/skills/debug.md +61 -0
- package/templates/skills/refactor.md +47 -0
- package/templates/subagents/domain/devops.md +1 -1
- package/templates/subagents/domain/testing.md +6 -10
- package/templates/subagents/workflow/prjct-shipper.md +16 -7
- package/templates/tools/bash.txt +22 -0
- package/templates/tools/edit.txt +18 -0
- package/templates/tools/glob.txt +19 -0
- package/templates/tools/grep.txt +21 -0
- package/templates/tools/read.txt +14 -0
- package/templates/tools/task.txt +20 -0
- package/templates/tools/webfetch.txt +16 -0
- package/templates/tools/websearch.txt +18 -0
- package/templates/tools/write.txt +17 -0
- package/core/agentic/command-executor/command-executor.ts +0 -312
- package/core/agentic/command-executor/index.ts +0 -16
- package/core/agentic/command-executor/status-signal.ts +0 -38
- package/core/agentic/command-executor/types.ts +0 -79
- package/core/agentic/ground-truth/index.ts +0 -76
- package/core/agentic/ground-truth/types.ts +0 -33
- package/core/agentic/ground-truth/utils.ts +0 -48
- package/core/agentic/ground-truth/verifiers/analyze.ts +0 -54
- package/core/agentic/ground-truth/verifiers/done.ts +0 -75
- package/core/agentic/ground-truth/verifiers/feature.ts +0 -70
- package/core/agentic/ground-truth/verifiers/index.ts +0 -37
- package/core/agentic/ground-truth/verifiers/init.ts +0 -52
- package/core/agentic/ground-truth/verifiers/now.ts +0 -57
- package/core/agentic/ground-truth/verifiers/ship.ts +0 -85
- package/core/agentic/ground-truth/verifiers/spec.ts +0 -45
- package/core/agentic/ground-truth/verifiers/sync.ts +0 -47
- package/core/agentic/ground-truth/verifiers.ts +0 -6
- package/core/agentic/loop-detector/error-analysis.ts +0 -97
- package/core/agentic/loop-detector/hallucination.ts +0 -71
- package/core/agentic/loop-detector/index.ts +0 -41
- package/core/agentic/loop-detector/loop-detector.ts +0 -222
- package/core/agentic/loop-detector/types.ts +0 -66
- package/core/agentic/memory-system/history.ts +0 -53
- package/core/agentic/memory-system/index.ts +0 -192
- package/core/agentic/memory-system/patterns.ts +0 -156
- package/core/agentic/memory-system/semantic-memories.ts +0 -278
- package/core/agentic/memory-system/session.ts +0 -21
- package/core/agentic/plan-mode/approval.ts +0 -57
- package/core/agentic/plan-mode/constants.ts +0 -44
- package/core/agentic/plan-mode/index.ts +0 -28
- package/core/agentic/plan-mode/plan-mode.ts +0 -407
- package/core/agentic/plan-mode/types.ts +0 -193
- package/core/agents/types.ts +0 -126
- package/core/command-registry/categories.ts +0 -23
- package/core/command-registry/commands.ts +0 -15
- package/core/command-registry/core-commands.ts +0 -344
- package/core/command-registry/index.ts +0 -158
- package/core/command-registry/optional-commands.ts +0 -163
- package/core/command-registry/setup-commands.ts +0 -83
- package/core/command-registry/types.ts +0 -59
- package/core/command-registry.ts +0 -9
- package/core/commands/types.ts +0 -185
- package/core/commands.ts +0 -11
- package/core/constants/formats.ts +0 -187
- package/core/context-sync.ts +0 -18
- package/core/data/index.ts +0 -27
- package/core/data/md-base-manager.ts +0 -203
- package/core/data/md-ideas-manager.ts +0 -155
- package/core/data/md-queue-manager.ts +0 -180
- package/core/data/md-shipped-manager.ts +0 -90
- package/core/data/md-state-manager.ts +0 -137
- package/core/domain/task-stack/index.ts +0 -19
- package/core/domain/task-stack/parser.ts +0 -86
- package/core/domain/task-stack/storage.ts +0 -123
- package/core/domain/task-stack/task-stack.ts +0 -340
- package/core/domain/task-stack/types.ts +0 -51
- package/core/infrastructure/command-installer/command-installer.ts +0 -327
- package/core/infrastructure/command-installer/global-config.ts +0 -136
- package/core/infrastructure/command-installer/index.ts +0 -25
- package/core/infrastructure/command-installer/types.ts +0 -41
- package/core/infrastructure/session-manager/index.ts +0 -23
- package/core/infrastructure/session-manager/types.ts +0 -45
- package/core/infrastructure/session-manager.ts +0 -8
- package/core/serializers/ideas-serializer.ts +0 -187
- package/core/serializers/index.ts +0 -36
- package/core/serializers/queue-serializer.ts +0 -210
- package/core/serializers/shipped-serializer.ts +0 -108
- package/core/serializers/state-serializer.ts +0 -136
- package/core/session/types.ts +0 -29
- /package/core/infrastructure/{agents/claude-agent.ts → claude-agent.ts} +0 -0
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Task Stack Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface TaskEntry {
|
|
6
|
-
id: string
|
|
7
|
-
task: string
|
|
8
|
-
agent: string
|
|
9
|
-
status: 'active' | 'paused' | 'completed'
|
|
10
|
-
started: string
|
|
11
|
-
paused: string | null
|
|
12
|
-
resumed: string | null
|
|
13
|
-
completed: string | null
|
|
14
|
-
duration: number | null
|
|
15
|
-
durationFormatted?: string
|
|
16
|
-
complexity: string
|
|
17
|
-
dev: string
|
|
18
|
-
pauseReason?: string
|
|
19
|
-
pausedDuration?: number
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface ParsedNowFile {
|
|
23
|
-
description: string
|
|
24
|
-
started: string | null
|
|
25
|
-
agent: string | null
|
|
26
|
-
complexity: string | null
|
|
27
|
-
dev: string | null
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface MigrationResult {
|
|
31
|
-
migrated: boolean
|
|
32
|
-
hadTask?: boolean
|
|
33
|
-
task?: TaskEntry
|
|
34
|
-
error?: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface SwitchResult {
|
|
38
|
-
paused: TaskEntry | null
|
|
39
|
-
resumed?: TaskEntry
|
|
40
|
-
started?: TaskEntry
|
|
41
|
-
type: 'resumed' | 'started'
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface StackSummary {
|
|
45
|
-
active: TaskEntry | null
|
|
46
|
-
paused: TaskEntry[]
|
|
47
|
-
pausedCount: number
|
|
48
|
-
completed: TaskEntry[]
|
|
49
|
-
completedCount: number
|
|
50
|
-
totalTasks: number
|
|
51
|
-
}
|
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CommandInstaller Class
|
|
3
|
-
* Installs prjct commands to Claude (Code + Desktop)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'fs/promises'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
import os from 'os'
|
|
9
|
-
import type { InstallResult, UninstallResult, CheckResult, SyncResult, GlobalConfigResult } from './types'
|
|
10
|
-
import { installGlobalConfig, installDocs } from './global-config'
|
|
11
|
-
|
|
12
|
-
export class CommandInstaller {
|
|
13
|
-
homeDir: string
|
|
14
|
-
claudeCommandsPath: string
|
|
15
|
-
claudeConfigPath: string
|
|
16
|
-
templatesDir: string
|
|
17
|
-
|
|
18
|
-
constructor() {
|
|
19
|
-
this.homeDir = os.homedir()
|
|
20
|
-
this.claudeCommandsPath = path.join(this.homeDir, '.claude', 'commands', 'p')
|
|
21
|
-
this.claudeConfigPath = path.join(this.homeDir, '.claude')
|
|
22
|
-
this.templatesDir = path.join(__dirname, '..', '..', '..', 'templates', 'commands')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Detect if Claude is installed
|
|
27
|
-
*/
|
|
28
|
-
async detectClaude(): Promise<boolean> {
|
|
29
|
-
try {
|
|
30
|
-
await fs.access(this.claudeConfigPath)
|
|
31
|
-
return true
|
|
32
|
-
} catch {
|
|
33
|
-
return false
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get list of command files to install
|
|
39
|
-
*/
|
|
40
|
-
async getCommandFiles(): Promise<string[]> {
|
|
41
|
-
try {
|
|
42
|
-
const files = await fs.readdir(this.templatesDir)
|
|
43
|
-
return files.filter((f) => f.endsWith('.md'))
|
|
44
|
-
} catch {
|
|
45
|
-
// Fallback to core commands if template directory not accessible
|
|
46
|
-
return [
|
|
47
|
-
'init.md',
|
|
48
|
-
'now.md',
|
|
49
|
-
'done.md',
|
|
50
|
-
'ship.md',
|
|
51
|
-
'next.md',
|
|
52
|
-
'idea.md',
|
|
53
|
-
'recap.md',
|
|
54
|
-
'progress.md',
|
|
55
|
-
'stuck.md',
|
|
56
|
-
'context.md',
|
|
57
|
-
'analyze.md',
|
|
58
|
-
'sync.md',
|
|
59
|
-
'roadmap.md',
|
|
60
|
-
'task.md',
|
|
61
|
-
'git.md',
|
|
62
|
-
'fix.md',
|
|
63
|
-
'test.md',
|
|
64
|
-
'cleanup.md',
|
|
65
|
-
'design.md',
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Install commands to Claude
|
|
72
|
-
*/
|
|
73
|
-
async installCommands(): Promise<InstallResult> {
|
|
74
|
-
const claudeDetected = await this.detectClaude()
|
|
75
|
-
|
|
76
|
-
if (!claudeDetected) {
|
|
77
|
-
return {
|
|
78
|
-
success: false,
|
|
79
|
-
error: 'Claude not detected. Please install Claude Code or Claude Desktop first.',
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
// Ensure commands directory exists
|
|
85
|
-
await fs.mkdir(this.claudeCommandsPath, { recursive: true })
|
|
86
|
-
|
|
87
|
-
const commandFiles = await this.getCommandFiles()
|
|
88
|
-
const installed: string[] = []
|
|
89
|
-
const errors: Array<{ file: string; error: string }> = []
|
|
90
|
-
|
|
91
|
-
for (const file of commandFiles) {
|
|
92
|
-
try {
|
|
93
|
-
const sourcePath = path.join(this.templatesDir, file)
|
|
94
|
-
const destPath = path.join(this.claudeCommandsPath, file)
|
|
95
|
-
|
|
96
|
-
const content = await fs.readFile(sourcePath, 'utf-8')
|
|
97
|
-
await fs.writeFile(destPath, content, 'utf-8')
|
|
98
|
-
|
|
99
|
-
installed.push(file.replace('.md', ''))
|
|
100
|
-
} catch (error) {
|
|
101
|
-
errors.push({ file, error: (error as Error).message })
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
success: true,
|
|
107
|
-
installed,
|
|
108
|
-
errors,
|
|
109
|
-
path: this.claudeCommandsPath,
|
|
110
|
-
}
|
|
111
|
-
} catch (error) {
|
|
112
|
-
return {
|
|
113
|
-
success: false,
|
|
114
|
-
error: (error as Error).message,
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Uninstall commands from Claude
|
|
121
|
-
*/
|
|
122
|
-
async uninstallCommands(): Promise<UninstallResult> {
|
|
123
|
-
try {
|
|
124
|
-
const commandFiles = await this.getCommandFiles()
|
|
125
|
-
const uninstalled: string[] = []
|
|
126
|
-
const errors: Array<{ file: string; error: string }> = []
|
|
127
|
-
|
|
128
|
-
for (const file of commandFiles) {
|
|
129
|
-
try {
|
|
130
|
-
const filePath = path.join(this.claudeCommandsPath, file)
|
|
131
|
-
await fs.unlink(filePath)
|
|
132
|
-
uninstalled.push(file.replace('.md', ''))
|
|
133
|
-
} catch (error) {
|
|
134
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
135
|
-
errors.push({ file, error: (error as Error).message })
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Try to remove the /p directory if empty
|
|
141
|
-
try {
|
|
142
|
-
await fs.rmdir(this.claudeCommandsPath)
|
|
143
|
-
} catch {
|
|
144
|
-
// Directory not empty or doesn't exist - that's fine
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return {
|
|
148
|
-
success: true,
|
|
149
|
-
uninstalled,
|
|
150
|
-
errors,
|
|
151
|
-
}
|
|
152
|
-
} catch (error) {
|
|
153
|
-
return {
|
|
154
|
-
success: false,
|
|
155
|
-
error: (error as Error).message,
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Check if commands are already installed
|
|
162
|
-
*/
|
|
163
|
-
async checkInstallation(): Promise<CheckResult> {
|
|
164
|
-
const claudeDetected = await this.detectClaude()
|
|
165
|
-
|
|
166
|
-
if (!claudeDetected) {
|
|
167
|
-
return {
|
|
168
|
-
installed: false,
|
|
169
|
-
claudeDetected: false,
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
try {
|
|
174
|
-
await fs.access(this.claudeCommandsPath)
|
|
175
|
-
const files = await fs.readdir(this.claudeCommandsPath)
|
|
176
|
-
const installedCommands = files
|
|
177
|
-
.filter((f) => f.endsWith('.md'))
|
|
178
|
-
.map((f) => f.replace('.md', ''))
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
installed: installedCommands.length > 0,
|
|
182
|
-
claudeDetected: true,
|
|
183
|
-
commands: installedCommands,
|
|
184
|
-
path: this.claudeCommandsPath,
|
|
185
|
-
}
|
|
186
|
-
} catch {
|
|
187
|
-
return {
|
|
188
|
-
installed: false,
|
|
189
|
-
claudeDetected: true,
|
|
190
|
-
commands: [],
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Update commands (reinstall with latest templates)
|
|
197
|
-
*/
|
|
198
|
-
async updateCommands(): Promise<InstallResult> {
|
|
199
|
-
// Simply reinstall - will overwrite with latest templates
|
|
200
|
-
console.log('🔄 Updating commands with latest templates...')
|
|
201
|
-
const result = await this.installCommands()
|
|
202
|
-
if (result.success && result.installed) {
|
|
203
|
-
console.log(`✅ Updated ${result.installed.length} commands`)
|
|
204
|
-
}
|
|
205
|
-
return result
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Install to all detected editors (alias for installCommands)
|
|
210
|
-
*/
|
|
211
|
-
async installToAll(): Promise<InstallResult> {
|
|
212
|
-
return await this.installCommands()
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Get installation path for Claude commands
|
|
217
|
-
*/
|
|
218
|
-
getInstallPath(): string {
|
|
219
|
-
return this.claudeCommandsPath
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Verify command template exists
|
|
224
|
-
*/
|
|
225
|
-
async verifyTemplate(commandName: string): Promise<boolean> {
|
|
226
|
-
try {
|
|
227
|
-
const templatePath = path.join(this.templatesDir, `${commandName}.md`)
|
|
228
|
-
await fs.access(templatePath)
|
|
229
|
-
return true
|
|
230
|
-
} catch {
|
|
231
|
-
return false
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Sync commands - intelligent update that detects and removes orphans
|
|
237
|
-
*/
|
|
238
|
-
async syncCommands(): Promise<SyncResult> {
|
|
239
|
-
const claudeDetected = await this.detectClaude()
|
|
240
|
-
|
|
241
|
-
if (!claudeDetected) {
|
|
242
|
-
return {
|
|
243
|
-
success: false,
|
|
244
|
-
error: 'Claude not detected',
|
|
245
|
-
added: 0,
|
|
246
|
-
updated: 0,
|
|
247
|
-
removed: 0,
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
try {
|
|
252
|
-
// Ensure commands directory exists
|
|
253
|
-
await fs.mkdir(this.claudeCommandsPath, { recursive: true })
|
|
254
|
-
|
|
255
|
-
// Get current state
|
|
256
|
-
const templateFiles = await this.getCommandFiles()
|
|
257
|
-
let installedFiles: string[] = []
|
|
258
|
-
|
|
259
|
-
try {
|
|
260
|
-
installedFiles = await fs.readdir(this.claudeCommandsPath)
|
|
261
|
-
installedFiles = installedFiles.filter((f) => f.endsWith('.md'))
|
|
262
|
-
} catch {
|
|
263
|
-
// Directory doesn't exist yet
|
|
264
|
-
installedFiles = []
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const results: SyncResult = {
|
|
268
|
-
success: true,
|
|
269
|
-
added: 0,
|
|
270
|
-
updated: 0,
|
|
271
|
-
removed: 0,
|
|
272
|
-
errors: [],
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Install/update all template files (always overwrite)
|
|
276
|
-
for (const file of templateFiles) {
|
|
277
|
-
try {
|
|
278
|
-
const sourcePath = path.join(this.templatesDir, file)
|
|
279
|
-
const destPath = path.join(this.claudeCommandsPath, file)
|
|
280
|
-
|
|
281
|
-
// Check if file exists in installed location
|
|
282
|
-
const exists = installedFiles.includes(file)
|
|
283
|
-
|
|
284
|
-
// Read and write (always overwrite to ensure latest version)
|
|
285
|
-
const content = await fs.readFile(sourcePath, 'utf-8')
|
|
286
|
-
await fs.writeFile(destPath, content, 'utf-8')
|
|
287
|
-
|
|
288
|
-
if (!exists) {
|
|
289
|
-
results.added++
|
|
290
|
-
} else {
|
|
291
|
-
results.updated++
|
|
292
|
-
}
|
|
293
|
-
} catch (error) {
|
|
294
|
-
results.errors!.push({ file, error: (error as Error).message })
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Note: We do NOT remove orphaned files
|
|
299
|
-
// Legacy commands from older versions are preserved
|
|
300
|
-
// to avoid breaking existing workflows
|
|
301
|
-
|
|
302
|
-
return results
|
|
303
|
-
} catch (error) {
|
|
304
|
-
return {
|
|
305
|
-
success: false,
|
|
306
|
-
error: (error as Error).message,
|
|
307
|
-
added: 0,
|
|
308
|
-
updated: 0,
|
|
309
|
-
removed: 0,
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Install or update global CLAUDE.md configuration
|
|
316
|
-
*/
|
|
317
|
-
async installGlobalConfig(): Promise<GlobalConfigResult> {
|
|
318
|
-
return installGlobalConfig(this.claudeConfigPath, () => this.detectClaude())
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Install documentation files to ~/.prjct-cli/docs/
|
|
323
|
-
*/
|
|
324
|
-
async installDocs(): Promise<{ success: boolean; error?: string }> {
|
|
325
|
-
return installDocs()
|
|
326
|
-
}
|
|
327
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global Config Operations
|
|
3
|
-
* Install/update global CLAUDE.md configuration and docs
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'fs/promises'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
import os from 'os'
|
|
9
|
-
import type { GlobalConfigResult } from './types'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Install documentation files to ~/.prjct-cli/docs/
|
|
13
|
-
*/
|
|
14
|
-
export async function installDocs(): Promise<{ success: boolean; error?: string }> {
|
|
15
|
-
try {
|
|
16
|
-
const docsDir = path.join(os.homedir(), '.prjct-cli', 'docs')
|
|
17
|
-
const templateDocsDir = path.join(__dirname, '../../../templates/global/docs')
|
|
18
|
-
|
|
19
|
-
// Ensure docs directory exists
|
|
20
|
-
await fs.mkdir(docsDir, { recursive: true })
|
|
21
|
-
|
|
22
|
-
// Read all doc files from template
|
|
23
|
-
const docFiles = await fs.readdir(templateDocsDir)
|
|
24
|
-
|
|
25
|
-
// Copy each doc file
|
|
26
|
-
for (const file of docFiles) {
|
|
27
|
-
if (file.endsWith('.md')) {
|
|
28
|
-
const srcPath = path.join(templateDocsDir, file)
|
|
29
|
-
const destPath = path.join(docsDir, file)
|
|
30
|
-
const content = await fs.readFile(srcPath, 'utf-8')
|
|
31
|
-
await fs.writeFile(destPath, content, 'utf-8')
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return { success: true }
|
|
36
|
-
} catch (error) {
|
|
37
|
-
return { success: false, error: (error as Error).message }
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Install or update global CLAUDE.md configuration
|
|
43
|
-
*/
|
|
44
|
-
export async function installGlobalConfig(
|
|
45
|
-
claudeConfigPath: string,
|
|
46
|
-
detectClaude: () => Promise<boolean>
|
|
47
|
-
): Promise<GlobalConfigResult> {
|
|
48
|
-
const claudeDetected = await detectClaude()
|
|
49
|
-
|
|
50
|
-
if (!claudeDetected) {
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
error: 'Claude not detected',
|
|
54
|
-
action: 'skipped',
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
// Ensure ~/.claude directory exists
|
|
60
|
-
const claudeDir = path.join(os.homedir(), '.claude')
|
|
61
|
-
await fs.mkdir(claudeDir, { recursive: true })
|
|
62
|
-
|
|
63
|
-
const globalConfigPath = path.join(claudeDir, 'CLAUDE.md')
|
|
64
|
-
const templatePath = path.join(__dirname, '../../../templates/global/CLAUDE.md')
|
|
65
|
-
|
|
66
|
-
// Read template content
|
|
67
|
-
const templateContent = await fs.readFile(templatePath, 'utf-8')
|
|
68
|
-
|
|
69
|
-
// Check if global config already exists
|
|
70
|
-
let existingContent = ''
|
|
71
|
-
let fileExists = false
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
existingContent = await fs.readFile(globalConfigPath, 'utf-8')
|
|
75
|
-
fileExists = true
|
|
76
|
-
} catch {
|
|
77
|
-
// File doesn't exist, will create new
|
|
78
|
-
fileExists = false
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!fileExists) {
|
|
82
|
-
// Create new file with full template
|
|
83
|
-
await fs.writeFile(globalConfigPath, templateContent, 'utf-8')
|
|
84
|
-
return {
|
|
85
|
-
success: true,
|
|
86
|
-
action: 'created',
|
|
87
|
-
path: globalConfigPath,
|
|
88
|
-
}
|
|
89
|
-
} else {
|
|
90
|
-
// File exists - perform intelligent merge
|
|
91
|
-
const startMarker = '<!-- prjct:start - DO NOT REMOVE THIS MARKER -->'
|
|
92
|
-
const endMarker = '<!-- prjct:end - DO NOT REMOVE THIS MARKER -->'
|
|
93
|
-
|
|
94
|
-
// Check if markers exist in existing file
|
|
95
|
-
const hasMarkers =
|
|
96
|
-
existingContent.includes(startMarker) && existingContent.includes(endMarker)
|
|
97
|
-
|
|
98
|
-
if (!hasMarkers) {
|
|
99
|
-
// No markers - append prjct section at the end
|
|
100
|
-
const updatedContent = existingContent + '\n\n' + templateContent
|
|
101
|
-
await fs.writeFile(globalConfigPath, updatedContent, 'utf-8')
|
|
102
|
-
return {
|
|
103
|
-
success: true,
|
|
104
|
-
action: 'appended',
|
|
105
|
-
path: globalConfigPath,
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
// Markers exist - replace content between markers
|
|
109
|
-
const beforeMarker = existingContent.substring(0, existingContent.indexOf(startMarker))
|
|
110
|
-
const afterMarker = existingContent.substring(
|
|
111
|
-
existingContent.indexOf(endMarker) + endMarker.length
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
// Extract prjct section from template
|
|
115
|
-
const prjctSection = templateContent.substring(
|
|
116
|
-
templateContent.indexOf(startMarker),
|
|
117
|
-
templateContent.indexOf(endMarker) + endMarker.length
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
const updatedContent = beforeMarker + prjctSection + afterMarker
|
|
121
|
-
await fs.writeFile(globalConfigPath, updatedContent, 'utf-8')
|
|
122
|
-
return {
|
|
123
|
-
success: true,
|
|
124
|
-
action: 'updated',
|
|
125
|
-
path: globalConfigPath,
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
} catch (error) {
|
|
130
|
-
return {
|
|
131
|
-
success: false,
|
|
132
|
-
error: (error as Error).message,
|
|
133
|
-
action: 'failed',
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CommandInstaller - Installs prjct commands to Claude (Code + Desktop)
|
|
3
|
-
*
|
|
4
|
-
* 100% Claude-focused architecture
|
|
5
|
-
* Handles installation and synchronization of /p:* commands
|
|
6
|
-
* to Claude's native slash command system
|
|
7
|
-
*
|
|
8
|
-
* @version 0.5.0
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export type {
|
|
12
|
-
InstallResult,
|
|
13
|
-
UninstallResult,
|
|
14
|
-
CheckResult,
|
|
15
|
-
SyncResult,
|
|
16
|
-
GlobalConfigResult,
|
|
17
|
-
} from './types'
|
|
18
|
-
|
|
19
|
-
export { installGlobalConfig, installDocs } from './global-config'
|
|
20
|
-
export { CommandInstaller } from './command-installer'
|
|
21
|
-
|
|
22
|
-
import { CommandInstaller } from './command-installer'
|
|
23
|
-
|
|
24
|
-
const commandInstaller = new CommandInstaller()
|
|
25
|
-
export default commandInstaller
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command Installer Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface InstallResult {
|
|
6
|
-
success: boolean
|
|
7
|
-
installed?: string[]
|
|
8
|
-
errors?: Array<{ file: string; error: string }>
|
|
9
|
-
path?: string
|
|
10
|
-
error?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface UninstallResult {
|
|
14
|
-
success: boolean
|
|
15
|
-
uninstalled?: string[]
|
|
16
|
-
errors?: Array<{ file: string; error: string }>
|
|
17
|
-
error?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface CheckResult {
|
|
21
|
-
installed: boolean
|
|
22
|
-
claudeDetected: boolean
|
|
23
|
-
commands?: string[]
|
|
24
|
-
path?: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface SyncResult {
|
|
28
|
-
success: boolean
|
|
29
|
-
added: number
|
|
30
|
-
updated: number
|
|
31
|
-
removed: number
|
|
32
|
-
errors?: Array<{ file: string; error: string }>
|
|
33
|
-
error?: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface GlobalConfigResult {
|
|
37
|
-
success: boolean
|
|
38
|
-
action: string
|
|
39
|
-
path?: string
|
|
40
|
-
error?: string
|
|
41
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session Manager
|
|
3
|
-
* Manages temporal fragmentation of logs and progress data.
|
|
4
|
-
*
|
|
5
|
-
* @module infrastructure/session-manager
|
|
6
|
-
* @version 0.2.1
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export type {
|
|
10
|
-
SessionEntry,
|
|
11
|
-
SessionMetadata,
|
|
12
|
-
SessionStats,
|
|
13
|
-
MigrationResult,
|
|
14
|
-
SessionInfo,
|
|
15
|
-
} from './types'
|
|
16
|
-
|
|
17
|
-
export { migrateLegacyJsonl, migrateLegacyMarkdown } from './migration'
|
|
18
|
-
export { SessionManager } from './session-manager'
|
|
19
|
-
|
|
20
|
-
import { SessionManager } from './session-manager'
|
|
21
|
-
|
|
22
|
-
const sessionManager = new SessionManager()
|
|
23
|
-
export default sessionManager
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session Manager Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface SessionEntry {
|
|
6
|
-
timestamp?: string
|
|
7
|
-
data?: {
|
|
8
|
-
timestamp?: string
|
|
9
|
-
}
|
|
10
|
-
_sessionDate?: Date
|
|
11
|
-
[key: string]: unknown
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface SessionMetadata {
|
|
15
|
-
created?: string
|
|
16
|
-
lastActivity?: string
|
|
17
|
-
entryCount?: number
|
|
18
|
-
shipCount?: number
|
|
19
|
-
version?: string
|
|
20
|
-
migrated?: boolean
|
|
21
|
-
migratedAt?: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface SessionStats {
|
|
25
|
-
totalSessions: number
|
|
26
|
-
activeDays: number
|
|
27
|
-
totalEntries: number
|
|
28
|
-
totalShips: number
|
|
29
|
-
averageEntriesPerDay: number
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface MigrationResult {
|
|
33
|
-
success: boolean
|
|
34
|
-
message: string
|
|
35
|
-
entriesMigrated: number
|
|
36
|
-
sessionsCreated?: number
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface SessionInfo {
|
|
40
|
-
path: string
|
|
41
|
-
date: Date
|
|
42
|
-
year: string
|
|
43
|
-
month: string
|
|
44
|
-
day: string
|
|
45
|
-
}
|