prjct-cli 0.47.0 → 0.49.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 +52 -3821
- package/core/agentic/context-builder.ts +4 -4
- package/core/agentic/memory-system.ts +3 -1
- package/core/agentic/prompt-builder.ts +6 -2
- package/core/agentic/smart-context.ts +2 -2
- package/core/ai-tools/generator.ts +11 -1
- package/core/cli/linear.ts +5 -4
- package/core/commands/analytics.ts +4 -2
- package/core/commands/cleanup.ts +1 -1
- package/core/commands/commands.ts +1 -1
- package/core/commands/planning.ts +4 -4
- package/core/commands/registry.ts +3 -2
- package/core/commands/shipping.ts +1 -1
- package/core/commands/snapshots.ts +6 -6
- package/core/commands/workflow.ts +6 -6
- package/core/constants/index.ts +3 -1
- package/core/context-tools/imports-tool.ts +1 -1
- package/core/context-tools/signatures-tool.ts +1 -1
- package/core/plugin/hooks.ts +1 -1
- package/core/services/agent-generator.ts +58 -6
- package/core/services/context-generator.ts +35 -15
- package/core/utils/error-messages.ts +161 -0
- package/core/utils/help.ts +0 -1
- package/core/utils/markdown-builder.ts +9 -3
- package/core/utils/output.ts +24 -0
- package/core/utils/preserve-sections.ts +1 -1
- package/core/utils/project-commands.ts +0 -6
- package/core/utils/subtask-table.ts +1 -1
- package/dist/bin/prjct.mjs +308 -96
- package/package.json +1 -1
- package/templates/global/CLAUDE.md +27 -0
package/dist/bin/prjct.mjs
CHANGED
|
@@ -1944,10 +1944,130 @@ var init_branding = __esm({
|
|
|
1944
1944
|
}
|
|
1945
1945
|
});
|
|
1946
1946
|
|
|
1947
|
+
// core/utils/error-messages.ts
|
|
1948
|
+
function getError(code, overrides) {
|
|
1949
|
+
const base = ERRORS[code];
|
|
1950
|
+
return { ...base, ...overrides };
|
|
1951
|
+
}
|
|
1952
|
+
function createError(message, hint, options) {
|
|
1953
|
+
return {
|
|
1954
|
+
message,
|
|
1955
|
+
hint,
|
|
1956
|
+
...options
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
var ERRORS;
|
|
1960
|
+
var init_error_messages = __esm({
|
|
1961
|
+
"core/utils/error-messages.ts"() {
|
|
1962
|
+
"use strict";
|
|
1963
|
+
ERRORS = {
|
|
1964
|
+
// Project errors
|
|
1965
|
+
NO_PROJECT: {
|
|
1966
|
+
message: "No prjct project found in this directory",
|
|
1967
|
+
hint: "Run 'prjct init' to set up a new project",
|
|
1968
|
+
file: ".prjct/prjct.config.json"
|
|
1969
|
+
},
|
|
1970
|
+
NO_PROJECT_ID: {
|
|
1971
|
+
message: "Project ID not found",
|
|
1972
|
+
hint: "Run 'prjct init' or check .prjct/prjct.config.json",
|
|
1973
|
+
file: ".prjct/prjct.config.json"
|
|
1974
|
+
},
|
|
1975
|
+
CONFIG_NOT_FOUND: {
|
|
1976
|
+
message: "Configuration file not found",
|
|
1977
|
+
hint: "Run 'prjct init' to create project configuration",
|
|
1978
|
+
file: ".prjct/prjct.config.json"
|
|
1979
|
+
},
|
|
1980
|
+
CONFIG_INVALID: {
|
|
1981
|
+
message: "Invalid configuration file",
|
|
1982
|
+
hint: "Check JSON syntax or delete .prjct/ and run init again",
|
|
1983
|
+
file: ".prjct/prjct.config.json"
|
|
1984
|
+
},
|
|
1985
|
+
// Git errors
|
|
1986
|
+
GIT_NOT_FOUND: {
|
|
1987
|
+
message: "Git repository not detected",
|
|
1988
|
+
hint: "Run 'git init' first, then 'prjct init'"
|
|
1989
|
+
},
|
|
1990
|
+
GIT_NO_COMMITS: {
|
|
1991
|
+
message: "No commits in repository",
|
|
1992
|
+
hint: "Make an initial commit before using prjct"
|
|
1993
|
+
},
|
|
1994
|
+
GIT_DIRTY: {
|
|
1995
|
+
message: "Working directory has uncommitted changes",
|
|
1996
|
+
hint: "Commit or stash changes, or use '--force' to override"
|
|
1997
|
+
},
|
|
1998
|
+
GIT_ON_MAIN: {
|
|
1999
|
+
message: "Cannot ship from main/master branch",
|
|
2000
|
+
hint: "Create a feature branch first: git checkout -b feature/your-feature"
|
|
2001
|
+
},
|
|
2002
|
+
GIT_OPERATION_FAILED: {
|
|
2003
|
+
message: "Git operation failed",
|
|
2004
|
+
hint: "Check git status and resolve any conflicts"
|
|
2005
|
+
},
|
|
2006
|
+
// Auth errors
|
|
2007
|
+
GH_NOT_AUTHENTICATED: {
|
|
2008
|
+
message: "GitHub CLI not authenticated",
|
|
2009
|
+
hint: "Run 'gh auth login' to authenticate",
|
|
2010
|
+
docs: "https://cli.github.com/manual/gh_auth_login"
|
|
2011
|
+
},
|
|
2012
|
+
LINEAR_NOT_CONFIGURED: {
|
|
2013
|
+
message: "Linear integration not configured",
|
|
2014
|
+
hint: "Run 'p. linear setup' to configure Linear"
|
|
2015
|
+
},
|
|
2016
|
+
LINEAR_API_ERROR: {
|
|
2017
|
+
message: "Linear API error",
|
|
2018
|
+
hint: "Check your API key or network connection"
|
|
2019
|
+
},
|
|
2020
|
+
// Task errors
|
|
2021
|
+
NO_ACTIVE_TASK: {
|
|
2022
|
+
message: "No active task",
|
|
2023
|
+
hint: `Start a task with 'p. task "description"'`
|
|
2024
|
+
},
|
|
2025
|
+
TASK_ALREADY_ACTIVE: {
|
|
2026
|
+
message: "A task is already in progress",
|
|
2027
|
+
hint: "Complete it with 'p. done' or pause with 'p. pause'"
|
|
2028
|
+
},
|
|
2029
|
+
// Sync errors
|
|
2030
|
+
SYNC_FAILED: {
|
|
2031
|
+
message: "Project sync failed",
|
|
2032
|
+
hint: "Check file permissions and try again"
|
|
2033
|
+
},
|
|
2034
|
+
// Ship errors
|
|
2035
|
+
NOTHING_TO_SHIP: {
|
|
2036
|
+
message: "Nothing to ship",
|
|
2037
|
+
hint: "Make some changes first, then run ship"
|
|
2038
|
+
},
|
|
2039
|
+
PR_CREATE_FAILED: {
|
|
2040
|
+
message: "Failed to create pull request",
|
|
2041
|
+
hint: "Check GitHub auth and remote configuration"
|
|
2042
|
+
},
|
|
2043
|
+
// Provider errors
|
|
2044
|
+
NO_AI_PROVIDER: {
|
|
2045
|
+
message: "No AI provider detected",
|
|
2046
|
+
hint: "Install Claude Code or Gemini CLI, then run 'prjct start'",
|
|
2047
|
+
docs: "https://prjct.app/docs"
|
|
2048
|
+
},
|
|
2049
|
+
PROVIDER_NOT_CONFIGURED: {
|
|
2050
|
+
message: "AI provider not configured for prjct",
|
|
2051
|
+
hint: "Run 'prjct start' to configure your provider"
|
|
2052
|
+
},
|
|
2053
|
+
// Generic
|
|
2054
|
+
UNKNOWN: {
|
|
2055
|
+
message: "An unexpected error occurred",
|
|
2056
|
+
hint: "Check the error details and try again"
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
__name(getError, "getError");
|
|
2060
|
+
__name(createError, "createError");
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
|
|
1947
2064
|
// core/utils/output.ts
|
|
1948
2065
|
var output_exports = {};
|
|
1949
2066
|
__export(output_exports, {
|
|
2067
|
+
ERRORS: () => ERRORS,
|
|
2068
|
+
createError: () => createError,
|
|
1950
2069
|
default: () => output_default,
|
|
2070
|
+
getError: () => getError,
|
|
1951
2071
|
isQuietMode: () => isQuietMode,
|
|
1952
2072
|
setQuietMode: () => setQuietMode
|
|
1953
2073
|
});
|
|
@@ -1963,6 +2083,8 @@ var init_output = __esm({
|
|
|
1963
2083
|
"core/utils/output.ts"() {
|
|
1964
2084
|
"use strict";
|
|
1965
2085
|
init_branding();
|
|
2086
|
+
init_error_messages();
|
|
2087
|
+
init_error_messages();
|
|
1966
2088
|
_FRAMES = branding_default.spinner.frames;
|
|
1967
2089
|
SPEED = branding_default.spinner.speed;
|
|
1968
2090
|
interval = null;
|
|
@@ -2015,6 +2137,24 @@ var init_output = __esm({
|
|
|
2015
2137
|
console.error(`${chalk2.red("\u2717")} ${truncate(msg, 65)}`);
|
|
2016
2138
|
return this;
|
|
2017
2139
|
},
|
|
2140
|
+
// Rich error with context and recovery hint
|
|
2141
|
+
failWithHint(error) {
|
|
2142
|
+
this.stop();
|
|
2143
|
+
const err = typeof error === "string" ? getError(error) : error;
|
|
2144
|
+
console.error();
|
|
2145
|
+
console.error(`${chalk2.red("\u2717")} ${err.message}`);
|
|
2146
|
+
if (err.file) {
|
|
2147
|
+
console.error(chalk2.dim(` File: ${err.file}`));
|
|
2148
|
+
}
|
|
2149
|
+
if (err.hint) {
|
|
2150
|
+
console.error(chalk2.yellow(` \u{1F4A1} ${err.hint}`));
|
|
2151
|
+
}
|
|
2152
|
+
if (err.docs) {
|
|
2153
|
+
console.error(chalk2.dim(` Docs: ${err.docs}`));
|
|
2154
|
+
}
|
|
2155
|
+
console.error();
|
|
2156
|
+
return this;
|
|
2157
|
+
},
|
|
2018
2158
|
warn(msg) {
|
|
2019
2159
|
this.stop();
|
|
2020
2160
|
if (!quietMode) console.log(`${chalk2.yellow("\u26A0")} ${truncate(msg, 65)}`);
|
|
@@ -5863,7 +6003,7 @@ function formatSubtaskLine(index, subtask, spinnerFrame = "\u25B6") {
|
|
|
5863
6003
|
const num = `${DIM2}${String(index + 1).padStart(2)}${RESET2}`;
|
|
5864
6004
|
const domainColor = getDomainColor(subtask.domain);
|
|
5865
6005
|
const domain = `${domainColor}${subtask.domain.padEnd(10)}${RESET2}`;
|
|
5866
|
-
const desc = subtask.description.length > 32 ? subtask.description.slice(0, 29)
|
|
6006
|
+
const desc = subtask.description.length > 32 ? `${subtask.description.slice(0, 29)}...` : subtask.description.padEnd(32);
|
|
5867
6007
|
let status;
|
|
5868
6008
|
switch (subtask.status) {
|
|
5869
6009
|
case "completed":
|
|
@@ -8755,7 +8895,9 @@ var init_memory_system = __esm({
|
|
|
8755
8895
|
const matchingIds = /* @__PURE__ */ new Set();
|
|
8756
8896
|
for (const tag of parsedTags) {
|
|
8757
8897
|
const ids = db.index[tag];
|
|
8758
|
-
|
|
8898
|
+
for (const id of ids) {
|
|
8899
|
+
matchingIds.add(id);
|
|
8900
|
+
}
|
|
8759
8901
|
}
|
|
8760
8902
|
return db.memories.filter((m) => matchingIds.has(m.id));
|
|
8761
8903
|
}
|
|
@@ -9986,14 +10128,18 @@ var init_markdown_builder = __esm({
|
|
|
9986
10128
|
* Add multiple list items
|
|
9987
10129
|
*/
|
|
9988
10130
|
list(items, options) {
|
|
9989
|
-
|
|
10131
|
+
for (const item of items) {
|
|
10132
|
+
this.li(item, options);
|
|
10133
|
+
}
|
|
9990
10134
|
return this;
|
|
9991
10135
|
}
|
|
9992
10136
|
/**
|
|
9993
10137
|
* Add multiple numbered list items
|
|
9994
10138
|
*/
|
|
9995
10139
|
orderedList(items) {
|
|
9996
|
-
|
|
10140
|
+
for (let i = 0; i < items.length; i++) {
|
|
10141
|
+
this.oli(items[i], i + 1);
|
|
10142
|
+
}
|
|
9997
10143
|
return this;
|
|
9998
10144
|
}
|
|
9999
10145
|
/**
|
|
@@ -10079,7 +10225,9 @@ var init_markdown_builder = __esm({
|
|
|
10079
10225
|
* Iterate and build for each item
|
|
10080
10226
|
*/
|
|
10081
10227
|
each(items, builder) {
|
|
10082
|
-
|
|
10228
|
+
for (let i = 0; i < items.length; i++) {
|
|
10229
|
+
builder(this, items[i], i);
|
|
10230
|
+
}
|
|
10083
10231
|
return this;
|
|
10084
10232
|
}
|
|
10085
10233
|
/**
|
|
@@ -12415,12 +12563,16 @@ Stack: ${stack}
|
|
|
12415
12563
|
parts.push("\n## THINK FIRST (reasoning from analysis)\n");
|
|
12416
12564
|
if (thinkBlock.conclusions && thinkBlock.conclusions.length > 0) {
|
|
12417
12565
|
parts.push("Conclusions:\n");
|
|
12418
|
-
|
|
12419
|
-
`
|
|
12566
|
+
for (const c of thinkBlock.conclusions) {
|
|
12567
|
+
parts.push(` \u2192 ${c}
|
|
12568
|
+
`);
|
|
12569
|
+
}
|
|
12420
12570
|
}
|
|
12421
12571
|
parts.push("Plan:\n");
|
|
12422
|
-
|
|
12423
|
-
`
|
|
12572
|
+
for (let i = 0; i < thinkBlock.plan.length; i++) {
|
|
12573
|
+
parts.push(` ${i + 1}. ${thinkBlock.plan[i]}
|
|
12574
|
+
`);
|
|
12575
|
+
}
|
|
12424
12576
|
parts.push(`Confidence: ${Math.round((thinkBlock.confidence || 0.5) * 100)}%
|
|
12425
12577
|
`);
|
|
12426
12578
|
}
|
|
@@ -13378,10 +13530,100 @@ var init_update_checker = __esm({
|
|
|
13378
13530
|
}
|
|
13379
13531
|
});
|
|
13380
13532
|
|
|
13533
|
+
// core/utils/preserve-sections.ts
|
|
13534
|
+
function createPreserveStartRegex() {
|
|
13535
|
+
return /<!-- prjct:preserve(?::([\w-]+))? -->/g;
|
|
13536
|
+
}
|
|
13537
|
+
function extractPreservedSections(content) {
|
|
13538
|
+
const sections = [];
|
|
13539
|
+
const regex = createPreserveStartRegex();
|
|
13540
|
+
let match;
|
|
13541
|
+
let sectionIndex = 0;
|
|
13542
|
+
while ((match = regex.exec(content)) !== null) {
|
|
13543
|
+
const startIndex = match.index;
|
|
13544
|
+
const startTag = match[0];
|
|
13545
|
+
const sectionId = match[1] || `section-${sectionIndex++}`;
|
|
13546
|
+
const endTagStart = content.indexOf(PRESERVE_END_PATTERN, startIndex + startTag.length);
|
|
13547
|
+
if (endTagStart === -1) {
|
|
13548
|
+
continue;
|
|
13549
|
+
}
|
|
13550
|
+
const endIndex = endTagStart + PRESERVE_END_PATTERN.length;
|
|
13551
|
+
const fullContent = content.substring(startIndex, endIndex);
|
|
13552
|
+
sections.push({
|
|
13553
|
+
id: sectionId,
|
|
13554
|
+
content: fullContent,
|
|
13555
|
+
startIndex,
|
|
13556
|
+
endIndex
|
|
13557
|
+
});
|
|
13558
|
+
}
|
|
13559
|
+
return sections;
|
|
13560
|
+
}
|
|
13561
|
+
function mergePreservedSections(newContent, oldContent) {
|
|
13562
|
+
const preservedSections = extractPreservedSections(oldContent);
|
|
13563
|
+
if (preservedSections.length === 0) {
|
|
13564
|
+
return newContent;
|
|
13565
|
+
}
|
|
13566
|
+
let merged = newContent.trimEnd();
|
|
13567
|
+
merged += "\n\n---\n\n";
|
|
13568
|
+
merged += "## Your Customizations\n\n";
|
|
13569
|
+
merged += "_The sections below are preserved during sync. Edit freely._\n\n";
|
|
13570
|
+
for (const section of preservedSections) {
|
|
13571
|
+
merged += section.content;
|
|
13572
|
+
merged += "\n\n";
|
|
13573
|
+
}
|
|
13574
|
+
return `${merged.trimEnd()}
|
|
13575
|
+
`;
|
|
13576
|
+
}
|
|
13577
|
+
function validatePreserveBlocks(content) {
|
|
13578
|
+
const errors = [];
|
|
13579
|
+
const startMatches = content.match(/<!-- prjct:preserve(?::\w+)? -->/g) || [];
|
|
13580
|
+
const endMatches = content.match(/<!-- \/prjct:preserve -->/g) || [];
|
|
13581
|
+
if (startMatches.length !== endMatches.length) {
|
|
13582
|
+
errors.push(
|
|
13583
|
+
`Mismatched preserve markers: ${startMatches.length} opening, ${endMatches.length} closing`
|
|
13584
|
+
);
|
|
13585
|
+
}
|
|
13586
|
+
let depth = 0;
|
|
13587
|
+
let maxDepth = 0;
|
|
13588
|
+
const lines = content.split("\n");
|
|
13589
|
+
for (let i = 0; i < lines.length; i++) {
|
|
13590
|
+
const line = lines[i];
|
|
13591
|
+
if (/<!-- prjct:preserve(?::\w+)? -->/.test(line)) {
|
|
13592
|
+
depth++;
|
|
13593
|
+
maxDepth = Math.max(maxDepth, depth);
|
|
13594
|
+
}
|
|
13595
|
+
if (line.includes(PRESERVE_END_PATTERN)) {
|
|
13596
|
+
depth--;
|
|
13597
|
+
}
|
|
13598
|
+
if (depth > 1) {
|
|
13599
|
+
errors.push(`Nested preserve blocks detected at line ${i + 1} (not supported)`);
|
|
13600
|
+
}
|
|
13601
|
+
if (depth < 0) {
|
|
13602
|
+
errors.push(`Unexpected closing marker at line ${i + 1}`);
|
|
13603
|
+
}
|
|
13604
|
+
}
|
|
13605
|
+
return {
|
|
13606
|
+
valid: errors.length === 0,
|
|
13607
|
+
errors
|
|
13608
|
+
};
|
|
13609
|
+
}
|
|
13610
|
+
var PRESERVE_END_PATTERN;
|
|
13611
|
+
var init_preserve_sections = __esm({
|
|
13612
|
+
"core/utils/preserve-sections.ts"() {
|
|
13613
|
+
"use strict";
|
|
13614
|
+
PRESERVE_END_PATTERN = "<!-- /prjct:preserve -->";
|
|
13615
|
+
__name(createPreserveStartRegex, "createPreserveStartRegex");
|
|
13616
|
+
__name(extractPreservedSections, "extractPreservedSections");
|
|
13617
|
+
__name(mergePreservedSections, "mergePreservedSections");
|
|
13618
|
+
__name(validatePreserveBlocks, "validatePreserveBlocks");
|
|
13619
|
+
}
|
|
13620
|
+
});
|
|
13621
|
+
|
|
13381
13622
|
// core/services/agent-generator.ts
|
|
13382
13623
|
var init_agent_generator = __esm({
|
|
13383
13624
|
"core/services/agent-generator.ts"() {
|
|
13384
13625
|
"use strict";
|
|
13626
|
+
init_preserve_sections();
|
|
13385
13627
|
}
|
|
13386
13628
|
});
|
|
13387
13629
|
|
|
@@ -16636,7 +16878,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16636
16878
|
}
|
|
16637
16879
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16638
16880
|
if (!projectId) {
|
|
16639
|
-
output_default.
|
|
16881
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16640
16882
|
return { success: false, error: "No project ID found" };
|
|
16641
16883
|
}
|
|
16642
16884
|
output_default.spin(`planning ${description}...`);
|
|
@@ -16693,7 +16935,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16693
16935
|
}
|
|
16694
16936
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16695
16937
|
if (!projectId) {
|
|
16696
|
-
output_default.
|
|
16938
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16697
16939
|
return { success: false, error: "No project ID found" };
|
|
16698
16940
|
}
|
|
16699
16941
|
output_default.spin("tracking bug...");
|
|
@@ -16816,7 +17058,7 @@ ${"=".repeat(60)}`);
|
|
|
16816
17058
|
}
|
|
16817
17059
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16818
17060
|
if (!projectId) {
|
|
16819
|
-
output_default.
|
|
17061
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16820
17062
|
return { success: false, error: "No project ID found" };
|
|
16821
17063
|
}
|
|
16822
17064
|
const wordCount = description.split(/\s+/).length;
|
|
@@ -16874,7 +17116,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16874
17116
|
if (!initResult.success) return initResult;
|
|
16875
17117
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16876
17118
|
if (!projectId) {
|
|
16877
|
-
output_default.
|
|
17119
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16878
17120
|
return { success: false, error: "No project ID found" };
|
|
16879
17121
|
}
|
|
16880
17122
|
if (!featureName) {
|
|
@@ -17312,60 +17554,6 @@ var init_formatters = __esm({
|
|
|
17312
17554
|
}
|
|
17313
17555
|
});
|
|
17314
17556
|
|
|
17315
|
-
// core/utils/preserve-sections.ts
|
|
17316
|
-
function createPreserveStartRegex() {
|
|
17317
|
-
return /<!-- prjct:preserve(?::([\w-]+))? -->/g;
|
|
17318
|
-
}
|
|
17319
|
-
function extractPreservedSections(content) {
|
|
17320
|
-
const sections = [];
|
|
17321
|
-
const regex = createPreserveStartRegex();
|
|
17322
|
-
let match;
|
|
17323
|
-
let sectionIndex = 0;
|
|
17324
|
-
while ((match = regex.exec(content)) !== null) {
|
|
17325
|
-
const startIndex = match.index;
|
|
17326
|
-
const startTag = match[0];
|
|
17327
|
-
const sectionId = match[1] || `section-${sectionIndex++}`;
|
|
17328
|
-
const endTagStart = content.indexOf(PRESERVE_END_PATTERN, startIndex + startTag.length);
|
|
17329
|
-
if (endTagStart === -1) {
|
|
17330
|
-
continue;
|
|
17331
|
-
}
|
|
17332
|
-
const endIndex = endTagStart + PRESERVE_END_PATTERN.length;
|
|
17333
|
-
const fullContent = content.substring(startIndex, endIndex);
|
|
17334
|
-
sections.push({
|
|
17335
|
-
id: sectionId,
|
|
17336
|
-
content: fullContent,
|
|
17337
|
-
startIndex,
|
|
17338
|
-
endIndex
|
|
17339
|
-
});
|
|
17340
|
-
}
|
|
17341
|
-
return sections;
|
|
17342
|
-
}
|
|
17343
|
-
function mergePreservedSections(newContent, oldContent) {
|
|
17344
|
-
const preservedSections = extractPreservedSections(oldContent);
|
|
17345
|
-
if (preservedSections.length === 0) {
|
|
17346
|
-
return newContent;
|
|
17347
|
-
}
|
|
17348
|
-
let merged = newContent.trimEnd();
|
|
17349
|
-
merged += "\n\n---\n\n";
|
|
17350
|
-
merged += "## Your Customizations\n\n";
|
|
17351
|
-
merged += "_The sections below are preserved during sync. Edit freely._\n\n";
|
|
17352
|
-
for (const section of preservedSections) {
|
|
17353
|
-
merged += section.content;
|
|
17354
|
-
merged += "\n\n";
|
|
17355
|
-
}
|
|
17356
|
-
return merged.trimEnd() + "\n";
|
|
17357
|
-
}
|
|
17358
|
-
var PRESERVE_END_PATTERN;
|
|
17359
|
-
var init_preserve_sections = __esm({
|
|
17360
|
-
"core/utils/preserve-sections.ts"() {
|
|
17361
|
-
"use strict";
|
|
17362
|
-
PRESERVE_END_PATTERN = "<!-- /prjct:preserve -->";
|
|
17363
|
-
__name(createPreserveStartRegex, "createPreserveStartRegex");
|
|
17364
|
-
__name(extractPreservedSections, "extractPreservedSections");
|
|
17365
|
-
__name(mergePreservedSections, "mergePreservedSections");
|
|
17366
|
-
}
|
|
17367
|
-
});
|
|
17368
|
-
|
|
17369
17557
|
// core/ai-tools/registry.ts
|
|
17370
17558
|
import { execSync as execSync4 } from "node:child_process";
|
|
17371
17559
|
import fs34 from "node:fs";
|
|
@@ -17515,6 +17703,13 @@ async function generateForTool(context2, config, globalPath, repoPath) {
|
|
|
17515
17703
|
await fs35.mkdir(path38.dirname(outputPath), { recursive: true });
|
|
17516
17704
|
try {
|
|
17517
17705
|
const existingContent = await fs35.readFile(outputPath, "utf-8");
|
|
17706
|
+
const validation = validatePreserveBlocks(existingContent);
|
|
17707
|
+
if (!validation.valid) {
|
|
17708
|
+
console.warn(`\u26A0\uFE0F ${config.outputFile} has invalid preserve blocks:`);
|
|
17709
|
+
for (const error of validation.errors) {
|
|
17710
|
+
console.warn(` ${error}`);
|
|
17711
|
+
}
|
|
17712
|
+
}
|
|
17518
17713
|
content = mergePreservedSections(content, existingContent);
|
|
17519
17714
|
} catch {
|
|
17520
17715
|
}
|
|
@@ -17573,6 +17768,27 @@ var init_context_generator = __esm({
|
|
|
17573
17768
|
constructor(config) {
|
|
17574
17769
|
this.config = config;
|
|
17575
17770
|
}
|
|
17771
|
+
/**
|
|
17772
|
+
* Write file with preserved sections from existing content
|
|
17773
|
+
* This ensures user customizations survive regeneration
|
|
17774
|
+
*/
|
|
17775
|
+
async writeWithPreservation(filePath, content) {
|
|
17776
|
+
let finalContent = content;
|
|
17777
|
+
try {
|
|
17778
|
+
const existingContent = await fs36.readFile(filePath, "utf-8");
|
|
17779
|
+
const validation = validatePreserveBlocks(existingContent);
|
|
17780
|
+
if (!validation.valid) {
|
|
17781
|
+
const filename = path39.basename(filePath);
|
|
17782
|
+
console.warn(`\u26A0\uFE0F ${filename} has invalid preserve blocks:`);
|
|
17783
|
+
for (const error of validation.errors) {
|
|
17784
|
+
console.warn(` ${error}`);
|
|
17785
|
+
}
|
|
17786
|
+
}
|
|
17787
|
+
finalContent = mergePreservedSections(content, existingContent);
|
|
17788
|
+
} catch {
|
|
17789
|
+
}
|
|
17790
|
+
await fs36.writeFile(filePath, finalContent, "utf-8");
|
|
17791
|
+
}
|
|
17576
17792
|
/**
|
|
17577
17793
|
* Generate all context files in parallel
|
|
17578
17794
|
*/
|
|
@@ -17672,13 +17888,7 @@ Load from \`~/.prjct-cli/projects/${this.config.projectId}/agents/\`:
|
|
|
17672
17888
|
**Domain**: ${domainAgents.join(", ") || "none"}
|
|
17673
17889
|
`;
|
|
17674
17890
|
const claudePath = path39.join(contextPath, "CLAUDE.md");
|
|
17675
|
-
|
|
17676
|
-
try {
|
|
17677
|
-
const existingContent = await fs36.readFile(claudePath, "utf-8");
|
|
17678
|
-
finalContent = mergePreservedSections(content, existingContent);
|
|
17679
|
-
} catch {
|
|
17680
|
-
}
|
|
17681
|
-
await fs36.writeFile(claudePath, finalContent, "utf-8");
|
|
17891
|
+
await this.writeWithPreservation(claudePath, content);
|
|
17682
17892
|
}
|
|
17683
17893
|
/**
|
|
17684
17894
|
* Generate now.md - current task status
|
|
@@ -17703,7 +17913,7 @@ _No active task_
|
|
|
17703
17913
|
|
|
17704
17914
|
Use \`p. task "description"\` to start working.
|
|
17705
17915
|
`;
|
|
17706
|
-
await
|
|
17916
|
+
await this.writeWithPreservation(path39.join(contextPath, "now.md"), content);
|
|
17707
17917
|
}
|
|
17708
17918
|
/**
|
|
17709
17919
|
* Generate next.md - task queue
|
|
@@ -17719,7 +17929,7 @@ Use \`p. task "description"\` to start working.
|
|
|
17719
17929
|
|
|
17720
17930
|
${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue_"}
|
|
17721
17931
|
`;
|
|
17722
|
-
await
|
|
17932
|
+
await this.writeWithPreservation(path39.join(contextPath, "next.md"), content);
|
|
17723
17933
|
}
|
|
17724
17934
|
/**
|
|
17725
17935
|
* Generate ideas.md - captured ideas
|
|
@@ -17735,7 +17945,7 @@ ${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}
|
|
|
17735
17945
|
|
|
17736
17946
|
${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [${i.priority}]` : ""}`).join("\n") : "_No ideas captured yet_"}
|
|
17737
17947
|
`;
|
|
17738
|
-
await
|
|
17948
|
+
await this.writeWithPreservation(path39.join(contextPath, "ideas.md"), content);
|
|
17739
17949
|
}
|
|
17740
17950
|
/**
|
|
17741
17951
|
* Generate shipped.md - completed features
|
|
@@ -17755,7 +17965,7 @@ ${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.na
|
|
|
17755
17965
|
|
|
17756
17966
|
**Total shipped:** ${shipped.shipped.length}
|
|
17757
17967
|
`;
|
|
17758
|
-
await
|
|
17968
|
+
await this.writeWithPreservation(path39.join(contextPath, "shipped.md"), content);
|
|
17759
17969
|
}
|
|
17760
17970
|
};
|
|
17761
17971
|
}
|
|
@@ -20997,7 +21207,7 @@ var init_analytics = __esm({
|
|
|
20997
21207
|
if (!initResult.success) return initResult;
|
|
20998
21208
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
20999
21209
|
if (!projectId) {
|
|
21000
|
-
output_default.
|
|
21210
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21001
21211
|
return { success: false, error: "No project ID found" };
|
|
21002
21212
|
}
|
|
21003
21213
|
const projectName = path45.basename(projectPath);
|
|
@@ -21173,7 +21383,9 @@ ${"\u2550".repeat(50)}`);
|
|
|
21173
21383
|
}
|
|
21174
21384
|
if (command.features) {
|
|
21175
21385
|
console.log("\nFeatures:");
|
|
21176
|
-
|
|
21386
|
+
for (const f of command.features) {
|
|
21387
|
+
console.log(` \u2022 ${f}`);
|
|
21388
|
+
}
|
|
21177
21389
|
}
|
|
21178
21390
|
console.log(`
|
|
21179
21391
|
${"\u2550".repeat(50)}
|
|
@@ -21435,7 +21647,7 @@ async function cleanup(options = {}, projectPath = process.cwd()) {
|
|
|
21435
21647
|
output_default.spin("cleaning up...");
|
|
21436
21648
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21437
21649
|
if (!projectId) {
|
|
21438
|
-
output_default.
|
|
21650
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21439
21651
|
return { success: false, error: "No project ID found" };
|
|
21440
21652
|
}
|
|
21441
21653
|
const cleaned = [];
|
|
@@ -21594,7 +21806,7 @@ async function recover(projectPath = process.cwd()) {
|
|
|
21594
21806
|
try {
|
|
21595
21807
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21596
21808
|
if (!projectId) {
|
|
21597
|
-
output_default.
|
|
21809
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21598
21810
|
return { success: false, error: "No project ID found" };
|
|
21599
21811
|
}
|
|
21600
21812
|
output_default.spin("checking for abandoned sessions...");
|
|
@@ -21638,7 +21850,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21638
21850
|
output_default.spin("creating undo point...");
|
|
21639
21851
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21640
21852
|
if (!projectId) {
|
|
21641
|
-
output_default.
|
|
21853
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21642
21854
|
return { success: false, error: "No project ID found" };
|
|
21643
21855
|
}
|
|
21644
21856
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21683,7 +21895,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21683
21895
|
output_default.done("changes stashed (use /p:redo to restore)");
|
|
21684
21896
|
return { success: true, snapshotId: stashMessage };
|
|
21685
21897
|
} catch (gitError) {
|
|
21686
|
-
output_default.
|
|
21898
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21687
21899
|
return { success: false, error: gitError.message };
|
|
21688
21900
|
}
|
|
21689
21901
|
} catch (error) {
|
|
@@ -21696,7 +21908,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21696
21908
|
output_default.spin("restoring changes...");
|
|
21697
21909
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21698
21910
|
if (!projectId) {
|
|
21699
|
-
output_default.
|
|
21911
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21700
21912
|
return { success: false, error: "No project ID found" };
|
|
21701
21913
|
}
|
|
21702
21914
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21744,7 +21956,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21744
21956
|
output_default.done("changes restored");
|
|
21745
21957
|
return { success: true };
|
|
21746
21958
|
} catch (gitError) {
|
|
21747
|
-
output_default.
|
|
21959
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21748
21960
|
return { success: false, error: gitError.message };
|
|
21749
21961
|
}
|
|
21750
21962
|
} catch (error) {
|
|
@@ -21756,7 +21968,7 @@ async function history(projectPath = process.cwd()) {
|
|
|
21756
21968
|
try {
|
|
21757
21969
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21758
21970
|
if (!projectId) {
|
|
21759
|
-
output_default.
|
|
21971
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21760
21972
|
return { success: false, error: "No project ID found" };
|
|
21761
21973
|
}
|
|
21762
21974
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -22411,7 +22623,7 @@ ${result.stderr}`.trim();
|
|
|
22411
22623
|
if (!initResult.success) return initResult;
|
|
22412
22624
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
22413
22625
|
if (!projectId) {
|
|
22414
|
-
output_default.
|
|
22626
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
22415
22627
|
return { success: false, error: "No project ID found" };
|
|
22416
22628
|
}
|
|
22417
22629
|
let featureName = feature;
|
|
@@ -23485,7 +23697,7 @@ var init_workflow = __esm({
|
|
|
23485
23697
|
if (!initResult.success) return initResult;
|
|
23486
23698
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23487
23699
|
if (!projectId) {
|
|
23488
|
-
output_default.
|
|
23700
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23489
23701
|
return { success: false, error: "No project ID found" };
|
|
23490
23702
|
}
|
|
23491
23703
|
if (task) {
|
|
@@ -23577,7 +23789,7 @@ var init_workflow = __esm({
|
|
|
23577
23789
|
if (!initResult.success) return initResult;
|
|
23578
23790
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23579
23791
|
if (!projectId) {
|
|
23580
|
-
output_default.
|
|
23792
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23581
23793
|
return { success: false, error: "No project ID found" };
|
|
23582
23794
|
}
|
|
23583
23795
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23643,7 +23855,7 @@ var init_workflow = __esm({
|
|
|
23643
23855
|
if (!initResult.success) return initResult;
|
|
23644
23856
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23645
23857
|
if (!projectId) {
|
|
23646
|
-
output_default.
|
|
23858
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23647
23859
|
return { success: false, error: "No project ID found" };
|
|
23648
23860
|
}
|
|
23649
23861
|
const tasks = await queueStorage.getActiveTasks(projectId);
|
|
@@ -23668,7 +23880,7 @@ var init_workflow = __esm({
|
|
|
23668
23880
|
if (!initResult.success) return initResult;
|
|
23669
23881
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23670
23882
|
if (!projectId) {
|
|
23671
|
-
output_default.
|
|
23883
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23672
23884
|
return { success: false, error: "No project ID found" };
|
|
23673
23885
|
}
|
|
23674
23886
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23701,7 +23913,7 @@ var init_workflow = __esm({
|
|
|
23701
23913
|
if (!initResult.success) return initResult;
|
|
23702
23914
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23703
23915
|
if (!projectId) {
|
|
23704
|
-
output_default.
|
|
23916
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23705
23917
|
return { success: false, error: "No project ID found" };
|
|
23706
23918
|
}
|
|
23707
23919
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23739,7 +23951,7 @@ var init_workflow = __esm({
|
|
|
23739
23951
|
if (!initResult.success) return initResult;
|
|
23740
23952
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23741
23953
|
if (!projectId) {
|
|
23742
|
-
output_default.
|
|
23954
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23743
23955
|
return { success: false, error: "No project ID found" };
|
|
23744
23956
|
}
|
|
23745
23957
|
if (!input) {
|
|
@@ -23903,7 +24115,7 @@ var init_commands = __esm({
|
|
|
23903
24115
|
return this.setupCmds.installStatusLine();
|
|
23904
24116
|
}
|
|
23905
24117
|
showAsciiArt() {
|
|
23906
|
-
|
|
24118
|
+
this.setupCmds.showAsciiArt();
|
|
23907
24119
|
}
|
|
23908
24120
|
// ========== Delegated Base Methods ==========
|
|
23909
24121
|
async initializeAgent() {
|
|
@@ -24008,7 +24220,7 @@ var require_package = __commonJS({
|
|
|
24008
24220
|
"package.json"(exports, module) {
|
|
24009
24221
|
module.exports = {
|
|
24010
24222
|
name: "prjct-cli",
|
|
24011
|
-
version: "0.
|
|
24223
|
+
version: "0.49.0",
|
|
24012
24224
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
24013
24225
|
main: "core/index.ts",
|
|
24014
24226
|
bin: {
|