prjct-cli 0.35.0 → 0.35.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 +35 -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/types/agentic.ts +62 -0
- package/core/types/index.ts +5 -0
- package/dist/bin/prjct.mjs +646 -123
- package/package.json +1 -1
package/dist/bin/prjct.mjs
CHANGED
|
@@ -16,10 +16,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
16
16
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
17
17
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
18
18
|
});
|
|
19
|
-
var __glob = (map) => (
|
|
20
|
-
var fn = map[
|
|
19
|
+
var __glob = (map) => (path35) => {
|
|
20
|
+
var fn = map[path35];
|
|
21
21
|
if (fn) return fn();
|
|
22
|
-
throw new Error("Module not found in bundle: " +
|
|
22
|
+
throw new Error("Module not found in bundle: " + path35);
|
|
23
23
|
};
|
|
24
24
|
var __esm = (fn, res) => function __init() {
|
|
25
25
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -5706,7 +5706,7 @@ var init_prompt_builder = __esm({
|
|
|
5706
5706
|
* Build a complete prompt for Claude from template, context, and enhancements
|
|
5707
5707
|
* @deprecated Use buildWithInjection for auto-injected context
|
|
5708
5708
|
*/
|
|
5709
|
-
build(template, context, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null) {
|
|
5709
|
+
build(template, context, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null, orchestratorContext = null) {
|
|
5710
5710
|
const parts = [];
|
|
5711
5711
|
this._currentContext = context;
|
|
5712
5712
|
const commandName = template.frontmatter?.name?.replace("p:", "") || "";
|
|
@@ -5737,6 +5737,70 @@ Apply specialized expertise. Read agent file for details if needed.
|
|
|
5737
5737
|
}
|
|
5738
5738
|
parts.push("\n---\n");
|
|
5739
5739
|
parts.push(template.content);
|
|
5740
|
+
if (orchestratorContext) {
|
|
5741
|
+
parts.push("\n## ORCHESTRATOR CONTEXT\n");
|
|
5742
|
+
parts.push(`**Primary Domain**: ${orchestratorContext.primaryDomain}
|
|
5743
|
+
`);
|
|
5744
|
+
parts.push(`**Domains**: ${orchestratorContext.detectedDomains.join(", ")}
|
|
5745
|
+
`);
|
|
5746
|
+
parts.push(`**Ecosystem**: ${orchestratorContext.project.ecosystem}
|
|
5747
|
+
|
|
5748
|
+
`);
|
|
5749
|
+
if (orchestratorContext.agents.length > 0) {
|
|
5750
|
+
parts.push("### LOADED AGENTS (Project-Specific Specialists)\n\n");
|
|
5751
|
+
for (const agent2 of orchestratorContext.agents) {
|
|
5752
|
+
parts.push(`#### Agent: ${agent2.name} (${agent2.domain})
|
|
5753
|
+
`);
|
|
5754
|
+
if (agent2.skills.length > 0) {
|
|
5755
|
+
parts.push(`Skills: ${agent2.skills.join(", ")}
|
|
5756
|
+
`);
|
|
5757
|
+
}
|
|
5758
|
+
const truncatedContent = agent2.content.length > 1500 ? agent2.content.substring(0, 1500) + "\n... (truncated, read full file for more)" : agent2.content;
|
|
5759
|
+
parts.push(`\`\`\`markdown
|
|
5760
|
+
${truncatedContent}
|
|
5761
|
+
\`\`\`
|
|
5762
|
+
|
|
5763
|
+
`);
|
|
5764
|
+
}
|
|
5765
|
+
}
|
|
5766
|
+
if (orchestratorContext.skills.length > 0) {
|
|
5767
|
+
parts.push("### LOADED SKILLS (From Agent Frontmatter)\n\n");
|
|
5768
|
+
for (const skill of orchestratorContext.skills) {
|
|
5769
|
+
parts.push(`#### Skill: ${skill.name}
|
|
5770
|
+
`);
|
|
5771
|
+
const truncatedContent = skill.content.length > 1e3 ? skill.content.substring(0, 1e3) + "\n... (truncated)" : skill.content;
|
|
5772
|
+
parts.push(`\`\`\`markdown
|
|
5773
|
+
${truncatedContent}
|
|
5774
|
+
\`\`\`
|
|
5775
|
+
|
|
5776
|
+
`);
|
|
5777
|
+
}
|
|
5778
|
+
}
|
|
5779
|
+
if (orchestratorContext.requiresFragmentation && orchestratorContext.subtasks) {
|
|
5780
|
+
parts.push("### SUBTASKS (Execute in Order)\n\n");
|
|
5781
|
+
parts.push("**IMPORTANT**: Focus on the CURRENT subtask. Use `p. done` when complete to advance.\n\n");
|
|
5782
|
+
parts.push("| # | Domain | Description | Status |\n");
|
|
5783
|
+
parts.push("|---|--------|-------------|--------|\n");
|
|
5784
|
+
for (const subtask of orchestratorContext.subtasks) {
|
|
5785
|
+
const statusIcon = subtask.status === "in_progress" ? "\u25B6\uFE0F **CURRENT**" : subtask.status === "completed" ? "\u2705 Done" : subtask.status === "failed" ? "\u274C Failed" : "\u23F3 Pending";
|
|
5786
|
+
parts.push(`| ${subtask.order} | ${subtask.domain} | ${subtask.description} | ${statusIcon} |
|
|
5787
|
+
`);
|
|
5788
|
+
}
|
|
5789
|
+
const currentSubtask = orchestratorContext.subtasks.find((s) => s.status === "in_progress");
|
|
5790
|
+
if (currentSubtask) {
|
|
5791
|
+
parts.push(`
|
|
5792
|
+
**FOCUS ON SUBTASK #${currentSubtask.order}**: ${currentSubtask.description}
|
|
5793
|
+
`);
|
|
5794
|
+
parts.push(`Agent: ${currentSubtask.agent} | Domain: ${currentSubtask.domain}
|
|
5795
|
+
`);
|
|
5796
|
+
if (currentSubtask.dependsOn.length > 0) {
|
|
5797
|
+
parts.push(`Dependencies: ${currentSubtask.dependsOn.join(", ")}
|
|
5798
|
+
`);
|
|
5799
|
+
}
|
|
5800
|
+
}
|
|
5801
|
+
parts.push("\n");
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5740
5804
|
const relevantState = this.filterRelevantState(state);
|
|
5741
5805
|
if (relevantState) {
|
|
5742
5806
|
parts.push("\n## PRJCT STATE (Project Management Data)\n");
|
|
@@ -8412,24 +8476,462 @@ When fragmenting tasks:
|
|
|
8412
8476
|
}
|
|
8413
8477
|
});
|
|
8414
8478
|
|
|
8415
|
-
// core/agentic/
|
|
8416
|
-
import fs20 from "fs";
|
|
8479
|
+
// core/agentic/orchestrator-executor.ts
|
|
8480
|
+
import fs20 from "fs/promises";
|
|
8417
8481
|
import path19 from "path";
|
|
8418
8482
|
import os8 from "os";
|
|
8483
|
+
var DOMAIN_KEYWORDS, DOMAIN_DEPENDENCY_ORDER, OrchestratorExecutor, orchestratorExecutor, orchestrator_executor_default;
|
|
8484
|
+
var init_orchestrator_executor = __esm({
|
|
8485
|
+
"core/agentic/orchestrator-executor.ts"() {
|
|
8486
|
+
"use strict";
|
|
8487
|
+
init_path_manager();
|
|
8488
|
+
init_config_manager();
|
|
8489
|
+
init_storage2();
|
|
8490
|
+
init_fs();
|
|
8491
|
+
init_template_loader();
|
|
8492
|
+
DOMAIN_KEYWORDS = {
|
|
8493
|
+
database: [
|
|
8494
|
+
"database",
|
|
8495
|
+
"db",
|
|
8496
|
+
"sql",
|
|
8497
|
+
"query",
|
|
8498
|
+
"table",
|
|
8499
|
+
"schema",
|
|
8500
|
+
"migration",
|
|
8501
|
+
"postgres",
|
|
8502
|
+
"mysql",
|
|
8503
|
+
"sqlite",
|
|
8504
|
+
"mongo",
|
|
8505
|
+
"redis",
|
|
8506
|
+
"prisma",
|
|
8507
|
+
"drizzle",
|
|
8508
|
+
"orm",
|
|
8509
|
+
"model",
|
|
8510
|
+
"entity",
|
|
8511
|
+
"repository",
|
|
8512
|
+
"data layer",
|
|
8513
|
+
"persist"
|
|
8514
|
+
],
|
|
8515
|
+
backend: [
|
|
8516
|
+
"api",
|
|
8517
|
+
"endpoint",
|
|
8518
|
+
"route",
|
|
8519
|
+
"server",
|
|
8520
|
+
"controller",
|
|
8521
|
+
"service",
|
|
8522
|
+
"middleware",
|
|
8523
|
+
"auth",
|
|
8524
|
+
"authentication",
|
|
8525
|
+
"authorization",
|
|
8526
|
+
"jwt",
|
|
8527
|
+
"oauth",
|
|
8528
|
+
"rest",
|
|
8529
|
+
"graphql",
|
|
8530
|
+
"trpc",
|
|
8531
|
+
"express",
|
|
8532
|
+
"fastify",
|
|
8533
|
+
"hono",
|
|
8534
|
+
"nest",
|
|
8535
|
+
"validation",
|
|
8536
|
+
"business logic"
|
|
8537
|
+
],
|
|
8538
|
+
frontend: [
|
|
8539
|
+
"ui",
|
|
8540
|
+
"component",
|
|
8541
|
+
"page",
|
|
8542
|
+
"form",
|
|
8543
|
+
"button",
|
|
8544
|
+
"input",
|
|
8545
|
+
"modal",
|
|
8546
|
+
"dialog",
|
|
8547
|
+
"react",
|
|
8548
|
+
"vue",
|
|
8549
|
+
"svelte",
|
|
8550
|
+
"angular",
|
|
8551
|
+
"next",
|
|
8552
|
+
"nuxt",
|
|
8553
|
+
"solid",
|
|
8554
|
+
"css",
|
|
8555
|
+
"style",
|
|
8556
|
+
"tailwind",
|
|
8557
|
+
"layout",
|
|
8558
|
+
"responsive",
|
|
8559
|
+
"animation",
|
|
8560
|
+
"hook",
|
|
8561
|
+
"state",
|
|
8562
|
+
"context",
|
|
8563
|
+
"redux",
|
|
8564
|
+
"zustand",
|
|
8565
|
+
"jotai"
|
|
8566
|
+
],
|
|
8567
|
+
testing: [
|
|
8568
|
+
"test",
|
|
8569
|
+
"spec",
|
|
8570
|
+
"unit",
|
|
8571
|
+
"integration",
|
|
8572
|
+
"e2e",
|
|
8573
|
+
"jest",
|
|
8574
|
+
"vitest",
|
|
8575
|
+
"playwright",
|
|
8576
|
+
"cypress",
|
|
8577
|
+
"mocha",
|
|
8578
|
+
"chai",
|
|
8579
|
+
"mock",
|
|
8580
|
+
"stub",
|
|
8581
|
+
"fixture",
|
|
8582
|
+
"coverage",
|
|
8583
|
+
"assertion"
|
|
8584
|
+
],
|
|
8585
|
+
devops: [
|
|
8586
|
+
"docker",
|
|
8587
|
+
"kubernetes",
|
|
8588
|
+
"k8s",
|
|
8589
|
+
"ci",
|
|
8590
|
+
"cd",
|
|
8591
|
+
"pipeline",
|
|
8592
|
+
"deploy",
|
|
8593
|
+
"github actions",
|
|
8594
|
+
"vercel",
|
|
8595
|
+
"aws",
|
|
8596
|
+
"gcp",
|
|
8597
|
+
"azure",
|
|
8598
|
+
"terraform",
|
|
8599
|
+
"nginx",
|
|
8600
|
+
"caddy",
|
|
8601
|
+
"env",
|
|
8602
|
+
"environment",
|
|
8603
|
+
"config",
|
|
8604
|
+
"secret"
|
|
8605
|
+
],
|
|
8606
|
+
uxui: [
|
|
8607
|
+
"design",
|
|
8608
|
+
"ux",
|
|
8609
|
+
"user experience",
|
|
8610
|
+
"accessibility",
|
|
8611
|
+
"a11y",
|
|
8612
|
+
"color",
|
|
8613
|
+
"typography",
|
|
8614
|
+
"spacing",
|
|
8615
|
+
"prototype",
|
|
8616
|
+
"wireframe",
|
|
8617
|
+
"figma",
|
|
8618
|
+
"user flow",
|
|
8619
|
+
"interaction"
|
|
8620
|
+
]
|
|
8621
|
+
};
|
|
8622
|
+
DOMAIN_DEPENDENCY_ORDER = [
|
|
8623
|
+
"database",
|
|
8624
|
+
"backend",
|
|
8625
|
+
"frontend",
|
|
8626
|
+
"testing",
|
|
8627
|
+
"devops"
|
|
8628
|
+
];
|
|
8629
|
+
OrchestratorExecutor = class {
|
|
8630
|
+
static {
|
|
8631
|
+
__name(this, "OrchestratorExecutor");
|
|
8632
|
+
}
|
|
8633
|
+
/**
|
|
8634
|
+
* Main entry point - executes full orchestration
|
|
8635
|
+
*
|
|
8636
|
+
* @param command - The command being executed (e.g., 'task')
|
|
8637
|
+
* @param taskDescription - The task description from user
|
|
8638
|
+
* @param projectPath - Path to the project
|
|
8639
|
+
* @returns Full orchestrator context with loaded agents, skills, and subtasks
|
|
8640
|
+
*/
|
|
8641
|
+
async execute(command, taskDescription, projectPath) {
|
|
8642
|
+
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
8643
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
8644
|
+
const repoAnalysis = await this.loadRepoAnalysis(globalPath);
|
|
8645
|
+
const { domains, primary } = await this.detectDomains(
|
|
8646
|
+
taskDescription,
|
|
8647
|
+
projectId,
|
|
8648
|
+
repoAnalysis
|
|
8649
|
+
);
|
|
8650
|
+
const agents = await this.loadAgents(domains, projectId);
|
|
8651
|
+
const skills = await this.loadSkills(agents);
|
|
8652
|
+
const requiresFragmentation = this.shouldFragment(domains, taskDescription);
|
|
8653
|
+
let subtasks = null;
|
|
8654
|
+
if (requiresFragmentation && command === "task") {
|
|
8655
|
+
subtasks = await this.createSubtasks(
|
|
8656
|
+
taskDescription,
|
|
8657
|
+
domains,
|
|
8658
|
+
agents,
|
|
8659
|
+
projectId
|
|
8660
|
+
);
|
|
8661
|
+
}
|
|
8662
|
+
return {
|
|
8663
|
+
detectedDomains: domains,
|
|
8664
|
+
primaryDomain: primary,
|
|
8665
|
+
agents,
|
|
8666
|
+
skills,
|
|
8667
|
+
requiresFragmentation,
|
|
8668
|
+
subtasks,
|
|
8669
|
+
project: {
|
|
8670
|
+
id: projectId,
|
|
8671
|
+
ecosystem: repoAnalysis?.ecosystem || "unknown",
|
|
8672
|
+
conventions: repoAnalysis?.conventions || []
|
|
8673
|
+
}
|
|
8674
|
+
};
|
|
8675
|
+
}
|
|
8676
|
+
/**
|
|
8677
|
+
* Load repo-analysis.json for project context
|
|
8678
|
+
*/
|
|
8679
|
+
async loadRepoAnalysis(globalPath) {
|
|
8680
|
+
try {
|
|
8681
|
+
const analysisPath = path19.join(globalPath, "analysis", "repo-analysis.json");
|
|
8682
|
+
const content = await fs20.readFile(analysisPath, "utf-8");
|
|
8683
|
+
return JSON.parse(content);
|
|
8684
|
+
} catch (error) {
|
|
8685
|
+
if (isNotFoundError(error)) return null;
|
|
8686
|
+
console.warn("Failed to load repo-analysis.json:", error.message);
|
|
8687
|
+
return null;
|
|
8688
|
+
}
|
|
8689
|
+
}
|
|
8690
|
+
/**
|
|
8691
|
+
* Detect which domains are relevant for this task
|
|
8692
|
+
*
|
|
8693
|
+
* Uses keyword matching + project context to determine domains.
|
|
8694
|
+
* More intelligent than simple string matching - considers:
|
|
8695
|
+
* - Task description keywords
|
|
8696
|
+
* - Project technology stack
|
|
8697
|
+
* - Available agents
|
|
8698
|
+
*/
|
|
8699
|
+
async detectDomains(taskDescription, projectId, repoAnalysis) {
|
|
8700
|
+
const taskLower = taskDescription.toLowerCase();
|
|
8701
|
+
const detectedDomains = /* @__PURE__ */ new Map();
|
|
8702
|
+
for (const [domain, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
|
|
8703
|
+
let score = 0;
|
|
8704
|
+
for (const keyword of keywords) {
|
|
8705
|
+
if (taskLower.includes(keyword.toLowerCase())) {
|
|
8706
|
+
score += keyword.includes(" ") ? 3 : 1;
|
|
8707
|
+
}
|
|
8708
|
+
}
|
|
8709
|
+
if (score > 0) {
|
|
8710
|
+
detectedDomains.set(domain, score);
|
|
8711
|
+
}
|
|
8712
|
+
}
|
|
8713
|
+
if (repoAnalysis?.technologies) {
|
|
8714
|
+
const techStr = repoAnalysis.technologies.join(" ").toLowerCase();
|
|
8715
|
+
if (/react|vue|svelte|angular|next|nuxt/.test(techStr)) {
|
|
8716
|
+
const current = detectedDomains.get("frontend") || 0;
|
|
8717
|
+
if (current > 0) detectedDomains.set("frontend", current + 2);
|
|
8718
|
+
}
|
|
8719
|
+
if (/express|fastify|hono|nest|koa/.test(techStr)) {
|
|
8720
|
+
const current = detectedDomains.get("backend") || 0;
|
|
8721
|
+
if (current > 0) detectedDomains.set("backend", current + 2);
|
|
8722
|
+
}
|
|
8723
|
+
if (/prisma|drizzle|mongoose|typeorm|sequelize/.test(techStr)) {
|
|
8724
|
+
const current = detectedDomains.get("database") || 0;
|
|
8725
|
+
if (current > 0) detectedDomains.set("database", current + 2);
|
|
8726
|
+
}
|
|
8727
|
+
}
|
|
8728
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
8729
|
+
const availableAgents = await this.getAvailableAgentNames(globalPath);
|
|
8730
|
+
const validDomains = Array.from(detectedDomains.entries()).filter(([domain]) => {
|
|
8731
|
+
return availableAgents.some(
|
|
8732
|
+
(agent) => agent === domain || agent.includes(domain) || domain.includes(agent.replace(".md", ""))
|
|
8733
|
+
);
|
|
8734
|
+
}).sort((a, b) => b[1] - a[1]).map(([domain]) => domain);
|
|
8735
|
+
if (validDomains.length === 0) {
|
|
8736
|
+
return { domains: ["general"], primary: "general" };
|
|
8737
|
+
}
|
|
8738
|
+
const primary = validDomains[0];
|
|
8739
|
+
return { domains: validDomains, primary };
|
|
8740
|
+
}
|
|
8741
|
+
/**
|
|
8742
|
+
* Get list of available agent file names
|
|
8743
|
+
*/
|
|
8744
|
+
async getAvailableAgentNames(globalPath) {
|
|
8745
|
+
try {
|
|
8746
|
+
const agentsDir = path19.join(globalPath, "agents");
|
|
8747
|
+
const files = await fs20.readdir(agentsDir);
|
|
8748
|
+
return files.filter((f) => f.endsWith(".md")).map((f) => f.replace(".md", ""));
|
|
8749
|
+
} catch {
|
|
8750
|
+
return [];
|
|
8751
|
+
}
|
|
8752
|
+
}
|
|
8753
|
+
/**
|
|
8754
|
+
* Load agents for the detected domains
|
|
8755
|
+
*
|
|
8756
|
+
* Reads agent markdown files from {globalPath}/agents/
|
|
8757
|
+
* and extracts their content and skills from frontmatter.
|
|
8758
|
+
*/
|
|
8759
|
+
async loadAgents(domains, projectId) {
|
|
8760
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
8761
|
+
const agentsDir = path19.join(globalPath, "agents");
|
|
8762
|
+
const agents = [];
|
|
8763
|
+
for (const domain of domains) {
|
|
8764
|
+
const possibleNames = [
|
|
8765
|
+
`${domain}.md`,
|
|
8766
|
+
`${domain}-agent.md`,
|
|
8767
|
+
`prjct-${domain}.md`
|
|
8768
|
+
];
|
|
8769
|
+
for (const fileName of possibleNames) {
|
|
8770
|
+
const filePath = path19.join(agentsDir, fileName);
|
|
8771
|
+
try {
|
|
8772
|
+
const content = await fs20.readFile(filePath, "utf-8");
|
|
8773
|
+
const { frontmatter, body } = this.parseAgentFile(content);
|
|
8774
|
+
agents.push({
|
|
8775
|
+
name: fileName.replace(".md", ""),
|
|
8776
|
+
domain,
|
|
8777
|
+
content: body,
|
|
8778
|
+
skills: frontmatter.skills || [],
|
|
8779
|
+
filePath
|
|
8780
|
+
});
|
|
8781
|
+
break;
|
|
8782
|
+
} catch {
|
|
8783
|
+
continue;
|
|
8784
|
+
}
|
|
8785
|
+
}
|
|
8786
|
+
}
|
|
8787
|
+
return agents;
|
|
8788
|
+
}
|
|
8789
|
+
/**
|
|
8790
|
+
* Parse agent markdown file to extract frontmatter and body
|
|
8791
|
+
*/
|
|
8792
|
+
parseAgentFile(content) {
|
|
8793
|
+
const parsed = parseFrontmatter(content);
|
|
8794
|
+
const frontmatter = { ...parsed.frontmatter };
|
|
8795
|
+
if (typeof frontmatter.skills === "string") {
|
|
8796
|
+
frontmatter.skills = frontmatter.skills.split(",").map((s) => s.trim());
|
|
8797
|
+
}
|
|
8798
|
+
return {
|
|
8799
|
+
frontmatter,
|
|
8800
|
+
body: parsed.content
|
|
8801
|
+
};
|
|
8802
|
+
}
|
|
8803
|
+
/**
|
|
8804
|
+
* Load skills from agent frontmatter
|
|
8805
|
+
*
|
|
8806
|
+
* Skills are stored in ~/.claude/skills/{name}.md
|
|
8807
|
+
*/
|
|
8808
|
+
async loadSkills(agents) {
|
|
8809
|
+
const skillsDir = path19.join(os8.homedir(), ".claude", "skills");
|
|
8810
|
+
const skills = [];
|
|
8811
|
+
const loadedSkillNames = /* @__PURE__ */ new Set();
|
|
8812
|
+
for (const agent of agents) {
|
|
8813
|
+
for (const skillName of agent.skills) {
|
|
8814
|
+
if (loadedSkillNames.has(skillName)) continue;
|
|
8815
|
+
const skillPath = path19.join(skillsDir, `${skillName}.md`);
|
|
8816
|
+
try {
|
|
8817
|
+
const content = await fs20.readFile(skillPath, "utf-8");
|
|
8818
|
+
skills.push({
|
|
8819
|
+
name: skillName,
|
|
8820
|
+
content,
|
|
8821
|
+
filePath: skillPath
|
|
8822
|
+
});
|
|
8823
|
+
loadedSkillNames.add(skillName);
|
|
8824
|
+
} catch {
|
|
8825
|
+
console.warn(`Skill not found: ${skillName}`);
|
|
8826
|
+
}
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
return skills;
|
|
8830
|
+
}
|
|
8831
|
+
/**
|
|
8832
|
+
* Determine if task should be fragmented into subtasks
|
|
8833
|
+
*
|
|
8834
|
+
* Fragmentation is needed when:
|
|
8835
|
+
* - 3+ domains are involved
|
|
8836
|
+
* - Task explicitly mentions multiple areas
|
|
8837
|
+
* - Task is complex (many keywords)
|
|
8838
|
+
*/
|
|
8839
|
+
shouldFragment(domains, taskDescription) {
|
|
8840
|
+
if (domains.length >= 3) return true;
|
|
8841
|
+
const multiAreaIndicators = [
|
|
8842
|
+
"full stack",
|
|
8843
|
+
"fullstack",
|
|
8844
|
+
"end to end",
|
|
8845
|
+
"e2e",
|
|
8846
|
+
"complete feature",
|
|
8847
|
+
"from database to ui",
|
|
8848
|
+
"across layers"
|
|
8849
|
+
];
|
|
8850
|
+
const taskLower = taskDescription.toLowerCase();
|
|
8851
|
+
for (const indicator of multiAreaIndicators) {
|
|
8852
|
+
if (taskLower.includes(indicator)) return true;
|
|
8853
|
+
}
|
|
8854
|
+
const wordCount = taskDescription.split(/\s+/).length;
|
|
8855
|
+
if (wordCount > 30 && domains.length >= 2) return true;
|
|
8856
|
+
return false;
|
|
8857
|
+
}
|
|
8858
|
+
/**
|
|
8859
|
+
* Create subtasks for a fragmented task
|
|
8860
|
+
*
|
|
8861
|
+
* Orders subtasks by domain dependency (database -> backend -> frontend)
|
|
8862
|
+
* and stores them in state.json
|
|
8863
|
+
*/
|
|
8864
|
+
async createSubtasks(taskDescription, domains, agents, projectId) {
|
|
8865
|
+
const sortedDomains = [...domains].sort((a, b) => {
|
|
8866
|
+
const orderA = DOMAIN_DEPENDENCY_ORDER.indexOf(a);
|
|
8867
|
+
const orderB = DOMAIN_DEPENDENCY_ORDER.indexOf(b);
|
|
8868
|
+
return (orderA === -1 ? 99 : orderA) - (orderB === -1 ? 99 : orderB);
|
|
8869
|
+
});
|
|
8870
|
+
const subtasks = sortedDomains.map((domain, index) => {
|
|
8871
|
+
const agent = agents.find((a) => a.domain === domain);
|
|
8872
|
+
const agentFile = agent ? `${agent.name}.md` : `${domain}.md`;
|
|
8873
|
+
const dependsOn = sortedDomains.slice(0, index).map((d, i) => `subtask-${i + 1}`);
|
|
8874
|
+
return {
|
|
8875
|
+
id: `subtask-${index + 1}`,
|
|
8876
|
+
description: this.generateSubtaskDescription(taskDescription, domain),
|
|
8877
|
+
domain,
|
|
8878
|
+
agent: agentFile,
|
|
8879
|
+
status: index === 0 ? "in_progress" : "pending",
|
|
8880
|
+
dependsOn,
|
|
8881
|
+
order: index + 1
|
|
8882
|
+
};
|
|
8883
|
+
});
|
|
8884
|
+
await stateStorage.createSubtasks(
|
|
8885
|
+
projectId,
|
|
8886
|
+
subtasks.map((st) => ({
|
|
8887
|
+
id: st.id,
|
|
8888
|
+
description: st.description,
|
|
8889
|
+
domain: st.domain,
|
|
8890
|
+
agent: st.agent,
|
|
8891
|
+
dependsOn: st.dependsOn
|
|
8892
|
+
}))
|
|
8893
|
+
);
|
|
8894
|
+
return subtasks;
|
|
8895
|
+
}
|
|
8896
|
+
/**
|
|
8897
|
+
* Generate a domain-specific subtask description
|
|
8898
|
+
*/
|
|
8899
|
+
generateSubtaskDescription(fullTask, domain) {
|
|
8900
|
+
const domainDescriptions = {
|
|
8901
|
+
database: "Set up data layer: schema, models, migrations",
|
|
8902
|
+
backend: "Implement API: routes, controllers, services, validation",
|
|
8903
|
+
frontend: "Build UI: components, forms, state management",
|
|
8904
|
+
testing: "Write tests: unit, integration, e2e",
|
|
8905
|
+
devops: "Configure deployment: CI/CD, environment, containers",
|
|
8906
|
+
uxui: "Design user experience: flows, accessibility, styling"
|
|
8907
|
+
};
|
|
8908
|
+
const prefix = domainDescriptions[domain] || `Handle ${domain} aspects`;
|
|
8909
|
+
return `[${domain.toUpperCase()}] ${prefix} for: ${fullTask.substring(0, 80)}${fullTask.length > 80 ? "..." : ""}`;
|
|
8910
|
+
}
|
|
8911
|
+
};
|
|
8912
|
+
orchestratorExecutor = new OrchestratorExecutor();
|
|
8913
|
+
orchestrator_executor_default = orchestratorExecutor;
|
|
8914
|
+
}
|
|
8915
|
+
});
|
|
8916
|
+
|
|
8917
|
+
// core/agentic/command-executor.ts
|
|
8918
|
+
import fs21 from "fs";
|
|
8919
|
+
import path20 from "path";
|
|
8920
|
+
import os9 from "os";
|
|
8419
8921
|
function signalStart(commandName) {
|
|
8420
8922
|
try {
|
|
8421
|
-
const dir =
|
|
8422
|
-
if (!
|
|
8423
|
-
|
|
8923
|
+
const dir = path20.dirname(RUNNING_FILE);
|
|
8924
|
+
if (!fs21.existsSync(dir)) {
|
|
8925
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
8424
8926
|
}
|
|
8425
|
-
|
|
8927
|
+
fs21.writeFileSync(RUNNING_FILE, `/p:${commandName}`);
|
|
8426
8928
|
} catch (_error) {
|
|
8427
8929
|
}
|
|
8428
8930
|
}
|
|
8429
8931
|
function signalEnd() {
|
|
8430
8932
|
try {
|
|
8431
|
-
if (
|
|
8432
|
-
|
|
8933
|
+
if (fs21.existsSync(RUNNING_FILE)) {
|
|
8934
|
+
fs21.unlinkSync(RUNNING_FILE);
|
|
8433
8935
|
}
|
|
8434
8936
|
} catch (_error) {
|
|
8435
8937
|
}
|
|
@@ -8448,7 +8950,8 @@ var init_command_executor = __esm({
|
|
|
8448
8950
|
init_ground_truth();
|
|
8449
8951
|
init_plan_mode();
|
|
8450
8952
|
init_template_executor();
|
|
8451
|
-
|
|
8953
|
+
init_orchestrator_executor();
|
|
8954
|
+
RUNNING_FILE = path20.join(os9.homedir(), ".prjct-cli", ".running");
|
|
8452
8955
|
__name(signalStart, "signalStart");
|
|
8453
8956
|
__name(signalEnd, "signalEnd");
|
|
8454
8957
|
CommandExecutor = class {
|
|
@@ -8528,6 +9031,24 @@ var init_command_executor = __esm({
|
|
|
8528
9031
|
projectPath
|
|
8529
9032
|
);
|
|
8530
9033
|
const agenticInfo = template_executor_default.buildAgenticPrompt(agenticExecContext);
|
|
9034
|
+
let orchestratorContext = null;
|
|
9035
|
+
if (template_executor_default.requiresOrchestration(commandName) && taskDescription) {
|
|
9036
|
+
try {
|
|
9037
|
+
orchestratorContext = await orchestrator_executor_default.execute(
|
|
9038
|
+
commandName,
|
|
9039
|
+
taskDescription,
|
|
9040
|
+
projectPath
|
|
9041
|
+
);
|
|
9042
|
+
console.log(`\u{1F3AF} Orchestrator:`);
|
|
9043
|
+
console.log(` \u2192 Domains: ${orchestratorContext.detectedDomains.join(", ")}`);
|
|
9044
|
+
console.log(` \u2192 Agents: ${orchestratorContext.agents.map((a) => a.name).join(", ") || "none loaded"}`);
|
|
9045
|
+
if (orchestratorContext.requiresFragmentation && orchestratorContext.subtasks) {
|
|
9046
|
+
console.log(` \u2192 Subtasks: ${orchestratorContext.subtasks.length}`);
|
|
9047
|
+
}
|
|
9048
|
+
} catch (error) {
|
|
9049
|
+
console.warn(`\u26A0\uFE0F Orchestrator warning: ${error.message}`);
|
|
9050
|
+
}
|
|
9051
|
+
}
|
|
8531
9052
|
const context = {
|
|
8532
9053
|
...metadataContext,
|
|
8533
9054
|
agentsPath: agenticExecContext.paths.agentsDir,
|
|
@@ -8570,7 +9091,8 @@ var init_command_executor = __esm({
|
|
|
8570
9091
|
learnedPatterns,
|
|
8571
9092
|
null,
|
|
8572
9093
|
relevantMemories,
|
|
8573
|
-
planInfo
|
|
9094
|
+
planInfo,
|
|
9095
|
+
orchestratorContext
|
|
8574
9096
|
);
|
|
8575
9097
|
console.log(`\u{1F916} Template-first execution: Claude reads templates and decides`);
|
|
8576
9098
|
if (agenticInfo.requiresOrchestration) {
|
|
@@ -8597,6 +9119,7 @@ var init_command_executor = __esm({
|
|
|
8597
9119
|
groundTruth: groundTruthResult,
|
|
8598
9120
|
learnedPatterns,
|
|
8599
9121
|
relevantMemories,
|
|
9122
|
+
orchestratorContext,
|
|
8600
9123
|
memory: {
|
|
8601
9124
|
create: /* @__PURE__ */ __name((memory) => memory_system_default.createMemory(metadataContext.projectId, memory), "create"),
|
|
8602
9125
|
autoRemember: /* @__PURE__ */ __name((type, value, ctx) => memory_system_default.autoRemember(metadataContext.projectId, type, value, ctx), "autoRemember"),
|
|
@@ -8705,9 +9228,9 @@ var init_command_executor = __esm({
|
|
|
8705
9228
|
|
|
8706
9229
|
// core/infrastructure/update-checker.ts
|
|
8707
9230
|
import https from "https";
|
|
8708
|
-
import
|
|
8709
|
-
import
|
|
8710
|
-
import
|
|
9231
|
+
import fs22 from "fs";
|
|
9232
|
+
import path21 from "path";
|
|
9233
|
+
import os10 from "os";
|
|
8711
9234
|
import chalk from "chalk";
|
|
8712
9235
|
var UpdateChecker, update_checker_default;
|
|
8713
9236
|
var init_update_checker = __esm({
|
|
@@ -8723,8 +9246,8 @@ var init_update_checker = __esm({
|
|
|
8723
9246
|
checkInterval;
|
|
8724
9247
|
constructor() {
|
|
8725
9248
|
this.packageName = "prjct-cli";
|
|
8726
|
-
this.cacheDir =
|
|
8727
|
-
this.cacheFile =
|
|
9249
|
+
this.cacheDir = path21.join(os10.homedir(), ".prjct-cli", "config");
|
|
9250
|
+
this.cacheFile = path21.join(this.cacheDir, "update-cache.json");
|
|
8728
9251
|
this.checkInterval = 24 * 60 * 60 * 1e3;
|
|
8729
9252
|
}
|
|
8730
9253
|
/**
|
|
@@ -8732,8 +9255,8 @@ var init_update_checker = __esm({
|
|
|
8732
9255
|
*/
|
|
8733
9256
|
getCurrentVersion() {
|
|
8734
9257
|
try {
|
|
8735
|
-
const packageJsonPath =
|
|
8736
|
-
const packageJson = JSON.parse(
|
|
9258
|
+
const packageJsonPath = path21.join(__dirname, "..", "..", "package.json");
|
|
9259
|
+
const packageJson = JSON.parse(fs22.readFileSync(packageJsonPath, "utf8"));
|
|
8737
9260
|
return packageJson.version;
|
|
8738
9261
|
} catch (error) {
|
|
8739
9262
|
console.error("Error reading package version:", error.message);
|
|
@@ -8802,8 +9325,8 @@ var init_update_checker = __esm({
|
|
|
8802
9325
|
*/
|
|
8803
9326
|
readCache() {
|
|
8804
9327
|
try {
|
|
8805
|
-
if (
|
|
8806
|
-
const cache2 = JSON.parse(
|
|
9328
|
+
if (fs22.existsSync(this.cacheFile)) {
|
|
9329
|
+
const cache2 = JSON.parse(fs22.readFileSync(this.cacheFile, "utf8"));
|
|
8807
9330
|
return cache2;
|
|
8808
9331
|
}
|
|
8809
9332
|
} catch (_error) {
|
|
@@ -8815,10 +9338,10 @@ var init_update_checker = __esm({
|
|
|
8815
9338
|
*/
|
|
8816
9339
|
writeCache(data) {
|
|
8817
9340
|
try {
|
|
8818
|
-
if (!
|
|
8819
|
-
|
|
9341
|
+
if (!fs22.existsSync(this.cacheDir)) {
|
|
9342
|
+
fs22.mkdirSync(this.cacheDir, { recursive: true });
|
|
8820
9343
|
}
|
|
8821
|
-
|
|
9344
|
+
fs22.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2), "utf8");
|
|
8822
9345
|
} catch (_error) {
|
|
8823
9346
|
}
|
|
8824
9347
|
}
|
|
@@ -8981,15 +9504,15 @@ var init_output = __esm({
|
|
|
8981
9504
|
});
|
|
8982
9505
|
|
|
8983
9506
|
// core/infrastructure/agent-detector.ts
|
|
8984
|
-
import
|
|
8985
|
-
import
|
|
9507
|
+
import fs23 from "fs";
|
|
9508
|
+
import path22 from "path";
|
|
8986
9509
|
function isClaudeEnvironment() {
|
|
8987
9510
|
if (process.env.CLAUDE_AGENT || process.env.ANTHROPIC_CLAUDE) return true;
|
|
8988
9511
|
if (global.mcp || process.env.MCP_AVAILABLE) return true;
|
|
8989
9512
|
const projectRoot = process.cwd();
|
|
8990
|
-
if (
|
|
9513
|
+
if (fs23.existsSync(path22.join(projectRoot, "CLAUDE.md"))) return true;
|
|
8991
9514
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
8992
|
-
if (
|
|
9515
|
+
if (fs23.existsSync(path22.join(homeDir, ".claude"))) return true;
|
|
8993
9516
|
const cwd = process.cwd();
|
|
8994
9517
|
if (cwd.includes("/.claude/") || cwd.includes("/claude-workspace/")) return true;
|
|
8995
9518
|
return false;
|
|
@@ -9102,8 +9625,8 @@ var init_agent_detector = __esm({
|
|
|
9102
9625
|
});
|
|
9103
9626
|
|
|
9104
9627
|
// core/agentic/agent-router.ts
|
|
9105
|
-
import
|
|
9106
|
-
import
|
|
9628
|
+
import fs24 from "fs/promises";
|
|
9629
|
+
import path23 from "path";
|
|
9107
9630
|
var AgentRouter, agent_router_default;
|
|
9108
9631
|
var init_agent_router = __esm({
|
|
9109
9632
|
"core/agentic/agent-router.ts"() {
|
|
@@ -9132,12 +9655,12 @@ var init_agent_router = __esm({
|
|
|
9132
9655
|
async loadAvailableAgents() {
|
|
9133
9656
|
if (!this.agentsPath) return [];
|
|
9134
9657
|
try {
|
|
9135
|
-
const files = await
|
|
9658
|
+
const files = await fs24.readdir(this.agentsPath);
|
|
9136
9659
|
const agents = [];
|
|
9137
9660
|
for (const file of files) {
|
|
9138
9661
|
if (file.endsWith(".md")) {
|
|
9139
9662
|
const name = file.replace(".md", "");
|
|
9140
|
-
const content = await
|
|
9663
|
+
const content = await fs24.readFile(path23.join(this.agentsPath, file), "utf-8");
|
|
9141
9664
|
agents.push({ name, content });
|
|
9142
9665
|
}
|
|
9143
9666
|
}
|
|
@@ -9162,8 +9685,8 @@ var init_agent_router = __esm({
|
|
|
9162
9685
|
async loadAgent(name) {
|
|
9163
9686
|
if (!this.agentsPath) return null;
|
|
9164
9687
|
try {
|
|
9165
|
-
const filePath =
|
|
9166
|
-
const content = await
|
|
9688
|
+
const filePath = path23.join(this.agentsPath, `${name}.md`);
|
|
9689
|
+
const content = await fs24.readFile(filePath, "utf-8");
|
|
9167
9690
|
return { name, content };
|
|
9168
9691
|
} catch (error) {
|
|
9169
9692
|
if (!isNotFoundError(error)) {
|
|
@@ -9191,7 +9714,7 @@ var init_agent_router = __esm({
|
|
|
9191
9714
|
*/
|
|
9192
9715
|
async logUsage(task, agent, _projectPath) {
|
|
9193
9716
|
try {
|
|
9194
|
-
const logPath =
|
|
9717
|
+
const logPath = path23.join(
|
|
9195
9718
|
process.env.HOME || "",
|
|
9196
9719
|
".prjct-cli",
|
|
9197
9720
|
"projects",
|
|
@@ -9204,7 +9727,7 @@ var init_agent_router = __esm({
|
|
|
9204
9727
|
agent: typeof agent === "string" ? agent : agent.name,
|
|
9205
9728
|
projectId: this.projectId
|
|
9206
9729
|
}) + "\n";
|
|
9207
|
-
await
|
|
9730
|
+
await fs24.appendFile(logPath, entry);
|
|
9208
9731
|
} catch (error) {
|
|
9209
9732
|
if (!isNotFoundError(error)) {
|
|
9210
9733
|
console.error(`Agent usage log error: ${error.message}`);
|
|
@@ -9359,8 +9882,8 @@ var init_agent_service = __esm({
|
|
|
9359
9882
|
});
|
|
9360
9883
|
|
|
9361
9884
|
// core/domain/analyzer.ts
|
|
9362
|
-
import
|
|
9363
|
-
import
|
|
9885
|
+
import fs25 from "fs/promises";
|
|
9886
|
+
import path24 from "path";
|
|
9364
9887
|
import { promisify as promisify3 } from "util";
|
|
9365
9888
|
import { exec as execCallback2 } from "child_process";
|
|
9366
9889
|
var exec3, CodebaseAnalyzer, analyzer, analyzer_default2;
|
|
@@ -9385,8 +9908,8 @@ var init_analyzer2 = __esm({
|
|
|
9385
9908
|
*/
|
|
9386
9909
|
async readPackageJson() {
|
|
9387
9910
|
try {
|
|
9388
|
-
const packagePath =
|
|
9389
|
-
const content = await
|
|
9911
|
+
const packagePath = path24.join(this.projectPath, "package.json");
|
|
9912
|
+
const content = await fs25.readFile(packagePath, "utf-8");
|
|
9390
9913
|
return JSON.parse(content);
|
|
9391
9914
|
} catch (error) {
|
|
9392
9915
|
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
@@ -9400,8 +9923,8 @@ var init_analyzer2 = __esm({
|
|
|
9400
9923
|
*/
|
|
9401
9924
|
async readCargoToml() {
|
|
9402
9925
|
try {
|
|
9403
|
-
const cargoPath =
|
|
9404
|
-
return await
|
|
9926
|
+
const cargoPath = path24.join(this.projectPath, "Cargo.toml");
|
|
9927
|
+
return await fs25.readFile(cargoPath, "utf-8");
|
|
9405
9928
|
} catch (error) {
|
|
9406
9929
|
if (isNotFoundError(error)) {
|
|
9407
9930
|
return null;
|
|
@@ -9414,8 +9937,8 @@ var init_analyzer2 = __esm({
|
|
|
9414
9937
|
*/
|
|
9415
9938
|
async readRequirements() {
|
|
9416
9939
|
try {
|
|
9417
|
-
const reqPath =
|
|
9418
|
-
return await
|
|
9940
|
+
const reqPath = path24.join(this.projectPath, "requirements.txt");
|
|
9941
|
+
return await fs25.readFile(reqPath, "utf-8");
|
|
9419
9942
|
} catch (error) {
|
|
9420
9943
|
if (isNotFoundError(error)) {
|
|
9421
9944
|
return null;
|
|
@@ -9428,8 +9951,8 @@ var init_analyzer2 = __esm({
|
|
|
9428
9951
|
*/
|
|
9429
9952
|
async readGoMod() {
|
|
9430
9953
|
try {
|
|
9431
|
-
const goModPath =
|
|
9432
|
-
return await
|
|
9954
|
+
const goModPath = path24.join(this.projectPath, "go.mod");
|
|
9955
|
+
return await fs25.readFile(goModPath, "utf-8");
|
|
9433
9956
|
} catch (error) {
|
|
9434
9957
|
if (isNotFoundError(error)) {
|
|
9435
9958
|
return null;
|
|
@@ -9442,8 +9965,8 @@ var init_analyzer2 = __esm({
|
|
|
9442
9965
|
*/
|
|
9443
9966
|
async readGemfile() {
|
|
9444
9967
|
try {
|
|
9445
|
-
const gemfilePath =
|
|
9446
|
-
return await
|
|
9968
|
+
const gemfilePath = path24.join(this.projectPath, "Gemfile");
|
|
9969
|
+
return await fs25.readFile(gemfilePath, "utf-8");
|
|
9447
9970
|
} catch (error) {
|
|
9448
9971
|
if (isNotFoundError(error)) {
|
|
9449
9972
|
return null;
|
|
@@ -9456,8 +9979,8 @@ var init_analyzer2 = __esm({
|
|
|
9456
9979
|
*/
|
|
9457
9980
|
async readMixExs() {
|
|
9458
9981
|
try {
|
|
9459
|
-
const mixPath =
|
|
9460
|
-
return await
|
|
9982
|
+
const mixPath = path24.join(this.projectPath, "mix.exs");
|
|
9983
|
+
return await fs25.readFile(mixPath, "utf-8");
|
|
9461
9984
|
} catch (error) {
|
|
9462
9985
|
if (isNotFoundError(error)) {
|
|
9463
9986
|
return null;
|
|
@@ -9470,8 +9993,8 @@ var init_analyzer2 = __esm({
|
|
|
9470
9993
|
*/
|
|
9471
9994
|
async readPomXml() {
|
|
9472
9995
|
try {
|
|
9473
|
-
const pomPath =
|
|
9474
|
-
return await
|
|
9996
|
+
const pomPath = path24.join(this.projectPath, "pom.xml");
|
|
9997
|
+
return await fs25.readFile(pomPath, "utf-8");
|
|
9475
9998
|
} catch (error) {
|
|
9476
9999
|
if (isNotFoundError(error)) {
|
|
9477
10000
|
return null;
|
|
@@ -9484,8 +10007,8 @@ var init_analyzer2 = __esm({
|
|
|
9484
10007
|
*/
|
|
9485
10008
|
async readComposerJson() {
|
|
9486
10009
|
try {
|
|
9487
|
-
const composerPath =
|
|
9488
|
-
const content = await
|
|
10010
|
+
const composerPath = path24.join(this.projectPath, "composer.json");
|
|
10011
|
+
const content = await fs25.readFile(composerPath, "utf-8");
|
|
9489
10012
|
return JSON.parse(content);
|
|
9490
10013
|
} catch (error) {
|
|
9491
10014
|
if (isNotFoundError(error) || error instanceof SyntaxError) {
|
|
@@ -9499,8 +10022,8 @@ var init_analyzer2 = __esm({
|
|
|
9499
10022
|
*/
|
|
9500
10023
|
async readPyprojectToml() {
|
|
9501
10024
|
try {
|
|
9502
|
-
const pyprojectPath =
|
|
9503
|
-
return await
|
|
10025
|
+
const pyprojectPath = path24.join(this.projectPath, "pyproject.toml");
|
|
10026
|
+
return await fs25.readFile(pyprojectPath, "utf-8");
|
|
9504
10027
|
} catch (error) {
|
|
9505
10028
|
if (isNotFoundError(error)) {
|
|
9506
10029
|
return null;
|
|
@@ -9536,7 +10059,7 @@ var init_analyzer2 = __esm({
|
|
|
9536
10059
|
*/
|
|
9537
10060
|
async listConfigFiles() {
|
|
9538
10061
|
try {
|
|
9539
|
-
const entries = await
|
|
10062
|
+
const entries = await fs25.readdir(this.projectPath);
|
|
9540
10063
|
const configPatterns = [
|
|
9541
10064
|
/^package\.json$/,
|
|
9542
10065
|
/^Cargo\.toml$/,
|
|
@@ -9566,7 +10089,7 @@ var init_analyzer2 = __esm({
|
|
|
9566
10089
|
*/
|
|
9567
10090
|
async listDirectories() {
|
|
9568
10091
|
try {
|
|
9569
|
-
const entries = await
|
|
10092
|
+
const entries = await fs25.readdir(this.projectPath, { withFileTypes: true });
|
|
9570
10093
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
9571
10094
|
} catch (error) {
|
|
9572
10095
|
if (isNotFoundError(error)) {
|
|
@@ -9634,7 +10157,7 @@ var init_analyzer2 = __esm({
|
|
|
9634
10157
|
*/
|
|
9635
10158
|
async fileExists(filename) {
|
|
9636
10159
|
try {
|
|
9637
|
-
await
|
|
10160
|
+
await fs25.access(path24.join(this.projectPath, filename));
|
|
9638
10161
|
return true;
|
|
9639
10162
|
} catch (error) {
|
|
9640
10163
|
if (isNotFoundError(error)) {
|
|
@@ -9648,8 +10171,8 @@ var init_analyzer2 = __esm({
|
|
|
9648
10171
|
*/
|
|
9649
10172
|
async readFile(relativePath) {
|
|
9650
10173
|
try {
|
|
9651
|
-
const fullPath =
|
|
9652
|
-
return await
|
|
10174
|
+
const fullPath = path24.join(this.projectPath, relativePath);
|
|
10175
|
+
return await fs25.readFile(fullPath, "utf-8");
|
|
9653
10176
|
} catch (error) {
|
|
9654
10177
|
if (isNotFoundError(error)) {
|
|
9655
10178
|
return null;
|
|
@@ -9678,15 +10201,15 @@ var init_analyzer2 = __esm({
|
|
|
9678
10201
|
});
|
|
9679
10202
|
|
|
9680
10203
|
// core/context/generator.ts
|
|
9681
|
-
import
|
|
9682
|
-
import
|
|
10204
|
+
import fs26 from "fs/promises";
|
|
10205
|
+
import path25 from "path";
|
|
9683
10206
|
import { exec as exec4 } from "child_process";
|
|
9684
10207
|
import { promisify as promisify4 } from "util";
|
|
9685
10208
|
async function generateContext(projectId, repoPath) {
|
|
9686
10209
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
9687
10210
|
const contextPath = path_manager_default.getContextPath(projectId);
|
|
9688
10211
|
const storage = getStorage(projectId);
|
|
9689
|
-
await
|
|
10212
|
+
await fs26.mkdir(contextPath, { recursive: true });
|
|
9690
10213
|
const project = await storage.read(["project"]) || {};
|
|
9691
10214
|
const taskPaths = await storage.list(["task"]);
|
|
9692
10215
|
const featurePaths = await storage.list(["feature"]);
|
|
@@ -9752,8 +10275,8 @@ async function getPackageData(repoPath) {
|
|
|
9752
10275
|
scripts: {}
|
|
9753
10276
|
};
|
|
9754
10277
|
try {
|
|
9755
|
-
const pkgPath =
|
|
9756
|
-
const pkg = JSON.parse(await
|
|
10278
|
+
const pkgPath = path25.join(repoPath, "package.json");
|
|
10279
|
+
const pkg = JSON.parse(await fs26.readFile(pkgPath, "utf-8"));
|
|
9757
10280
|
data.dependencies = pkg.dependencies || {};
|
|
9758
10281
|
data.devDependencies = pkg.devDependencies || {};
|
|
9759
10282
|
data.scripts = pkg.scripts || {};
|
|
@@ -9762,7 +10285,7 @@ async function getPackageData(repoPath) {
|
|
|
9762
10285
|
return data;
|
|
9763
10286
|
}
|
|
9764
10287
|
async function generateClaudeMd(contextPath, projectId, project, tasks, features, ideas, agents, gitData, pkgData, repoPath) {
|
|
9765
|
-
const projectName = project.name ||
|
|
10288
|
+
const projectName = project.name || path25.basename(repoPath);
|
|
9766
10289
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
9767
10290
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
9768
10291
|
const activeFeatures = features.filter((f) => f.status === "in_progress" || f.status === "active");
|
|
@@ -9837,7 +10360,7 @@ ${agents.length > 0 ? agents.map((a) => `- **${a.name}**: ${a.role || "Specialis
|
|
|
9837
10360
|
\u2514\u2500\u2500 pending.json
|
|
9838
10361
|
\`\`\`
|
|
9839
10362
|
`;
|
|
9840
|
-
await
|
|
10363
|
+
await fs26.writeFile(path25.join(contextPath, "CLAUDE.md"), content, "utf-8");
|
|
9841
10364
|
}
|
|
9842
10365
|
async function generateNowMd(contextPath, tasks) {
|
|
9843
10366
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
@@ -9852,7 +10375,7 @@ async function generateNowMd(contextPath, tasks) {
|
|
|
9852
10375
|
|
|
9853
10376
|
_No active task. Use /p:now to start._
|
|
9854
10377
|
`;
|
|
9855
|
-
await
|
|
10378
|
+
await fs26.writeFile(path25.join(contextPath, "now.md"), content, "utf-8");
|
|
9856
10379
|
}
|
|
9857
10380
|
async function generateQueueMd(contextPath, tasks) {
|
|
9858
10381
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
@@ -9860,7 +10383,7 @@ async function generateQueueMd(contextPath, tasks) {
|
|
|
9860
10383
|
|
|
9861
10384
|
${pendingTasks.length > 0 ? pendingTasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue. Use /p:next to add tasks._"}
|
|
9862
10385
|
`;
|
|
9863
|
-
await
|
|
10386
|
+
await fs26.writeFile(path25.join(contextPath, "queue.md"), content, "utf-8");
|
|
9864
10387
|
}
|
|
9865
10388
|
async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
9866
10389
|
const content = `# PROJECT SUMMARY
|
|
@@ -9880,7 +10403,7 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
|
9880
10403
|
- Production: ${Object.keys(pkgData.dependencies).length}
|
|
9881
10404
|
- Dev: ${Object.keys(pkgData.devDependencies).length}
|
|
9882
10405
|
`;
|
|
9883
|
-
await
|
|
10406
|
+
await fs26.writeFile(path25.join(contextPath, "summary.md"), content, "utf-8");
|
|
9884
10407
|
}
|
|
9885
10408
|
var execAsync2;
|
|
9886
10409
|
var init_generator = __esm({
|
|
@@ -9904,7 +10427,7 @@ var analysis_exports = {};
|
|
|
9904
10427
|
__export(analysis_exports, {
|
|
9905
10428
|
AnalysisCommands: () => AnalysisCommands
|
|
9906
10429
|
});
|
|
9907
|
-
import
|
|
10430
|
+
import path26 from "path";
|
|
9908
10431
|
var AnalysisCommands;
|
|
9909
10432
|
var init_analysis2 = __esm({
|
|
9910
10433
|
"core/commands/analysis.ts"() {
|
|
@@ -9984,7 +10507,7 @@ var init_analysis2 = __esm({
|
|
|
9984
10507
|
lines.push("# Repository Analysis\n");
|
|
9985
10508
|
lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
9986
10509
|
`);
|
|
9987
|
-
const projectName =
|
|
10510
|
+
const projectName = path26.basename(projectPath);
|
|
9988
10511
|
lines.push(`## Project: ${projectName}
|
|
9989
10512
|
`);
|
|
9990
10513
|
lines.push("## Stack Detected\n");
|
|
@@ -10108,7 +10631,7 @@ var planning_exports = {};
|
|
|
10108
10631
|
__export(planning_exports, {
|
|
10109
10632
|
PlanningCommands: () => PlanningCommands
|
|
10110
10633
|
});
|
|
10111
|
-
import
|
|
10634
|
+
import path27 from "path";
|
|
10112
10635
|
async function getAnalysisCommands() {
|
|
10113
10636
|
if (!_analysisCommands) {
|
|
10114
10637
|
const { AnalysisCommands: AnalysisCommands2 } = await Promise.resolve().then(() => (init_analysis2(), analysis_exports));
|
|
@@ -10173,7 +10696,7 @@ var init_planning = __esm({
|
|
|
10173
10696
|
}, null, 2)
|
|
10174
10697
|
};
|
|
10175
10698
|
for (const [filePath, content] of Object.entries(baseFiles)) {
|
|
10176
|
-
await tool_registry_default.get("Write")(
|
|
10699
|
+
await tool_registry_default.get("Write")(path27.join(globalPath, filePath), content);
|
|
10177
10700
|
}
|
|
10178
10701
|
const isEmpty = await this._detectEmptyDirectory(projectPath);
|
|
10179
10702
|
const hasCode = await this._detectExistingCode(projectPath);
|
|
@@ -10194,7 +10717,7 @@ var init_planning = __esm({
|
|
|
10194
10717
|
return { success: true, mode: "blank_no_idea", projectId };
|
|
10195
10718
|
}
|
|
10196
10719
|
output_default.spin("architect mode...");
|
|
10197
|
-
const sessionPath =
|
|
10720
|
+
const sessionPath = path27.join(globalPath, "planning", "architect-session.md");
|
|
10198
10721
|
const sessionContent = `# Architect Session
|
|
10199
10722
|
|
|
10200
10723
|
## Idea
|
|
@@ -10336,7 +10859,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10336
10859
|
if (!initResult.success) return initResult;
|
|
10337
10860
|
console.log("\u{1F3D7}\uFE0F Architect Mode - Code Generation\n");
|
|
10338
10861
|
const globalPath = await this.getGlobalProjectPath(projectPath);
|
|
10339
|
-
const planPath =
|
|
10862
|
+
const planPath = path27.join(globalPath, "planning", "architect-session.md");
|
|
10340
10863
|
let planContent;
|
|
10341
10864
|
try {
|
|
10342
10865
|
planContent = await file_helper_exports.readFile(planPath);
|
|
@@ -10410,7 +10933,7 @@ ${steps}`);
|
|
|
10410
10933
|
if (isComplex) {
|
|
10411
10934
|
output_default.spin("analyzing idea...");
|
|
10412
10935
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
10413
|
-
const sessionPath =
|
|
10936
|
+
const sessionPath = path27.join(globalPath, "planning", "architect-session.md");
|
|
10414
10937
|
const sessionContent = `# Architect Session
|
|
10415
10938
|
|
|
10416
10939
|
## Idea
|
|
@@ -10465,10 +10988,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10465
10988
|
if (!featureName) {
|
|
10466
10989
|
output_default.spin("loading specs...");
|
|
10467
10990
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
10468
|
-
const specsPath2 =
|
|
10991
|
+
const specsPath2 = path27.join(globalPath2, "planning", "specs");
|
|
10469
10992
|
try {
|
|
10470
|
-
const
|
|
10471
|
-
const files = await
|
|
10993
|
+
const fs28 = await import("fs/promises");
|
|
10994
|
+
const files = await fs28.readdir(specsPath2);
|
|
10472
10995
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
10473
10996
|
if (specs.length === 0) {
|
|
10474
10997
|
output_default.warn("no specs yet");
|
|
@@ -10490,10 +11013,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10490
11013
|
}
|
|
10491
11014
|
output_default.spin("creating spec...");
|
|
10492
11015
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
10493
|
-
const specsPath =
|
|
11016
|
+
const specsPath = path27.join(globalPath, "planning", "specs");
|
|
10494
11017
|
await file_helper_exports.ensureDir(specsPath);
|
|
10495
11018
|
const slug = featureName.toLowerCase().replace(/\s+/g, "-");
|
|
10496
|
-
const specFile =
|
|
11019
|
+
const specFile = path27.join(specsPath, `${slug}.md`);
|
|
10497
11020
|
const specContent = `# Specification: ${featureName}
|
|
10498
11021
|
|
|
10499
11022
|
## Overview
|
|
@@ -11133,18 +11656,18 @@ var init_workflow = __esm({
|
|
|
11133
11656
|
});
|
|
11134
11657
|
|
|
11135
11658
|
// core/utils/project-commands.ts
|
|
11136
|
-
import
|
|
11659
|
+
import path28 from "path";
|
|
11137
11660
|
async function detectPackageManager(projectPath, pkg) {
|
|
11138
11661
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
11139
11662
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
11140
11663
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
11141
11664
|
if (declared?.startsWith("bun@")) return "bun";
|
|
11142
11665
|
if (declared?.startsWith("npm@")) return "npm";
|
|
11143
|
-
if (await fileExists(
|
|
11144
|
-
if (await fileExists(
|
|
11145
|
-
if (await fileExists(
|
|
11146
|
-
if (await fileExists(
|
|
11147
|
-
if (await fileExists(
|
|
11666
|
+
if (await fileExists(path28.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
11667
|
+
if (await fileExists(path28.join(projectPath, "yarn.lock"))) return "yarn";
|
|
11668
|
+
if (await fileExists(path28.join(projectPath, "bun.lockb"))) return "bun";
|
|
11669
|
+
if (await fileExists(path28.join(projectPath, "bun.lock"))) return "bun";
|
|
11670
|
+
if (await fileExists(path28.join(projectPath, "package-lock.json"))) return "npm";
|
|
11148
11671
|
return "npm";
|
|
11149
11672
|
}
|
|
11150
11673
|
function pmRun(pm, scriptName) {
|
|
@@ -11160,7 +11683,7 @@ function pmTest(pm) {
|
|
|
11160
11683
|
return "npm test";
|
|
11161
11684
|
}
|
|
11162
11685
|
async function detectProjectCommands(projectPath) {
|
|
11163
|
-
const pkgPath =
|
|
11686
|
+
const pkgPath = path28.join(projectPath, "package.json");
|
|
11164
11687
|
const pkg = await readJson(pkgPath, null);
|
|
11165
11688
|
if (pkg) {
|
|
11166
11689
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -11177,27 +11700,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
11177
11700
|
}
|
|
11178
11701
|
return result;
|
|
11179
11702
|
}
|
|
11180
|
-
if (await fileExists(
|
|
11703
|
+
if (await fileExists(path28.join(projectPath, "pytest.ini"))) {
|
|
11181
11704
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
11182
11705
|
}
|
|
11183
|
-
const pyproject = await readFile(
|
|
11706
|
+
const pyproject = await readFile(path28.join(projectPath, "pyproject.toml"), "");
|
|
11184
11707
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
11185
11708
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
11186
11709
|
}
|
|
11187
|
-
if (await fileExists(
|
|
11710
|
+
if (await fileExists(path28.join(projectPath, "Cargo.toml"))) {
|
|
11188
11711
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
11189
11712
|
}
|
|
11190
|
-
if (await fileExists(
|
|
11713
|
+
if (await fileExists(path28.join(projectPath, "go.mod"))) {
|
|
11191
11714
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
11192
11715
|
}
|
|
11193
11716
|
const files = await listFiles(projectPath);
|
|
11194
11717
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
11195
11718
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
11196
11719
|
}
|
|
11197
|
-
if (await fileExists(
|
|
11720
|
+
if (await fileExists(path28.join(projectPath, "pom.xml"))) {
|
|
11198
11721
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
11199
11722
|
}
|
|
11200
|
-
if (await fileExists(
|
|
11723
|
+
if (await fileExists(path28.join(projectPath, "gradlew")) && (await fileExists(path28.join(projectPath, "build.gradle")) || await fileExists(path28.join(projectPath, "build.gradle.kts")))) {
|
|
11201
11724
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
11202
11725
|
}
|
|
11203
11726
|
return { stack: "unknown" };
|
|
@@ -11214,7 +11737,7 @@ var init_project_commands = __esm({
|
|
|
11214
11737
|
});
|
|
11215
11738
|
|
|
11216
11739
|
// core/commands/shipping.ts
|
|
11217
|
-
import
|
|
11740
|
+
import path29 from "path";
|
|
11218
11741
|
var ShippingCommands;
|
|
11219
11742
|
var init_shipping = __esm({
|
|
11220
11743
|
"core/commands/shipping.ts"() {
|
|
@@ -11343,7 +11866,7 @@ ${result.stderr}`.trim();
|
|
|
11343
11866
|
*/
|
|
11344
11867
|
async _bumpVersion(projectPath) {
|
|
11345
11868
|
try {
|
|
11346
|
-
const pkgPath =
|
|
11869
|
+
const pkgPath = path29.join(projectPath, "package.json");
|
|
11347
11870
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
11348
11871
|
const oldVersion = pkg?.version || "0.0.0";
|
|
11349
11872
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -11365,7 +11888,7 @@ ${result.stderr}`.trim();
|
|
|
11365
11888
|
*/
|
|
11366
11889
|
async _updateChangelog(feature, version, projectPath) {
|
|
11367
11890
|
try {
|
|
11368
|
-
const changelogPath =
|
|
11891
|
+
const changelogPath = path29.join(projectPath, "CHANGELOG.md");
|
|
11369
11892
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
11370
11893
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
11371
11894
|
|
|
@@ -11761,7 +12284,7 @@ var init_registry = __esm({
|
|
|
11761
12284
|
});
|
|
11762
12285
|
|
|
11763
12286
|
// core/commands/analytics.ts
|
|
11764
|
-
import
|
|
12287
|
+
import path30 from "path";
|
|
11765
12288
|
var AnalyticsCommands;
|
|
11766
12289
|
var init_analytics = __esm({
|
|
11767
12290
|
"core/commands/analytics.ts"() {
|
|
@@ -11786,7 +12309,7 @@ var init_analytics = __esm({
|
|
|
11786
12309
|
output_default.fail("no project ID");
|
|
11787
12310
|
return { success: false, error: "No project ID found" };
|
|
11788
12311
|
}
|
|
11789
|
-
const projectName =
|
|
12312
|
+
const projectName = path30.basename(projectPath);
|
|
11790
12313
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
11791
12314
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
11792
12315
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -12024,7 +12547,7 @@ ${catInfo?.title || cat}:`);
|
|
|
12024
12547
|
});
|
|
12025
12548
|
|
|
12026
12549
|
// core/commands/cleanup.ts
|
|
12027
|
-
import
|
|
12550
|
+
import path31 from "path";
|
|
12028
12551
|
async function cleanupMemory(projectPath) {
|
|
12029
12552
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
12030
12553
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -12040,7 +12563,7 @@ async function cleanupMemory(projectPath) {
|
|
|
12040
12563
|
results.totalSize += sizeMB;
|
|
12041
12564
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
12042
12565
|
if (rotated) {
|
|
12043
|
-
results.rotated.push(
|
|
12566
|
+
results.rotated.push(path31.basename(filePath));
|
|
12044
12567
|
results.freedSpace += sizeMB;
|
|
12045
12568
|
}
|
|
12046
12569
|
}
|
|
@@ -12147,7 +12670,7 @@ var init_cleanup = __esm({
|
|
|
12147
12670
|
});
|
|
12148
12671
|
|
|
12149
12672
|
// core/commands/design.ts
|
|
12150
|
-
import
|
|
12673
|
+
import path32 from "path";
|
|
12151
12674
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
12152
12675
|
try {
|
|
12153
12676
|
const designType = options.type || "architecture";
|
|
@@ -12159,7 +12682,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
12159
12682
|
const designTarget = target || "system";
|
|
12160
12683
|
output_default.spin(`designing ${designType}...`);
|
|
12161
12684
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
12162
|
-
const designsPath =
|
|
12685
|
+
const designsPath = path32.join(
|
|
12163
12686
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12164
12687
|
"planning",
|
|
12165
12688
|
"designs"
|
|
@@ -12199,7 +12722,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
12199
12722
|
break;
|
|
12200
12723
|
}
|
|
12201
12724
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
12202
|
-
const designFilePath =
|
|
12725
|
+
const designFilePath = path32.join(designsPath, designFileName);
|
|
12203
12726
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
12204
12727
|
await memoryService.log(projectPath, "design_created", {
|
|
12205
12728
|
type: designType,
|
|
@@ -12223,7 +12746,7 @@ var init_design = __esm({
|
|
|
12223
12746
|
});
|
|
12224
12747
|
|
|
12225
12748
|
// core/commands/snapshots.ts
|
|
12226
|
-
import
|
|
12749
|
+
import path33 from "path";
|
|
12227
12750
|
async function recover(projectPath = process.cwd()) {
|
|
12228
12751
|
try {
|
|
12229
12752
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -12275,7 +12798,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
12275
12798
|
output_default.fail("no project ID");
|
|
12276
12799
|
return { success: false, error: "No project ID found" };
|
|
12277
12800
|
}
|
|
12278
|
-
const snapshotsPath =
|
|
12801
|
+
const snapshotsPath = path33.join(
|
|
12279
12802
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12280
12803
|
"snapshots"
|
|
12281
12804
|
);
|
|
@@ -12296,7 +12819,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
12296
12819
|
cwd: projectPath,
|
|
12297
12820
|
encoding: "utf-8"
|
|
12298
12821
|
});
|
|
12299
|
-
const snapshotFile =
|
|
12822
|
+
const snapshotFile = path33.join(snapshotsPath, "history.json");
|
|
12300
12823
|
let history2 = { snapshots: [], current: -1 };
|
|
12301
12824
|
try {
|
|
12302
12825
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -12336,11 +12859,11 @@ async function redo(projectPath = process.cwd()) {
|
|
|
12336
12859
|
output_default.fail("no project ID");
|
|
12337
12860
|
return { success: false, error: "No project ID found" };
|
|
12338
12861
|
}
|
|
12339
|
-
const snapshotsPath =
|
|
12862
|
+
const snapshotsPath = path33.join(
|
|
12340
12863
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12341
12864
|
"snapshots"
|
|
12342
12865
|
);
|
|
12343
|
-
const snapshotFile =
|
|
12866
|
+
const snapshotFile = path33.join(snapshotsPath, "history.json");
|
|
12344
12867
|
let history2;
|
|
12345
12868
|
try {
|
|
12346
12869
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -12399,11 +12922,11 @@ async function history(projectPath = process.cwd()) {
|
|
|
12399
12922
|
output_default.fail("no project ID");
|
|
12400
12923
|
return { success: false, error: "No project ID found" };
|
|
12401
12924
|
}
|
|
12402
|
-
const snapshotsPath =
|
|
12925
|
+
const snapshotsPath = path33.join(
|
|
12403
12926
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12404
12927
|
"snapshots"
|
|
12405
12928
|
);
|
|
12406
|
-
const snapshotFile =
|
|
12929
|
+
const snapshotFile = path33.join(snapshotsPath, "history.json");
|
|
12407
12930
|
let snapshotHistory;
|
|
12408
12931
|
try {
|
|
12409
12932
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -12509,8 +13032,8 @@ var init_maintenance = __esm({
|
|
|
12509
13032
|
});
|
|
12510
13033
|
|
|
12511
13034
|
// core/commands/setup.ts
|
|
12512
|
-
import
|
|
12513
|
-
import
|
|
13035
|
+
import path34 from "path";
|
|
13036
|
+
import fs27 from "fs";
|
|
12514
13037
|
import chalk4 from "chalk";
|
|
12515
13038
|
var SetupCommands;
|
|
12516
13039
|
var init_setup2 = __esm({
|
|
@@ -12620,7 +13143,7 @@ var init_setup2 = __esm({
|
|
|
12620
13143
|
try {
|
|
12621
13144
|
const claudeDir = path_manager_default.getClaudeDir();
|
|
12622
13145
|
const settingsPath = path_manager_default.getClaudeSettingsPath();
|
|
12623
|
-
const statusLinePath =
|
|
13146
|
+
const statusLinePath = path34.join(claudeDir, "prjct-statusline.sh");
|
|
12624
13147
|
const scriptContent = `#!/bin/bash
|
|
12625
13148
|
# prjct Status Line for Claude Code
|
|
12626
13149
|
# Shows version update notifications and current task
|
|
@@ -12678,11 +13201,11 @@ fi
|
|
|
12678
13201
|
# Default: show prjct branding
|
|
12679
13202
|
echo "\u26A1 prjct"
|
|
12680
13203
|
`;
|
|
12681
|
-
|
|
13204
|
+
fs27.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
12682
13205
|
let settings = {};
|
|
12683
|
-
if (
|
|
13206
|
+
if (fs27.existsSync(settingsPath)) {
|
|
12684
13207
|
try {
|
|
12685
|
-
settings = JSON.parse(
|
|
13208
|
+
settings = JSON.parse(fs27.readFileSync(settingsPath, "utf8"));
|
|
12686
13209
|
} catch (_error) {
|
|
12687
13210
|
}
|
|
12688
13211
|
}
|
|
@@ -12690,7 +13213,7 @@ echo "\u26A1 prjct"
|
|
|
12690
13213
|
type: "command",
|
|
12691
13214
|
command: statusLinePath
|
|
12692
13215
|
};
|
|
12693
|
-
|
|
13216
|
+
fs27.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
12694
13217
|
return { success: true };
|
|
12695
13218
|
} catch (error) {
|
|
12696
13219
|
return { success: false, error: error.message };
|
|
@@ -13323,7 +13846,7 @@ var require_package = __commonJS({
|
|
|
13323
13846
|
"package.json"(exports, module) {
|
|
13324
13847
|
module.exports = {
|
|
13325
13848
|
name: "prjct-cli",
|
|
13326
|
-
version: "0.
|
|
13849
|
+
version: "0.35.0",
|
|
13327
13850
|
description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
|
|
13328
13851
|
main: "core/index.ts",
|
|
13329
13852
|
bin: {
|