prjct-cli 0.35.0 → 0.35.2
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 +50 -0
- package/core/agentic/command-executor.ts +29 -1
- package/core/agentic/index.ts +6 -0
- package/core/agentic/orchestrator-executor.ts +482 -0
- package/core/agentic/prompt-builder.ts +67 -1
- package/core/commands/workflow.ts +24 -9
- package/core/types/agentic.ts +62 -0
- package/core/types/index.ts +5 -0
- package/dist/bin/prjct.mjs +665 -129
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
ThinkBlock,
|
|
25
25
|
Memory,
|
|
26
26
|
PlanInfo,
|
|
27
|
+
OrchestratorContext,
|
|
27
28
|
} from '../types'
|
|
28
29
|
|
|
29
30
|
// Re-export types for convenience
|
|
@@ -287,7 +288,8 @@ class PromptBuilder {
|
|
|
287
288
|
learnedPatterns: LearnedPatterns | null = null,
|
|
288
289
|
thinkBlock: ThinkBlock | null = null,
|
|
289
290
|
relevantMemories: Memory[] | null = null,
|
|
290
|
-
planInfo: PlanInfo | null = null
|
|
291
|
+
planInfo: PlanInfo | null = null,
|
|
292
|
+
orchestratorContext: OrchestratorContext | null = null
|
|
291
293
|
): string {
|
|
292
294
|
const parts: string[] = []
|
|
293
295
|
|
|
@@ -326,6 +328,70 @@ class PromptBuilder {
|
|
|
326
328
|
// This ensures Claude sees ALL instructions including critical rules at the top
|
|
327
329
|
parts.push(template.content)
|
|
328
330
|
|
|
331
|
+
// ORCHESTRATOR CONTEXT: Inject loaded agents, skills, and subtasks
|
|
332
|
+
if (orchestratorContext) {
|
|
333
|
+
parts.push('\n## ORCHESTRATOR CONTEXT\n')
|
|
334
|
+
parts.push(`**Primary Domain**: ${orchestratorContext.primaryDomain}\n`)
|
|
335
|
+
parts.push(`**Domains**: ${orchestratorContext.detectedDomains.join(', ')}\n`)
|
|
336
|
+
parts.push(`**Ecosystem**: ${orchestratorContext.project.ecosystem}\n\n`)
|
|
337
|
+
|
|
338
|
+
// Inject loaded agent content (truncated for context efficiency)
|
|
339
|
+
if (orchestratorContext.agents.length > 0) {
|
|
340
|
+
parts.push('### LOADED AGENTS (Project-Specific Specialists)\n\n')
|
|
341
|
+
for (const agent of orchestratorContext.agents) {
|
|
342
|
+
parts.push(`#### Agent: ${agent.name} (${agent.domain})\n`)
|
|
343
|
+
if (agent.skills.length > 0) {
|
|
344
|
+
parts.push(`Skills: ${agent.skills.join(', ')}\n`)
|
|
345
|
+
}
|
|
346
|
+
// Include first 1500 chars of agent content
|
|
347
|
+
const truncatedContent = agent.content.length > 1500
|
|
348
|
+
? agent.content.substring(0, 1500) + '\n... (truncated, read full file for more)'
|
|
349
|
+
: agent.content
|
|
350
|
+
parts.push(`\`\`\`markdown\n${truncatedContent}\n\`\`\`\n\n`)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Inject loaded skill content (truncated)
|
|
355
|
+
if (orchestratorContext.skills.length > 0) {
|
|
356
|
+
parts.push('### LOADED SKILLS (From Agent Frontmatter)\n\n')
|
|
357
|
+
for (const skill of orchestratorContext.skills) {
|
|
358
|
+
parts.push(`#### Skill: ${skill.name}\n`)
|
|
359
|
+
// Include first 1000 chars of skill content
|
|
360
|
+
const truncatedContent = skill.content.length > 1000
|
|
361
|
+
? skill.content.substring(0, 1000) + '\n... (truncated)'
|
|
362
|
+
: skill.content
|
|
363
|
+
parts.push(`\`\`\`markdown\n${truncatedContent}\n\`\`\`\n\n`)
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Inject subtasks if fragmented
|
|
368
|
+
if (orchestratorContext.requiresFragmentation && orchestratorContext.subtasks) {
|
|
369
|
+
parts.push('### SUBTASKS (Execute in Order)\n\n')
|
|
370
|
+
parts.push('**IMPORTANT**: Focus on the CURRENT subtask. Use `p. done` when complete to advance.\n\n')
|
|
371
|
+
parts.push('| # | Domain | Description | Status |\n')
|
|
372
|
+
parts.push('|---|--------|-------------|--------|\n')
|
|
373
|
+
|
|
374
|
+
for (const subtask of orchestratorContext.subtasks) {
|
|
375
|
+
const statusIcon = subtask.status === 'in_progress' ? '▶️ **CURRENT**'
|
|
376
|
+
: subtask.status === 'completed' ? '✅ Done'
|
|
377
|
+
: subtask.status === 'failed' ? '❌ Failed'
|
|
378
|
+
: '⏳ Pending'
|
|
379
|
+
parts.push(`| ${subtask.order} | ${subtask.domain} | ${subtask.description} | ${statusIcon} |\n`)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Find and highlight current subtask
|
|
383
|
+
const currentSubtask = orchestratorContext.subtasks.find(s => s.status === 'in_progress')
|
|
384
|
+
if (currentSubtask) {
|
|
385
|
+
parts.push(`\n**FOCUS ON SUBTASK #${currentSubtask.order}**: ${currentSubtask.description}\n`)
|
|
386
|
+
parts.push(`Agent: ${currentSubtask.agent} | Domain: ${currentSubtask.domain}\n`)
|
|
387
|
+
if (currentSubtask.dependsOn.length > 0) {
|
|
388
|
+
parts.push(`Dependencies: ${currentSubtask.dependsOn.join(', ')}\n`)
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
parts.push('\n')
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
329
395
|
// Current state (only if exists and relevant)
|
|
330
396
|
const relevantState = this.filterRelevantState(state)
|
|
331
397
|
if (relevantState) {
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from './base'
|
|
20
20
|
import { stateStorage, queueStorage } from '../storage'
|
|
21
21
|
import { templateExecutor } from '../agentic/template-executor'
|
|
22
|
+
import commandExecutor from '../agentic/command-executor'
|
|
22
23
|
|
|
23
24
|
export class WorkflowCommands extends PrjctCommandsBase {
|
|
24
25
|
/**
|
|
@@ -36,12 +37,13 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
if (task) {
|
|
39
|
-
// AGENTIC:
|
|
40
|
-
const
|
|
41
|
-
const agenticInfo = templateExecutor.buildAgenticPrompt(execContext)
|
|
40
|
+
// AGENTIC: Use CommandExecutor for full orchestration support
|
|
41
|
+
const result = await commandExecutor.execute('task', { task }, projectPath)
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
out.fail(result.error || 'Failed to execute task')
|
|
45
|
+
return { success: false, error: result.error }
|
|
46
|
+
}
|
|
45
47
|
|
|
46
48
|
// Write-through: JSON → MD → Event
|
|
47
49
|
await stateStorage.startTask(projectId, {
|
|
@@ -50,18 +52,31 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
50
52
|
sessionId: generateUUID()
|
|
51
53
|
})
|
|
52
54
|
|
|
53
|
-
//
|
|
55
|
+
// Log orchestrator results if available
|
|
56
|
+
if (result.orchestratorContext) {
|
|
57
|
+
const oc = result.orchestratorContext
|
|
58
|
+
const agentsList = oc.agents.map((a: { name: string }) => a.name).join(', ') || 'none'
|
|
59
|
+
const domainsList = oc.detectedDomains.join(', ')
|
|
60
|
+
console.log(`🎯 Orchestrator: ${domainsList} → [${agentsList}]`)
|
|
61
|
+
|
|
62
|
+
if (oc.requiresFragmentation && oc.subtasks) {
|
|
63
|
+
console.log(` → ${oc.subtasks.length} subtasks created`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Get available agents for backward compatibility
|
|
68
|
+
const availableAgents = await templateExecutor.getAvailableAgents(projectPath)
|
|
54
69
|
const agentsList = availableAgents.length > 0
|
|
55
70
|
? availableAgents.join(', ')
|
|
56
71
|
: 'none (run p. sync)'
|
|
57
72
|
|
|
58
|
-
console.log(`🤖 Agentic mode: Claude will read templates and decide`)
|
|
59
73
|
out.done(`${task} [specialists: ${agentsList}]`)
|
|
60
74
|
|
|
61
75
|
await this.logToMemory(projectPath, 'task_started', {
|
|
62
76
|
task,
|
|
63
77
|
agenticMode: true,
|
|
64
78
|
availableAgents,
|
|
79
|
+
orchestratorContext: result.orchestratorContext,
|
|
65
80
|
timestamp: dateHelper.getTimestamp(),
|
|
66
81
|
})
|
|
67
82
|
|
|
@@ -70,8 +85,8 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
70
85
|
task,
|
|
71
86
|
agenticMode: true,
|
|
72
87
|
availableAgents,
|
|
73
|
-
|
|
74
|
-
|
|
88
|
+
// Include full CommandExecutor result (orchestratorContext, prompt, etc.)
|
|
89
|
+
...result,
|
|
75
90
|
}
|
|
76
91
|
} else {
|
|
77
92
|
// Read from storage (JSON is source of truth)
|
package/core/types/agentic.ts
CHANGED
|
@@ -443,6 +443,7 @@ export interface ExecutionResult {
|
|
|
443
443
|
compressionMetrics?: unknown
|
|
444
444
|
learnedPatterns?: unknown
|
|
445
445
|
relevantMemories?: unknown
|
|
446
|
+
orchestratorContext?: OrchestratorContext | null
|
|
446
447
|
formatResponse?: (data: unknown) => string
|
|
447
448
|
formatThinkBlock?: (verbose: boolean) => string
|
|
448
449
|
parallel?: {
|
|
@@ -571,3 +572,64 @@ export interface LearnedPatterns {
|
|
|
571
572
|
preferred_agent?: string | null
|
|
572
573
|
[key: string]: string | null | undefined
|
|
573
574
|
}
|
|
575
|
+
|
|
576
|
+
// =============================================================================
|
|
577
|
+
// Orchestrator Types
|
|
578
|
+
// =============================================================================
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* A loaded agent with its content
|
|
582
|
+
*/
|
|
583
|
+
export interface LoadedAgent {
|
|
584
|
+
name: string
|
|
585
|
+
domain: string
|
|
586
|
+
content: string
|
|
587
|
+
skills: string[]
|
|
588
|
+
filePath: string
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* A loaded skill with its content
|
|
593
|
+
*/
|
|
594
|
+
export interface LoadedSkill {
|
|
595
|
+
name: string
|
|
596
|
+
content: string
|
|
597
|
+
filePath: string
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Subtask for task fragmentation
|
|
602
|
+
*/
|
|
603
|
+
export interface OrchestratorSubtask {
|
|
604
|
+
id: string
|
|
605
|
+
description: string
|
|
606
|
+
domain: string
|
|
607
|
+
agent: string
|
|
608
|
+
status: 'pending' | 'in_progress' | 'completed' | 'failed'
|
|
609
|
+
dependsOn: string[]
|
|
610
|
+
order: number
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Full orchestrator context returned after execution
|
|
615
|
+
*/
|
|
616
|
+
export interface OrchestratorContext {
|
|
617
|
+
/** Domains detected for this task */
|
|
618
|
+
detectedDomains: string[]
|
|
619
|
+
/** Primary domain (most important) */
|
|
620
|
+
primaryDomain: string
|
|
621
|
+
/** Loaded agents with their content */
|
|
622
|
+
agents: LoadedAgent[]
|
|
623
|
+
/** Loaded skills from agent frontmatter */
|
|
624
|
+
skills: LoadedSkill[]
|
|
625
|
+
/** Whether task requires fragmentation (3+ domains) */
|
|
626
|
+
requiresFragmentation: boolean
|
|
627
|
+
/** Subtasks if fragmented, null otherwise */
|
|
628
|
+
subtasks: OrchestratorSubtask[] | null
|
|
629
|
+
/** Project info */
|
|
630
|
+
project: {
|
|
631
|
+
id: string
|
|
632
|
+
ecosystem: string
|
|
633
|
+
conventions: string[]
|
|
634
|
+
}
|
|
635
|
+
}
|
package/core/types/index.ts
CHANGED
|
@@ -158,6 +158,11 @@ export type {
|
|
|
158
158
|
ReasoningStep,
|
|
159
159
|
ReasoningResult,
|
|
160
160
|
ChainOfThoughtResult,
|
|
161
|
+
// Orchestrator types
|
|
162
|
+
OrchestratorContext,
|
|
163
|
+
LoadedAgent,
|
|
164
|
+
LoadedSkill,
|
|
165
|
+
OrchestratorSubtask,
|
|
161
166
|
} from './agentic'
|
|
162
167
|
|
|
163
168
|
// =============================================================================
|