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,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop Detection & User Escalation
|
|
3
|
-
*
|
|
4
|
-
* Detects when commands are failing repeatedly and escalates to user
|
|
5
|
-
* instead of continuing in infinite loops.
|
|
6
|
-
*
|
|
7
|
-
* OPTIMIZATION (P2.4): Loop Detection
|
|
8
|
-
* - Track attempt counts per command/error type
|
|
9
|
-
* - Auto-escalate after 3 failed attempts
|
|
10
|
-
* - Provide specific help based on error patterns
|
|
11
|
-
*
|
|
12
|
-
* ANTI-HALLUCINATION: Detects contradictory/impossible outputs
|
|
13
|
-
* - Patterns that indicate Claude is hallucinating (saying file exists when it doesn't)
|
|
14
|
-
* - Contradictory statements in same response
|
|
15
|
-
* - Completing tasks that were never started
|
|
16
|
-
*
|
|
17
|
-
* Source: Augment Code pattern
|
|
18
|
-
* "If you notice yourself going around in circles... ask the user for help"
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
export type {
|
|
22
|
-
ErrorEntry,
|
|
23
|
-
AttemptRecord,
|
|
24
|
-
ErrorPattern,
|
|
25
|
-
EscalationInfo,
|
|
26
|
-
AttemptResult,
|
|
27
|
-
AttemptInfo,
|
|
28
|
-
HallucinationPattern,
|
|
29
|
-
HallucinationResult,
|
|
30
|
-
OutputAnalysis,
|
|
31
|
-
} from './types'
|
|
32
|
-
|
|
33
|
-
export { HALLUCINATION_PATTERNS, detectHallucination, getHallucinationSuggestion } from './hallucination'
|
|
34
|
-
export { isSimilarError, analyzeErrorPattern, generateEscalationMessage, generateSuggestion } from './error-analysis'
|
|
35
|
-
export { LoopDetector } from './loop-detector'
|
|
36
|
-
|
|
37
|
-
import { LoopDetector } from './loop-detector'
|
|
38
|
-
|
|
39
|
-
// Singleton instance
|
|
40
|
-
const loopDetector = new LoopDetector()
|
|
41
|
-
export default loopDetector
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop Detector Class
|
|
3
|
-
* Core loop detection and user escalation functionality
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { AttemptRecord, EscalationInfo, AttemptResult, AttemptInfo, OutputAnalysis } from './types'
|
|
7
|
-
import { isSimilarError, analyzeErrorPattern, generateEscalationMessage, generateSuggestion } from './error-analysis'
|
|
8
|
-
import { detectHallucination } from './hallucination'
|
|
9
|
-
|
|
10
|
-
export class LoopDetector {
|
|
11
|
-
private _attempts: Map<string, AttemptRecord>
|
|
12
|
-
private _errorPatterns: Map<string, unknown>
|
|
13
|
-
maxAttempts: number
|
|
14
|
-
sessionTimeout: number
|
|
15
|
-
|
|
16
|
-
constructor() {
|
|
17
|
-
// Track attempts per command session
|
|
18
|
-
this._attempts = new Map()
|
|
19
|
-
|
|
20
|
-
// Track error patterns
|
|
21
|
-
this._errorPatterns = new Map()
|
|
22
|
-
|
|
23
|
-
// Configuration
|
|
24
|
-
this.maxAttempts = 3
|
|
25
|
-
this.sessionTimeout = 5 * 60 * 1000 // 5 minutes
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Generate a unique key for tracking attempts
|
|
30
|
-
*/
|
|
31
|
-
private _getKey(command: string, context: string = ''): string {
|
|
32
|
-
return `${command}:${context}`.toLowerCase()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Record an attempt for a command
|
|
37
|
-
*/
|
|
38
|
-
recordAttempt(command: string, context: string = '', result: AttemptResult = {}): AttemptInfo {
|
|
39
|
-
const key = this._getKey(command, context)
|
|
40
|
-
const now = Date.now()
|
|
41
|
-
|
|
42
|
-
// Get or create attempt record
|
|
43
|
-
let record = this._attempts.get(key)
|
|
44
|
-
|
|
45
|
-
if (!record || now - record.lastAttempt > this.sessionTimeout) {
|
|
46
|
-
// New session or timed out
|
|
47
|
-
record = {
|
|
48
|
-
command,
|
|
49
|
-
context,
|
|
50
|
-
attempts: 0,
|
|
51
|
-
errors: [],
|
|
52
|
-
firstAttempt: now,
|
|
53
|
-
lastAttempt: now,
|
|
54
|
-
success: false,
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Update record
|
|
59
|
-
record.attempts++
|
|
60
|
-
record.lastAttempt = now
|
|
61
|
-
record.success = result.success || false
|
|
62
|
-
|
|
63
|
-
if (result.error) {
|
|
64
|
-
record.errors.push({
|
|
65
|
-
message: result.error,
|
|
66
|
-
timestamp: now,
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
this._attempts.set(key, record)
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
attemptNumber: record.attempts,
|
|
74
|
-
isLooping: this.isLooping(command, context),
|
|
75
|
-
shouldEscalate: this.shouldEscalate(command, context),
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Check if a command is in a loop (repeated failures)
|
|
81
|
-
*/
|
|
82
|
-
isLooping(command: string, context: string = ''): boolean {
|
|
83
|
-
const key = this._getKey(command, context)
|
|
84
|
-
const record = this._attempts.get(key)
|
|
85
|
-
|
|
86
|
-
if (!record) return false
|
|
87
|
-
|
|
88
|
-
// Check if multiple failures with same error
|
|
89
|
-
if (record.attempts >= 2 && !record.success) {
|
|
90
|
-
const recentErrors = record.errors.slice(-3)
|
|
91
|
-
if (recentErrors.length >= 2) {
|
|
92
|
-
// Check if errors are similar
|
|
93
|
-
const firstError = recentErrors[0]?.message || ''
|
|
94
|
-
const sameError = recentErrors.every((e) => isSimilarError(e.message, firstError))
|
|
95
|
-
return sameError
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return false
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Check if we should escalate to user
|
|
104
|
-
*/
|
|
105
|
-
shouldEscalate(command: string, context: string = ''): boolean {
|
|
106
|
-
const key = this._getKey(command, context)
|
|
107
|
-
const record = this._attempts.get(key)
|
|
108
|
-
|
|
109
|
-
if (!record) return false
|
|
110
|
-
|
|
111
|
-
// Escalate after max attempts without success
|
|
112
|
-
return record.attempts >= this.maxAttempts && !record.success
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get escalation message for user
|
|
117
|
-
*/
|
|
118
|
-
getEscalationInfo(command: string, context: string = ''): EscalationInfo | null {
|
|
119
|
-
const key = this._getKey(command, context)
|
|
120
|
-
const record = this._attempts.get(key)
|
|
121
|
-
|
|
122
|
-
if (!record) {
|
|
123
|
-
return null
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Analyze error pattern
|
|
127
|
-
const errorPattern = analyzeErrorPattern(record.errors)
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
status: 'BLOCKED',
|
|
131
|
-
command,
|
|
132
|
-
context,
|
|
133
|
-
attempts: record.attempts,
|
|
134
|
-
duration: record.lastAttempt - record.firstAttempt,
|
|
135
|
-
errorPattern,
|
|
136
|
-
message: generateEscalationMessage(command, errorPattern, this.maxAttempts),
|
|
137
|
-
suggestion: generateSuggestion(errorPattern),
|
|
138
|
-
lastError: record.errors[record.errors.length - 1]?.message || null,
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Mark a command as successful (resets tracking)
|
|
144
|
-
*/
|
|
145
|
-
recordSuccess(command: string, context: string = ''): void {
|
|
146
|
-
const key = this._getKey(command, context)
|
|
147
|
-
const record = this._attempts.get(key)
|
|
148
|
-
|
|
149
|
-
if (record) {
|
|
150
|
-
record.success = true
|
|
151
|
-
record.attempts = 0
|
|
152
|
-
record.errors = []
|
|
153
|
-
this._attempts.set(key, record)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Clear all tracking for a command
|
|
159
|
-
*/
|
|
160
|
-
clearTracking(command: string, context: string = ''): void {
|
|
161
|
-
const key = this._getKey(command, context)
|
|
162
|
-
this._attempts.delete(key)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Clear all tracking data
|
|
167
|
-
*/
|
|
168
|
-
clearAll(): void {
|
|
169
|
-
this._attempts.clear()
|
|
170
|
-
this._errorPatterns.clear()
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Get statistics for debugging
|
|
175
|
-
*/
|
|
176
|
-
getStats(): { activeTracking: number; commands: Record<string, unknown> } {
|
|
177
|
-
const stats: { activeTracking: number; commands: Record<string, unknown> } = {
|
|
178
|
-
activeTracking: this._attempts.size,
|
|
179
|
-
commands: {},
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
for (const [key, record] of this._attempts) {
|
|
183
|
-
stats.commands[key] = {
|
|
184
|
-
attempts: record.attempts,
|
|
185
|
-
success: record.success,
|
|
186
|
-
errorCount: record.errors.length,
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return stats
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* ANTI-HALLUCINATION: Detect potential hallucination patterns in output
|
|
195
|
-
*/
|
|
196
|
-
detectHallucination(output: string) {
|
|
197
|
-
return detectHallucination(output)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Analyze output and record if hallucination detected
|
|
202
|
-
*/
|
|
203
|
-
analyzeOutput(command: string, output: string): OutputAnalysis {
|
|
204
|
-
const hallucination = this.detectHallucination(output)
|
|
205
|
-
|
|
206
|
-
if (hallucination.detected) {
|
|
207
|
-
// Record as a special type of error
|
|
208
|
-
this.recordAttempt(command, 'hallucination', {
|
|
209
|
-
success: false,
|
|
210
|
-
error: `HALLUCINATION: ${hallucination.description}`,
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
return {
|
|
214
|
-
...hallucination,
|
|
215
|
-
shouldBlock: true,
|
|
216
|
-
action: 'VERIFY_STATE',
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return { detected: false, shouldBlock: false }
|
|
221
|
-
}
|
|
222
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop Detector Types
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export interface ErrorEntry {
|
|
6
|
-
message: string
|
|
7
|
-
timestamp: number
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface AttemptRecord {
|
|
11
|
-
command: string
|
|
12
|
-
context: string
|
|
13
|
-
attempts: number
|
|
14
|
-
errors: ErrorEntry[]
|
|
15
|
-
firstAttempt: number
|
|
16
|
-
lastAttempt: number
|
|
17
|
-
success: boolean
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface ErrorPattern {
|
|
21
|
-
type: string
|
|
22
|
-
description: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface EscalationInfo {
|
|
26
|
-
status: string
|
|
27
|
-
command: string
|
|
28
|
-
context: string
|
|
29
|
-
attempts: number
|
|
30
|
-
duration: number
|
|
31
|
-
errorPattern: ErrorPattern
|
|
32
|
-
message: string
|
|
33
|
-
suggestion: string
|
|
34
|
-
lastError: string | null
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface AttemptResult {
|
|
38
|
-
success?: boolean
|
|
39
|
-
error?: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface AttemptInfo {
|
|
43
|
-
attemptNumber: number
|
|
44
|
-
isLooping: boolean
|
|
45
|
-
shouldEscalate: boolean
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface HallucinationPattern {
|
|
49
|
-
pattern: RegExp
|
|
50
|
-
type: string
|
|
51
|
-
description: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface HallucinationResult {
|
|
55
|
-
detected: boolean
|
|
56
|
-
type?: string
|
|
57
|
-
pattern?: string
|
|
58
|
-
description?: string
|
|
59
|
-
message?: string
|
|
60
|
-
suggestion?: string
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface OutputAnalysis extends HallucinationResult {
|
|
64
|
-
shouldBlock: boolean
|
|
65
|
-
action?: string
|
|
66
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* History - Tier 3
|
|
3
|
-
* Append-only JSONL audit log.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'fs/promises'
|
|
7
|
-
import path from 'path'
|
|
8
|
-
import pathManager from '../../infrastructure/path-manager'
|
|
9
|
-
import type { HistoryEntry } from './types'
|
|
10
|
-
|
|
11
|
-
export class HistoryStore {
|
|
12
|
-
private _getSessionPath(projectId: string): string {
|
|
13
|
-
const now = new Date()
|
|
14
|
-
const yearMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`
|
|
15
|
-
const day = now.toISOString().split('T')[0]
|
|
16
|
-
|
|
17
|
-
return path.join(pathManager.getGlobalProjectPath(projectId), 'memory', 'sessions', yearMonth, `${day}.jsonl`)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async appendHistory(projectId: string, entry: Record<string, unknown>): Promise<void> {
|
|
21
|
-
const sessionPath = this._getSessionPath(projectId)
|
|
22
|
-
await fs.mkdir(path.dirname(sessionPath), { recursive: true })
|
|
23
|
-
|
|
24
|
-
const logEntry: HistoryEntry = {
|
|
25
|
-
ts: new Date().toISOString(),
|
|
26
|
-
type: entry.type as string,
|
|
27
|
-
...entry,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
await fs.appendFile(sessionPath, JSON.stringify(logEntry) + '\n', 'utf-8')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async getRecentHistory(projectId: string, limit: number = 20): Promise<HistoryEntry[]> {
|
|
34
|
-
try {
|
|
35
|
-
const sessionPath = this._getSessionPath(projectId)
|
|
36
|
-
const content = await fs.readFile(sessionPath, 'utf-8')
|
|
37
|
-
const lines = content.trim().split('\n').filter(Boolean)
|
|
38
|
-
|
|
39
|
-
return lines
|
|
40
|
-
.slice(-limit)
|
|
41
|
-
.map((line) => {
|
|
42
|
-
try {
|
|
43
|
-
return JSON.parse(line)
|
|
44
|
-
} catch {
|
|
45
|
-
return null
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
.filter((entry): entry is HistoryEntry => entry !== null)
|
|
49
|
-
} catch {
|
|
50
|
-
return []
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Layered Memory System
|
|
3
|
-
* Three-tier memory for learning user patterns and preferences.
|
|
4
|
-
*
|
|
5
|
-
* @module agentic/memory-system
|
|
6
|
-
* @version 3.3
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { SemanticMemories } from './semantic-memories'
|
|
10
|
-
import { PatternStore } from './patterns'
|
|
11
|
-
import { HistoryStore } from './history'
|
|
12
|
-
import { SessionStore } from './session'
|
|
13
|
-
import type { Memory, Context, Workflow } from './types'
|
|
14
|
-
export { MEMORY_TAGS } from './types'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Three-tier memory system for learning user patterns.
|
|
18
|
-
* Tier 1: Session (ephemeral), Tier 2: Patterns (persistent), Tier 3: History (JSONL)
|
|
19
|
-
*/
|
|
20
|
-
class MemorySystem {
|
|
21
|
-
private _semanticMemories: SemanticMemories
|
|
22
|
-
private _patternStore: PatternStore
|
|
23
|
-
private _historyStore: HistoryStore
|
|
24
|
-
private _sessionStore: SessionStore
|
|
25
|
-
|
|
26
|
-
constructor() {
|
|
27
|
-
this._semanticMemories = new SemanticMemories()
|
|
28
|
-
this._patternStore = new PatternStore()
|
|
29
|
-
this._historyStore = new HistoryStore()
|
|
30
|
-
this._sessionStore = new SessionStore()
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ═══════════════════════════════════════════════════════════
|
|
34
|
-
// P3.3: SEMANTIC MEMORIES
|
|
35
|
-
// ═══════════════════════════════════════════════════════════
|
|
36
|
-
|
|
37
|
-
loadMemories(projectId: string) {
|
|
38
|
-
return this._semanticMemories.loadMemories(projectId)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
saveMemories(projectId: string) {
|
|
42
|
-
return this._semanticMemories.saveMemories(projectId)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
createMemory(
|
|
46
|
-
projectId: string,
|
|
47
|
-
options: { title: string; content: string; tags?: string[]; userTriggered?: boolean }
|
|
48
|
-
): Promise<string> {
|
|
49
|
-
return this._semanticMemories.createMemory(projectId, options)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
updateMemory(
|
|
53
|
-
projectId: string,
|
|
54
|
-
memoryId: string,
|
|
55
|
-
updates: { title?: string; content?: string; tags?: string[] }
|
|
56
|
-
): Promise<boolean> {
|
|
57
|
-
return this._semanticMemories.updateMemory(projectId, memoryId, updates)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
deleteMemory(projectId: string, memoryId: string): Promise<boolean> {
|
|
61
|
-
return this._semanticMemories.deleteMemory(projectId, memoryId)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
findByTags(projectId: string, tags: string[], matchAll?: boolean): Promise<Memory[]> {
|
|
65
|
-
return this._semanticMemories.findByTags(projectId, tags, matchAll)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
searchMemories(projectId: string, query: string): Promise<Memory[]> {
|
|
69
|
-
return this._semanticMemories.searchMemories(projectId, query)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
getRelevantMemories(projectId: string, context: Context, limit?: number): Promise<Memory[]> {
|
|
73
|
-
return this._semanticMemories.getRelevantMemories(projectId, context, limit)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
autoRemember(projectId: string, decisionType: string, value: string, context?: string): Promise<void> {
|
|
77
|
-
return this._semanticMemories.autoRemember(projectId, decisionType, value, context)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
getAllMemories(projectId: string): Promise<Memory[]> {
|
|
81
|
-
return this._semanticMemories.getAllMemories(projectId)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
getMemoryStats(projectId: string) {
|
|
85
|
-
return this._semanticMemories.getMemoryStats(projectId)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ═══════════════════════════════════════════════════════════
|
|
89
|
-
// TIER 1: Session Memory
|
|
90
|
-
// ═══════════════════════════════════════════════════════════
|
|
91
|
-
|
|
92
|
-
setSession(key: string, value: unknown): void {
|
|
93
|
-
this._sessionStore.setSession(key, value)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
getSession(key: string): unknown {
|
|
97
|
-
return this._sessionStore.getSession(key)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
clearSession(): void {
|
|
101
|
-
this._sessionStore.clearSession()
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ═══════════════════════════════════════════════════════════
|
|
105
|
-
// TIER 2: Patterns
|
|
106
|
-
// ═══════════════════════════════════════════════════════════
|
|
107
|
-
|
|
108
|
-
loadPatterns(projectId: string) {
|
|
109
|
-
return this._patternStore.loadPatterns(projectId)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
savePatterns(projectId: string) {
|
|
113
|
-
return this._patternStore.savePatterns(projectId)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
recordDecision(projectId: string, key: string, value: string, context?: string): Promise<void> {
|
|
117
|
-
return this._patternStore.recordDecision(projectId, key, value, context)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
getDecision(projectId: string, key: string): Promise<{ value: string; confidence: string } | null> {
|
|
121
|
-
return this._patternStore.getDecision(projectId, key)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
hasPattern(projectId: string, key: string): Promise<boolean> {
|
|
125
|
-
return this._patternStore.hasPattern(projectId, key)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
recordWorkflow(projectId: string, workflowName: string, pattern: Record<string, unknown>): Promise<void> {
|
|
129
|
-
return this._patternStore.recordWorkflow(projectId, workflowName, pattern)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getWorkflow(projectId: string, workflowName: string): Promise<Workflow | null> {
|
|
133
|
-
return this._patternStore.getWorkflow(projectId, workflowName)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
setPreference(projectId: string, key: string, value: unknown): Promise<void> {
|
|
137
|
-
return this._patternStore.setPreference(projectId, key, value)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
getPreference(projectId: string, key: string, defaultValue?: unknown): Promise<unknown> {
|
|
141
|
-
return this._patternStore.getPreference(projectId, key, defaultValue)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
getPatternsSummary(projectId: string) {
|
|
145
|
-
return this._patternStore.getPatternsSummary(projectId)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// ═══════════════════════════════════════════════════════════
|
|
149
|
-
// TIER 3: History
|
|
150
|
-
// ═══════════════════════════════════════════════════════════
|
|
151
|
-
|
|
152
|
-
appendHistory(projectId: string, entry: Record<string, unknown>): Promise<void> {
|
|
153
|
-
return this._historyStore.appendHistory(projectId, entry)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
getRecentHistory(projectId: string, limit?: number) {
|
|
157
|
-
return this._historyStore.getRecentHistory(projectId, limit)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// ═══════════════════════════════════════════════════════════
|
|
161
|
-
// CONVENIENCE: Combined operations
|
|
162
|
-
// ═══════════════════════════════════════════════════════════
|
|
163
|
-
|
|
164
|
-
async getSmartDecision(projectId: string, key: string): Promise<string | null> {
|
|
165
|
-
const sessionValue = this.getSession(`decision:${key}`)
|
|
166
|
-
if (sessionValue !== undefined) return sessionValue as string
|
|
167
|
-
|
|
168
|
-
const pattern = await this.getDecision(projectId, key)
|
|
169
|
-
if (pattern) return pattern.value
|
|
170
|
-
|
|
171
|
-
return null
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
async learnDecision(projectId: string, key: string, value: string, context: string = ''): Promise<void> {
|
|
175
|
-
this.setSession(`decision:${key}`, value)
|
|
176
|
-
await this.recordDecision(projectId, key, value, context)
|
|
177
|
-
await this.appendHistory(projectId, { type: 'decision', key, value, context })
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Reset internal state (for testing)
|
|
182
|
-
*/
|
|
183
|
-
resetState(): void {
|
|
184
|
-
this._sessionStore.clearSession()
|
|
185
|
-
this._semanticMemories.reset()
|
|
186
|
-
this._patternStore.reset()
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const memorySystem = new MemorySystem()
|
|
191
|
-
export default memorySystem
|
|
192
|
-
export { MemorySystem }
|