prjct-cli 0.25.2 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +233 -0
- package/CLAUDE.md +117 -110
- package/core/infrastructure/command-installer.ts +27 -0
- package/core/infrastructure/setup.ts +99 -0
- package/dist/bin/prjct.mjs +525 -267
- package/package.json +1 -1
- package/templates/agentic/agents/uxui.md +8 -0
- package/templates/agentic/skill-integration.md +311 -0
- package/templates/agentic/subagent-generation.md +28 -12
- package/templates/commands/bug.md +72 -17
- package/templates/commands/cleanup.md +74 -10
- package/templates/commands/done.md +158 -8
- package/templates/commands/git.md +21 -5
- package/templates/commands/merge.md +202 -0
- package/templates/commands/p.md +32 -0
- package/templates/commands/pause.md +40 -7
- package/templates/commands/resume.md +113 -33
- package/templates/commands/review.md +276 -0
- package/templates/commands/ship.md +193 -17
- package/templates/commands/sync.md +442 -47
- package/templates/commands/task.md +168 -542
- package/templates/commands/test.md +75 -3
- package/templates/commands/verify.md +204 -0
- package/templates/config/skill-mappings.json +87 -0
- package/templates/global/CLAUDE.md +38 -52
- package/templates/global/docs/commands.md +29 -31
- package/templates/hooks/prjct-session-start.sh +50 -0
- package/templates/skills/prjct-done/SKILL.md +97 -0
- package/templates/skills/prjct-ship/SKILL.md +150 -0
- package/templates/skills/prjct-sync/SKILL.md +108 -0
- package/templates/skills/prjct-task/SKILL.md +101 -0
- package/templates/subagents/domain/backend.md +1 -0
- package/templates/subagents/domain/devops.md +1 -0
- package/templates/subagents/domain/frontend.md +1 -0
- package/templates/subagents/domain/testing.md +1 -0
- package/templates/subagents/workflow/prjct-planner.md +1 -0
- package/templates/subagents/workflow/prjct-shipper.md +1 -0
package/dist/bin/prjct.mjs
CHANGED
|
@@ -10,10 +10,10 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
10
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
11
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
12
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
13
|
-
var __glob = (map) => (
|
|
14
|
-
var fn = map[
|
|
13
|
+
var __glob = (map) => (path32) => {
|
|
14
|
+
var fn = map[path32];
|
|
15
15
|
if (fn) return fn();
|
|
16
|
-
throw new Error("Module not found in bundle: " +
|
|
16
|
+
throw new Error("Module not found in bundle: " + path32);
|
|
17
17
|
};
|
|
18
18
|
var __esm = (fn, res) => function __init() {
|
|
19
19
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -1567,6 +1567,7 @@ var init_command_installer = __esm({
|
|
|
1567
1567
|
};
|
|
1568
1568
|
}
|
|
1569
1569
|
try {
|
|
1570
|
+
await this.installRouter();
|
|
1570
1571
|
await fs7.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1571
1572
|
const commandFiles = await this.getCommandFiles();
|
|
1572
1573
|
const installed = [];
|
|
@@ -1694,6 +1695,22 @@ var init_command_installer = __esm({
|
|
|
1694
1695
|
return false;
|
|
1695
1696
|
}
|
|
1696
1697
|
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Install the p.md router to ~/.claude/commands/
|
|
1700
|
+
* This enables the "p. task" natural language trigger
|
|
1701
|
+
* Claude Code bug #2422 prevents subdirectory slash command discovery
|
|
1702
|
+
*/
|
|
1703
|
+
async installRouter() {
|
|
1704
|
+
try {
|
|
1705
|
+
const routerSource = path7.join(this.templatesDir, "p.md");
|
|
1706
|
+
const routerDest = path7.join(this.homeDir, ".claude", "commands", "p.md");
|
|
1707
|
+
const content = await fs7.readFile(routerSource, "utf-8");
|
|
1708
|
+
await fs7.writeFile(routerDest, content, "utf-8");
|
|
1709
|
+
return true;
|
|
1710
|
+
} catch {
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1697
1714
|
/**
|
|
1698
1715
|
* Sync commands - intelligent update that detects and removes orphans
|
|
1699
1716
|
*/
|
|
@@ -1709,6 +1726,7 @@ var init_command_installer = __esm({
|
|
|
1709
1726
|
};
|
|
1710
1727
|
}
|
|
1711
1728
|
try {
|
|
1729
|
+
await this.installRouter();
|
|
1712
1730
|
await fs7.mkdir(this.claudeCommandsPath, { recursive: true });
|
|
1713
1731
|
const templateFiles = await this.getCommandFiles();
|
|
1714
1732
|
let installedFiles = [];
|
|
@@ -1777,6 +1795,9 @@ __export(setup_exports, {
|
|
|
1777
1795
|
run: () => run
|
|
1778
1796
|
});
|
|
1779
1797
|
import { execSync } from "child_process";
|
|
1798
|
+
import fs8 from "fs";
|
|
1799
|
+
import path8 from "path";
|
|
1800
|
+
import os4 from "os";
|
|
1780
1801
|
async function hasClaudeCodeCLI() {
|
|
1781
1802
|
try {
|
|
1782
1803
|
execSync("which claude", { stdio: "ignore" });
|
|
@@ -1829,11 +1850,190 @@ async function run() {
|
|
|
1829
1850
|
results.configAction = configResult.action;
|
|
1830
1851
|
}
|
|
1831
1852
|
await command_installer_default.installDocs();
|
|
1853
|
+
await installStatusLine();
|
|
1854
|
+
await installSessionHook();
|
|
1855
|
+
await installSkills();
|
|
1832
1856
|
}
|
|
1833
1857
|
await editors_config_default.saveConfig(VERSION, command_installer_default.getInstallPath());
|
|
1858
|
+
await migrateProjectsCliVersion();
|
|
1834
1859
|
showResults(results);
|
|
1835
1860
|
return results;
|
|
1836
1861
|
}
|
|
1862
|
+
async function migrateProjectsCliVersion() {
|
|
1863
|
+
try {
|
|
1864
|
+
const projectsDir = path8.join(os4.homedir(), ".prjct-cli", "projects");
|
|
1865
|
+
if (!fs8.existsSync(projectsDir)) {
|
|
1866
|
+
return;
|
|
1867
|
+
}
|
|
1868
|
+
const projectDirs = fs8.readdirSync(projectsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
1869
|
+
let migrated = 0;
|
|
1870
|
+
for (const projectId of projectDirs) {
|
|
1871
|
+
const projectJsonPath = path8.join(projectsDir, projectId, "project.json");
|
|
1872
|
+
if (!fs8.existsSync(projectJsonPath)) {
|
|
1873
|
+
continue;
|
|
1874
|
+
}
|
|
1875
|
+
try {
|
|
1876
|
+
const content = fs8.readFileSync(projectJsonPath, "utf8");
|
|
1877
|
+
const project = JSON.parse(content);
|
|
1878
|
+
if (project.cliVersion !== VERSION) {
|
|
1879
|
+
project.cliVersion = VERSION;
|
|
1880
|
+
fs8.writeFileSync(projectJsonPath, JSON.stringify(project, null, 2));
|
|
1881
|
+
migrated++;
|
|
1882
|
+
}
|
|
1883
|
+
} catch {
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
if (migrated > 0) {
|
|
1887
|
+
console.log(` ${GREEN}\u2713${NC} Updated ${migrated} project(s) to v${VERSION}`);
|
|
1888
|
+
}
|
|
1889
|
+
} catch {
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
async function installStatusLine() {
|
|
1893
|
+
try {
|
|
1894
|
+
const claudeDir = path8.join(os4.homedir(), ".claude");
|
|
1895
|
+
const settingsPath = path8.join(claudeDir, "settings.json");
|
|
1896
|
+
const statusLinePath = path8.join(claudeDir, "prjct-statusline.sh");
|
|
1897
|
+
if (!fs8.existsSync(claudeDir)) {
|
|
1898
|
+
fs8.mkdirSync(claudeDir, { recursive: true });
|
|
1899
|
+
}
|
|
1900
|
+
const scriptContent = `#!/bin/bash
|
|
1901
|
+
# prjct Status Line for Claude Code
|
|
1902
|
+
# Shows version update notifications and current task
|
|
1903
|
+
|
|
1904
|
+
# Current CLI version (embedded at install time)
|
|
1905
|
+
CLI_VERSION="${VERSION}"
|
|
1906
|
+
|
|
1907
|
+
# Read JSON context from stdin (provided by Claude Code)
|
|
1908
|
+
read -r json
|
|
1909
|
+
|
|
1910
|
+
# Extract cwd from JSON
|
|
1911
|
+
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1912
|
+
|
|
1913
|
+
# Check if this is a prjct project
|
|
1914
|
+
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
1915
|
+
if [[ -f "$CONFIG" ]]; then
|
|
1916
|
+
# Extract projectId
|
|
1917
|
+
PROJECT_ID=$(grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | sed 's/.*"projectId"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1918
|
+
|
|
1919
|
+
if [[ -n "$PROJECT_ID" ]]; then
|
|
1920
|
+
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
1921
|
+
|
|
1922
|
+
# Check version mismatch
|
|
1923
|
+
if [[ -f "$PROJECT_JSON" ]]; then
|
|
1924
|
+
PROJECT_VERSION=$(grep -o '"cliVersion"[[:space:]]*:[[:space:]]*"[^"]*"' "$PROJECT_JSON" | sed 's/.*"cliVersion"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1925
|
+
|
|
1926
|
+
# If no cliVersion or different version, show update notice
|
|
1927
|
+
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
1928
|
+
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
1929
|
+
exit 0
|
|
1930
|
+
fi
|
|
1931
|
+
else
|
|
1932
|
+
# No project.json means project needs sync
|
|
1933
|
+
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
1934
|
+
exit 0
|
|
1935
|
+
fi
|
|
1936
|
+
|
|
1937
|
+
# Show current task if exists
|
|
1938
|
+
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
1939
|
+
if [[ -f "$STATE" ]]; then
|
|
1940
|
+
TASK=$(grep -o '"description"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1941
|
+
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"status"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
1942
|
+
|
|
1943
|
+
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
1944
|
+
# Truncate task to 40 chars
|
|
1945
|
+
TASK_SHORT="\${TASK:0:40}"
|
|
1946
|
+
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
1947
|
+
echo "\u{1F3AF} $TASK_SHORT"
|
|
1948
|
+
exit 0
|
|
1949
|
+
fi
|
|
1950
|
+
fi
|
|
1951
|
+
fi
|
|
1952
|
+
fi
|
|
1953
|
+
|
|
1954
|
+
# Default: show prjct branding
|
|
1955
|
+
echo "\u26A1 prjct"
|
|
1956
|
+
`;
|
|
1957
|
+
fs8.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
1958
|
+
let settings = {};
|
|
1959
|
+
if (fs8.existsSync(settingsPath)) {
|
|
1960
|
+
try {
|
|
1961
|
+
settings = JSON.parse(fs8.readFileSync(settingsPath, "utf8"));
|
|
1962
|
+
} catch {
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
settings.statusLine = {
|
|
1966
|
+
type: "command",
|
|
1967
|
+
command: statusLinePath
|
|
1968
|
+
};
|
|
1969
|
+
fs8.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1970
|
+
} catch {
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
async function installSessionHook() {
|
|
1974
|
+
try {
|
|
1975
|
+
const claudeDir = path8.join(os4.homedir(), ".claude");
|
|
1976
|
+
const hooksDir = path8.join(claudeDir, "hooks");
|
|
1977
|
+
const hookPath = path8.join(hooksDir, "prjct-session-start.sh");
|
|
1978
|
+
const settingsPath = path8.join(claudeDir, "settings.json");
|
|
1979
|
+
if (!fs8.existsSync(hooksDir)) {
|
|
1980
|
+
fs8.mkdirSync(hooksDir, { recursive: true });
|
|
1981
|
+
}
|
|
1982
|
+
const templateHookPath = path8.join(__dirname, "../../templates/hooks/prjct-session-start.sh");
|
|
1983
|
+
if (fs8.existsSync(templateHookPath)) {
|
|
1984
|
+
const hookContent = fs8.readFileSync(templateHookPath, "utf8");
|
|
1985
|
+
fs8.writeFileSync(hookPath, hookContent, { mode: 493 });
|
|
1986
|
+
}
|
|
1987
|
+
let settings = {};
|
|
1988
|
+
if (fs8.existsSync(settingsPath)) {
|
|
1989
|
+
try {
|
|
1990
|
+
settings = JSON.parse(fs8.readFileSync(settingsPath, "utf8"));
|
|
1991
|
+
} catch {
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
const hooks = settings.hooks || {};
|
|
1995
|
+
hooks.SessionStart = [
|
|
1996
|
+
{
|
|
1997
|
+
matcher: "startup",
|
|
1998
|
+
hooks: [
|
|
1999
|
+
{
|
|
2000
|
+
type: "command",
|
|
2001
|
+
command: hookPath
|
|
2002
|
+
}
|
|
2003
|
+
]
|
|
2004
|
+
}
|
|
2005
|
+
];
|
|
2006
|
+
settings.hooks = hooks;
|
|
2007
|
+
fs8.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
2008
|
+
console.log(` ${GREEN}\u2713${NC} SessionStart hook installed`);
|
|
2009
|
+
} catch {
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
async function installSkills() {
|
|
2013
|
+
try {
|
|
2014
|
+
const claudeDir = path8.join(os4.homedir(), ".claude");
|
|
2015
|
+
const skillsDir = path8.join(claudeDir, "skills");
|
|
2016
|
+
const templateSkillsDir = path8.join(__dirname, "../../templates/skills");
|
|
2017
|
+
const skillNames = ["prjct-task", "prjct-sync", "prjct-done", "prjct-ship"];
|
|
2018
|
+
let installed = 0;
|
|
2019
|
+
for (const skillName of skillNames) {
|
|
2020
|
+
const destDir = path8.join(skillsDir, skillName);
|
|
2021
|
+
const templatePath = path8.join(templateSkillsDir, skillName, "SKILL.md");
|
|
2022
|
+
if (fs8.existsSync(templatePath)) {
|
|
2023
|
+
if (!fs8.existsSync(destDir)) {
|
|
2024
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
2025
|
+
}
|
|
2026
|
+
const skillContent = fs8.readFileSync(templatePath, "utf8");
|
|
2027
|
+
fs8.writeFileSync(path8.join(destDir, "SKILL.md"), skillContent);
|
|
2028
|
+
installed++;
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
if (installed > 0) {
|
|
2032
|
+
console.log(` ${GREEN}\u2713${NC} ${installed} Skills installed`);
|
|
2033
|
+
}
|
|
2034
|
+
} catch {
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
1837
2037
|
function showResults(results) {
|
|
1838
2038
|
console.log("");
|
|
1839
2039
|
if (results.claudeInstalled) {
|
|
@@ -1874,6 +2074,10 @@ var init_setup = __esm({
|
|
|
1874
2074
|
__name(installClaudeCode, "installClaudeCode");
|
|
1875
2075
|
__name(run, "run");
|
|
1876
2076
|
setup_default = { run };
|
|
2077
|
+
__name(migrateProjectsCliVersion, "migrateProjectsCliVersion");
|
|
2078
|
+
__name(installStatusLine, "installStatusLine");
|
|
2079
|
+
__name(installSessionHook, "installSessionHook");
|
|
2080
|
+
__name(installSkills, "installSkills");
|
|
1877
2081
|
__name(showResults, "showResults");
|
|
1878
2082
|
}
|
|
1879
2083
|
});
|
|
@@ -1979,6 +2183,8 @@ var init_project = __esm({
|
|
|
1979
2183
|
repoPath: z3.string(),
|
|
1980
2184
|
description: z3.string().optional(),
|
|
1981
2185
|
version: z3.string().optional(),
|
|
2186
|
+
cliVersion: z3.string().optional(),
|
|
2187
|
+
// prjct-cli version used to sync
|
|
1982
2188
|
techStack: z3.array(z3.string()),
|
|
1983
2189
|
fileCount: z3.number(),
|
|
1984
2190
|
commitCount: z3.number(),
|
|
@@ -2401,8 +2607,8 @@ var init_schemas2 = __esm({
|
|
|
2401
2607
|
});
|
|
2402
2608
|
|
|
2403
2609
|
// core/agentic/template-loader.ts
|
|
2404
|
-
import
|
|
2405
|
-
import
|
|
2610
|
+
import fs9 from "fs/promises";
|
|
2611
|
+
import path9 from "path";
|
|
2406
2612
|
function updateLruOrder(key) {
|
|
2407
2613
|
const index = cacheOrder.indexOf(key);
|
|
2408
2614
|
if (index > -1) cacheOrder.splice(index, 1);
|
|
@@ -2440,9 +2646,9 @@ async function load(commandName) {
|
|
|
2440
2646
|
updateLruOrder(commandName);
|
|
2441
2647
|
return cache.get(commandName);
|
|
2442
2648
|
}
|
|
2443
|
-
const templatePath =
|
|
2649
|
+
const templatePath = path9.join(TEMPLATES_DIR, `${commandName}.md`);
|
|
2444
2650
|
try {
|
|
2445
|
-
const rawContent = await
|
|
2651
|
+
const rawContent = await fs9.readFile(templatePath, "utf-8");
|
|
2446
2652
|
const parsed = parseFrontmatter(rawContent);
|
|
2447
2653
|
evictLru();
|
|
2448
2654
|
cache.set(commandName, parsed);
|
|
@@ -2465,7 +2671,7 @@ var init_template_loader = __esm({
|
|
|
2465
2671
|
"core/agentic/template-loader.ts"() {
|
|
2466
2672
|
"use strict";
|
|
2467
2673
|
init_errors();
|
|
2468
|
-
TEMPLATES_DIR =
|
|
2674
|
+
TEMPLATES_DIR = path9.join(__dirname, "..", "..", "templates", "commands");
|
|
2469
2675
|
MAX_CACHE_SIZE = 50;
|
|
2470
2676
|
cache = /* @__PURE__ */ new Map();
|
|
2471
2677
|
cacheOrder = [];
|
|
@@ -2485,7 +2691,7 @@ var init_template_loader = __esm({
|
|
|
2485
2691
|
});
|
|
2486
2692
|
|
|
2487
2693
|
// core/agentic/context-builder.ts
|
|
2488
|
-
import
|
|
2694
|
+
import fs10 from "fs/promises";
|
|
2489
2695
|
var ContextBuilder, contextBuilder, context_builder_default;
|
|
2490
2696
|
var init_context_builder = __esm({
|
|
2491
2697
|
"core/agentic/context-builder.ts"() {
|
|
@@ -2563,7 +2769,7 @@ var init_context_builder = __esm({
|
|
|
2563
2769
|
for (const [, filePath] of filteredEntries) {
|
|
2564
2770
|
if (this._cache.has(filePath)) {
|
|
2565
2771
|
try {
|
|
2566
|
-
const stat = await
|
|
2772
|
+
const stat = await fs10.stat(filePath);
|
|
2567
2773
|
const cachedMtime = this._mtimes.get(filePath);
|
|
2568
2774
|
if (!cachedMtime || stat.mtimeMs > cachedMtime) {
|
|
2569
2775
|
this._cache.delete(filePath);
|
|
@@ -2586,7 +2792,7 @@ var init_context_builder = __esm({
|
|
|
2586
2792
|
if (uncachedEntries.length > 0) {
|
|
2587
2793
|
const readPromises = uncachedEntries.map(async ([key, filePath]) => {
|
|
2588
2794
|
try {
|
|
2589
|
-
const [content, stat] = await Promise.all([
|
|
2795
|
+
const [content, stat] = await Promise.all([fs10.readFile(filePath, "utf-8"), fs10.stat(filePath)]);
|
|
2590
2796
|
return { key, filePath, content, mtime: stat.mtimeMs };
|
|
2591
2797
|
} catch {
|
|
2592
2798
|
return { key, filePath, content: null, mtime: null };
|
|
@@ -2656,7 +2862,7 @@ var init_context_builder = __esm({
|
|
|
2656
2862
|
if (uncachedPaths.length > 0) {
|
|
2657
2863
|
const readPromises = uncachedPaths.map(async (filePath) => {
|
|
2658
2864
|
try {
|
|
2659
|
-
const content = await
|
|
2865
|
+
const content = await fs10.readFile(filePath, "utf-8");
|
|
2660
2866
|
return { filePath, content };
|
|
2661
2867
|
} catch {
|
|
2662
2868
|
return { filePath, content: null };
|
|
@@ -2687,7 +2893,7 @@ var init_context_builder = __esm({
|
|
|
2687
2893
|
*/
|
|
2688
2894
|
async fileExists(filePath) {
|
|
2689
2895
|
try {
|
|
2690
|
-
await
|
|
2896
|
+
await fs10.access(filePath);
|
|
2691
2897
|
return true;
|
|
2692
2898
|
} catch {
|
|
2693
2899
|
return false;
|
|
@@ -2892,8 +3098,8 @@ var init_cache = __esm({
|
|
|
2892
3098
|
});
|
|
2893
3099
|
|
|
2894
3100
|
// core/storage/storage-manager.ts
|
|
2895
|
-
import
|
|
2896
|
-
import
|
|
3101
|
+
import fs11 from "fs/promises";
|
|
3102
|
+
import path10 from "path";
|
|
2897
3103
|
var StorageManager;
|
|
2898
3104
|
var init_storage_manager = __esm({
|
|
2899
3105
|
"core/storage/storage-manager.ts"() {
|
|
@@ -2936,7 +3142,7 @@ var init_storage_manager = __esm({
|
|
|
2936
3142
|
}
|
|
2937
3143
|
const filePath = this.getStoragePath(projectId);
|
|
2938
3144
|
try {
|
|
2939
|
-
const content = await
|
|
3145
|
+
const content = await fs11.readFile(filePath, "utf-8");
|
|
2940
3146
|
const data = JSON.parse(content);
|
|
2941
3147
|
this.cache.set(projectId, data);
|
|
2942
3148
|
return data;
|
|
@@ -2950,13 +3156,13 @@ var init_storage_manager = __esm({
|
|
|
2950
3156
|
async write(projectId, data) {
|
|
2951
3157
|
const storagePath = this.getStoragePath(projectId);
|
|
2952
3158
|
const contextPath = this.getContextPath(projectId, this.getMdFilename());
|
|
2953
|
-
await
|
|
2954
|
-
await
|
|
3159
|
+
await fs11.mkdir(path10.dirname(storagePath), { recursive: true });
|
|
3160
|
+
await fs11.mkdir(path10.dirname(contextPath), { recursive: true });
|
|
2955
3161
|
const tempPath = `${storagePath}.${Date.now()}.tmp`;
|
|
2956
|
-
await
|
|
2957
|
-
await
|
|
3162
|
+
await fs11.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
3163
|
+
await fs11.rename(tempPath, storagePath);
|
|
2958
3164
|
const md2 = this.toMarkdown(data);
|
|
2959
|
-
await
|
|
3165
|
+
await fs11.writeFile(contextPath, md2, "utf-8");
|
|
2960
3166
|
this.cache.set(projectId, data);
|
|
2961
3167
|
}
|
|
2962
3168
|
/**
|
|
@@ -3004,7 +3210,7 @@ var init_storage_manager = __esm({
|
|
|
3004
3210
|
async exists(projectId) {
|
|
3005
3211
|
const filePath = this.getStoragePath(projectId);
|
|
3006
3212
|
try {
|
|
3007
|
-
await
|
|
3213
|
+
await fs11.access(filePath);
|
|
3008
3214
|
return true;
|
|
3009
3215
|
} catch {
|
|
3010
3216
|
return false;
|
|
@@ -4055,9 +4261,9 @@ var init_shipped_storage = __esm({
|
|
|
4055
4261
|
});
|
|
4056
4262
|
|
|
4057
4263
|
// core/storage/storage.ts
|
|
4058
|
-
import
|
|
4059
|
-
import
|
|
4060
|
-
import
|
|
4264
|
+
import fs12 from "fs/promises";
|
|
4265
|
+
import path11 from "path";
|
|
4266
|
+
import os5 from "os";
|
|
4061
4267
|
function getStorage(projectId) {
|
|
4062
4268
|
return new FileStorage(projectId);
|
|
4063
4269
|
}
|
|
@@ -4074,7 +4280,7 @@ var init_storage = __esm({
|
|
|
4074
4280
|
basePath;
|
|
4075
4281
|
constructor(projectId) {
|
|
4076
4282
|
this.projectId = projectId;
|
|
4077
|
-
this.basePath =
|
|
4283
|
+
this.basePath = path11.join(os5.homedir(), ".prjct-cli/projects", projectId, "data");
|
|
4078
4284
|
}
|
|
4079
4285
|
/**
|
|
4080
4286
|
* Convert path array to file path
|
|
@@ -4083,17 +4289,17 @@ var init_storage = __esm({
|
|
|
4083
4289
|
*/
|
|
4084
4290
|
pathToFile(pathArray) {
|
|
4085
4291
|
if (pathArray.length === 1) {
|
|
4086
|
-
return
|
|
4292
|
+
return path11.join(this.basePath, `${pathArray[0]}.json`);
|
|
4087
4293
|
}
|
|
4088
4294
|
const dir = pathArray[0] + "s";
|
|
4089
4295
|
const rest = pathArray.slice(1);
|
|
4090
4296
|
const filename = rest.join("/") + ".json";
|
|
4091
|
-
return
|
|
4297
|
+
return path11.join(this.basePath, dir, filename);
|
|
4092
4298
|
}
|
|
4093
4299
|
async write(pathArray, data) {
|
|
4094
4300
|
const filePath = this.pathToFile(pathArray);
|
|
4095
|
-
await
|
|
4096
|
-
await
|
|
4301
|
+
await fs12.mkdir(path11.dirname(filePath), { recursive: true });
|
|
4302
|
+
await fs12.writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
4097
4303
|
eventBus.publish({
|
|
4098
4304
|
type: inferEventType(pathArray, "write"),
|
|
4099
4305
|
path: pathArray,
|
|
@@ -4108,16 +4314,16 @@ var init_storage = __esm({
|
|
|
4108
4314
|
async read(pathArray) {
|
|
4109
4315
|
const filePath = this.pathToFile(pathArray);
|
|
4110
4316
|
try {
|
|
4111
|
-
const content = await
|
|
4317
|
+
const content = await fs12.readFile(filePath, "utf-8");
|
|
4112
4318
|
return JSON.parse(content);
|
|
4113
4319
|
} catch {
|
|
4114
4320
|
return null;
|
|
4115
4321
|
}
|
|
4116
4322
|
}
|
|
4117
4323
|
async list(prefix) {
|
|
4118
|
-
const dir =
|
|
4324
|
+
const dir = path11.join(this.basePath, prefix[0] + "s");
|
|
4119
4325
|
try {
|
|
4120
|
-
const files = await
|
|
4326
|
+
const files = await fs12.readdir(dir);
|
|
4121
4327
|
return files.filter((f) => f.endsWith(".json") && f !== "index.json").map((f) => [...prefix, f.replace(".json", "")]);
|
|
4122
4328
|
} catch {
|
|
4123
4329
|
return [];
|
|
@@ -4126,7 +4332,7 @@ var init_storage = __esm({
|
|
|
4126
4332
|
async delete(pathArray) {
|
|
4127
4333
|
const filePath = this.pathToFile(pathArray);
|
|
4128
4334
|
try {
|
|
4129
|
-
await
|
|
4335
|
+
await fs12.unlink(filePath);
|
|
4130
4336
|
eventBus.publish({
|
|
4131
4337
|
type: inferEventType(pathArray, "delete"),
|
|
4132
4338
|
path: pathArray,
|
|
@@ -4143,7 +4349,7 @@ var init_storage = __esm({
|
|
|
4143
4349
|
async exists(pathArray) {
|
|
4144
4350
|
const filePath = this.pathToFile(pathArray);
|
|
4145
4351
|
try {
|
|
4146
|
-
await
|
|
4352
|
+
await fs12.access(filePath);
|
|
4147
4353
|
return true;
|
|
4148
4354
|
} catch {
|
|
4149
4355
|
return false;
|
|
@@ -4153,10 +4359,10 @@ var init_storage = __esm({
|
|
|
4153
4359
|
* Update collection index
|
|
4154
4360
|
*/
|
|
4155
4361
|
async updateIndex(collection, id, action) {
|
|
4156
|
-
const indexPath =
|
|
4362
|
+
const indexPath = path11.join(this.basePath, collection + "s", "index.json");
|
|
4157
4363
|
let index = { ids: [], updatedAt: "" };
|
|
4158
4364
|
try {
|
|
4159
|
-
const content = await
|
|
4365
|
+
const content = await fs12.readFile(indexPath, "utf-8");
|
|
4160
4366
|
index = JSON.parse(content);
|
|
4161
4367
|
} catch {
|
|
4162
4368
|
}
|
|
@@ -4166,8 +4372,8 @@ var init_storage = __esm({
|
|
|
4166
4372
|
index.ids = index.ids.filter((i) => i !== id);
|
|
4167
4373
|
}
|
|
4168
4374
|
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4169
|
-
await
|
|
4170
|
-
await
|
|
4375
|
+
await fs12.mkdir(path11.dirname(indexPath), { recursive: true });
|
|
4376
|
+
await fs12.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
4171
4377
|
}
|
|
4172
4378
|
};
|
|
4173
4379
|
__name(getStorage, "getStorage");
|
|
@@ -4188,7 +4394,7 @@ var init_storage2 = __esm({
|
|
|
4188
4394
|
});
|
|
4189
4395
|
|
|
4190
4396
|
// core/outcomes/recorder.ts
|
|
4191
|
-
import
|
|
4397
|
+
import path12 from "path";
|
|
4192
4398
|
var OUTCOMES_DIR, OUTCOMES_FILE, OutcomeRecorder, outcomeRecorder, recorder_default;
|
|
4193
4399
|
var init_recorder = __esm({
|
|
4194
4400
|
"core/outcomes/recorder.ts"() {
|
|
@@ -4207,13 +4413,13 @@ var init_recorder = __esm({
|
|
|
4207
4413
|
*/
|
|
4208
4414
|
getOutcomesDir(projectId) {
|
|
4209
4415
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
4210
|
-
return
|
|
4416
|
+
return path12.join(globalPath, OUTCOMES_DIR);
|
|
4211
4417
|
}
|
|
4212
4418
|
/**
|
|
4213
4419
|
* Get outcomes file path for a project.
|
|
4214
4420
|
*/
|
|
4215
4421
|
getOutcomesPath(projectId) {
|
|
4216
|
-
return
|
|
4422
|
+
return path12.join(this.getOutcomesDir(projectId), OUTCOMES_FILE);
|
|
4217
4423
|
}
|
|
4218
4424
|
/**
|
|
4219
4425
|
* Record an outcome.
|
|
@@ -4224,7 +4430,7 @@ var init_recorder = __esm({
|
|
|
4224
4430
|
id: generateUUID()
|
|
4225
4431
|
};
|
|
4226
4432
|
const outcomesPath = this.getOutcomesPath(projectId);
|
|
4227
|
-
await ensureDir(
|
|
4433
|
+
await ensureDir(path12.dirname(outcomesPath));
|
|
4228
4434
|
await appendLine(outcomesPath, JSON.stringify(outcome));
|
|
4229
4435
|
return outcome;
|
|
4230
4436
|
}
|
|
@@ -4591,6 +4797,13 @@ var init_memory = __esm({
|
|
|
4591
4797
|
}
|
|
4592
4798
|
});
|
|
4593
4799
|
|
|
4800
|
+
// core/types/integrations.ts
|
|
4801
|
+
var init_integrations = __esm({
|
|
4802
|
+
"core/types/integrations.ts"() {
|
|
4803
|
+
"use strict";
|
|
4804
|
+
}
|
|
4805
|
+
});
|
|
4806
|
+
|
|
4594
4807
|
// core/types/bus.ts
|
|
4595
4808
|
var init_bus = __esm({
|
|
4596
4809
|
"core/types/bus.ts"() {
|
|
@@ -4604,6 +4817,7 @@ var init_types = __esm({
|
|
|
4604
4817
|
"use strict";
|
|
4605
4818
|
init_fs();
|
|
4606
4819
|
init_memory();
|
|
4820
|
+
init_integrations();
|
|
4607
4821
|
init_bus();
|
|
4608
4822
|
}
|
|
4609
4823
|
});
|
|
@@ -4619,8 +4833,8 @@ var init_outcomes2 = __esm({
|
|
|
4619
4833
|
});
|
|
4620
4834
|
|
|
4621
4835
|
// core/agentic/prompt-builder.ts
|
|
4622
|
-
import
|
|
4623
|
-
import
|
|
4836
|
+
import fs13 from "fs";
|
|
4837
|
+
import path13 from "path";
|
|
4624
4838
|
var PromptBuilder, promptBuilder, prompt_builder_default;
|
|
4625
4839
|
var init_prompt_builder = __esm({
|
|
4626
4840
|
"core/agentic/prompt-builder.ts"() {
|
|
@@ -4654,14 +4868,14 @@ var init_prompt_builder = __esm({
|
|
|
4654
4868
|
*/
|
|
4655
4869
|
loadChecklists() {
|
|
4656
4870
|
if (this._checklistsCache) return this._checklistsCache;
|
|
4657
|
-
const checklistsDir =
|
|
4871
|
+
const checklistsDir = path13.join(__dirname, "..", "..", "templates", "checklists");
|
|
4658
4872
|
const checklists = {};
|
|
4659
4873
|
try {
|
|
4660
|
-
if (
|
|
4661
|
-
const files =
|
|
4874
|
+
if (fs13.existsSync(checklistsDir)) {
|
|
4875
|
+
const files = fs13.readdirSync(checklistsDir).filter((f) => f.endsWith(".md"));
|
|
4662
4876
|
for (const file of files) {
|
|
4663
4877
|
const name = file.replace(".md", "");
|
|
4664
|
-
const content =
|
|
4878
|
+
const content = fs13.readFileSync(path13.join(checklistsDir, file), "utf-8");
|
|
4665
4879
|
checklists[name] = content;
|
|
4666
4880
|
}
|
|
4667
4881
|
}
|
|
@@ -4762,10 +4976,10 @@ var init_prompt_builder = __esm({
|
|
|
4762
4976
|
*/
|
|
4763
4977
|
loadChecklistRouting() {
|
|
4764
4978
|
if (this._checklistRoutingCache) return this._checklistRoutingCache;
|
|
4765
|
-
const routingPath =
|
|
4979
|
+
const routingPath = path13.join(__dirname, "..", "..", "templates", "agentic", "checklist-routing.md");
|
|
4766
4980
|
try {
|
|
4767
|
-
if (
|
|
4768
|
-
this._checklistRoutingCache =
|
|
4981
|
+
if (fs13.existsSync(routingPath)) {
|
|
4982
|
+
this._checklistRoutingCache = fs13.readFileSync(routingPath, "utf-8");
|
|
4769
4983
|
}
|
|
4770
4984
|
} catch {
|
|
4771
4985
|
}
|
|
@@ -5023,7 +5237,7 @@ Context: ${fileCount} files available. Read what you need.
|
|
|
5023
5237
|
});
|
|
5024
5238
|
|
|
5025
5239
|
// core/agentic/tool-registry.ts
|
|
5026
|
-
import
|
|
5240
|
+
import fs14 from "fs/promises";
|
|
5027
5241
|
import { exec as exec2 } from "child_process";
|
|
5028
5242
|
import { promisify as promisify2 } from "util";
|
|
5029
5243
|
var execAsync, toolRegistry, tool_registry_default;
|
|
@@ -5068,14 +5282,14 @@ var init_tool_registry = __esm({
|
|
|
5068
5282
|
};
|
|
5069
5283
|
toolRegistry.register("Read", async (filePath) => {
|
|
5070
5284
|
try {
|
|
5071
|
-
return await
|
|
5285
|
+
return await fs14.readFile(filePath, "utf-8");
|
|
5072
5286
|
} catch {
|
|
5073
5287
|
return null;
|
|
5074
5288
|
}
|
|
5075
5289
|
});
|
|
5076
5290
|
toolRegistry.register("Write", async (filePath, content) => {
|
|
5077
5291
|
try {
|
|
5078
|
-
await
|
|
5292
|
+
await fs14.writeFile(filePath, content, "utf-8");
|
|
5079
5293
|
return true;
|
|
5080
5294
|
} catch {
|
|
5081
5295
|
return false;
|
|
@@ -5546,10 +5760,10 @@ var init_chain_of_thought = __esm({
|
|
|
5546
5760
|
});
|
|
5547
5761
|
|
|
5548
5762
|
// core/utils/jsonl-helper.ts
|
|
5549
|
-
import
|
|
5763
|
+
import fs15 from "fs/promises";
|
|
5550
5764
|
import fsSync from "fs";
|
|
5551
5765
|
import readline from "readline";
|
|
5552
|
-
import
|
|
5766
|
+
import path14 from "path";
|
|
5553
5767
|
function parseJsonLines(content) {
|
|
5554
5768
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
5555
5769
|
const entries = [];
|
|
@@ -5566,7 +5780,7 @@ function stringifyJsonLines(objects) {
|
|
|
5566
5780
|
}
|
|
5567
5781
|
async function readJsonLines(filePath) {
|
|
5568
5782
|
try {
|
|
5569
|
-
const content = await
|
|
5783
|
+
const content = await fs15.readFile(filePath, "utf-8");
|
|
5570
5784
|
return parseJsonLines(content);
|
|
5571
5785
|
} catch (error) {
|
|
5572
5786
|
if (isNotFoundError(error)) {
|
|
@@ -5577,15 +5791,15 @@ async function readJsonLines(filePath) {
|
|
|
5577
5791
|
}
|
|
5578
5792
|
async function writeJsonLines(filePath, objects) {
|
|
5579
5793
|
const content = stringifyJsonLines(objects);
|
|
5580
|
-
await
|
|
5794
|
+
await fs15.writeFile(filePath, content, "utf-8");
|
|
5581
5795
|
}
|
|
5582
5796
|
async function appendJsonLine(filePath, object) {
|
|
5583
5797
|
const line = JSON.stringify(object) + "\n";
|
|
5584
|
-
await
|
|
5798
|
+
await fs15.appendFile(filePath, line, "utf-8");
|
|
5585
5799
|
}
|
|
5586
5800
|
async function appendJsonLines(filePath, objects) {
|
|
5587
5801
|
const content = stringifyJsonLines(objects);
|
|
5588
|
-
await
|
|
5802
|
+
await fs15.appendFile(filePath, content, "utf-8");
|
|
5589
5803
|
}
|
|
5590
5804
|
async function filterJsonLines(filePath, predicate) {
|
|
5591
5805
|
const entries = await readJsonLines(filePath);
|
|
@@ -5593,7 +5807,7 @@ async function filterJsonLines(filePath, predicate) {
|
|
|
5593
5807
|
}
|
|
5594
5808
|
async function countJsonLines(filePath) {
|
|
5595
5809
|
try {
|
|
5596
|
-
const content = await
|
|
5810
|
+
const content = await fs15.readFile(filePath, "utf-8");
|
|
5597
5811
|
const lines = content.split("\n").filter((line) => line.trim());
|
|
5598
5812
|
return lines.length;
|
|
5599
5813
|
} catch (error) {
|
|
@@ -5652,7 +5866,7 @@ async function readJsonLinesStreaming(filePath, maxLines = 1e3) {
|
|
|
5652
5866
|
}
|
|
5653
5867
|
async function getFileSizeMB(filePath) {
|
|
5654
5868
|
try {
|
|
5655
|
-
const stats = await
|
|
5869
|
+
const stats = await fs15.stat(filePath);
|
|
5656
5870
|
return stats.size / (1024 * 1024);
|
|
5657
5871
|
} catch (error) {
|
|
5658
5872
|
if (isNotFoundError(error)) {
|
|
@@ -5667,12 +5881,12 @@ async function rotateJsonLinesIfNeeded(filePath, maxSizeMB = 10) {
|
|
|
5667
5881
|
return false;
|
|
5668
5882
|
}
|
|
5669
5883
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
5670
|
-
const dir =
|
|
5671
|
-
const ext =
|
|
5672
|
-
const base =
|
|
5673
|
-
const archivePath =
|
|
5674
|
-
await
|
|
5675
|
-
console.log(`\u{1F4E6} Rotated ${
|
|
5884
|
+
const dir = path14.dirname(filePath);
|
|
5885
|
+
const ext = path14.extname(filePath);
|
|
5886
|
+
const base = path14.basename(filePath, ext);
|
|
5887
|
+
const archivePath = path14.join(dir, `${base}-${timestamp}${ext}`);
|
|
5888
|
+
await fs15.rename(filePath, archivePath);
|
|
5889
|
+
console.log(`\u{1F4E6} Rotated ${path14.basename(filePath)} (${sizeMB.toFixed(1)}MB) \u2192 ${path14.basename(archivePath)}`);
|
|
5676
5890
|
return true;
|
|
5677
5891
|
}
|
|
5678
5892
|
async function appendJsonLineWithRotation(filePath, object, maxSizeMB = 10) {
|
|
@@ -5684,7 +5898,7 @@ async function checkFileSizeWarning(filePath, warnThresholdMB = 50) {
|
|
|
5684
5898
|
const isLarge = sizeMB > warnThresholdMB;
|
|
5685
5899
|
if (isLarge) {
|
|
5686
5900
|
console.warn(
|
|
5687
|
-
`\u26A0\uFE0F Large file detected: ${
|
|
5901
|
+
`\u26A0\uFE0F Large file detected: ${path14.basename(filePath)} (${sizeMB.toFixed(1)}MB). Reading may use significant memory.`
|
|
5688
5902
|
);
|
|
5689
5903
|
}
|
|
5690
5904
|
return { sizeMB, isLarge };
|
|
@@ -5734,8 +5948,8 @@ var init_jsonl_helper = __esm({
|
|
|
5734
5948
|
});
|
|
5735
5949
|
|
|
5736
5950
|
// core/agentic/memory-system.ts
|
|
5737
|
-
import
|
|
5738
|
-
import
|
|
5951
|
+
import fs16 from "fs/promises";
|
|
5952
|
+
import path15 from "path";
|
|
5739
5953
|
var CachedStore, SessionStore, HistoryStore, PatternStore, SemanticMemories, MemorySystem, memorySystem, memory_system_default;
|
|
5740
5954
|
var init_memory_system = __esm({
|
|
5741
5955
|
"core/agentic/memory-system.ts"() {
|
|
@@ -5765,12 +5979,12 @@ var init_memory_system = __esm({
|
|
|
5765
5979
|
* Get full path for the store file
|
|
5766
5980
|
*/
|
|
5767
5981
|
getPath(projectId) {
|
|
5768
|
-
const basePath =
|
|
5982
|
+
const basePath = path15.join(path_manager_default.getGlobalProjectPath(projectId), "memory");
|
|
5769
5983
|
const subdir = this.getSubdirectory();
|
|
5770
5984
|
if (subdir) {
|
|
5771
|
-
return
|
|
5985
|
+
return path15.join(basePath, subdir, this.getFilename());
|
|
5772
5986
|
}
|
|
5773
|
-
return
|
|
5987
|
+
return path15.join(basePath, this.getFilename());
|
|
5774
5988
|
}
|
|
5775
5989
|
/**
|
|
5776
5990
|
* Load data from disk (with caching)
|
|
@@ -5782,7 +5996,7 @@ var init_memory_system = __esm({
|
|
|
5782
5996
|
}
|
|
5783
5997
|
const filePath = this.getPath(projectId);
|
|
5784
5998
|
try {
|
|
5785
|
-
const content = await
|
|
5999
|
+
const content = await fs16.readFile(filePath, "utf-8");
|
|
5786
6000
|
this._data = JSON.parse(content);
|
|
5787
6001
|
this.afterLoad(this._data);
|
|
5788
6002
|
} catch (error) {
|
|
@@ -5808,8 +6022,8 @@ var init_memory_system = __esm({
|
|
|
5808
6022
|
async save(projectId) {
|
|
5809
6023
|
if (!this._data) return;
|
|
5810
6024
|
const filePath = this.getPath(projectId);
|
|
5811
|
-
await
|
|
5812
|
-
await
|
|
6025
|
+
await fs16.mkdir(path15.dirname(filePath), { recursive: true });
|
|
6026
|
+
await fs16.writeFile(filePath, JSON.stringify(this._data, null, 2), "utf-8");
|
|
5813
6027
|
}
|
|
5814
6028
|
/**
|
|
5815
6029
|
* Get cached data without loading (may be null)
|
|
@@ -5875,11 +6089,11 @@ var init_memory_system = __esm({
|
|
|
5875
6089
|
const now = /* @__PURE__ */ new Date();
|
|
5876
6090
|
const yearMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
5877
6091
|
const day = getTodayKey();
|
|
5878
|
-
return
|
|
6092
|
+
return path15.join(path_manager_default.getGlobalProjectPath(projectId), "memory", "sessions", yearMonth, `${day}.jsonl`);
|
|
5879
6093
|
}
|
|
5880
6094
|
async appendHistory(projectId, entry) {
|
|
5881
6095
|
const sessionPath = this._getSessionPath(projectId);
|
|
5882
|
-
await ensureDir(
|
|
6096
|
+
await ensureDir(path15.dirname(sessionPath));
|
|
5883
6097
|
const logEntry = {
|
|
5884
6098
|
ts: getTimestamp(),
|
|
5885
6099
|
...entry,
|
|
@@ -6348,9 +6562,9 @@ Context: ${context}` : ""}`,
|
|
|
6348
6562
|
});
|
|
6349
6563
|
|
|
6350
6564
|
// core/agentic/ground-truth.ts
|
|
6351
|
-
import
|
|
6352
|
-
import
|
|
6353
|
-
import
|
|
6565
|
+
import fs17 from "fs/promises";
|
|
6566
|
+
import path16 from "path";
|
|
6567
|
+
import os6 from "os";
|
|
6354
6568
|
import { execSync as execSync2 } from "child_process";
|
|
6355
6569
|
function formatDuration2(ms) {
|
|
6356
6570
|
const hours = Math.floor(ms / (1e3 * 60 * 60));
|
|
@@ -6387,7 +6601,7 @@ async function verifyDone(context) {
|
|
|
6387
6601
|
const actual = {};
|
|
6388
6602
|
const nowPath = context.paths.now;
|
|
6389
6603
|
try {
|
|
6390
|
-
const nowContent = await
|
|
6604
|
+
const nowContent = await fs17.readFile(nowPath, "utf-8");
|
|
6391
6605
|
actual.nowExists = true;
|
|
6392
6606
|
actual.nowContent = nowContent.trim();
|
|
6393
6607
|
actual.nowLength = nowContent.length;
|
|
@@ -6411,7 +6625,7 @@ async function verifyDone(context) {
|
|
|
6411
6625
|
}
|
|
6412
6626
|
const nextPath = context.paths.next;
|
|
6413
6627
|
try {
|
|
6414
|
-
const nextContent = await
|
|
6628
|
+
const nextContent = await fs17.readFile(nextPath, "utf-8");
|
|
6415
6629
|
actual.nextExists = true;
|
|
6416
6630
|
const tasks = nextContent.match(/- \[ \]/g) || [];
|
|
6417
6631
|
actual.pendingTasks = tasks.length;
|
|
@@ -6421,7 +6635,7 @@ async function verifyDone(context) {
|
|
|
6421
6635
|
}
|
|
6422
6636
|
const metricsPath = context.paths.metrics;
|
|
6423
6637
|
try {
|
|
6424
|
-
await
|
|
6638
|
+
await fs17.access(path16.dirname(metricsPath), fs17.constants.W_OK);
|
|
6425
6639
|
actual.metricsWritable = true;
|
|
6426
6640
|
} catch {
|
|
6427
6641
|
actual.metricsWritable = false;
|
|
@@ -6452,9 +6666,9 @@ async function verifyShip(context) {
|
|
|
6452
6666
|
} catch {
|
|
6453
6667
|
actual.gitAvailable = false;
|
|
6454
6668
|
}
|
|
6455
|
-
const pkgPath =
|
|
6669
|
+
const pkgPath = path16.join(context.projectPath, "package.json");
|
|
6456
6670
|
try {
|
|
6457
|
-
const pkgContent = await
|
|
6671
|
+
const pkgContent = await fs17.readFile(pkgPath, "utf-8");
|
|
6458
6672
|
const pkg = JSON.parse(pkgContent);
|
|
6459
6673
|
actual.currentVersion = pkg.version;
|
|
6460
6674
|
actual.hasPackageJson = true;
|
|
@@ -6463,7 +6677,7 @@ async function verifyShip(context) {
|
|
|
6463
6677
|
}
|
|
6464
6678
|
const shippedPath = context.paths.shipped;
|
|
6465
6679
|
try {
|
|
6466
|
-
const shippedContent = await
|
|
6680
|
+
const shippedContent = await fs17.readFile(shippedPath, "utf-8");
|
|
6467
6681
|
actual.shippedExists = true;
|
|
6468
6682
|
const featureName = context.params.feature || context.params.description;
|
|
6469
6683
|
if (featureName) {
|
|
@@ -6479,7 +6693,7 @@ async function verifyShip(context) {
|
|
|
6479
6693
|
}
|
|
6480
6694
|
if (actual.hasPackageJson) {
|
|
6481
6695
|
try {
|
|
6482
|
-
const pkgContent = await
|
|
6696
|
+
const pkgContent = await fs17.readFile(pkgPath, "utf-8");
|
|
6483
6697
|
const pkg = JSON.parse(pkgContent);
|
|
6484
6698
|
actual.hasTestScript = !!pkg.scripts?.test;
|
|
6485
6699
|
} catch {
|
|
@@ -6499,7 +6713,7 @@ async function verifyFeature(context) {
|
|
|
6499
6713
|
const actual = {};
|
|
6500
6714
|
const nextPath = context.paths.next;
|
|
6501
6715
|
try {
|
|
6502
|
-
const nextContent = await
|
|
6716
|
+
const nextContent = await fs17.readFile(nextPath, "utf-8");
|
|
6503
6717
|
actual.nextExists = true;
|
|
6504
6718
|
const tasks = nextContent.match(/- \[[ x]\]/g) || [];
|
|
6505
6719
|
actual.taskCount = tasks.length;
|
|
@@ -6514,7 +6728,7 @@ async function verifyFeature(context) {
|
|
|
6514
6728
|
}
|
|
6515
6729
|
const roadmapPath = context.paths.roadmap;
|
|
6516
6730
|
try {
|
|
6517
|
-
const roadmapContent = await
|
|
6731
|
+
const roadmapContent = await fs17.readFile(roadmapPath, "utf-8");
|
|
6518
6732
|
actual.roadmapExists = true;
|
|
6519
6733
|
const featureName = context.params.description || context.params.feature;
|
|
6520
6734
|
if (featureName) {
|
|
@@ -6529,7 +6743,7 @@ async function verifyFeature(context) {
|
|
|
6529
6743
|
}
|
|
6530
6744
|
const nowPath = context.paths.now;
|
|
6531
6745
|
try {
|
|
6532
|
-
const nowContent = await
|
|
6746
|
+
const nowContent = await fs17.readFile(nowPath, "utf-8");
|
|
6533
6747
|
actual.hasActiveTask = nowContent.trim().length > 0 && !nowContent.includes("No current task");
|
|
6534
6748
|
if (actual.hasActiveTask) {
|
|
6535
6749
|
recommendations.push("Consider completing current task first with /p:done");
|
|
@@ -6550,7 +6764,7 @@ async function verifyNow(context) {
|
|
|
6550
6764
|
const actual = {};
|
|
6551
6765
|
const nowPath = context.paths.now;
|
|
6552
6766
|
try {
|
|
6553
|
-
const nowContent = await
|
|
6767
|
+
const nowContent = await fs17.readFile(nowPath, "utf-8");
|
|
6554
6768
|
actual.nowExists = true;
|
|
6555
6769
|
actual.nowContent = nowContent.trim();
|
|
6556
6770
|
const hasRealTask = nowContent.trim().length > 0 && !nowContent.includes("No current task") && !nowContent.match(/^#\s*NOW\s*$/m);
|
|
@@ -6566,7 +6780,7 @@ async function verifyNow(context) {
|
|
|
6566
6780
|
}
|
|
6567
6781
|
const nextPath = context.paths.next;
|
|
6568
6782
|
try {
|
|
6569
|
-
const nextContent = await
|
|
6783
|
+
const nextContent = await fs17.readFile(nextPath, "utf-8");
|
|
6570
6784
|
const pendingTasks = (nextContent.match(/- \[ \]/g) || []).length;
|
|
6571
6785
|
actual.pendingTasks = pendingTasks;
|
|
6572
6786
|
if (!context.params.task && pendingTasks > 0) {
|
|
@@ -6586,9 +6800,9 @@ async function verifyInit(context) {
|
|
|
6586
6800
|
const warnings = [];
|
|
6587
6801
|
const recommendations = [];
|
|
6588
6802
|
const actual = {};
|
|
6589
|
-
const configPath =
|
|
6803
|
+
const configPath = path16.join(context.projectPath, ".prjct/prjct.config.json");
|
|
6590
6804
|
try {
|
|
6591
|
-
const configContent = await
|
|
6805
|
+
const configContent = await fs17.readFile(configPath, "utf-8");
|
|
6592
6806
|
actual.alreadyInitialized = true;
|
|
6593
6807
|
actual.existingConfig = JSON.parse(configContent);
|
|
6594
6808
|
warnings.push("Project already initialized");
|
|
@@ -6596,13 +6810,13 @@ async function verifyInit(context) {
|
|
|
6596
6810
|
} catch {
|
|
6597
6811
|
actual.alreadyInitialized = false;
|
|
6598
6812
|
}
|
|
6599
|
-
const globalPath =
|
|
6813
|
+
const globalPath = path16.join(os6.homedir(), ".prjct-cli");
|
|
6600
6814
|
try {
|
|
6601
|
-
await
|
|
6815
|
+
await fs17.access(globalPath, fs17.constants.W_OK);
|
|
6602
6816
|
actual.globalPathWritable = true;
|
|
6603
6817
|
} catch {
|
|
6604
6818
|
try {
|
|
6605
|
-
await
|
|
6819
|
+
await fs17.mkdir(globalPath, { recursive: true });
|
|
6606
6820
|
actual.globalPathWritable = true;
|
|
6607
6821
|
actual.globalPathCreated = true;
|
|
6608
6822
|
} catch {
|
|
@@ -6622,9 +6836,9 @@ async function verifySync(context) {
|
|
|
6622
6836
|
const warnings = [];
|
|
6623
6837
|
const recommendations = [];
|
|
6624
6838
|
const actual = {};
|
|
6625
|
-
const configPath =
|
|
6839
|
+
const configPath = path16.join(context.projectPath, ".prjct/prjct.config.json");
|
|
6626
6840
|
try {
|
|
6627
|
-
const configContent = await
|
|
6841
|
+
const configContent = await fs17.readFile(configPath, "utf-8");
|
|
6628
6842
|
actual.hasConfig = true;
|
|
6629
6843
|
actual.config = JSON.parse(configContent);
|
|
6630
6844
|
} catch {
|
|
@@ -6634,9 +6848,9 @@ async function verifySync(context) {
|
|
|
6634
6848
|
return { verified: false, actual, warnings, recommendations };
|
|
6635
6849
|
}
|
|
6636
6850
|
const projectId = actual.config?.projectId;
|
|
6637
|
-
const globalProjectPath =
|
|
6851
|
+
const globalProjectPath = path16.join(os6.homedir(), ".prjct-cli/projects", projectId || "");
|
|
6638
6852
|
try {
|
|
6639
|
-
await
|
|
6853
|
+
await fs17.access(globalProjectPath);
|
|
6640
6854
|
actual.globalStorageExists = true;
|
|
6641
6855
|
} catch {
|
|
6642
6856
|
actual.globalStorageExists = false;
|
|
@@ -6658,7 +6872,7 @@ async function verifyAnalyze(context) {
|
|
|
6658
6872
|
actual.detectedFiles = [];
|
|
6659
6873
|
for (const file of files) {
|
|
6660
6874
|
try {
|
|
6661
|
-
await
|
|
6875
|
+
await fs17.access(path16.join(context.projectPath, file));
|
|
6662
6876
|
actual.detectedFiles.push(file);
|
|
6663
6877
|
} catch {
|
|
6664
6878
|
}
|
|
@@ -6671,7 +6885,7 @@ async function verifyAnalyze(context) {
|
|
|
6671
6885
|
actual.detectedSrcDirs = [];
|
|
6672
6886
|
for (const dir of srcDirs) {
|
|
6673
6887
|
try {
|
|
6674
|
-
const stat = await
|
|
6888
|
+
const stat = await fs17.stat(path16.join(context.projectPath, dir));
|
|
6675
6889
|
if (stat.isDirectory()) {
|
|
6676
6890
|
;
|
|
6677
6891
|
actual.detectedSrcDirs.push(dir);
|
|
@@ -6693,9 +6907,9 @@ async function verifySpec(context) {
|
|
|
6693
6907
|
const actual = {};
|
|
6694
6908
|
const specsPath = context.paths.specs;
|
|
6695
6909
|
try {
|
|
6696
|
-
await
|
|
6910
|
+
await fs17.access(specsPath);
|
|
6697
6911
|
actual.specsExists = true;
|
|
6698
|
-
const files = await
|
|
6912
|
+
const files = await fs17.readdir(specsPath);
|
|
6699
6913
|
actual.existingSpecs = files.filter((f) => f.endsWith(".md"));
|
|
6700
6914
|
actual.specCount = actual.existingSpecs.length;
|
|
6701
6915
|
} catch {
|
|
@@ -7227,23 +7441,23 @@ var init_plan_mode = __esm({
|
|
|
7227
7441
|
});
|
|
7228
7442
|
|
|
7229
7443
|
// core/agentic/command-executor.ts
|
|
7230
|
-
import
|
|
7231
|
-
import
|
|
7232
|
-
import
|
|
7444
|
+
import fs18 from "fs";
|
|
7445
|
+
import path17 from "path";
|
|
7446
|
+
import os7 from "os";
|
|
7233
7447
|
function signalStart(commandName) {
|
|
7234
7448
|
try {
|
|
7235
|
-
const dir =
|
|
7236
|
-
if (!
|
|
7237
|
-
|
|
7449
|
+
const dir = path17.dirname(RUNNING_FILE);
|
|
7450
|
+
if (!fs18.existsSync(dir)) {
|
|
7451
|
+
fs18.mkdirSync(dir, { recursive: true });
|
|
7238
7452
|
}
|
|
7239
|
-
|
|
7453
|
+
fs18.writeFileSync(RUNNING_FILE, `/p:${commandName}`);
|
|
7240
7454
|
} catch {
|
|
7241
7455
|
}
|
|
7242
7456
|
}
|
|
7243
7457
|
function signalEnd() {
|
|
7244
7458
|
try {
|
|
7245
|
-
if (
|
|
7246
|
-
|
|
7459
|
+
if (fs18.existsSync(RUNNING_FILE)) {
|
|
7460
|
+
fs18.unlinkSync(RUNNING_FILE);
|
|
7247
7461
|
}
|
|
7248
7462
|
} catch {
|
|
7249
7463
|
}
|
|
@@ -7261,7 +7475,7 @@ var init_command_executor = __esm({
|
|
|
7261
7475
|
init_memory_system();
|
|
7262
7476
|
init_ground_truth();
|
|
7263
7477
|
init_plan_mode();
|
|
7264
|
-
RUNNING_FILE =
|
|
7478
|
+
RUNNING_FILE = path17.join(os7.homedir(), ".prjct-cli", ".running");
|
|
7265
7479
|
__name(signalStart, "signalStart");
|
|
7266
7480
|
__name(signalEnd, "signalEnd");
|
|
7267
7481
|
CommandExecutor = class {
|
|
@@ -7337,8 +7551,8 @@ var init_command_executor = __esm({
|
|
|
7337
7551
|
let context = metadataContext;
|
|
7338
7552
|
context = {
|
|
7339
7553
|
...context,
|
|
7340
|
-
agentsPath:
|
|
7341
|
-
agentRoutingPath:
|
|
7554
|
+
agentsPath: path17.join(os7.homedir(), ".prjct-cli", "projects", metadataContext.projectId || "", "agents"),
|
|
7555
|
+
agentRoutingPath: path17.join(__dirname, "..", "..", "templates", "agentic", "agent-routing.md"),
|
|
7342
7556
|
agenticDelegation: true
|
|
7343
7557
|
};
|
|
7344
7558
|
const state = await context_builder_default.loadState(metadataContext);
|
|
@@ -7500,9 +7714,9 @@ var init_command_executor = __esm({
|
|
|
7500
7714
|
|
|
7501
7715
|
// core/infrastructure/update-checker.ts
|
|
7502
7716
|
import https from "https";
|
|
7503
|
-
import
|
|
7504
|
-
import
|
|
7505
|
-
import
|
|
7717
|
+
import fs19 from "fs";
|
|
7718
|
+
import path18 from "path";
|
|
7719
|
+
import os8 from "os";
|
|
7506
7720
|
import chalk from "chalk";
|
|
7507
7721
|
var UpdateChecker, update_checker_default;
|
|
7508
7722
|
var init_update_checker = __esm({
|
|
@@ -7518,8 +7732,8 @@ var init_update_checker = __esm({
|
|
|
7518
7732
|
checkInterval;
|
|
7519
7733
|
constructor() {
|
|
7520
7734
|
this.packageName = "prjct-cli";
|
|
7521
|
-
this.cacheDir =
|
|
7522
|
-
this.cacheFile =
|
|
7735
|
+
this.cacheDir = path18.join(os8.homedir(), ".prjct-cli", "config");
|
|
7736
|
+
this.cacheFile = path18.join(this.cacheDir, "update-cache.json");
|
|
7523
7737
|
this.checkInterval = 24 * 60 * 60 * 1e3;
|
|
7524
7738
|
}
|
|
7525
7739
|
/**
|
|
@@ -7527,8 +7741,8 @@ var init_update_checker = __esm({
|
|
|
7527
7741
|
*/
|
|
7528
7742
|
getCurrentVersion() {
|
|
7529
7743
|
try {
|
|
7530
|
-
const packageJsonPath =
|
|
7531
|
-
const packageJson = JSON.parse(
|
|
7744
|
+
const packageJsonPath = path18.join(__dirname, "..", "..", "package.json");
|
|
7745
|
+
const packageJson = JSON.parse(fs19.readFileSync(packageJsonPath, "utf8"));
|
|
7532
7746
|
return packageJson.version;
|
|
7533
7747
|
} catch (error) {
|
|
7534
7748
|
console.error("Error reading package version:", error.message);
|
|
@@ -7597,8 +7811,8 @@ var init_update_checker = __esm({
|
|
|
7597
7811
|
*/
|
|
7598
7812
|
readCache() {
|
|
7599
7813
|
try {
|
|
7600
|
-
if (
|
|
7601
|
-
const cache2 = JSON.parse(
|
|
7814
|
+
if (fs19.existsSync(this.cacheFile)) {
|
|
7815
|
+
const cache2 = JSON.parse(fs19.readFileSync(this.cacheFile, "utf8"));
|
|
7602
7816
|
return cache2;
|
|
7603
7817
|
}
|
|
7604
7818
|
} catch {
|
|
@@ -7610,10 +7824,10 @@ var init_update_checker = __esm({
|
|
|
7610
7824
|
*/
|
|
7611
7825
|
writeCache(data) {
|
|
7612
7826
|
try {
|
|
7613
|
-
if (!
|
|
7614
|
-
|
|
7827
|
+
if (!fs19.existsSync(this.cacheDir)) {
|
|
7828
|
+
fs19.mkdirSync(this.cacheDir, { recursive: true });
|
|
7615
7829
|
}
|
|
7616
|
-
|
|
7830
|
+
fs19.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2), "utf8");
|
|
7617
7831
|
} catch {
|
|
7618
7832
|
}
|
|
7619
7833
|
}
|
|
@@ -7776,15 +7990,15 @@ var init_output = __esm({
|
|
|
7776
7990
|
});
|
|
7777
7991
|
|
|
7778
7992
|
// core/infrastructure/agent-detector.ts
|
|
7779
|
-
import
|
|
7780
|
-
import
|
|
7993
|
+
import fs20 from "fs";
|
|
7994
|
+
import path19 from "path";
|
|
7781
7995
|
function isClaudeEnvironment() {
|
|
7782
7996
|
if (process.env.CLAUDE_AGENT || process.env.ANTHROPIC_CLAUDE) return true;
|
|
7783
7997
|
if (global.mcp || process.env.MCP_AVAILABLE) return true;
|
|
7784
7998
|
const projectRoot = process.cwd();
|
|
7785
|
-
if (
|
|
7999
|
+
if (fs20.existsSync(path19.join(projectRoot, "CLAUDE.md"))) return true;
|
|
7786
8000
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
7787
|
-
if (
|
|
8001
|
+
if (fs20.existsSync(path19.join(homeDir, ".claude"))) return true;
|
|
7788
8002
|
const cwd = process.cwd();
|
|
7789
8003
|
if (cwd.includes("/.claude/") || cwd.includes("/claude-workspace/")) return true;
|
|
7790
8004
|
return false;
|
|
@@ -7897,8 +8111,8 @@ var init_agent_detector = __esm({
|
|
|
7897
8111
|
});
|
|
7898
8112
|
|
|
7899
8113
|
// core/agentic/agent-router.ts
|
|
7900
|
-
import
|
|
7901
|
-
import
|
|
8114
|
+
import fs21 from "fs/promises";
|
|
8115
|
+
import path20 from "path";
|
|
7902
8116
|
var AgentRouter, agent_router_default;
|
|
7903
8117
|
var init_agent_router = __esm({
|
|
7904
8118
|
"core/agentic/agent-router.ts"() {
|
|
@@ -7926,12 +8140,12 @@ var init_agent_router = __esm({
|
|
|
7926
8140
|
async loadAvailableAgents() {
|
|
7927
8141
|
if (!this.agentsPath) return [];
|
|
7928
8142
|
try {
|
|
7929
|
-
const files = await
|
|
8143
|
+
const files = await fs21.readdir(this.agentsPath);
|
|
7930
8144
|
const agents = [];
|
|
7931
8145
|
for (const file of files) {
|
|
7932
8146
|
if (file.endsWith(".md")) {
|
|
7933
8147
|
const name = file.replace(".md", "");
|
|
7934
|
-
const content = await
|
|
8148
|
+
const content = await fs21.readFile(path20.join(this.agentsPath, file), "utf-8");
|
|
7935
8149
|
agents.push({ name, content });
|
|
7936
8150
|
}
|
|
7937
8151
|
}
|
|
@@ -7953,8 +8167,8 @@ var init_agent_router = __esm({
|
|
|
7953
8167
|
async loadAgent(name) {
|
|
7954
8168
|
if (!this.agentsPath) return null;
|
|
7955
8169
|
try {
|
|
7956
|
-
const filePath =
|
|
7957
|
-
const content = await
|
|
8170
|
+
const filePath = path20.join(this.agentsPath, `${name}.md`);
|
|
8171
|
+
const content = await fs21.readFile(filePath, "utf-8");
|
|
7958
8172
|
return { name, content };
|
|
7959
8173
|
} catch {
|
|
7960
8174
|
return null;
|
|
@@ -7979,7 +8193,7 @@ var init_agent_router = __esm({
|
|
|
7979
8193
|
*/
|
|
7980
8194
|
async logUsage(task, agent, _projectPath) {
|
|
7981
8195
|
try {
|
|
7982
|
-
const logPath =
|
|
8196
|
+
const logPath = path20.join(
|
|
7983
8197
|
process.env.HOME || "",
|
|
7984
8198
|
".prjct-cli",
|
|
7985
8199
|
"projects",
|
|
@@ -7992,7 +8206,7 @@ var init_agent_router = __esm({
|
|
|
7992
8206
|
agent: typeof agent === "string" ? agent : agent.name,
|
|
7993
8207
|
projectId: this.projectId
|
|
7994
8208
|
}) + "\n";
|
|
7995
|
-
await
|
|
8209
|
+
await fs21.appendFile(logPath, entry);
|
|
7996
8210
|
} catch {
|
|
7997
8211
|
}
|
|
7998
8212
|
}
|
|
@@ -8143,8 +8357,8 @@ var init_agent_service = __esm({
|
|
|
8143
8357
|
});
|
|
8144
8358
|
|
|
8145
8359
|
// core/domain/analyzer.ts
|
|
8146
|
-
import
|
|
8147
|
-
import
|
|
8360
|
+
import fs22 from "fs/promises";
|
|
8361
|
+
import path21 from "path";
|
|
8148
8362
|
import { promisify as promisify3 } from "util";
|
|
8149
8363
|
import { exec as execCallback2 } from "child_process";
|
|
8150
8364
|
var exec3, CodebaseAnalyzer, analyzer, analyzer_default2;
|
|
@@ -8168,8 +8382,8 @@ var init_analyzer2 = __esm({
|
|
|
8168
8382
|
*/
|
|
8169
8383
|
async readPackageJson() {
|
|
8170
8384
|
try {
|
|
8171
|
-
const packagePath =
|
|
8172
|
-
const content = await
|
|
8385
|
+
const packagePath = path21.join(this.projectPath, "package.json");
|
|
8386
|
+
const content = await fs22.readFile(packagePath, "utf-8");
|
|
8173
8387
|
return JSON.parse(content);
|
|
8174
8388
|
} catch {
|
|
8175
8389
|
return null;
|
|
@@ -8180,8 +8394,8 @@ var init_analyzer2 = __esm({
|
|
|
8180
8394
|
*/
|
|
8181
8395
|
async readCargoToml() {
|
|
8182
8396
|
try {
|
|
8183
|
-
const cargoPath =
|
|
8184
|
-
return await
|
|
8397
|
+
const cargoPath = path21.join(this.projectPath, "Cargo.toml");
|
|
8398
|
+
return await fs22.readFile(cargoPath, "utf-8");
|
|
8185
8399
|
} catch {
|
|
8186
8400
|
return null;
|
|
8187
8401
|
}
|
|
@@ -8191,8 +8405,8 @@ var init_analyzer2 = __esm({
|
|
|
8191
8405
|
*/
|
|
8192
8406
|
async readRequirements() {
|
|
8193
8407
|
try {
|
|
8194
|
-
const reqPath =
|
|
8195
|
-
return await
|
|
8408
|
+
const reqPath = path21.join(this.projectPath, "requirements.txt");
|
|
8409
|
+
return await fs22.readFile(reqPath, "utf-8");
|
|
8196
8410
|
} catch {
|
|
8197
8411
|
return null;
|
|
8198
8412
|
}
|
|
@@ -8202,8 +8416,8 @@ var init_analyzer2 = __esm({
|
|
|
8202
8416
|
*/
|
|
8203
8417
|
async readGoMod() {
|
|
8204
8418
|
try {
|
|
8205
|
-
const goModPath =
|
|
8206
|
-
return await
|
|
8419
|
+
const goModPath = path21.join(this.projectPath, "go.mod");
|
|
8420
|
+
return await fs22.readFile(goModPath, "utf-8");
|
|
8207
8421
|
} catch {
|
|
8208
8422
|
return null;
|
|
8209
8423
|
}
|
|
@@ -8213,8 +8427,8 @@ var init_analyzer2 = __esm({
|
|
|
8213
8427
|
*/
|
|
8214
8428
|
async readGemfile() {
|
|
8215
8429
|
try {
|
|
8216
|
-
const gemfilePath =
|
|
8217
|
-
return await
|
|
8430
|
+
const gemfilePath = path21.join(this.projectPath, "Gemfile");
|
|
8431
|
+
return await fs22.readFile(gemfilePath, "utf-8");
|
|
8218
8432
|
} catch {
|
|
8219
8433
|
return null;
|
|
8220
8434
|
}
|
|
@@ -8224,8 +8438,8 @@ var init_analyzer2 = __esm({
|
|
|
8224
8438
|
*/
|
|
8225
8439
|
async readMixExs() {
|
|
8226
8440
|
try {
|
|
8227
|
-
const mixPath =
|
|
8228
|
-
return await
|
|
8441
|
+
const mixPath = path21.join(this.projectPath, "mix.exs");
|
|
8442
|
+
return await fs22.readFile(mixPath, "utf-8");
|
|
8229
8443
|
} catch {
|
|
8230
8444
|
return null;
|
|
8231
8445
|
}
|
|
@@ -8235,8 +8449,8 @@ var init_analyzer2 = __esm({
|
|
|
8235
8449
|
*/
|
|
8236
8450
|
async readPomXml() {
|
|
8237
8451
|
try {
|
|
8238
|
-
const pomPath =
|
|
8239
|
-
return await
|
|
8452
|
+
const pomPath = path21.join(this.projectPath, "pom.xml");
|
|
8453
|
+
return await fs22.readFile(pomPath, "utf-8");
|
|
8240
8454
|
} catch {
|
|
8241
8455
|
return null;
|
|
8242
8456
|
}
|
|
@@ -8246,8 +8460,8 @@ var init_analyzer2 = __esm({
|
|
|
8246
8460
|
*/
|
|
8247
8461
|
async readComposerJson() {
|
|
8248
8462
|
try {
|
|
8249
|
-
const composerPath =
|
|
8250
|
-
const content = await
|
|
8463
|
+
const composerPath = path21.join(this.projectPath, "composer.json");
|
|
8464
|
+
const content = await fs22.readFile(composerPath, "utf-8");
|
|
8251
8465
|
return JSON.parse(content);
|
|
8252
8466
|
} catch {
|
|
8253
8467
|
return null;
|
|
@@ -8258,8 +8472,8 @@ var init_analyzer2 = __esm({
|
|
|
8258
8472
|
*/
|
|
8259
8473
|
async readPyprojectToml() {
|
|
8260
8474
|
try {
|
|
8261
|
-
const pyprojectPath =
|
|
8262
|
-
return await
|
|
8475
|
+
const pyprojectPath = path21.join(this.projectPath, "pyproject.toml");
|
|
8476
|
+
return await fs22.readFile(pyprojectPath, "utf-8");
|
|
8263
8477
|
} catch {
|
|
8264
8478
|
return null;
|
|
8265
8479
|
}
|
|
@@ -8292,7 +8506,7 @@ var init_analyzer2 = __esm({
|
|
|
8292
8506
|
*/
|
|
8293
8507
|
async listConfigFiles() {
|
|
8294
8508
|
try {
|
|
8295
|
-
const entries = await
|
|
8509
|
+
const entries = await fs22.readdir(this.projectPath);
|
|
8296
8510
|
const configPatterns = [
|
|
8297
8511
|
/^package\.json$/,
|
|
8298
8512
|
/^Cargo\.toml$/,
|
|
@@ -8319,7 +8533,7 @@ var init_analyzer2 = __esm({
|
|
|
8319
8533
|
*/
|
|
8320
8534
|
async listDirectories() {
|
|
8321
8535
|
try {
|
|
8322
|
-
const entries = await
|
|
8536
|
+
const entries = await fs22.readdir(this.projectPath, { withFileTypes: true });
|
|
8323
8537
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => !name.startsWith(".") && name !== "node_modules");
|
|
8324
8538
|
} catch {
|
|
8325
8539
|
return [];
|
|
@@ -8384,7 +8598,7 @@ var init_analyzer2 = __esm({
|
|
|
8384
8598
|
*/
|
|
8385
8599
|
async fileExists(filename) {
|
|
8386
8600
|
try {
|
|
8387
|
-
await
|
|
8601
|
+
await fs22.access(path21.join(this.projectPath, filename));
|
|
8388
8602
|
return true;
|
|
8389
8603
|
} catch {
|
|
8390
8604
|
return false;
|
|
@@ -8395,8 +8609,8 @@ var init_analyzer2 = __esm({
|
|
|
8395
8609
|
*/
|
|
8396
8610
|
async readFile(relativePath) {
|
|
8397
8611
|
try {
|
|
8398
|
-
const fullPath =
|
|
8399
|
-
return await
|
|
8612
|
+
const fullPath = path21.join(this.projectPath, relativePath);
|
|
8613
|
+
return await fs22.readFile(fullPath, "utf-8");
|
|
8400
8614
|
} catch {
|
|
8401
8615
|
return null;
|
|
8402
8616
|
}
|
|
@@ -8422,16 +8636,16 @@ var init_analyzer2 = __esm({
|
|
|
8422
8636
|
});
|
|
8423
8637
|
|
|
8424
8638
|
// core/context/generator.ts
|
|
8425
|
-
import
|
|
8426
|
-
import
|
|
8427
|
-
import
|
|
8639
|
+
import fs23 from "fs/promises";
|
|
8640
|
+
import path22 from "path";
|
|
8641
|
+
import os9 from "os";
|
|
8428
8642
|
import { exec as exec4 } from "child_process";
|
|
8429
8643
|
import { promisify as promisify4 } from "util";
|
|
8430
8644
|
async function generateContext(projectId, repoPath) {
|
|
8431
|
-
const globalPath =
|
|
8432
|
-
const contextPath =
|
|
8645
|
+
const globalPath = path22.join(os9.homedir(), ".prjct-cli/projects", projectId);
|
|
8646
|
+
const contextPath = path22.join(globalPath, "context");
|
|
8433
8647
|
const storage = getStorage(projectId);
|
|
8434
|
-
await
|
|
8648
|
+
await fs23.mkdir(contextPath, { recursive: true });
|
|
8435
8649
|
const project = await storage.read(["project"]) || {};
|
|
8436
8650
|
const taskPaths = await storage.list(["task"]);
|
|
8437
8651
|
const featurePaths = await storage.list(["feature"]);
|
|
@@ -8497,8 +8711,8 @@ async function getPackageData(repoPath) {
|
|
|
8497
8711
|
scripts: {}
|
|
8498
8712
|
};
|
|
8499
8713
|
try {
|
|
8500
|
-
const pkgPath =
|
|
8501
|
-
const pkg = JSON.parse(await
|
|
8714
|
+
const pkgPath = path22.join(repoPath, "package.json");
|
|
8715
|
+
const pkg = JSON.parse(await fs23.readFile(pkgPath, "utf-8"));
|
|
8502
8716
|
data.dependencies = pkg.dependencies || {};
|
|
8503
8717
|
data.devDependencies = pkg.devDependencies || {};
|
|
8504
8718
|
data.scripts = pkg.scripts || {};
|
|
@@ -8507,7 +8721,7 @@ async function getPackageData(repoPath) {
|
|
|
8507
8721
|
return data;
|
|
8508
8722
|
}
|
|
8509
8723
|
async function generateClaudeMd(contextPath, projectId, project, tasks, features, ideas, agents, gitData, pkgData, repoPath) {
|
|
8510
|
-
const projectName = project.name ||
|
|
8724
|
+
const projectName = project.name || path22.basename(repoPath);
|
|
8511
8725
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
8512
8726
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
8513
8727
|
const activeFeatures = features.filter((f) => f.status === "in_progress" || f.status === "active");
|
|
@@ -8582,7 +8796,7 @@ ${agents.length > 0 ? agents.map((a) => `- **${a.name}**: ${a.role || "Specialis
|
|
|
8582
8796
|
\u2514\u2500\u2500 pending.json
|
|
8583
8797
|
\`\`\`
|
|
8584
8798
|
`;
|
|
8585
|
-
await
|
|
8799
|
+
await fs23.writeFile(path22.join(contextPath, "CLAUDE.md"), content, "utf-8");
|
|
8586
8800
|
}
|
|
8587
8801
|
async function generateNowMd(contextPath, tasks) {
|
|
8588
8802
|
const currentTask = tasks.find((t) => t.status === "in_progress");
|
|
@@ -8597,7 +8811,7 @@ async function generateNowMd(contextPath, tasks) {
|
|
|
8597
8811
|
|
|
8598
8812
|
_No active task. Use /p:now to start._
|
|
8599
8813
|
`;
|
|
8600
|
-
await
|
|
8814
|
+
await fs23.writeFile(path22.join(contextPath, "now.md"), content, "utf-8");
|
|
8601
8815
|
}
|
|
8602
8816
|
async function generateQueueMd(contextPath, tasks) {
|
|
8603
8817
|
const pendingTasks = tasks.filter((t) => t.status === "pending");
|
|
@@ -8605,7 +8819,7 @@ async function generateQueueMd(contextPath, tasks) {
|
|
|
8605
8819
|
|
|
8606
8820
|
${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._"}
|
|
8607
8821
|
`;
|
|
8608
|
-
await
|
|
8822
|
+
await fs23.writeFile(path22.join(contextPath, "queue.md"), content, "utf-8");
|
|
8609
8823
|
}
|
|
8610
8824
|
async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
8611
8825
|
const content = `# PROJECT SUMMARY
|
|
@@ -8625,7 +8839,7 @@ async function generateSummaryMd(contextPath, project, gitData, pkgData) {
|
|
|
8625
8839
|
- Production: ${Object.keys(pkgData.dependencies).length}
|
|
8626
8840
|
- Dev: ${Object.keys(pkgData.devDependencies).length}
|
|
8627
8841
|
`;
|
|
8628
|
-
await
|
|
8842
|
+
await fs23.writeFile(path22.join(contextPath, "summary.md"), content, "utf-8");
|
|
8629
8843
|
}
|
|
8630
8844
|
var execAsync2;
|
|
8631
8845
|
var init_generator = __esm({
|
|
@@ -8648,7 +8862,7 @@ var analysis_exports = {};
|
|
|
8648
8862
|
__export(analysis_exports, {
|
|
8649
8863
|
AnalysisCommands: () => AnalysisCommands
|
|
8650
8864
|
});
|
|
8651
|
-
import
|
|
8865
|
+
import path23 from "path";
|
|
8652
8866
|
var AnalysisCommands;
|
|
8653
8867
|
var init_analysis2 = __esm({
|
|
8654
8868
|
"core/commands/analysis.ts"() {
|
|
@@ -8728,7 +8942,7 @@ var init_analysis2 = __esm({
|
|
|
8728
8942
|
lines.push("# Repository Analysis\n");
|
|
8729
8943
|
lines.push(`Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
8730
8944
|
`);
|
|
8731
|
-
const projectName =
|
|
8945
|
+
const projectName = path23.basename(projectPath);
|
|
8732
8946
|
lines.push(`## Project: ${projectName}
|
|
8733
8947
|
`);
|
|
8734
8948
|
lines.push("## Stack Detected\n");
|
|
@@ -8852,7 +9066,7 @@ var planning_exports = {};
|
|
|
8852
9066
|
__export(planning_exports, {
|
|
8853
9067
|
PlanningCommands: () => PlanningCommands
|
|
8854
9068
|
});
|
|
8855
|
-
import
|
|
9069
|
+
import path24 from "path";
|
|
8856
9070
|
async function getAnalysisCommands() {
|
|
8857
9071
|
if (!_analysisCommands) {
|
|
8858
9072
|
const { AnalysisCommands: AnalysisCommands2 } = await Promise.resolve().then(() => (init_analysis2(), analysis_exports));
|
|
@@ -8917,7 +9131,7 @@ var init_planning = __esm({
|
|
|
8917
9131
|
}, null, 2)
|
|
8918
9132
|
};
|
|
8919
9133
|
for (const [filePath, content] of Object.entries(baseFiles)) {
|
|
8920
|
-
await tool_registry_default.get("Write")(
|
|
9134
|
+
await tool_registry_default.get("Write")(path24.join(globalPath, filePath), content);
|
|
8921
9135
|
}
|
|
8922
9136
|
const isEmpty = await this._detectEmptyDirectory(projectPath);
|
|
8923
9137
|
const hasCode = await this._detectExistingCode(projectPath);
|
|
@@ -8938,7 +9152,7 @@ var init_planning = __esm({
|
|
|
8938
9152
|
return { success: true, mode: "blank_no_idea", projectId };
|
|
8939
9153
|
}
|
|
8940
9154
|
output_default.spin("architect mode...");
|
|
8941
|
-
const sessionPath =
|
|
9155
|
+
const sessionPath = path24.join(globalPath, "planning", "architect-session.md");
|
|
8942
9156
|
const sessionContent = `# Architect Session
|
|
8943
9157
|
|
|
8944
9158
|
## Idea
|
|
@@ -9080,7 +9294,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9080
9294
|
if (!initResult.success) return initResult;
|
|
9081
9295
|
console.log("\u{1F3D7}\uFE0F Architect Mode - Code Generation\n");
|
|
9082
9296
|
const globalPath = await this.getGlobalProjectPath(projectPath);
|
|
9083
|
-
const planPath =
|
|
9297
|
+
const planPath = path24.join(globalPath, "planning", "architect-session.md");
|
|
9084
9298
|
let planContent;
|
|
9085
9299
|
try {
|
|
9086
9300
|
planContent = await file_helper_exports.readFile(planPath);
|
|
@@ -9154,7 +9368,7 @@ ${steps}`);
|
|
|
9154
9368
|
if (isComplex) {
|
|
9155
9369
|
output_default.spin("analyzing idea...");
|
|
9156
9370
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
9157
|
-
const sessionPath =
|
|
9371
|
+
const sessionPath = path24.join(globalPath, "planning", "architect-session.md");
|
|
9158
9372
|
const sessionContent = `# Architect Session
|
|
9159
9373
|
|
|
9160
9374
|
## Idea
|
|
@@ -9209,10 +9423,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9209
9423
|
if (!featureName) {
|
|
9210
9424
|
output_default.spin("loading specs...");
|
|
9211
9425
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
9212
|
-
const specsPath2 =
|
|
9426
|
+
const specsPath2 = path24.join(globalPath2, "planning", "specs");
|
|
9213
9427
|
try {
|
|
9214
|
-
const
|
|
9215
|
-
const files = await
|
|
9428
|
+
const fs25 = await import("fs/promises");
|
|
9429
|
+
const files = await fs25.readdir(specsPath2);
|
|
9216
9430
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
9217
9431
|
if (specs.length === 0) {
|
|
9218
9432
|
output_default.warn("no specs yet");
|
|
@@ -9234,10 +9448,10 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
9234
9448
|
}
|
|
9235
9449
|
output_default.spin("creating spec...");
|
|
9236
9450
|
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
9237
|
-
const specsPath =
|
|
9451
|
+
const specsPath = path24.join(globalPath, "planning", "specs");
|
|
9238
9452
|
await file_helper_exports.ensureDir(specsPath);
|
|
9239
9453
|
const slug = featureName.toLowerCase().replace(/\s+/g, "-");
|
|
9240
|
-
const specFile =
|
|
9454
|
+
const specFile = path24.join(specsPath, `${slug}.md`);
|
|
9241
9455
|
const specContent = `# Specification: ${featureName}
|
|
9242
9456
|
|
|
9243
9457
|
## Overview
|
|
@@ -9849,18 +10063,18 @@ var init_workflow = __esm({
|
|
|
9849
10063
|
});
|
|
9850
10064
|
|
|
9851
10065
|
// core/utils/project-commands.ts
|
|
9852
|
-
import
|
|
10066
|
+
import path25 from "path";
|
|
9853
10067
|
async function detectPackageManager(projectPath, pkg) {
|
|
9854
10068
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
9855
10069
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
9856
10070
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
9857
10071
|
if (declared?.startsWith("bun@")) return "bun";
|
|
9858
10072
|
if (declared?.startsWith("npm@")) return "npm";
|
|
9859
|
-
if (await fileExists(
|
|
9860
|
-
if (await fileExists(
|
|
9861
|
-
if (await fileExists(
|
|
9862
|
-
if (await fileExists(
|
|
9863
|
-
if (await fileExists(
|
|
10073
|
+
if (await fileExists(path25.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
10074
|
+
if (await fileExists(path25.join(projectPath, "yarn.lock"))) return "yarn";
|
|
10075
|
+
if (await fileExists(path25.join(projectPath, "bun.lockb"))) return "bun";
|
|
10076
|
+
if (await fileExists(path25.join(projectPath, "bun.lock"))) return "bun";
|
|
10077
|
+
if (await fileExists(path25.join(projectPath, "package-lock.json"))) return "npm";
|
|
9864
10078
|
return "npm";
|
|
9865
10079
|
}
|
|
9866
10080
|
function pmRun(pm, scriptName) {
|
|
@@ -9876,7 +10090,7 @@ function pmTest(pm) {
|
|
|
9876
10090
|
return "npm test";
|
|
9877
10091
|
}
|
|
9878
10092
|
async function detectProjectCommands(projectPath) {
|
|
9879
|
-
const pkgPath =
|
|
10093
|
+
const pkgPath = path25.join(projectPath, "package.json");
|
|
9880
10094
|
const pkg = await readJson(pkgPath, null);
|
|
9881
10095
|
if (pkg) {
|
|
9882
10096
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -9893,27 +10107,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
9893
10107
|
}
|
|
9894
10108
|
return result;
|
|
9895
10109
|
}
|
|
9896
|
-
if (await fileExists(
|
|
10110
|
+
if (await fileExists(path25.join(projectPath, "pytest.ini"))) {
|
|
9897
10111
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
9898
10112
|
}
|
|
9899
|
-
const pyproject = await readFile(
|
|
10113
|
+
const pyproject = await readFile(path25.join(projectPath, "pyproject.toml"), "");
|
|
9900
10114
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
9901
10115
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
9902
10116
|
}
|
|
9903
|
-
if (await fileExists(
|
|
10117
|
+
if (await fileExists(path25.join(projectPath, "Cargo.toml"))) {
|
|
9904
10118
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
9905
10119
|
}
|
|
9906
|
-
if (await fileExists(
|
|
10120
|
+
if (await fileExists(path25.join(projectPath, "go.mod"))) {
|
|
9907
10121
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
9908
10122
|
}
|
|
9909
10123
|
const files = await listFiles(projectPath);
|
|
9910
10124
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
9911
10125
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
9912
10126
|
}
|
|
9913
|
-
if (await fileExists(
|
|
10127
|
+
if (await fileExists(path25.join(projectPath, "pom.xml"))) {
|
|
9914
10128
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
9915
10129
|
}
|
|
9916
|
-
if (await fileExists(
|
|
10130
|
+
if (await fileExists(path25.join(projectPath, "gradlew")) && (await fileExists(path25.join(projectPath, "build.gradle")) || await fileExists(path25.join(projectPath, "build.gradle.kts")))) {
|
|
9917
10131
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
9918
10132
|
}
|
|
9919
10133
|
return { stack: "unknown" };
|
|
@@ -9930,7 +10144,7 @@ var init_project_commands = __esm({
|
|
|
9930
10144
|
});
|
|
9931
10145
|
|
|
9932
10146
|
// core/commands/shipping.ts
|
|
9933
|
-
import
|
|
10147
|
+
import path26 from "path";
|
|
9934
10148
|
var ShippingCommands;
|
|
9935
10149
|
var init_shipping = __esm({
|
|
9936
10150
|
"core/commands/shipping.ts"() {
|
|
@@ -10052,7 +10266,7 @@ ${result.stderr}`.trim();
|
|
|
10052
10266
|
*/
|
|
10053
10267
|
async _bumpVersion(projectPath) {
|
|
10054
10268
|
try {
|
|
10055
|
-
const pkgPath =
|
|
10269
|
+
const pkgPath = path26.join(projectPath, "package.json");
|
|
10056
10270
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
10057
10271
|
const oldVersion = pkg?.version || "0.0.0";
|
|
10058
10272
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -10071,7 +10285,7 @@ ${result.stderr}`.trim();
|
|
|
10071
10285
|
*/
|
|
10072
10286
|
async _updateChangelog(feature, version, projectPath) {
|
|
10073
10287
|
try {
|
|
10074
|
-
const changelogPath =
|
|
10288
|
+
const changelogPath = path26.join(projectPath, "CHANGELOG.md");
|
|
10075
10289
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
10076
10290
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
10077
10291
|
|
|
@@ -10457,7 +10671,7 @@ var init_registry = __esm({
|
|
|
10457
10671
|
});
|
|
10458
10672
|
|
|
10459
10673
|
// core/commands/analytics.ts
|
|
10460
|
-
import
|
|
10674
|
+
import path27 from "path";
|
|
10461
10675
|
var AnalyticsCommands;
|
|
10462
10676
|
var init_analytics = __esm({
|
|
10463
10677
|
"core/commands/analytics.ts"() {
|
|
@@ -10482,7 +10696,7 @@ var init_analytics = __esm({
|
|
|
10482
10696
|
output_default.fail("no project ID");
|
|
10483
10697
|
return { success: false, error: "No project ID found" };
|
|
10484
10698
|
}
|
|
10485
|
-
const projectName =
|
|
10699
|
+
const projectName = path27.basename(projectPath);
|
|
10486
10700
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
10487
10701
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
10488
10702
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -10720,7 +10934,7 @@ ${catInfo?.title || cat}:`);
|
|
|
10720
10934
|
});
|
|
10721
10935
|
|
|
10722
10936
|
// core/commands/cleanup.ts
|
|
10723
|
-
import
|
|
10937
|
+
import path28 from "path";
|
|
10724
10938
|
async function cleanupMemory(projectPath) {
|
|
10725
10939
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
10726
10940
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -10736,7 +10950,7 @@ async function cleanupMemory(projectPath) {
|
|
|
10736
10950
|
results.totalSize += sizeMB;
|
|
10737
10951
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
10738
10952
|
if (rotated) {
|
|
10739
|
-
results.rotated.push(
|
|
10953
|
+
results.rotated.push(path28.basename(filePath));
|
|
10740
10954
|
results.freedSpace += sizeMB;
|
|
10741
10955
|
}
|
|
10742
10956
|
}
|
|
@@ -10827,7 +11041,7 @@ var init_cleanup = __esm({
|
|
|
10827
11041
|
});
|
|
10828
11042
|
|
|
10829
11043
|
// core/commands/design.ts
|
|
10830
|
-
import
|
|
11044
|
+
import path29 from "path";
|
|
10831
11045
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
10832
11046
|
try {
|
|
10833
11047
|
const designType = options.type || "architecture";
|
|
@@ -10839,7 +11053,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
10839
11053
|
const designTarget = target || "system";
|
|
10840
11054
|
output_default.spin(`designing ${designType}...`);
|
|
10841
11055
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
10842
|
-
const designsPath =
|
|
11056
|
+
const designsPath = path29.join(
|
|
10843
11057
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
10844
11058
|
"planning",
|
|
10845
11059
|
"designs"
|
|
@@ -10879,7 +11093,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
10879
11093
|
break;
|
|
10880
11094
|
}
|
|
10881
11095
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
10882
|
-
const designFilePath =
|
|
11096
|
+
const designFilePath = path29.join(designsPath, designFileName);
|
|
10883
11097
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
10884
11098
|
await memoryService.log(projectPath, "design_created", {
|
|
10885
11099
|
type: designType,
|
|
@@ -10903,7 +11117,7 @@ var init_design = __esm({
|
|
|
10903
11117
|
});
|
|
10904
11118
|
|
|
10905
11119
|
// core/commands/snapshots.ts
|
|
10906
|
-
import
|
|
11120
|
+
import path30 from "path";
|
|
10907
11121
|
async function recover(projectPath = process.cwd()) {
|
|
10908
11122
|
try {
|
|
10909
11123
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -10951,7 +11165,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
10951
11165
|
output_default.fail("no project ID");
|
|
10952
11166
|
return { success: false, error: "No project ID found" };
|
|
10953
11167
|
}
|
|
10954
|
-
const snapshotsPath =
|
|
11168
|
+
const snapshotsPath = path30.join(
|
|
10955
11169
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
10956
11170
|
"snapshots"
|
|
10957
11171
|
);
|
|
@@ -10972,7 +11186,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
10972
11186
|
cwd: projectPath,
|
|
10973
11187
|
encoding: "utf-8"
|
|
10974
11188
|
});
|
|
10975
|
-
const snapshotFile =
|
|
11189
|
+
const snapshotFile = path30.join(snapshotsPath, "history.json");
|
|
10976
11190
|
let history2 = { snapshots: [], current: -1 };
|
|
10977
11191
|
try {
|
|
10978
11192
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11009,11 +11223,11 @@ async function redo(projectPath = process.cwd()) {
|
|
|
11009
11223
|
output_default.fail("no project ID");
|
|
11010
11224
|
return { success: false, error: "No project ID found" };
|
|
11011
11225
|
}
|
|
11012
|
-
const snapshotsPath =
|
|
11226
|
+
const snapshotsPath = path30.join(
|
|
11013
11227
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11014
11228
|
"snapshots"
|
|
11015
11229
|
);
|
|
11016
|
-
const snapshotFile =
|
|
11230
|
+
const snapshotFile = path30.join(snapshotsPath, "history.json");
|
|
11017
11231
|
let history2;
|
|
11018
11232
|
try {
|
|
11019
11233
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11069,11 +11283,11 @@ async function history(projectPath = process.cwd()) {
|
|
|
11069
11283
|
output_default.fail("no project ID");
|
|
11070
11284
|
return { success: false, error: "No project ID found" };
|
|
11071
11285
|
}
|
|
11072
|
-
const snapshotsPath =
|
|
11286
|
+
const snapshotsPath = path30.join(
|
|
11073
11287
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
11074
11288
|
"snapshots"
|
|
11075
11289
|
);
|
|
11076
|
-
const snapshotFile =
|
|
11290
|
+
const snapshotFile = path30.join(snapshotsPath, "history.json");
|
|
11077
11291
|
let snapshotHistory;
|
|
11078
11292
|
try {
|
|
11079
11293
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -11175,9 +11389,9 @@ var init_maintenance = __esm({
|
|
|
11175
11389
|
});
|
|
11176
11390
|
|
|
11177
11391
|
// core/commands/setup.ts
|
|
11178
|
-
import
|
|
11179
|
-
import
|
|
11180
|
-
import
|
|
11392
|
+
import path31 from "path";
|
|
11393
|
+
import fs24 from "fs";
|
|
11394
|
+
import os10 from "os";
|
|
11181
11395
|
import chalk4 from "chalk";
|
|
11182
11396
|
var SetupCommands;
|
|
11183
11397
|
var init_setup2 = __esm({
|
|
@@ -11284,37 +11498,71 @@ var init_setup2 = __esm({
|
|
|
11284
11498
|
*/
|
|
11285
11499
|
async installStatusLine() {
|
|
11286
11500
|
try {
|
|
11287
|
-
const claudeDir =
|
|
11288
|
-
const settingsPath =
|
|
11289
|
-
const statusLinePath =
|
|
11501
|
+
const claudeDir = path31.join(os10.homedir(), ".claude");
|
|
11502
|
+
const settingsPath = path31.join(claudeDir, "settings.json");
|
|
11503
|
+
const statusLinePath = path31.join(claudeDir, "prjct-statusline.sh");
|
|
11290
11504
|
const scriptContent = `#!/bin/bash
|
|
11291
11505
|
# prjct Status Line for Claude Code
|
|
11292
|
-
# Shows
|
|
11506
|
+
# Shows version update notifications and current task
|
|
11507
|
+
|
|
11508
|
+
# Current CLI version (embedded at install time)
|
|
11509
|
+
CLI_VERSION="${VERSION}"
|
|
11293
11510
|
|
|
11294
11511
|
# Read JSON context from stdin (provided by Claude Code)
|
|
11295
11512
|
read -r json
|
|
11296
11513
|
|
|
11297
|
-
#
|
|
11298
|
-
|
|
11299
|
-
|
|
11300
|
-
#
|
|
11301
|
-
|
|
11302
|
-
|
|
11303
|
-
#
|
|
11304
|
-
|
|
11305
|
-
|
|
11306
|
-
if [ -
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11514
|
+
# Extract cwd from JSON
|
|
11515
|
+
CWD=$(echo "$json" | grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
11516
|
+
|
|
11517
|
+
# Check if this is a prjct project
|
|
11518
|
+
CONFIG="$CWD/.prjct/prjct.config.json"
|
|
11519
|
+
if [[ -f "$CONFIG" ]]; then
|
|
11520
|
+
# Extract projectId
|
|
11521
|
+
PROJECT_ID=$(grep -o '"projectId"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | sed 's/.*"projectId"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
11522
|
+
|
|
11523
|
+
if [[ -n "$PROJECT_ID" ]]; then
|
|
11524
|
+
PROJECT_JSON="$HOME/.prjct-cli/projects/$PROJECT_ID/project.json"
|
|
11525
|
+
|
|
11526
|
+
# Check version mismatch
|
|
11527
|
+
if [[ -f "$PROJECT_JSON" ]]; then
|
|
11528
|
+
PROJECT_VERSION=$(grep -o '"cliVersion"[[:space:]]*:[[:space:]]*"[^"]*"' "$PROJECT_JSON" | sed 's/.*"cliVersion"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
11529
|
+
|
|
11530
|
+
# If no cliVersion or different version, show update notice
|
|
11531
|
+
if [[ -z "$PROJECT_VERSION" ]] || [[ "$PROJECT_VERSION" != "$CLI_VERSION" ]]; then
|
|
11532
|
+
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
11533
|
+
exit 0
|
|
11534
|
+
fi
|
|
11535
|
+
else
|
|
11536
|
+
# No project.json means project needs sync
|
|
11537
|
+
echo "\u26A0\uFE0F prjct v$CLI_VERSION available! Run /p:sync"
|
|
11538
|
+
exit 0
|
|
11539
|
+
fi
|
|
11540
|
+
|
|
11541
|
+
# Show current task if exists
|
|
11542
|
+
STATE="$HOME/.prjct-cli/projects/$PROJECT_ID/storage/state.json"
|
|
11543
|
+
if [[ -f "$STATE" ]]; then
|
|
11544
|
+
TASK=$(grep -o '"description"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"description"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
11545
|
+
STATUS=$(grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE" | head -1 | sed 's/.*"status"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/')
|
|
11546
|
+
|
|
11547
|
+
if [[ -n "$TASK" ]] && [[ "$STATUS" == "active" ]]; then
|
|
11548
|
+
# Truncate task to 40 chars
|
|
11549
|
+
TASK_SHORT="\${TASK:0:40}"
|
|
11550
|
+
[[ \${#TASK} -gt 40 ]] && TASK_SHORT="$TASK_SHORT..."
|
|
11551
|
+
echo "\u{1F3AF} $TASK_SHORT"
|
|
11552
|
+
exit 0
|
|
11553
|
+
fi
|
|
11554
|
+
fi
|
|
11555
|
+
fi
|
|
11311
11556
|
fi
|
|
11557
|
+
|
|
11558
|
+
# Default: show prjct branding
|
|
11559
|
+
echo "\u26A1 prjct"
|
|
11312
11560
|
`;
|
|
11313
|
-
|
|
11561
|
+
fs24.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
11314
11562
|
let settings = {};
|
|
11315
|
-
if (
|
|
11563
|
+
if (fs24.existsSync(settingsPath)) {
|
|
11316
11564
|
try {
|
|
11317
|
-
settings = JSON.parse(
|
|
11565
|
+
settings = JSON.parse(fs24.readFileSync(settingsPath, "utf8"));
|
|
11318
11566
|
} catch {
|
|
11319
11567
|
}
|
|
11320
11568
|
}
|
|
@@ -11322,7 +11570,7 @@ fi
|
|
|
11322
11570
|
type: "command",
|
|
11323
11571
|
command: statusLinePath
|
|
11324
11572
|
};
|
|
11325
|
-
|
|
11573
|
+
fs24.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
11326
11574
|
return { success: true };
|
|
11327
11575
|
} catch (error) {
|
|
11328
11576
|
return { success: false, error: error.message };
|
|
@@ -11355,8 +11603,8 @@ fi
|
|
|
11355
11603
|
console.log(` ${chalk4.bold("1.")} Initialize your project:`);
|
|
11356
11604
|
console.log(` ${chalk4.green("cd your-project && prjct init")}`);
|
|
11357
11605
|
console.log("");
|
|
11358
|
-
console.log(` ${chalk4.bold("2.")}
|
|
11359
|
-
console.log(` ${chalk4.green('prjct
|
|
11606
|
+
console.log(` ${chalk4.bold("2.")} Start your first task:`);
|
|
11607
|
+
console.log(` ${chalk4.green('prjct task "build auth"')}`);
|
|
11360
11608
|
console.log("");
|
|
11361
11609
|
console.log(` ${chalk4.bold("3.")} Ship & celebrate:`);
|
|
11362
11610
|
console.log(` ${chalk4.green('prjct ship "user login"')}`);
|
|
@@ -11578,16 +11826,27 @@ var init_command_data = __esm({
|
|
|
11578
11826
|
requiresProject: true,
|
|
11579
11827
|
features: ["Simple ideas -> Quick capture", "Complex ideas -> Full architecture"]
|
|
11580
11828
|
},
|
|
11829
|
+
{
|
|
11830
|
+
name: "task",
|
|
11831
|
+
group: "core",
|
|
11832
|
+
description: "Start task with agentic classification and 7-phase workflow",
|
|
11833
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
11834
|
+
params: "<description>",
|
|
11835
|
+
implemented: true,
|
|
11836
|
+
hasTemplate: true,
|
|
11837
|
+
requiresProject: true,
|
|
11838
|
+
features: ["Agentic type classification", "7-phase workflow", "Git branch management", "Task breakdown"]
|
|
11839
|
+
},
|
|
11581
11840
|
{
|
|
11582
11841
|
name: "feature",
|
|
11583
11842
|
group: "core",
|
|
11584
|
-
description: "
|
|
11585
|
-
usage: { claude: '/p:
|
|
11843
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
11844
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
11586
11845
|
params: "<description>",
|
|
11587
11846
|
implemented: true,
|
|
11588
11847
|
hasTemplate: true,
|
|
11589
11848
|
requiresProject: true,
|
|
11590
|
-
|
|
11849
|
+
deprecated: true
|
|
11591
11850
|
},
|
|
11592
11851
|
{
|
|
11593
11852
|
name: "spec",
|
|
@@ -11602,22 +11861,24 @@ var init_command_data = __esm({
|
|
|
11602
11861
|
{
|
|
11603
11862
|
name: "now",
|
|
11604
11863
|
group: "core",
|
|
11605
|
-
description: "
|
|
11606
|
-
usage: { claude: '/p:
|
|
11607
|
-
params: "[task]
|
|
11864
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
11865
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
11866
|
+
params: "[task]",
|
|
11608
11867
|
implemented: true,
|
|
11609
11868
|
hasTemplate: true,
|
|
11610
|
-
requiresProject: true
|
|
11869
|
+
requiresProject: true,
|
|
11870
|
+
deprecated: true
|
|
11611
11871
|
},
|
|
11612
11872
|
{
|
|
11613
11873
|
name: "work",
|
|
11614
11874
|
group: "core",
|
|
11615
|
-
description: "
|
|
11616
|
-
usage: { claude: '/p:
|
|
11875
|
+
description: "DEPRECATED - Use /p:task instead",
|
|
11876
|
+
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
11617
11877
|
params: "[task]",
|
|
11618
11878
|
implemented: true,
|
|
11619
11879
|
hasTemplate: true,
|
|
11620
|
-
requiresProject: true
|
|
11880
|
+
requiresProject: true,
|
|
11881
|
+
deprecated: true
|
|
11621
11882
|
},
|
|
11622
11883
|
{
|
|
11623
11884
|
name: "pause",
|
|
@@ -11942,7 +12203,7 @@ var require_package = __commonJS({
|
|
|
11942
12203
|
"package.json"(exports, module) {
|
|
11943
12204
|
module.exports = {
|
|
11944
12205
|
name: "prjct-cli",
|
|
11945
|
-
version: "0.
|
|
12206
|
+
version: "0.28.0",
|
|
11946
12207
|
description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
|
|
11947
12208
|
main: "core/index.ts",
|
|
11948
12209
|
bin: {
|
|
@@ -11991,7 +12252,7 @@ var require_package = __commonJS({
|
|
|
11991
12252
|
dependencies: {
|
|
11992
12253
|
"@hono/node-server": "^1.13.7",
|
|
11993
12254
|
chalk: "^4.1.2",
|
|
11994
|
-
esbuild: "^0.
|
|
12255
|
+
esbuild: "^0.25.0",
|
|
11995
12256
|
glob: "^10.3.10",
|
|
11996
12257
|
hono: "^4.11.3",
|
|
11997
12258
|
"jsonc-parser": "^3.3.1",
|
|
@@ -12040,10 +12301,7 @@ var require_package = __commonJS({
|
|
|
12040
12301
|
trustedDependencies: [
|
|
12041
12302
|
"chalk",
|
|
12042
12303
|
"prompts"
|
|
12043
|
-
]
|
|
12044
|
-
overrides: {
|
|
12045
|
-
esbuild: "^0.25.0"
|
|
12046
|
-
}
|
|
12304
|
+
]
|
|
12047
12305
|
};
|
|
12048
12306
|
}
|
|
12049
12307
|
});
|