prjct-cli 0.20.0 → 0.21.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.
Files changed (236) hide show
  1. package/CHANGELOG.md +24 -6
  2. package/CLAUDE.md +56 -15
  3. package/README.md +5 -6
  4. package/bin/prjct +59 -42
  5. package/bin/prjct.ts +60 -0
  6. package/core/__tests__/agentic/memory-system.test.ts +18 -3
  7. package/core/__tests__/agentic/plan-mode.test.ts +55 -26
  8. package/core/__tests__/agentic/prompt-builder.test.ts +6 -6
  9. package/core/__tests__/utils/project-commands.test.ts +72 -0
  10. package/core/agentic/agent-router.ts +3 -12
  11. package/core/agentic/command-executor.ts +372 -3
  12. package/core/agentic/context-builder.ts +7 -27
  13. package/core/agentic/ground-truth.ts +604 -5
  14. package/core/agentic/index.ts +180 -0
  15. package/core/agentic/loop-detector.ts +418 -4
  16. package/core/agentic/memory-system.ts +857 -3
  17. package/core/agentic/plan-mode.ts +491 -4
  18. package/core/agentic/prompt-builder.ts +44 -65
  19. package/core/agentic/services.ts +13 -5
  20. package/core/agentic/skill-loader.ts +112 -0
  21. package/core/agentic/smart-context.ts +37 -122
  22. package/core/agentic/template-loader.ts +79 -122
  23. package/core/agentic/tool-registry.ts +5 -11
  24. package/core/agents/index.ts +1 -1
  25. package/core/agents/performance.ts +4 -2
  26. package/core/bus/bus.ts +262 -0
  27. package/core/bus/index.ts +3 -313
  28. package/core/commands/analysis.ts +5 -5
  29. package/core/commands/analytics.ts +11 -11
  30. package/core/commands/base.ts +33 -209
  31. package/core/commands/cleanup.ts +148 -0
  32. package/core/commands/command-data.ts +346 -0
  33. package/core/commands/commands.ts +216 -0
  34. package/core/commands/design.ts +83 -0
  35. package/core/commands/index.ts +13 -207
  36. package/core/commands/maintenance.ts +52 -473
  37. package/core/commands/planning.ts +3 -3
  38. package/core/commands/register.ts +104 -0
  39. package/core/commands/registry.ts +441 -0
  40. package/core/commands/setup.ts +25 -9
  41. package/core/commands/shipping.ts +48 -11
  42. package/core/commands/snapshots.ts +299 -0
  43. package/core/commands/workflow.ts +2 -2
  44. package/core/constants/index.ts +254 -4
  45. package/core/domain/agent-loader.ts +5 -6
  46. package/core/domain/task-stack.ts +555 -4
  47. package/core/errors.ts +127 -1
  48. package/core/events/events.ts +87 -0
  49. package/core/events/index.ts +4 -138
  50. package/core/index.ts +15 -23
  51. package/core/infrastructure/agent-detector.ts +126 -201
  52. package/core/infrastructure/author-detector.ts +99 -171
  53. package/core/infrastructure/command-installer.ts +476 -4
  54. package/core/infrastructure/config-manager.ts +41 -37
  55. package/core/infrastructure/path-manager.ts +59 -9
  56. package/core/infrastructure/permission-manager.ts +286 -0
  57. package/core/integrations/notion/client.ts +323 -0
  58. package/core/integrations/notion/index.ts +43 -0
  59. package/core/integrations/notion/setup.ts +230 -0
  60. package/core/integrations/notion/sync.ts +311 -0
  61. package/core/integrations/notion/templates.ts +234 -0
  62. package/core/outcomes/analyzer.ts +7 -41
  63. package/core/outcomes/index.ts +1 -1
  64. package/core/outcomes/recorder.ts +1 -1
  65. package/core/plugin/builtin/notion.ts +178 -0
  66. package/core/{plugins → plugin/builtin}/webhook.ts +6 -22
  67. package/core/plugin/loader.ts +5 -5
  68. package/core/plugin/registry.ts +2 -2
  69. package/core/schemas/ideas.ts +85 -54
  70. package/core/schemas/index.ts +14 -33
  71. package/core/schemas/permissions.ts +177 -0
  72. package/core/schemas/project.ts +39 -12
  73. package/core/schemas/roadmap.ts +94 -59
  74. package/core/schemas/schemas.ts +39 -0
  75. package/core/schemas/shipped.ts +87 -60
  76. package/core/schemas/state.ts +110 -70
  77. package/core/server/index.ts +21 -0
  78. package/core/server/routes.ts +165 -0
  79. package/core/server/server.ts +136 -0
  80. package/core/server/sse.ts +135 -0
  81. package/core/services/agent-service.ts +170 -0
  82. package/core/services/breakdown-service.ts +126 -0
  83. package/core/services/index.ts +21 -0
  84. package/core/services/memory-service.ts +108 -0
  85. package/core/services/project-service.ts +146 -0
  86. package/core/services/skill-service.ts +253 -0
  87. package/core/session/compaction.ts +257 -0
  88. package/core/session/index.ts +20 -8
  89. package/core/{infrastructure/session-manager/migration.ts → session/log-migration.ts} +9 -9
  90. package/core/{infrastructure/session-manager/session-manager.ts → session/session-log-manager.ts} +27 -26
  91. package/core/session/{session-manager.ts → task-session-manager.ts} +7 -4
  92. package/core/session/utils.ts +1 -1
  93. package/core/storage/ideas-storage.ts +10 -26
  94. package/core/storage/index.ts +14 -162
  95. package/core/storage/queue-storage.ts +13 -11
  96. package/core/storage/shipped-storage.ts +4 -17
  97. package/core/storage/state-storage.ts +35 -43
  98. package/core/storage/storage-manager.ts +42 -52
  99. package/core/storage/storage.ts +160 -0
  100. package/core/sync/auth-config.ts +1 -8
  101. package/core/sync/index.ts +17 -10
  102. package/core/sync/oauth-handler.ts +1 -6
  103. package/core/sync/sync-client.ts +6 -34
  104. package/core/sync/sync-manager.ts +11 -40
  105. package/core/types/agentic.ts +577 -0
  106. package/core/types/agents.ts +145 -0
  107. package/core/types/bus.ts +82 -0
  108. package/core/types/commands.ts +366 -0
  109. package/core/types/config.ts +70 -0
  110. package/core/types/core.ts +96 -0
  111. package/core/types/domain.ts +71 -0
  112. package/core/types/events.ts +42 -0
  113. package/core/types/fs.ts +56 -0
  114. package/core/types/index.ts +396 -500
  115. package/core/types/infrastructure.ts +196 -0
  116. package/core/types/integrations.ts +57 -0
  117. package/core/{agentic/memory-system/types.ts → types/memory.ts} +33 -8
  118. package/core/{outcomes/types.ts → types/outcomes.ts} +53 -8
  119. package/core/types/plugin.ts +25 -0
  120. package/core/types/server.ts +54 -0
  121. package/core/types/services.ts +65 -0
  122. package/core/types/session.ts +135 -0
  123. package/core/types/storage.ts +148 -0
  124. package/core/types/sync.ts +121 -0
  125. package/core/types/task.ts +72 -0
  126. package/core/types/template.ts +24 -0
  127. package/core/types/utils.ts +90 -0
  128. package/core/utils/cache.ts +195 -0
  129. package/core/utils/collection-filters.ts +245 -0
  130. package/core/utils/date-helper.ts +1 -5
  131. package/core/utils/file-helper.ts +20 -10
  132. package/core/utils/jsonl-helper.ts +5 -8
  133. package/core/utils/markdown-builder.ts +277 -0
  134. package/core/utils/project-commands.ts +132 -0
  135. package/core/utils/runtime.ts +119 -0
  136. package/dist/bin/prjct.mjs +12568 -0
  137. package/package.json +13 -8
  138. package/scripts/build.js +106 -0
  139. package/scripts/postinstall.js +50 -8
  140. package/templates/agentic/subagent-generation.md +1 -1
  141. package/templates/commands/init.md +43 -0
  142. package/templates/commands/notion-setup.md +191 -0
  143. package/templates/commands/serve.md +118 -0
  144. package/templates/commands/ship.md +13 -2
  145. package/templates/commands/skill.md +110 -0
  146. package/templates/commands/sync.md +1 -1
  147. package/templates/commands/test.md +23 -4
  148. package/templates/mcp-config.json +28 -0
  149. package/templates/permissions/default.jsonc +60 -0
  150. package/templates/permissions/permissive.jsonc +49 -0
  151. package/templates/permissions/strict.jsonc +62 -0
  152. package/templates/skills/code-review.md +47 -0
  153. package/templates/skills/debug.md +61 -0
  154. package/templates/skills/refactor.md +47 -0
  155. package/templates/subagents/domain/devops.md +1 -1
  156. package/templates/subagents/domain/testing.md +6 -10
  157. package/templates/subagents/workflow/prjct-shipper.md +16 -7
  158. package/templates/tools/bash.txt +22 -0
  159. package/templates/tools/edit.txt +18 -0
  160. package/templates/tools/glob.txt +19 -0
  161. package/templates/tools/grep.txt +21 -0
  162. package/templates/tools/read.txt +14 -0
  163. package/templates/tools/task.txt +20 -0
  164. package/templates/tools/webfetch.txt +16 -0
  165. package/templates/tools/websearch.txt +18 -0
  166. package/templates/tools/write.txt +17 -0
  167. package/core/agentic/command-executor/command-executor.ts +0 -312
  168. package/core/agentic/command-executor/index.ts +0 -16
  169. package/core/agentic/command-executor/status-signal.ts +0 -38
  170. package/core/agentic/command-executor/types.ts +0 -79
  171. package/core/agentic/ground-truth/index.ts +0 -76
  172. package/core/agentic/ground-truth/types.ts +0 -33
  173. package/core/agentic/ground-truth/utils.ts +0 -48
  174. package/core/agentic/ground-truth/verifiers/analyze.ts +0 -54
  175. package/core/agentic/ground-truth/verifiers/done.ts +0 -75
  176. package/core/agentic/ground-truth/verifiers/feature.ts +0 -70
  177. package/core/agentic/ground-truth/verifiers/index.ts +0 -37
  178. package/core/agentic/ground-truth/verifiers/init.ts +0 -52
  179. package/core/agentic/ground-truth/verifiers/now.ts +0 -57
  180. package/core/agentic/ground-truth/verifiers/ship.ts +0 -85
  181. package/core/agentic/ground-truth/verifiers/spec.ts +0 -45
  182. package/core/agentic/ground-truth/verifiers/sync.ts +0 -47
  183. package/core/agentic/ground-truth/verifiers.ts +0 -6
  184. package/core/agentic/loop-detector/error-analysis.ts +0 -97
  185. package/core/agentic/loop-detector/hallucination.ts +0 -71
  186. package/core/agentic/loop-detector/index.ts +0 -41
  187. package/core/agentic/loop-detector/loop-detector.ts +0 -222
  188. package/core/agentic/loop-detector/types.ts +0 -66
  189. package/core/agentic/memory-system/history.ts +0 -53
  190. package/core/agentic/memory-system/index.ts +0 -192
  191. package/core/agentic/memory-system/patterns.ts +0 -156
  192. package/core/agentic/memory-system/semantic-memories.ts +0 -278
  193. package/core/agentic/memory-system/session.ts +0 -21
  194. package/core/agentic/plan-mode/approval.ts +0 -57
  195. package/core/agentic/plan-mode/constants.ts +0 -44
  196. package/core/agentic/plan-mode/index.ts +0 -28
  197. package/core/agentic/plan-mode/plan-mode.ts +0 -407
  198. package/core/agentic/plan-mode/types.ts +0 -193
  199. package/core/agents/types.ts +0 -126
  200. package/core/command-registry/categories.ts +0 -23
  201. package/core/command-registry/commands.ts +0 -15
  202. package/core/command-registry/core-commands.ts +0 -344
  203. package/core/command-registry/index.ts +0 -158
  204. package/core/command-registry/optional-commands.ts +0 -163
  205. package/core/command-registry/setup-commands.ts +0 -83
  206. package/core/command-registry/types.ts +0 -59
  207. package/core/command-registry.ts +0 -9
  208. package/core/commands/types.ts +0 -185
  209. package/core/commands.ts +0 -11
  210. package/core/constants/formats.ts +0 -187
  211. package/core/context-sync.ts +0 -18
  212. package/core/data/index.ts +0 -27
  213. package/core/data/md-base-manager.ts +0 -203
  214. package/core/data/md-ideas-manager.ts +0 -155
  215. package/core/data/md-queue-manager.ts +0 -180
  216. package/core/data/md-shipped-manager.ts +0 -90
  217. package/core/data/md-state-manager.ts +0 -137
  218. package/core/domain/task-stack/index.ts +0 -19
  219. package/core/domain/task-stack/parser.ts +0 -86
  220. package/core/domain/task-stack/storage.ts +0 -123
  221. package/core/domain/task-stack/task-stack.ts +0 -340
  222. package/core/domain/task-stack/types.ts +0 -51
  223. package/core/infrastructure/command-installer/command-installer.ts +0 -327
  224. package/core/infrastructure/command-installer/global-config.ts +0 -136
  225. package/core/infrastructure/command-installer/index.ts +0 -25
  226. package/core/infrastructure/command-installer/types.ts +0 -41
  227. package/core/infrastructure/session-manager/index.ts +0 -23
  228. package/core/infrastructure/session-manager/types.ts +0 -45
  229. package/core/infrastructure/session-manager.ts +0 -8
  230. package/core/serializers/ideas-serializer.ts +0 -187
  231. package/core/serializers/index.ts +0 -36
  232. package/core/serializers/queue-serializer.ts +0 -210
  233. package/core/serializers/shipped-serializer.ts +0 -108
  234. package/core/serializers/state-serializer.ts +0 -136
  235. package/core/session/types.ts +0 -29
  236. /package/core/infrastructure/{agents/claude-agent.ts → claude-agent.ts} +0 -0
@@ -0,0 +1,132 @@
1
+ import path from 'path'
2
+
3
+ import * as fileHelper from './file-helper'
4
+ import type { DetectedProjectCommands } from '../types'
5
+
6
+ type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun'
7
+ type DetectedStack = 'js' | 'python' | 'go' | 'rust' | 'dotnet' | 'java' | 'unknown'
8
+
9
+ interface DetectedCommand {
10
+ command: string
11
+ tool: string
12
+ }
13
+
14
+ interface PackageJson {
15
+ scripts?: Record<string, string>
16
+ packageManager?: string
17
+ }
18
+
19
+ /**
20
+ * Detect the most likely JS package manager for a project.
21
+ *
22
+ * Reason: installed users may not have Bun, and many projects use pnpm/yarn.
23
+ */
24
+ async function detectPackageManager(projectPath: string, pkg: PackageJson | null): Promise<PackageManager> {
25
+ const declared = pkg?.packageManager?.trim().toLowerCase()
26
+ if (declared?.startsWith('pnpm@')) return 'pnpm'
27
+ if (declared?.startsWith('yarn@')) return 'yarn'
28
+ if (declared?.startsWith('bun@')) return 'bun'
29
+ if (declared?.startsWith('npm@')) return 'npm'
30
+
31
+ // Lockfile heuristics
32
+ if (await fileHelper.fileExists(path.join(projectPath, 'pnpm-lock.yaml'))) return 'pnpm'
33
+ if (await fileHelper.fileExists(path.join(projectPath, 'yarn.lock'))) return 'yarn'
34
+ if (await fileHelper.fileExists(path.join(projectPath, 'bun.lockb'))) return 'bun'
35
+ if (await fileHelper.fileExists(path.join(projectPath, 'bun.lock'))) return 'bun'
36
+ if (await fileHelper.fileExists(path.join(projectPath, 'package-lock.json'))) return 'npm'
37
+
38
+ return 'npm'
39
+ }
40
+
41
+ function pmRun(pm: PackageManager, scriptName: string): string {
42
+ if (pm === 'yarn') return `yarn ${scriptName}`
43
+ if (pm === 'pnpm') return `pnpm run ${scriptName}`
44
+ if (pm === 'bun') return `bun run ${scriptName}`
45
+ return `npm run ${scriptName}`
46
+ }
47
+
48
+ function pmTest(pm: PackageManager): string {
49
+ if (pm === 'yarn') return 'yarn test'
50
+ if (pm === 'pnpm') return 'pnpm test'
51
+ if (pm === 'bun') return 'bun test'
52
+ return 'npm test'
53
+ }
54
+
55
+ /**
56
+ * Detect the appropriate lint/typecheck/test commands for a given project.
57
+ *
58
+ * - JS/TS projects: uses the project package manager + scripts when present
59
+ * - Python: prefers pytest when config is present
60
+ * - Go/Rust/.NET/Java: uses conventional defaults
61
+ *
62
+ * @param {string} projectPath - Repository root.
63
+ * @returns {Promise<DetectedProjectCommands>} detected commands (missing when not applicable).
64
+ */
65
+ export async function detectProjectCommands(projectPath: string): Promise<DetectedProjectCommands> {
66
+ const pkgPath = path.join(projectPath, 'package.json')
67
+ const pkg = await fileHelper.readJson<PackageJson | null>(pkgPath, null)
68
+
69
+ // JS/TS (prefer explicit scripts)
70
+ if (pkg) {
71
+ const pm = await detectPackageManager(projectPath, pkg)
72
+ const scripts = pkg.scripts || {}
73
+
74
+ const result: DetectedProjectCommands = { stack: 'js', packageManager: pm }
75
+
76
+ if (scripts.lint) {
77
+ result.lint = { tool: pm, command: pmRun(pm, 'lint') }
78
+ }
79
+
80
+ if (scripts.typecheck) {
81
+ result.typecheck = { tool: pm, command: pmRun(pm, 'typecheck') }
82
+ }
83
+
84
+ if (scripts.test) {
85
+ result.test = { tool: pm, command: pmTest(pm) }
86
+ }
87
+
88
+ return result
89
+ }
90
+
91
+ // Python
92
+ if (await fileHelper.fileExists(path.join(projectPath, 'pytest.ini'))) {
93
+ return { stack: 'python', test: { tool: 'pytest', command: 'pytest' } }
94
+ }
95
+
96
+ const pyproject = await fileHelper.readFile(path.join(projectPath, 'pyproject.toml'), '')
97
+ if (pyproject.includes('[tool.pytest') || pyproject.includes('pytest')) {
98
+ return { stack: 'python', test: { tool: 'pytest', command: 'pytest' } }
99
+ }
100
+
101
+ // Rust
102
+ if (await fileHelper.fileExists(path.join(projectPath, 'Cargo.toml'))) {
103
+ return { stack: 'rust', test: { tool: 'cargo', command: 'cargo test' } }
104
+ }
105
+
106
+ // Go
107
+ if (await fileHelper.fileExists(path.join(projectPath, 'go.mod'))) {
108
+ return { stack: 'go', test: { tool: 'go', command: 'go test ./...' } }
109
+ }
110
+
111
+ // .NET
112
+ const files = await fileHelper.listFiles(projectPath)
113
+ if (files.some((f) => f.endsWith('.sln') || f.endsWith('.csproj') || f.endsWith('.fsproj'))) {
114
+ return { stack: 'dotnet', test: { tool: 'dotnet', command: 'dotnet test' } }
115
+ }
116
+
117
+ // Java
118
+ if (await fileHelper.fileExists(path.join(projectPath, 'pom.xml'))) {
119
+ return { stack: 'java', test: { tool: 'maven', command: 'mvn test' } }
120
+ }
121
+ if (
122
+ (await fileHelper.fileExists(path.join(projectPath, 'gradlew'))) &&
123
+ ((await fileHelper.fileExists(path.join(projectPath, 'build.gradle'))) ||
124
+ (await fileHelper.fileExists(path.join(projectPath, 'build.gradle.kts'))))
125
+ ) {
126
+ return { stack: 'java', test: { tool: 'gradle', command: './gradlew test' } }
127
+ }
128
+
129
+ return { stack: 'unknown' }
130
+ }
131
+
132
+
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Runtime Detection Utility
3
+ *
4
+ * Detects available JavaScript runtimes and provides utilities
5
+ * for runtime-agnostic code execution.
6
+ *
7
+ * @version 1.0.0
8
+ */
9
+
10
+ import type { Runtime } from '../types'
11
+
12
+ /**
13
+ * Detect the current JavaScript runtime
14
+ */
15
+ export function detectRuntime(): Runtime {
16
+ // Check for Bun-specific global
17
+ if (typeof globalThis !== 'undefined' && 'Bun' in globalThis) {
18
+ return 'bun'
19
+ }
20
+
21
+ return 'node'
22
+ }
23
+
24
+ /**
25
+ * Check if Bun is available on the system
26
+ */
27
+ export function isBunAvailable(): boolean {
28
+ // If we're already running in Bun, it's available
29
+ if (detectRuntime() === 'bun') {
30
+ return true
31
+ }
32
+
33
+ // Check if bun command exists in PATH
34
+ try {
35
+ const { execSync } = require('child_process')
36
+ execSync('bun --version', { stdio: 'ignore' })
37
+ return true
38
+ } catch {
39
+ return false
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Check if Node is available on the system
45
+ */
46
+ export function isNodeAvailable(): boolean {
47
+ // If we're running, Node is available (either native or via Bun's node compat)
48
+ return true
49
+ }
50
+
51
+ /**
52
+ * Get runtime version
53
+ */
54
+ export function getRuntimeVersion(): string {
55
+ const runtime = detectRuntime()
56
+
57
+ if (runtime === 'bun') {
58
+ return `bun ${Bun.version || 'unknown'}`
59
+ }
60
+
61
+ return `node ${process.version}`
62
+ }
63
+
64
+ /**
65
+ * Check if we're running in a Bun environment
66
+ */
67
+ export function isBun(): boolean {
68
+ return detectRuntime() === 'bun'
69
+ }
70
+
71
+ /**
72
+ * Check if we're running in a Node environment
73
+ */
74
+ export function isNode(): boolean {
75
+ return detectRuntime() === 'node'
76
+ }
77
+
78
+ /**
79
+ * Get the preferred runtime for execution
80
+ * Returns 'bun' if available, otherwise 'node'
81
+ */
82
+ export function getPreferredRuntime(): Runtime {
83
+ if (isBunAvailable()) {
84
+ return 'bun'
85
+ }
86
+ return 'node'
87
+ }
88
+
89
+ /**
90
+ * Get command to run a script with the appropriate runtime
91
+ */
92
+ export function getRunCommand(scriptPath: string, args: string[] = []): string {
93
+ const runtime = getPreferredRuntime()
94
+ const argsStr = args.length > 0 ? ' ' + args.join(' ') : ''
95
+
96
+ if (runtime === 'bun') {
97
+ return `bun ${scriptPath}${argsStr}`
98
+ }
99
+
100
+ // For Node, check if it's a .ts file
101
+ if (scriptPath.endsWith('.ts')) {
102
+ // Use compiled version
103
+ const jsPath = scriptPath.replace(/\.ts$/, '.js').replace('/bin/', '/dist/bin/')
104
+ return `node ${jsPath}${argsStr}`
105
+ }
106
+
107
+ return `node ${scriptPath}${argsStr}`
108
+ }
109
+
110
+ export default {
111
+ detectRuntime,
112
+ isBunAvailable,
113
+ isNodeAvailable,
114
+ getRuntimeVersion,
115
+ isBun,
116
+ isNode,
117
+ getPreferredRuntime,
118
+ getRunCommand,
119
+ }