prjct-cli 0.19.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 +66 -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/agents/uxui.md +210 -0
- package/templates/agentic/subagent-generation.md +1 -1
- package/templates/commands/bug.md +219 -41
- package/templates/commands/feature.md +368 -80
- package/templates/commands/serve.md +118 -0
- package/templates/commands/ship.md +152 -14
- package/templates/commands/skill.md +110 -0
- package/templates/commands/sync.md +63 -4
- package/templates/commands/test.md +40 -188
- package/templates/mcp-config.json +0 -36
- 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,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: testing
|
|
3
|
-
description: Testing specialist for
|
|
3
|
+
description: Testing specialist for Bun test, Jest, Pytest, and testing libraries. Use PROACTIVELY when user works on tests, coverage, or test infrastructure.
|
|
4
4
|
tools: Read, Write, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -9,7 +9,7 @@ You are a testing specialist agent for this project.
|
|
|
9
9
|
|
|
10
10
|
## Your Expertise
|
|
11
11
|
|
|
12
|
-
- **JS/TS**:
|
|
12
|
+
- **JS/TS**: Bun test, Jest, Mocha
|
|
13
13
|
- **React**: Testing Library, Enzyme
|
|
14
14
|
- **Python**: Pytest, unittest
|
|
15
15
|
- **Go**: testing package, testify
|
|
@@ -18,15 +18,15 @@ You are a testing specialist agent for this project.
|
|
|
18
18
|
## Project Context
|
|
19
19
|
|
|
20
20
|
When invoked, analyze the project's testing setup:
|
|
21
|
-
1. Check for test config (
|
|
21
|
+
1. Check for test config (bunfig.toml, jest.config.js, pytest.ini)
|
|
22
22
|
2. Identify test file patterns
|
|
23
23
|
3. Check for existing test utilities
|
|
24
24
|
|
|
25
25
|
## Code Patterns
|
|
26
26
|
|
|
27
|
-
###
|
|
27
|
+
### Bun (Unit)
|
|
28
28
|
```typescript
|
|
29
|
-
import { describe, it, expect,
|
|
29
|
+
import { describe, it, expect, mock } from 'bun:test'
|
|
30
30
|
import { calculateTotal } from './cart'
|
|
31
31
|
|
|
32
32
|
describe('calculateTotal', () => {
|
|
@@ -48,7 +48,7 @@ import { Button } from './Button'
|
|
|
48
48
|
|
|
49
49
|
describe('Button', () => {
|
|
50
50
|
it('calls onClick when clicked', () => {
|
|
51
|
-
const onClick =
|
|
51
|
+
const onClick = mock(() => {})
|
|
52
52
|
render(<Button onClick={onClick}>Click me</Button>)
|
|
53
53
|
|
|
54
54
|
fireEvent.click(screen.getByRole('button'))
|
|
@@ -118,7 +118,6 @@ func TestCalculateTotal(t *testing.T) {
|
|
|
118
118
|
# JavaScript
|
|
119
119
|
npm test
|
|
120
120
|
bun test
|
|
121
|
-
vitest run
|
|
122
121
|
|
|
123
122
|
# Python
|
|
124
123
|
pytest
|
|
@@ -131,9 +130,6 @@ go test -cover ./...
|
|
|
131
130
|
|
|
132
131
|
### Coverage
|
|
133
132
|
```bash
|
|
134
|
-
# Vitest
|
|
135
|
-
vitest run --coverage
|
|
136
|
-
|
|
137
133
|
# Jest
|
|
138
134
|
jest --coverage
|
|
139
135
|
|
|
@@ -30,13 +30,22 @@ Run in sequence, stop on failure:
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
# 1. Lint (if configured)
|
|
33
|
-
|
|
33
|
+
# Use the project's own tooling (do not assume JS/Bun).
|
|
34
|
+
# Examples:
|
|
35
|
+
# - JS: pnpm run lint / yarn lint / npm run lint / bun run lint
|
|
36
|
+
# - Python: ruff/flake8 (only if project already uses it)
|
|
34
37
|
|
|
35
|
-
# 2. Type check (if
|
|
36
|
-
npm run typecheck
|
|
38
|
+
# 2. Type check (if configured)
|
|
39
|
+
# - TS: pnpm run typecheck / yarn typecheck / npm run typecheck / bun run typecheck
|
|
37
40
|
|
|
38
41
|
# 3. Tests (if configured)
|
|
39
|
-
|
|
42
|
+
# Use the project's own test runner:
|
|
43
|
+
# - JS: {packageManager} test (e.g. pnpm test, yarn test, npm test, bun test)
|
|
44
|
+
# - Python: pytest
|
|
45
|
+
# - Go: go test ./...
|
|
46
|
+
# - Rust: cargo test
|
|
47
|
+
# - .NET: dotnet test
|
|
48
|
+
# - Java: mvn test / ./gradlew test
|
|
40
49
|
```
|
|
41
50
|
|
|
42
51
|
If any fail:
|
|
@@ -125,12 +134,12 @@ Read from `.prjct/ship.config.json` if exists:
|
|
|
125
134
|
"typecheck": true,
|
|
126
135
|
"test": true
|
|
127
136
|
},
|
|
128
|
-
"testCommand": "
|
|
129
|
-
"lintCommand": "
|
|
137
|
+
"testCommand": "pytest",
|
|
138
|
+
"lintCommand": "npm run lint"
|
|
130
139
|
}
|
|
131
140
|
```
|
|
132
141
|
|
|
133
|
-
If no config, auto-detect from package.json scripts.
|
|
142
|
+
If no config, auto-detect from the repository (package.json scripts, pytest.ini, Cargo.toml, go.mod, etc.).
|
|
134
143
|
|
|
135
144
|
## Dry Run Mode
|
|
136
145
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Execute shell commands in a persistent bash session.
|
|
2
|
+
|
|
3
|
+
Use this tool for terminal operations like git, npm, docker, build commands, and system utilities. NOT for file operations (use Read, Write, Edit instead).
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Run any shell command
|
|
7
|
+
- Persistent session (environment persists between calls)
|
|
8
|
+
- Support for background execution
|
|
9
|
+
- Configurable timeout (up to 10 minutes)
|
|
10
|
+
|
|
11
|
+
Best practices:
|
|
12
|
+
- Quote paths with spaces using double quotes
|
|
13
|
+
- Use absolute paths to avoid cd
|
|
14
|
+
- Chain dependent commands with &&
|
|
15
|
+
- Run independent commands in parallel (multiple tool calls)
|
|
16
|
+
- Never use for file reading (use Read tool)
|
|
17
|
+
- Never use echo/printf to communicate (output text directly)
|
|
18
|
+
|
|
19
|
+
Git operations:
|
|
20
|
+
- Never update git config
|
|
21
|
+
- Never use destructive commands without explicit request
|
|
22
|
+
- Always use HEREDOC for commit messages
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Edit files using exact string replacement.
|
|
2
|
+
|
|
3
|
+
Use this tool to make precise changes to existing files. Requires reading the file first to ensure accurate matching.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Replace exact string matches in files
|
|
7
|
+
- Support for replace_all to change all occurrences
|
|
8
|
+
- Preserves file formatting and indentation
|
|
9
|
+
|
|
10
|
+
Requirements:
|
|
11
|
+
- Must read the file first (tool will error otherwise)
|
|
12
|
+
- old_string must be unique in the file (or use replace_all)
|
|
13
|
+
- Preserve exact indentation from the original
|
|
14
|
+
|
|
15
|
+
Best practices:
|
|
16
|
+
- Include enough context to make old_string unique
|
|
17
|
+
- Use replace_all for renaming variables/functions
|
|
18
|
+
- Never include line numbers in old_string or new_string
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Find files by pattern matching.
|
|
2
|
+
|
|
3
|
+
Use this tool to locate files using glob patterns. Fast and efficient for any codebase size.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Match files using glob patterns (e.g., "**/*.ts", "src/**/*.tsx")
|
|
7
|
+
- Returns paths sorted by modification time
|
|
8
|
+
- Works with any codebase size
|
|
9
|
+
|
|
10
|
+
Pattern examples:
|
|
11
|
+
- "**/*.ts" - all TypeScript files
|
|
12
|
+
- "src/**/*.tsx" - React components in src
|
|
13
|
+
- "**/test*.ts" - test files anywhere
|
|
14
|
+
- "core/**/*" - all files in core directory
|
|
15
|
+
|
|
16
|
+
Best practices:
|
|
17
|
+
- Use specific patterns to narrow results
|
|
18
|
+
- Prefer glob over bash find command
|
|
19
|
+
- Run multiple patterns in parallel if needed
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Search file contents using regex patterns.
|
|
2
|
+
|
|
3
|
+
Use this tool to search for code patterns, function definitions, imports, and text across the codebase. Built on ripgrep for speed.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Full regex syntax support
|
|
7
|
+
- Filter by file type or glob pattern
|
|
8
|
+
- Multiple output modes: files_with_matches, content, count
|
|
9
|
+
- Context lines before/after matches (-A, -B, -C)
|
|
10
|
+
- Multiline matching support
|
|
11
|
+
|
|
12
|
+
Output modes:
|
|
13
|
+
- files_with_matches (default): just file paths
|
|
14
|
+
- content: matching lines with context
|
|
15
|
+
- count: match counts per file
|
|
16
|
+
|
|
17
|
+
Best practices:
|
|
18
|
+
- Use specific patterns to reduce noise
|
|
19
|
+
- Filter by file type when possible (type: "ts")
|
|
20
|
+
- Use content mode with context for understanding matches
|
|
21
|
+
- Never use bash grep/rg directly (use this tool)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Read files from the filesystem.
|
|
2
|
+
|
|
3
|
+
Use this tool to read file contents before making edits. Always read a file before attempting to modify it to understand the current state and structure.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Read any text file by absolute path
|
|
7
|
+
- Supports line offset and limit for large files
|
|
8
|
+
- Returns content with line numbers for easy reference
|
|
9
|
+
- Can read images, PDFs, and Jupyter notebooks
|
|
10
|
+
|
|
11
|
+
Best practices:
|
|
12
|
+
- Always read before editing
|
|
13
|
+
- Use offset/limit for files > 2000 lines
|
|
14
|
+
- Read multiple related files in parallel when exploring
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Launch specialized agents for complex tasks.
|
|
2
|
+
|
|
3
|
+
Use this tool to delegate multi-step tasks to autonomous agents. Each agent type has specific capabilities and tools.
|
|
4
|
+
|
|
5
|
+
Agent types:
|
|
6
|
+
- Explore: Fast codebase exploration, file search, pattern finding
|
|
7
|
+
- Plan: Software architecture, implementation planning
|
|
8
|
+
- general-purpose: Research, code search, multi-step tasks
|
|
9
|
+
|
|
10
|
+
When to use:
|
|
11
|
+
- Complex multi-step tasks
|
|
12
|
+
- Open-ended exploration
|
|
13
|
+
- When multiple search rounds may be needed
|
|
14
|
+
- Tasks matching agent descriptions
|
|
15
|
+
|
|
16
|
+
Best practices:
|
|
17
|
+
- Provide clear, detailed prompts
|
|
18
|
+
- Launch multiple agents in parallel when independent
|
|
19
|
+
- Use Explore for codebase questions
|
|
20
|
+
- Use Plan for implementation design
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Fetch and analyze web content.
|
|
2
|
+
|
|
3
|
+
Use this tool to retrieve content from URLs and process it with AI. Useful for documentation, API references, and external resources.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Fetch any URL content
|
|
7
|
+
- Automatic HTML to markdown conversion
|
|
8
|
+
- AI-powered content extraction based on prompt
|
|
9
|
+
- 15-minute cache for repeated requests
|
|
10
|
+
- Automatic HTTP to HTTPS upgrade
|
|
11
|
+
|
|
12
|
+
Best practices:
|
|
13
|
+
- Provide specific prompts for extraction
|
|
14
|
+
- Handle redirects by following the provided URL
|
|
15
|
+
- Use for documentation and reference lookup
|
|
16
|
+
- Results may be summarized for large content
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Search the web for current information.
|
|
2
|
+
|
|
3
|
+
Use this tool to find up-to-date information beyond the knowledge cutoff. Returns search results with links.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Real-time web search
|
|
7
|
+
- Domain filtering (allow/block specific sites)
|
|
8
|
+
- Returns formatted results with URLs
|
|
9
|
+
|
|
10
|
+
Requirements:
|
|
11
|
+
- MUST include Sources section with URLs after answering
|
|
12
|
+
- Use current year in queries for recent info
|
|
13
|
+
|
|
14
|
+
Best practices:
|
|
15
|
+
- Be specific in search queries
|
|
16
|
+
- Include year for time-sensitive searches
|
|
17
|
+
- Always cite sources in response
|
|
18
|
+
- Filter domains when targeting specific sites
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Write or create files on the filesystem.
|
|
2
|
+
|
|
3
|
+
Use this tool to create new files or completely overwrite existing ones. For modifications to existing files, prefer the Edit tool instead.
|
|
4
|
+
|
|
5
|
+
Capabilities:
|
|
6
|
+
- Create new files with specified content
|
|
7
|
+
- Overwrite existing files completely
|
|
8
|
+
- Create parent directories automatically
|
|
9
|
+
|
|
10
|
+
Requirements:
|
|
11
|
+
- Must read existing file first before overwriting
|
|
12
|
+
- Use absolute paths only
|
|
13
|
+
|
|
14
|
+
Best practices:
|
|
15
|
+
- Prefer Edit for modifications to existing files
|
|
16
|
+
- Only create new files when truly necessary
|
|
17
|
+
- Never create documentation files unless explicitly requested
|
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command Executor Class
|
|
3
|
-
* Orchestrates command execution with agentic delegation.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import path from 'path'
|
|
7
|
-
import os from 'os'
|
|
8
|
-
import templateLoader from '../template-loader'
|
|
9
|
-
import contextBuilder from '../context-builder'
|
|
10
|
-
import promptBuilder from '../prompt-builder'
|
|
11
|
-
import toolRegistry from '../tool-registry'
|
|
12
|
-
import loopDetector from '../loop-detector'
|
|
13
|
-
import chainOfThought from '../chain-of-thought'
|
|
14
|
-
import memorySystem from '../memory-system'
|
|
15
|
-
import groundTruth from '../ground-truth'
|
|
16
|
-
import planMode from '../plan-mode'
|
|
17
|
-
import { signalStart, signalEnd } from './status-signal'
|
|
18
|
-
import type { ExecutionResult, SimpleExecutionResult, ExecutionToolsFn } from './types'
|
|
19
|
-
|
|
20
|
-
export class CommandExecutor {
|
|
21
|
-
/**
|
|
22
|
-
* Signal that a command is running (for status line)
|
|
23
|
-
*/
|
|
24
|
-
signalStart(commandName: string): void {
|
|
25
|
-
signalStart(commandName)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Signal that command has finished (for status line)
|
|
30
|
-
*/
|
|
31
|
-
signalEnd(): void {
|
|
32
|
-
signalEnd()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Execute a prjct command with full agentic delegation
|
|
37
|
-
*/
|
|
38
|
-
async execute(
|
|
39
|
-
commandName: string,
|
|
40
|
-
params: Record<string, unknown>,
|
|
41
|
-
projectPath: string
|
|
42
|
-
): Promise<ExecutionResult> {
|
|
43
|
-
// Signal start for status line
|
|
44
|
-
this.signalStart(commandName)
|
|
45
|
-
|
|
46
|
-
// Context for loop detection
|
|
47
|
-
const loopContext = (params.task as string) || (params.description as string) || ''
|
|
48
|
-
|
|
49
|
-
// Check if we're in a loop BEFORE attempting
|
|
50
|
-
if (loopDetector.shouldEscalate(commandName, loopContext)) {
|
|
51
|
-
const escalation = loopDetector.getEscalationInfo(commandName, loopContext)
|
|
52
|
-
this.signalEnd()
|
|
53
|
-
return {
|
|
54
|
-
success: false,
|
|
55
|
-
error: escalation?.message,
|
|
56
|
-
escalation,
|
|
57
|
-
isLoopDetected: true,
|
|
58
|
-
suggestion: escalation?.suggestion,
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
// 1. Load template
|
|
64
|
-
const template = await templateLoader.load(commandName)
|
|
65
|
-
|
|
66
|
-
// 2. Build METADATA context only (lazy loading - no file reads yet)
|
|
67
|
-
const metadataContext = await contextBuilder.build(projectPath, params)
|
|
68
|
-
|
|
69
|
-
// 2.55. P3.4 PLAN MODE: Check if command requires planning
|
|
70
|
-
const requiresPlanning = planMode.requiresPlanning(commandName)
|
|
71
|
-
const isDestructive = planMode.isDestructive(commandName)
|
|
72
|
-
const isInPlanningMode = planMode.isInPlanningMode(metadataContext.projectId!)
|
|
73
|
-
|
|
74
|
-
// Start planning mode if required and not already in it
|
|
75
|
-
let activePlan = null
|
|
76
|
-
if (requiresPlanning && !isInPlanningMode && !params.skipPlanning) {
|
|
77
|
-
activePlan = planMode.startPlanning(metadataContext.projectId!, commandName, params)
|
|
78
|
-
} else if (isInPlanningMode) {
|
|
79
|
-
activePlan = planMode.getActivePlan(metadataContext.projectId!)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// 2.6. GROUND TRUTH: Verify actual state before critical operations
|
|
83
|
-
let groundTruthResult = null
|
|
84
|
-
if (groundTruth.requiresVerification(commandName)) {
|
|
85
|
-
const preState = await contextBuilder.loadStateForCommand(metadataContext, commandName)
|
|
86
|
-
groundTruthResult = await groundTruth.verify(
|
|
87
|
-
commandName,
|
|
88
|
-
metadataContext as unknown as Parameters<typeof groundTruth.verify>[1],
|
|
89
|
-
preState
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
// Log warnings but don't block (user can override)
|
|
93
|
-
if (!groundTruthResult.verified && groundTruthResult.warnings.length > 0) {
|
|
94
|
-
console.log(groundTruth.formatWarnings(groundTruthResult))
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 2.8. CHAIN OF THOUGHT: Reasoning for critical commands
|
|
99
|
-
let reasoning = null
|
|
100
|
-
if (chainOfThought.requiresReasoning(commandName)) {
|
|
101
|
-
const reasoningState = await contextBuilder.loadStateForCommand(metadataContext, commandName)
|
|
102
|
-
reasoning = await chainOfThought.reason(
|
|
103
|
-
commandName,
|
|
104
|
-
metadataContext as unknown as Parameters<typeof chainOfThought.reason>[1],
|
|
105
|
-
reasoningState as Parameters<typeof chainOfThought.reason>[2]
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
// If reasoning shows critical issues, warn but continue
|
|
109
|
-
if (reasoning.reasoning && !reasoning.reasoning.allPassed) {
|
|
110
|
-
console.log('⚠️ Chain of Thought detected issues:')
|
|
111
|
-
console.log(chainOfThought.formatPlan(reasoning))
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// 3. AGENTIC: Claude decides agent assignment via templates
|
|
116
|
-
let context: Record<string, unknown> = metadataContext as unknown as Record<string, unknown>
|
|
117
|
-
|
|
118
|
-
// Provide agent info to context so Claude can delegate
|
|
119
|
-
context = {
|
|
120
|
-
...context,
|
|
121
|
-
agentsPath: path.join(os.homedir(), '.prjct-cli', 'projects', metadataContext.projectId || '', 'agents'),
|
|
122
|
-
agentRoutingPath: path.join(__dirname, '..', '..', '..', 'templates', 'agentic', 'agent-routing.md'),
|
|
123
|
-
agenticDelegation: true,
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// 6. Load state with filtered context
|
|
127
|
-
const state = await contextBuilder.loadState(metadataContext)
|
|
128
|
-
|
|
129
|
-
// 7. MEMORY: Load learned patterns AND relevant memories for this command
|
|
130
|
-
let learnedPatterns = null
|
|
131
|
-
let relevantMemories = null
|
|
132
|
-
if (metadataContext.projectId) {
|
|
133
|
-
learnedPatterns = {
|
|
134
|
-
commit_footer: await memorySystem.getSmartDecision(metadataContext.projectId, 'commit_footer'),
|
|
135
|
-
branch_naming: await memorySystem.getSmartDecision(metadataContext.projectId, 'branch_naming'),
|
|
136
|
-
test_before_ship: await memorySystem.getSmartDecision(metadataContext.projectId, 'test_before_ship'),
|
|
137
|
-
preferred_agent: await memorySystem.getSmartDecision(
|
|
138
|
-
metadataContext.projectId,
|
|
139
|
-
`preferred_agent_${commandName}`
|
|
140
|
-
),
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// P3.3: Get relevant memories for context
|
|
144
|
-
relevantMemories = await memorySystem.getRelevantMemories(
|
|
145
|
-
metadataContext.projectId,
|
|
146
|
-
{ commandName, params },
|
|
147
|
-
5
|
|
148
|
-
)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// 9. Build prompt - NO agent assignment here, Claude decides via templates
|
|
152
|
-
const planInfo = {
|
|
153
|
-
isPlanning: requiresPlanning || isInPlanningMode,
|
|
154
|
-
requiresApproval: isDestructive && !params.approved,
|
|
155
|
-
active: activePlan,
|
|
156
|
-
allowedTools: planMode.getAllowedTools(isInPlanningMode, template.frontmatter['allowed-tools'] || []),
|
|
157
|
-
}
|
|
158
|
-
// Agent is null - Claude assigns via Task tool using agent-routing.md
|
|
159
|
-
const prompt = promptBuilder.build(
|
|
160
|
-
template,
|
|
161
|
-
context as Parameters<typeof promptBuilder.build>[1],
|
|
162
|
-
state,
|
|
163
|
-
null,
|
|
164
|
-
learnedPatterns,
|
|
165
|
-
null,
|
|
166
|
-
relevantMemories,
|
|
167
|
-
planInfo
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
// Log agentic mode
|
|
171
|
-
console.log(`🤖 Agentic delegation enabled - Claude will assign agent via Task tool`)
|
|
172
|
-
|
|
173
|
-
// Record successful attempt
|
|
174
|
-
loopDetector.recordSuccess(commandName, loopContext)
|
|
175
|
-
|
|
176
|
-
// Signal end for status line
|
|
177
|
-
this.signalEnd()
|
|
178
|
-
|
|
179
|
-
return {
|
|
180
|
-
success: true,
|
|
181
|
-
template,
|
|
182
|
-
context,
|
|
183
|
-
state,
|
|
184
|
-
prompt,
|
|
185
|
-
agenticDelegation: true,
|
|
186
|
-
agentsPath: context.agentsPath as string,
|
|
187
|
-
agentRoutingPath: context.agentRoutingPath as string,
|
|
188
|
-
reasoning,
|
|
189
|
-
groundTruth: groundTruthResult,
|
|
190
|
-
learnedPatterns,
|
|
191
|
-
relevantMemories,
|
|
192
|
-
memory: {
|
|
193
|
-
create: (memory: unknown) =>
|
|
194
|
-
memorySystem.createMemory(metadataContext.projectId!, memory as Parameters<typeof memorySystem.createMemory>[1]),
|
|
195
|
-
autoRemember: (type: string, value: string, ctx?: string) =>
|
|
196
|
-
memorySystem.autoRemember(metadataContext.projectId!, type, value, ctx),
|
|
197
|
-
search: (query: string) => memorySystem.searchMemories(metadataContext.projectId!, query),
|
|
198
|
-
findByTags: (tags: string[]) => memorySystem.findByTags(metadataContext.projectId!, tags),
|
|
199
|
-
getStats: () => memorySystem.getMemoryStats(metadataContext.projectId!),
|
|
200
|
-
},
|
|
201
|
-
plan: {
|
|
202
|
-
active: activePlan,
|
|
203
|
-
isPlanning: requiresPlanning || isInPlanningMode,
|
|
204
|
-
isDestructive,
|
|
205
|
-
requiresApproval: isDestructive && !params.approved,
|
|
206
|
-
recordInfo: (info: unknown) =>
|
|
207
|
-
planMode.recordGatheredInfo(metadataContext.projectId!, info as Parameters<typeof planMode.recordGatheredInfo>[1]),
|
|
208
|
-
setAnalysis: (analysis: unknown) => planMode.setAnalysis(metadataContext.projectId!, analysis),
|
|
209
|
-
propose: (plan: unknown) =>
|
|
210
|
-
planMode.proposePlan(metadataContext.projectId!, plan as Parameters<typeof planMode.proposePlan>[1]),
|
|
211
|
-
approve: (feedback?: string | null) => planMode.approvePlan(metadataContext.projectId!, feedback),
|
|
212
|
-
reject: (reason?: string | null) => planMode.rejectPlan(metadataContext.projectId!, reason),
|
|
213
|
-
getApprovalPrompt: () =>
|
|
214
|
-
planMode.generateApprovalPrompt(commandName, context as Parameters<typeof planMode.generateApprovalPrompt>[1]),
|
|
215
|
-
startExecution: () => planMode.startExecution(metadataContext.projectId!),
|
|
216
|
-
getNextStep: () => planMode.getNextStep(metadataContext.projectId!),
|
|
217
|
-
completeStep: (result?: unknown) => planMode.completeStep(metadataContext.projectId!, result),
|
|
218
|
-
failStep: (error: string) => planMode.failStep(metadataContext.projectId!, error),
|
|
219
|
-
abort: (reason?: string) => planMode.abortPlan(metadataContext.projectId!, reason),
|
|
220
|
-
getStatus: () => planMode.formatStatus(metadataContext.projectId!),
|
|
221
|
-
getAllowedTools: () =>
|
|
222
|
-
planMode.getAllowedTools(isInPlanningMode, template.frontmatter['allowed-tools'] || []),
|
|
223
|
-
},
|
|
224
|
-
}
|
|
225
|
-
} catch (error) {
|
|
226
|
-
// Signal end for status line
|
|
227
|
-
this.signalEnd()
|
|
228
|
-
|
|
229
|
-
// Record failed attempt for loop detection
|
|
230
|
-
const attemptInfo = loopDetector.recordAttempt(commandName, loopContext, {
|
|
231
|
-
success: false,
|
|
232
|
-
error: (error as Error).message,
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
// Check if we should escalate after this failure
|
|
236
|
-
if (attemptInfo.shouldEscalate) {
|
|
237
|
-
const escalation = loopDetector.getEscalationInfo(commandName, loopContext)
|
|
238
|
-
return {
|
|
239
|
-
success: false,
|
|
240
|
-
error: escalation?.message,
|
|
241
|
-
escalation,
|
|
242
|
-
isLoopDetected: true,
|
|
243
|
-
suggestion: escalation?.suggestion,
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
success: false,
|
|
249
|
-
error: (error as Error).message,
|
|
250
|
-
attemptNumber: attemptInfo.attemptNumber,
|
|
251
|
-
isLooping: attemptInfo.isLooping,
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Execute tool with permission check
|
|
258
|
-
*/
|
|
259
|
-
async executeTool(toolName: string, args: unknown[], allowedTools: string[]): Promise<unknown> {
|
|
260
|
-
// Check if tool is allowed
|
|
261
|
-
if (!toolRegistry.isAllowed(toolName, allowedTools)) {
|
|
262
|
-
throw new Error(`Tool ${toolName} not allowed for this command`)
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Get tool function
|
|
266
|
-
const tool = toolRegistry.get(toolName)
|
|
267
|
-
if (!tool) {
|
|
268
|
-
throw new Error(`Tool ${toolName} not found`)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Execute tool
|
|
272
|
-
return await tool(...args)
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Simple execution for direct tool access (legacy migration helper)
|
|
277
|
-
*/
|
|
278
|
-
async executeSimple(
|
|
279
|
-
commandName: string,
|
|
280
|
-
executionFn: ExecutionToolsFn,
|
|
281
|
-
projectPath: string
|
|
282
|
-
): Promise<SimpleExecutionResult> {
|
|
283
|
-
try {
|
|
284
|
-
// Load template to get allowed tools
|
|
285
|
-
const template = await templateLoader.load(commandName)
|
|
286
|
-
const allowedTools = template.frontmatter['allowed-tools'] || []
|
|
287
|
-
|
|
288
|
-
// Build context
|
|
289
|
-
const context = await contextBuilder.build(projectPath)
|
|
290
|
-
|
|
291
|
-
// Create tools proxy that checks permissions
|
|
292
|
-
const tools = {
|
|
293
|
-
read: async (filePath: string) => this.executeTool('Read', [filePath], allowedTools),
|
|
294
|
-
write: async (filePath: string, content: string) => this.executeTool('Write', [filePath, content], allowedTools),
|
|
295
|
-
bash: async (command: string) => this.executeTool('Bash', [command], allowedTools),
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Execute user function with tools
|
|
299
|
-
const result = await executionFn(tools, context)
|
|
300
|
-
|
|
301
|
-
return {
|
|
302
|
-
success: true,
|
|
303
|
-
result,
|
|
304
|
-
}
|
|
305
|
-
} catch (error) {
|
|
306
|
-
return {
|
|
307
|
-
success: false,
|
|
308
|
-
error: (error as Error).message,
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Command Executor
|
|
3
|
-
* Orchestrates command execution with agentic delegation.
|
|
4
|
-
*
|
|
5
|
-
* @module agentic/command-executor
|
|
6
|
-
* @version 3.4
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export type { ExecutionResult, SimpleExecutionResult, ExecutionToolsFn } from './types'
|
|
10
|
-
export { signalStart, signalEnd } from './status-signal'
|
|
11
|
-
export { CommandExecutor } from './command-executor'
|
|
12
|
-
|
|
13
|
-
import { CommandExecutor } from './command-executor'
|
|
14
|
-
|
|
15
|
-
const commandExecutor = new CommandExecutor()
|
|
16
|
-
export default commandExecutor
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status Signal
|
|
3
|
-
* Running file for status line integration
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'fs'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
import os from 'os'
|
|
9
|
-
|
|
10
|
-
const RUNNING_FILE = path.join(os.homedir(), '.prjct-cli', '.running')
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Signal that a command is running (for status line)
|
|
14
|
-
*/
|
|
15
|
-
export function signalStart(commandName: string): void {
|
|
16
|
-
try {
|
|
17
|
-
const dir = path.dirname(RUNNING_FILE)
|
|
18
|
-
if (!fs.existsSync(dir)) {
|
|
19
|
-
fs.mkdirSync(dir, { recursive: true })
|
|
20
|
-
}
|
|
21
|
-
fs.writeFileSync(RUNNING_FILE, `/p:${commandName}`)
|
|
22
|
-
} catch {
|
|
23
|
-
// Silently ignore - status line is optional
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Signal that command has finished (for status line)
|
|
29
|
-
*/
|
|
30
|
-
export function signalEnd(): void {
|
|
31
|
-
try {
|
|
32
|
-
if (fs.existsSync(RUNNING_FILE)) {
|
|
33
|
-
fs.unlinkSync(RUNNING_FILE)
|
|
34
|
-
}
|
|
35
|
-
} catch {
|
|
36
|
-
// Silently ignore - status line is optional
|
|
37
|
-
}
|
|
38
|
-
}
|