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.
- 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/integrations/notion/client.ts +323 -0
- package/core/integrations/notion/index.ts +43 -0
- package/core/integrations/notion/setup.ts +230 -0
- package/core/integrations/notion/sync.ts +311 -0
- package/core/integrations/notion/templates.ts +234 -0
- package/core/outcomes/analyzer.ts +7 -41
- package/core/outcomes/index.ts +1 -1
- package/core/outcomes/recorder.ts +1 -1
- package/core/plugin/builtin/notion.ts +178 -0
- 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 +70 -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 +396 -500
- package/core/types/infrastructure.ts +196 -0
- package/core/types/integrations.ts +57 -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/init.md +43 -0
- package/templates/commands/notion-setup.md +191 -0
- 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/mcp-config.json +28 -0
- 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
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notion Database Templates
|
|
3
|
+
* Schemas for auto-creating prjct databases in Notion.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { NotionDatabaseSchema } from './client'
|
|
7
|
+
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Database Schemas
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shipped Features Database Schema
|
|
14
|
+
* Tracks shipped features with metrics
|
|
15
|
+
*/
|
|
16
|
+
export const SHIPPED_DATABASE_SCHEMA: NotionDatabaseSchema = {
|
|
17
|
+
title: 'prjct: Shipped Features',
|
|
18
|
+
properties: {
|
|
19
|
+
Name: { type: 'title', title: {} },
|
|
20
|
+
Version: { type: 'rich_text', rich_text: {} },
|
|
21
|
+
Type: {
|
|
22
|
+
type: 'select',
|
|
23
|
+
select: {
|
|
24
|
+
options: [
|
|
25
|
+
{ name: 'feature', color: 'blue' },
|
|
26
|
+
{ name: 'fix', color: 'red' },
|
|
27
|
+
{ name: 'improvement', color: 'green' },
|
|
28
|
+
{ name: 'refactor', color: 'purple' },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
'Shipped Date': { type: 'date', date: {} },
|
|
33
|
+
'Lines Changed': { type: 'number', number: { format: 'number' } },
|
|
34
|
+
'Files Changed': { type: 'number', number: { format: 'number' } },
|
|
35
|
+
Commits: { type: 'number', number: { format: 'number' } },
|
|
36
|
+
Duration: { type: 'rich_text', rich_text: {} },
|
|
37
|
+
Description: { type: 'rich_text', rich_text: {} },
|
|
38
|
+
Project: { type: 'rich_text', rich_text: {} },
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Roadmap Database Schema
|
|
44
|
+
* Tracks feature roadmap and progress
|
|
45
|
+
*/
|
|
46
|
+
export const ROADMAP_DATABASE_SCHEMA: NotionDatabaseSchema = {
|
|
47
|
+
title: 'prjct: Roadmap',
|
|
48
|
+
properties: {
|
|
49
|
+
Feature: { type: 'title', title: {} },
|
|
50
|
+
Status: {
|
|
51
|
+
type: 'status',
|
|
52
|
+
status: {
|
|
53
|
+
options: [
|
|
54
|
+
{ name: 'Planned', color: 'gray' },
|
|
55
|
+
{ name: 'Active', color: 'blue' },
|
|
56
|
+
{ name: 'Completed', color: 'green' },
|
|
57
|
+
{ name: 'Shipped', color: 'purple' },
|
|
58
|
+
],
|
|
59
|
+
groups: [
|
|
60
|
+
{ name: 'To Do', option_ids: [], color: 'gray' },
|
|
61
|
+
{ name: 'In Progress', option_ids: [], color: 'blue' },
|
|
62
|
+
{ name: 'Done', option_ids: [], color: 'green' },
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
Priority: {
|
|
67
|
+
type: 'select',
|
|
68
|
+
select: {
|
|
69
|
+
options: [
|
|
70
|
+
{ name: 'High', color: 'red' },
|
|
71
|
+
{ name: 'Medium', color: 'yellow' },
|
|
72
|
+
{ name: 'Low', color: 'gray' },
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
Progress: { type: 'number', number: { format: 'percent' } },
|
|
77
|
+
Phase: { type: 'rich_text', rich_text: {} },
|
|
78
|
+
'Target Date': { type: 'date', date: {} },
|
|
79
|
+
Description: { type: 'rich_text', rich_text: {} },
|
|
80
|
+
Tasks: { type: 'number', number: { format: 'number' } },
|
|
81
|
+
Project: { type: 'rich_text', rich_text: {} },
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Ideas Database Schema
|
|
87
|
+
* Captures and tracks ideas
|
|
88
|
+
*/
|
|
89
|
+
export const IDEAS_DATABASE_SCHEMA: NotionDatabaseSchema = {
|
|
90
|
+
title: 'prjct: Ideas',
|
|
91
|
+
properties: {
|
|
92
|
+
Idea: { type: 'title', title: {} },
|
|
93
|
+
Status: {
|
|
94
|
+
type: 'status',
|
|
95
|
+
status: {
|
|
96
|
+
options: [
|
|
97
|
+
{ name: 'Pending', color: 'gray' },
|
|
98
|
+
{ name: 'Converted', color: 'green' },
|
|
99
|
+
{ name: 'Archived', color: 'default' },
|
|
100
|
+
],
|
|
101
|
+
groups: [
|
|
102
|
+
{ name: 'Not Started', option_ids: [], color: 'gray' },
|
|
103
|
+
{ name: 'Done', option_ids: [], color: 'green' },
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
Priority: {
|
|
108
|
+
type: 'select',
|
|
109
|
+
select: {
|
|
110
|
+
options: [
|
|
111
|
+
{ name: 'high', color: 'red' },
|
|
112
|
+
{ name: 'medium', color: 'yellow' },
|
|
113
|
+
{ name: 'low', color: 'gray' },
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
Tags: { type: 'multi_select', multi_select: { options: [] } },
|
|
118
|
+
Created: { type: 'date', date: {} },
|
|
119
|
+
'Converted To': { type: 'rich_text', rich_text: {} },
|
|
120
|
+
Project: { type: 'rich_text', rich_text: {} },
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Active Tasks Database Schema
|
|
126
|
+
* Tracks current task queue
|
|
127
|
+
*/
|
|
128
|
+
export const TASKS_DATABASE_SCHEMA: NotionDatabaseSchema = {
|
|
129
|
+
title: 'prjct: Active Tasks',
|
|
130
|
+
properties: {
|
|
131
|
+
Task: { type: 'title', title: {} },
|
|
132
|
+
Priority: {
|
|
133
|
+
type: 'select',
|
|
134
|
+
select: {
|
|
135
|
+
options: [
|
|
136
|
+
{ name: 'critical', color: 'red' },
|
|
137
|
+
{ name: 'high', color: 'orange' },
|
|
138
|
+
{ name: 'medium', color: 'yellow' },
|
|
139
|
+
{ name: 'low', color: 'gray' },
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
Type: {
|
|
144
|
+
type: 'select',
|
|
145
|
+
select: {
|
|
146
|
+
options: [
|
|
147
|
+
{ name: 'feature', color: 'blue' },
|
|
148
|
+
{ name: 'bug', color: 'red' },
|
|
149
|
+
{ name: 'improvement', color: 'green' },
|
|
150
|
+
{ name: 'chore', color: 'gray' },
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
Section: {
|
|
155
|
+
type: 'select',
|
|
156
|
+
select: {
|
|
157
|
+
options: [
|
|
158
|
+
{ name: 'active', color: 'blue' },
|
|
159
|
+
{ name: 'backlog', color: 'gray' },
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
Completed: { type: 'checkbox', checkbox: {} },
|
|
164
|
+
Agent: { type: 'rich_text', rich_text: {} },
|
|
165
|
+
Feature: { type: 'rich_text', rich_text: {} },
|
|
166
|
+
Created: { type: 'date', date: {} },
|
|
167
|
+
'Completed At': { type: 'date', date: {} },
|
|
168
|
+
Project: { type: 'rich_text', rich_text: {} },
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// =============================================================================
|
|
173
|
+
// Dashboard Template
|
|
174
|
+
// =============================================================================
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Dashboard page content template
|
|
178
|
+
*/
|
|
179
|
+
export function getDashboardContent(
|
|
180
|
+
projectName: string,
|
|
181
|
+
databases: {
|
|
182
|
+
shipped?: string
|
|
183
|
+
roadmap?: string
|
|
184
|
+
ideas?: string
|
|
185
|
+
tasks?: string
|
|
186
|
+
}
|
|
187
|
+
): string {
|
|
188
|
+
const sections = []
|
|
189
|
+
|
|
190
|
+
sections.push(`# ${projectName} Dashboard`)
|
|
191
|
+
sections.push('')
|
|
192
|
+
sections.push('This dashboard is automatically synced by prjct-cli.')
|
|
193
|
+
sections.push('')
|
|
194
|
+
|
|
195
|
+
if (databases.shipped) {
|
|
196
|
+
sections.push('## Shipped Features')
|
|
197
|
+
sections.push(`View all shipped features and metrics.`)
|
|
198
|
+
sections.push('')
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (databases.roadmap) {
|
|
202
|
+
sections.push('## Roadmap')
|
|
203
|
+
sections.push(`Track feature progress and planning.`)
|
|
204
|
+
sections.push('')
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (databases.ideas) {
|
|
208
|
+
sections.push('## Ideas')
|
|
209
|
+
sections.push(`Captured ideas and their status.`)
|
|
210
|
+
sections.push('')
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (databases.tasks) {
|
|
214
|
+
sections.push('## Active Tasks')
|
|
215
|
+
sections.push(`Current task queue and completion status.`)
|
|
216
|
+
sections.push('')
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
sections.push('---')
|
|
220
|
+
sections.push('Powered by [prjct-cli](https://prjct.app)')
|
|
221
|
+
|
|
222
|
+
return sections.join('\n')
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// =============================================================================
|
|
226
|
+
// All Schemas Export
|
|
227
|
+
// =============================================================================
|
|
228
|
+
|
|
229
|
+
export const ALL_DATABASE_SCHEMAS = {
|
|
230
|
+
shipped: SHIPPED_DATABASE_SCHEMA,
|
|
231
|
+
roadmap: ROADMAP_DATABASE_SCHEMA,
|
|
232
|
+
ideas: IDEAS_DATABASE_SCHEMA,
|
|
233
|
+
tasks: TASKS_DATABASE_SCHEMA,
|
|
234
|
+
} as const
|
|
@@ -6,47 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import outcomeRecorder from './recorder'
|
|
9
|
-
import type {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
description: string
|
|
17
|
-
|
|
18
|
-
/** Confidence level (0-1) */
|
|
19
|
-
confidence: number
|
|
20
|
-
|
|
21
|
-
/** Number of occurrences supporting this pattern */
|
|
22
|
-
occurrences: number
|
|
23
|
-
|
|
24
|
-
/** Suggested action based on pattern */
|
|
25
|
-
suggestedAction?: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Agent performance metrics.
|
|
30
|
-
*/
|
|
31
|
-
export interface AgentMetrics {
|
|
32
|
-
/** Agent name */
|
|
33
|
-
agent: string
|
|
34
|
-
|
|
35
|
-
/** Number of tasks completed */
|
|
36
|
-
tasksCompleted: number
|
|
37
|
-
|
|
38
|
-
/** Success rate (0-100) */
|
|
39
|
-
successRate: number
|
|
40
|
-
|
|
41
|
-
/** Average quality score */
|
|
42
|
-
avgQualityScore: number
|
|
43
|
-
|
|
44
|
-
/** Estimate accuracy */
|
|
45
|
-
estimateAccuracy: number
|
|
46
|
-
|
|
47
|
-
/** Best task types for this agent */
|
|
48
|
-
bestFor: string[]
|
|
49
|
-
}
|
|
9
|
+
import type {
|
|
10
|
+
Outcome,
|
|
11
|
+
OutcomeSummary,
|
|
12
|
+
QualityScore,
|
|
13
|
+
DetectedPattern,
|
|
14
|
+
AgentMetrics,
|
|
15
|
+
} from '../types'
|
|
50
16
|
|
|
51
17
|
/**
|
|
52
18
|
* OutcomeAnalyzer - Extracts insights from outcomes.
|
package/core/outcomes/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ import path from 'path'
|
|
|
9
9
|
import * as fileHelper from '../utils/file-helper'
|
|
10
10
|
import pathManager from '../infrastructure/path-manager'
|
|
11
11
|
import { generateUUID } from '../schemas'
|
|
12
|
-
import type { Outcome, OutcomeInput, OutcomeFilter } from '
|
|
12
|
+
import type { Outcome, OutcomeInput, OutcomeFilter } from '../types'
|
|
13
13
|
|
|
14
14
|
const OUTCOMES_DIR = 'outcomes'
|
|
15
15
|
const OUTCOMES_FILE = 'outcomes.jsonl'
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notion Plugin for prjct-cli
|
|
3
|
+
*
|
|
4
|
+
* Syncs prjct data to Notion databases on events.
|
|
5
|
+
* Activated when project has integrations.notion.enabled = true
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*
|
|
9
|
+
* Configuration in GlobalConfig.integrations.notion:
|
|
10
|
+
* {
|
|
11
|
+
* "enabled": true,
|
|
12
|
+
* "databases": {
|
|
13
|
+
* "shipped": "notion-db-id",
|
|
14
|
+
* "ideas": "notion-db-id"
|
|
15
|
+
* },
|
|
16
|
+
* "syncOn": { "ship": true, "idea": true }
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { HookPoints } from '../hooks'
|
|
21
|
+
import type { NotionIntegrationConfig } from '../../types/integrations'
|
|
22
|
+
import type { ShippedFeature, Idea } from '../../types/storage'
|
|
23
|
+
import { notionClient, syncShippedFeature, syncIdea } from '../../integrations/notion'
|
|
24
|
+
|
|
25
|
+
interface NotionPluginContext {
|
|
26
|
+
projectId: string
|
|
27
|
+
config: NotionIntegrationConfig
|
|
28
|
+
apiToken?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const plugin = {
|
|
32
|
+
name: 'notion',
|
|
33
|
+
version: '1.0.0',
|
|
34
|
+
description: 'Sync prjct data to Notion',
|
|
35
|
+
|
|
36
|
+
// Plugin state
|
|
37
|
+
enabled: false,
|
|
38
|
+
projectId: null as string | null,
|
|
39
|
+
config: null as NotionIntegrationConfig | null,
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Activate plugin
|
|
43
|
+
*/
|
|
44
|
+
async activate(context: NotionPluginContext): Promise<void> {
|
|
45
|
+
const { projectId, config, apiToken } = context
|
|
46
|
+
|
|
47
|
+
if (!config?.enabled) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Initialize Notion client
|
|
52
|
+
notionClient.initialize(config, apiToken || process.env.NOTION_TOKEN)
|
|
53
|
+
|
|
54
|
+
if (!notionClient.isReady()) {
|
|
55
|
+
console.warn('[notion] API token not configured, plugin disabled')
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
plugin.enabled = true
|
|
60
|
+
plugin.projectId = projectId
|
|
61
|
+
plugin.config = config
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Deactivate plugin
|
|
66
|
+
*/
|
|
67
|
+
async deactivate(): Promise<void> {
|
|
68
|
+
plugin.enabled = false
|
|
69
|
+
plugin.projectId = null
|
|
70
|
+
plugin.config = null
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Hook handlers
|
|
75
|
+
*/
|
|
76
|
+
hooks: {
|
|
77
|
+
/**
|
|
78
|
+
* Sync shipped feature to Notion after ship
|
|
79
|
+
*/
|
|
80
|
+
[HookPoints.AFTER_FEATURE_SHIP]: async function (data: {
|
|
81
|
+
feature: ShippedFeature
|
|
82
|
+
projectId?: string
|
|
83
|
+
}): Promise<void> {
|
|
84
|
+
if (!plugin.enabled || !plugin.config || !plugin.projectId) return
|
|
85
|
+
if (!plugin.config.syncOn?.ship) return
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const result = await syncShippedFeature(
|
|
89
|
+
data.projectId || plugin.projectId,
|
|
90
|
+
data.feature,
|
|
91
|
+
plugin.config
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if (result.success) {
|
|
95
|
+
console.log(`[notion] Synced: ${data.feature.name} (${result.action})`)
|
|
96
|
+
} else if (result.error) {
|
|
97
|
+
console.warn(`[notion] Sync failed: ${result.error}`)
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
// Graceful degradation - don't fail the ship
|
|
101
|
+
console.warn('[notion] Sync error:', (error as Error).message)
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Sync idea to Notion after capture
|
|
107
|
+
*/
|
|
108
|
+
[HookPoints.AFTER_IDEA_CAPTURE]: async function (data: {
|
|
109
|
+
idea: Idea
|
|
110
|
+
projectId?: string
|
|
111
|
+
}): Promise<void> {
|
|
112
|
+
if (!plugin.enabled || !plugin.config || !plugin.projectId) return
|
|
113
|
+
if (!plugin.config.syncOn?.idea) return
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const result = await syncIdea(
|
|
117
|
+
data.projectId || plugin.projectId,
|
|
118
|
+
data.idea,
|
|
119
|
+
plugin.config
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if (result.success) {
|
|
123
|
+
console.log(`[notion] Synced idea: ${data.idea.text.slice(0, 30)}... (${result.action})`)
|
|
124
|
+
} else if (result.error) {
|
|
125
|
+
console.warn(`[notion] Sync failed: ${result.error}`)
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
// Graceful degradation - don't fail the idea capture
|
|
129
|
+
console.warn('[notion] Sync error:', (error as Error).message)
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Sync task completion (optional)
|
|
135
|
+
*/
|
|
136
|
+
[HookPoints.AFTER_TASK_COMPLETE]: async function (data: {
|
|
137
|
+
taskName?: string
|
|
138
|
+
projectId?: string
|
|
139
|
+
}): Promise<void> {
|
|
140
|
+
if (!plugin.enabled || !plugin.config || !plugin.projectId) return
|
|
141
|
+
if (!plugin.config.syncOn?.done) return
|
|
142
|
+
|
|
143
|
+
// Task sync is optional and less critical
|
|
144
|
+
// Could update task status in Notion if database exists
|
|
145
|
+
if (data.taskName) {
|
|
146
|
+
console.log(`[notion] Task completed: ${data.taskName}`)
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check if plugin is active
|
|
153
|
+
*/
|
|
154
|
+
isActive(): boolean {
|
|
155
|
+
return plugin.enabled && plugin.config?.enabled === true
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Get current sync status
|
|
160
|
+
*/
|
|
161
|
+
getStatus(): {
|
|
162
|
+
enabled: boolean
|
|
163
|
+
databases: number
|
|
164
|
+
lastSync?: string
|
|
165
|
+
} {
|
|
166
|
+
const dbCount = plugin.config?.databases
|
|
167
|
+
? Object.values(plugin.config.databases).filter(Boolean).length
|
|
168
|
+
: 0
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
enabled: plugin.enabled,
|
|
172
|
+
databases: dbCount,
|
|
173
|
+
lastSync: plugin.config?.lastSyncAt,
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export default plugin
|
|
@@ -18,25 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import crypto from 'crypto'
|
|
21
|
-
import { EventTypes } from '
|
|
22
|
-
import { HookPoints } from '../
|
|
23
|
-
|
|
24
|
-
interface WebhookConfig {
|
|
25
|
-
url?: string
|
|
26
|
-
events?: string[]
|
|
27
|
-
secret?: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface PluginContext {
|
|
31
|
-
config: WebhookConfig
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface WebhookPayload {
|
|
35
|
-
event: string
|
|
36
|
-
timestamp: string
|
|
37
|
-
source: string
|
|
38
|
-
data: unknown
|
|
39
|
-
}
|
|
21
|
+
import { EventTypes } from '../../bus'
|
|
22
|
+
import { HookPoints } from '../hooks'
|
|
23
|
+
import type { WebhookConfig, WebhookPluginContext, WebhookPayload } from '../../types'
|
|
40
24
|
|
|
41
25
|
const plugin = {
|
|
42
26
|
name: 'webhook',
|
|
@@ -46,12 +30,12 @@ const plugin = {
|
|
|
46
30
|
// Plugin state
|
|
47
31
|
config: null as WebhookConfig | null,
|
|
48
32
|
enabled: false,
|
|
49
|
-
|
|
33
|
+
enabledEvents: [] as string[],
|
|
50
34
|
|
|
51
35
|
/**
|
|
52
36
|
* Activate plugin
|
|
53
37
|
*/
|
|
54
|
-
async activate({ config }:
|
|
38
|
+
async activate({ config }: WebhookPluginContext): Promise<void> {
|
|
55
39
|
plugin.config = config
|
|
56
40
|
|
|
57
41
|
if (!config.url) {
|
|
@@ -60,7 +44,7 @@ const plugin = {
|
|
|
60
44
|
}
|
|
61
45
|
|
|
62
46
|
plugin.enabled = true
|
|
63
|
-
plugin.
|
|
47
|
+
plugin.enabledEvents = config.events || [
|
|
64
48
|
EventTypes.SESSION_COMPLETED,
|
|
65
49
|
EventTypes.FEATURE_SHIPPED,
|
|
66
50
|
EventTypes.SNAPSHOT_CREATED
|
package/core/plugin/loader.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import fs from 'fs/promises'
|
|
13
13
|
import path from 'path'
|
|
14
14
|
import { hookSystem } from './hooks'
|
|
15
|
-
import { eventBus } from '../bus'
|
|
15
|
+
import { eventBus, type EventCallback } from '../bus'
|
|
16
16
|
import pathManager from '../infrastructure/path-manager'
|
|
17
17
|
|
|
18
18
|
type PluginSource = 'builtin' | 'global' | 'project'
|
|
@@ -23,7 +23,7 @@ interface Plugin {
|
|
|
23
23
|
version?: string
|
|
24
24
|
description?: string
|
|
25
25
|
hooks?: Record<string, HookHandler>
|
|
26
|
-
events?: Record<string,
|
|
26
|
+
events?: Record<string, EventCallback>
|
|
27
27
|
commands?: Record<string, { handler: () => void; description?: string }>
|
|
28
28
|
priority?: number
|
|
29
29
|
activate?: (context: PluginContext) => Promise<void>
|
|
@@ -83,10 +83,10 @@ class PluginLoader {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* Load built-in plugins from core/
|
|
86
|
+
* Load built-in plugins from core/plugin/builtin
|
|
87
87
|
*/
|
|
88
88
|
async loadBuiltinPlugins(): Promise<void> {
|
|
89
|
-
const builtinPath = path.join(__dirname, '
|
|
89
|
+
const builtinPath = path.join(__dirname, 'builtin')
|
|
90
90
|
|
|
91
91
|
try {
|
|
92
92
|
const files = await fs.readdir(builtinPath)
|
|
@@ -106,7 +106,7 @@ class PluginLoader {
|
|
|
106
106
|
* Load global plugins from ~/.prjct-cli/plugins
|
|
107
107
|
*/
|
|
108
108
|
async loadGlobalPlugins(): Promise<void> {
|
|
109
|
-
const globalPath = path.join(pathManager.
|
|
109
|
+
const globalPath = path.join(pathManager.getGlobalBasePath(), 'plugins')
|
|
110
110
|
|
|
111
111
|
try {
|
|
112
112
|
const files = await fs.readdir(globalPath)
|
package/core/plugin/registry.ts
CHANGED
|
@@ -57,7 +57,7 @@ class PluginRegistry {
|
|
|
57
57
|
|
|
58
58
|
// Global plugins
|
|
59
59
|
await this.discoverFromPath(
|
|
60
|
-
path.join(pathManager.
|
|
60
|
+
path.join(pathManager.getGlobalBasePath(), 'plugins'),
|
|
61
61
|
'global'
|
|
62
62
|
)
|
|
63
63
|
}
|
|
@@ -188,7 +188,7 @@ class PluginRegistry {
|
|
|
188
188
|
* Install a plugin (copy to global plugins)
|
|
189
189
|
*/
|
|
190
190
|
async install(sourcePath: string, name: string | null = null): Promise<void> {
|
|
191
|
-
const globalPluginsPath = path.join(pathManager.
|
|
191
|
+
const globalPluginsPath = path.join(pathManager.getGlobalBasePath(), 'plugins')
|
|
192
192
|
await fs.mkdir(globalPluginsPath, { recursive: true })
|
|
193
193
|
|
|
194
194
|
const stat = await fs.stat(sourcePath)
|