prjct-cli 0.35.3 → 0.35.4
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/core/commands/analysis.ts +58 -32
- package/core/commands/command-data.ts +11 -50
- package/core/commands/commands.ts +18 -21
- package/core/commands/context.ts +238 -0
- package/core/commands/register.ts +7 -5
- package/core/commands/setup.ts +1 -17
- package/core/index.ts +2 -4
- package/core/services/index.ts +2 -0
- package/core/services/sync-service.ts +1080 -0
- package/core/types/commands.ts +0 -12
- package/core/types/index.ts +0 -1
- package/dist/bin/prjct.mjs +1215 -307
- package/package.json +2 -8
- package/templates/agentic/agent-routing.md +22 -88
- package/templates/agentic/agents/uxui.md +42 -197
- package/templates/agentic/context-filtering.md +14 -56
- package/templates/agentic/orchestrator.md +26 -302
- package/templates/agentic/skill-integration.md +37 -289
- package/templates/agentic/subagent-generation.md +31 -104
- package/templates/agentic/task-fragmentation.md +39 -273
- package/templates/agents/AGENTS.md +32 -188
- package/templates/commands/bug.md +22 -520
- package/templates/commands/dash.md +26 -161
- package/templates/commands/done.md +19 -250
- package/templates/commands/enrich.md +21 -732
- package/templates/commands/idea.md +18 -160
- package/templates/commands/init.md +20 -209
- package/templates/commands/merge.md +21 -185
- package/templates/commands/next.md +21 -103
- package/templates/commands/pause.md +21 -272
- package/templates/commands/resume.md +18 -411
- package/templates/commands/setup.md +0 -1
- package/templates/commands/ship.md +30 -627
- package/templates/commands/sync.md +11 -1448
- package/templates/commands/task.md +17 -439
- package/templates/commands/test.md +30 -259
- package/CLAUDE.md +0 -211
- package/packages/shared/package.json +0 -29
- package/packages/shared/src/index.ts +0 -10
- package/packages/shared/src/schemas.ts +0 -124
- package/packages/shared/src/types.ts +0 -187
- package/packages/shared/src/unified.ts +0 -174
- package/packages/shared/src/utils.ts +0 -148
- package/packages/shared/tsconfig.json +0 -18
package/dist/bin/prjct.mjs
CHANGED
|
@@ -16,10 +16,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
16
16
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
17
17
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
18
18
|
});
|
|
19
|
-
var __glob = (map) => (
|
|
20
|
-
var fn = map[
|
|
19
|
+
var __glob = (map) => (path37) => {
|
|
20
|
+
var fn = map[path37];
|
|
21
21
|
if (fn) return fn();
|
|
22
|
-
throw new Error("Module not found in bundle: " +
|
|
22
|
+
throw new Error("Module not found in bundle: " + path37);
|
|
23
23
|
};
|
|
24
24
|
var __esm = (fn, res) => function __init() {
|
|
25
25
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
@@ -3201,10 +3201,10 @@ var init_context_builder = __esm({
|
|
|
3201
3201
|
* Load current project state - PARALLEL VERSION
|
|
3202
3202
|
* Uses Promise.all() for 40-60% faster file I/O
|
|
3203
3203
|
*/
|
|
3204
|
-
async loadState(
|
|
3204
|
+
async loadState(context2, onlyKeys = null) {
|
|
3205
3205
|
this._clearCacheIfStale();
|
|
3206
3206
|
const state = {};
|
|
3207
|
-
const entries = Object.entries(
|
|
3207
|
+
const entries = Object.entries(context2.paths);
|
|
3208
3208
|
const filteredEntries = onlyKeys ? entries.filter(([key]) => onlyKeys.includes(key)) : entries;
|
|
3209
3209
|
for (const [, filePath] of filteredEntries) {
|
|
3210
3210
|
if (this._cache.has(filePath)) {
|
|
@@ -3260,7 +3260,7 @@ var init_context_builder = __esm({
|
|
|
3260
3260
|
* Load state for specific command - optimized selective loading
|
|
3261
3261
|
* Each command only loads what it needs
|
|
3262
3262
|
*/
|
|
3263
|
-
async loadStateForCommand(
|
|
3263
|
+
async loadStateForCommand(context2, commandName) {
|
|
3264
3264
|
const commandFileMap = {
|
|
3265
3265
|
// Core workflow
|
|
3266
3266
|
now: ["now", "next", "analysis", "codePatterns"],
|
|
@@ -3289,7 +3289,7 @@ var init_context_builder = __esm({
|
|
|
3289
3289
|
default: ["analysis", "codePatterns"]
|
|
3290
3290
|
};
|
|
3291
3291
|
const requiredFiles = commandFileMap[commandName] || commandFileMap.default;
|
|
3292
|
-
return this.loadState(
|
|
3292
|
+
return this.loadState(context2, requiredFiles);
|
|
3293
3293
|
}
|
|
3294
3294
|
/**
|
|
3295
3295
|
* Batch read multiple files in parallel
|
|
@@ -5540,8 +5540,8 @@ var init_prompt_builder = __esm({
|
|
|
5540
5540
|
/**
|
|
5541
5541
|
* Set context for testing
|
|
5542
5542
|
*/
|
|
5543
|
-
setContext(
|
|
5544
|
-
this._currentContext =
|
|
5543
|
+
setContext(context2) {
|
|
5544
|
+
this._currentContext = context2;
|
|
5545
5545
|
}
|
|
5546
5546
|
/**
|
|
5547
5547
|
* Load quality checklists from templates/checklists/
|
|
@@ -5681,17 +5681,17 @@ var init_prompt_builder = __esm({
|
|
|
5681
5681
|
* Build a complete prompt with auto-injected context.
|
|
5682
5682
|
* This is the preferred method - automatically includes state and insights.
|
|
5683
5683
|
*/
|
|
5684
|
-
async buildWithInjection(template,
|
|
5684
|
+
async buildWithInjection(template, context2, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null) {
|
|
5685
5685
|
const parts = [];
|
|
5686
|
-
if (
|
|
5687
|
-
const injected = await this.buildInjectedContext(
|
|
5686
|
+
if (context2.projectId) {
|
|
5687
|
+
const injected = await this.buildInjectedContext(context2.projectId);
|
|
5688
5688
|
if (injected) {
|
|
5689
5689
|
parts.push(injected);
|
|
5690
5690
|
}
|
|
5691
5691
|
}
|
|
5692
5692
|
const basePrompt = this.build(
|
|
5693
5693
|
template,
|
|
5694
|
-
|
|
5694
|
+
context2,
|
|
5695
5695
|
state,
|
|
5696
5696
|
agent,
|
|
5697
5697
|
learnedPatterns,
|
|
@@ -5706,9 +5706,9 @@ var init_prompt_builder = __esm({
|
|
|
5706
5706
|
* Build a complete prompt for Claude from template, context, and enhancements
|
|
5707
5707
|
* @deprecated Use buildWithInjection for auto-injected context
|
|
5708
5708
|
*/
|
|
5709
|
-
build(template,
|
|
5709
|
+
build(template, context2, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null, orchestratorContext = null) {
|
|
5710
5710
|
const parts = [];
|
|
5711
|
-
this._currentContext =
|
|
5711
|
+
this._currentContext = context2;
|
|
5712
5712
|
const commandName = template.frontmatter?.name?.replace("p:", "") || "";
|
|
5713
5713
|
const agentCommands = ["now", "build", "feature", "design", "fix", "bug", "test", "work", "cleanup", "spec"];
|
|
5714
5714
|
const needsAgent = agentCommands.includes(commandName);
|
|
@@ -5730,7 +5730,7 @@ Apply specialized expertise. Read agent file for details if needed.
|
|
|
5730
5730
|
parts.push(`TOOLS: ${template.frontmatter["allowed-tools"].join(", ")}
|
|
5731
5731
|
`);
|
|
5732
5732
|
}
|
|
5733
|
-
const params =
|
|
5733
|
+
const params = context2;
|
|
5734
5734
|
if (params.params?.task || params.params?.description) {
|
|
5735
5735
|
parts.push(`INPUT: ${params.params.task || params.params.description}
|
|
5736
5736
|
`);
|
|
@@ -5807,16 +5807,16 @@ ${truncatedContent}
|
|
|
5807
5807
|
parts.push(relevantState);
|
|
5808
5808
|
parts.push("\n");
|
|
5809
5809
|
}
|
|
5810
|
-
const files =
|
|
5810
|
+
const files = context2.files || [];
|
|
5811
5811
|
if (files.length > 0) {
|
|
5812
5812
|
const top5 = files.slice(0, 5).join(", ");
|
|
5813
5813
|
parts.push(`
|
|
5814
5814
|
## FILES: ${files.length} available. Top: ${top5}
|
|
5815
5815
|
`);
|
|
5816
5816
|
parts.push("Read BEFORE modifying. Use Glob/Grep to find more.\n\n");
|
|
5817
|
-
} else if (
|
|
5817
|
+
} else if (context2.projectPath) {
|
|
5818
5818
|
parts.push(`
|
|
5819
|
-
## PROJECT: ${
|
|
5819
|
+
## PROJECT: ${context2.projectPath}
|
|
5820
5820
|
Read files before modifying.
|
|
5821
5821
|
|
|
5822
5822
|
`);
|
|
@@ -5937,7 +5937,7 @@ ${content.substring(0, 500)}... (truncated, use Read tool for full content)`
|
|
|
5937
5937
|
/**
|
|
5938
5938
|
* Build an analysis prompt for pre-action investigation tasks
|
|
5939
5939
|
*/
|
|
5940
|
-
buildAnalysis(analysisType,
|
|
5940
|
+
buildAnalysis(analysisType, context2) {
|
|
5941
5941
|
const parts = [];
|
|
5942
5942
|
parts.push(`# Analyze: ${analysisType}
|
|
5943
5943
|
|
|
@@ -5945,9 +5945,9 @@ ${content.substring(0, 500)}... (truncated, use Read tool for full content)`
|
|
|
5945
5945
|
parts.push("Read the project context and provide your analysis.\n");
|
|
5946
5946
|
parts.push("No predetermined patterns - decide based on what you find.\n\n");
|
|
5947
5947
|
parts.push("## Project Context\n");
|
|
5948
|
-
parts.push(`- Path: ${
|
|
5948
|
+
parts.push(`- Path: ${context2.projectPath}
|
|
5949
5949
|
`);
|
|
5950
|
-
parts.push(`- ID: ${
|
|
5950
|
+
parts.push(`- ID: ${context2.projectId}
|
|
5951
5951
|
|
|
5952
5952
|
`);
|
|
5953
5953
|
return parts.join("");
|
|
@@ -6211,20 +6211,20 @@ var init_loop_detector = __esm({
|
|
|
6211
6211
|
/**
|
|
6212
6212
|
* Generate a unique key for tracking attempts
|
|
6213
6213
|
*/
|
|
6214
|
-
_getKey(command,
|
|
6215
|
-
return `${command}:${
|
|
6214
|
+
_getKey(command, context2 = "") {
|
|
6215
|
+
return `${command}:${context2}`.toLowerCase();
|
|
6216
6216
|
}
|
|
6217
6217
|
/**
|
|
6218
6218
|
* Record an attempt for a command
|
|
6219
6219
|
*/
|
|
6220
|
-
recordAttempt(command,
|
|
6221
|
-
const key = this._getKey(command,
|
|
6220
|
+
recordAttempt(command, context2 = "", result = {}) {
|
|
6221
|
+
const key = this._getKey(command, context2);
|
|
6222
6222
|
const now = Date.now();
|
|
6223
6223
|
let record = this._attempts.get(key);
|
|
6224
6224
|
if (!record || now - record.lastAttempt > this.sessionTimeout) {
|
|
6225
6225
|
record = {
|
|
6226
6226
|
command,
|
|
6227
|
-
context,
|
|
6227
|
+
context: context2,
|
|
6228
6228
|
attempts: 0,
|
|
6229
6229
|
errors: [],
|
|
6230
6230
|
firstAttempt: now,
|
|
@@ -6244,15 +6244,15 @@ var init_loop_detector = __esm({
|
|
|
6244
6244
|
this._attempts.set(key, record);
|
|
6245
6245
|
return {
|
|
6246
6246
|
attemptNumber: record.attempts,
|
|
6247
|
-
isLooping: this.isLooping(command,
|
|
6248
|
-
shouldEscalate: this.shouldEscalate(command,
|
|
6247
|
+
isLooping: this.isLooping(command, context2),
|
|
6248
|
+
shouldEscalate: this.shouldEscalate(command, context2)
|
|
6249
6249
|
};
|
|
6250
6250
|
}
|
|
6251
6251
|
/**
|
|
6252
6252
|
* Check if a command is in a loop (repeated failures)
|
|
6253
6253
|
*/
|
|
6254
|
-
isLooping(command,
|
|
6255
|
-
const key = this._getKey(command,
|
|
6254
|
+
isLooping(command, context2 = "") {
|
|
6255
|
+
const key = this._getKey(command, context2);
|
|
6256
6256
|
const record = this._attempts.get(key);
|
|
6257
6257
|
if (!record) return false;
|
|
6258
6258
|
if (record.attempts >= 2 && !record.success) {
|
|
@@ -6268,8 +6268,8 @@ var init_loop_detector = __esm({
|
|
|
6268
6268
|
/**
|
|
6269
6269
|
* Check if we should escalate to user
|
|
6270
6270
|
*/
|
|
6271
|
-
shouldEscalate(command,
|
|
6272
|
-
const key = this._getKey(command,
|
|
6271
|
+
shouldEscalate(command, context2 = "") {
|
|
6272
|
+
const key = this._getKey(command, context2);
|
|
6273
6273
|
const record = this._attempts.get(key);
|
|
6274
6274
|
if (!record) return false;
|
|
6275
6275
|
return record.attempts >= this.maxAttempts && !record.success;
|
|
@@ -6277,8 +6277,8 @@ var init_loop_detector = __esm({
|
|
|
6277
6277
|
/**
|
|
6278
6278
|
* Get escalation message for user
|
|
6279
6279
|
*/
|
|
6280
|
-
getEscalationInfo(command,
|
|
6281
|
-
const key = this._getKey(command,
|
|
6280
|
+
getEscalationInfo(command, context2 = "") {
|
|
6281
|
+
const key = this._getKey(command, context2);
|
|
6282
6282
|
const record = this._attempts.get(key);
|
|
6283
6283
|
if (!record) {
|
|
6284
6284
|
return null;
|
|
@@ -6287,7 +6287,7 @@ var init_loop_detector = __esm({
|
|
|
6287
6287
|
return {
|
|
6288
6288
|
status: "BLOCKED",
|
|
6289
6289
|
command,
|
|
6290
|
-
context,
|
|
6290
|
+
context: context2,
|
|
6291
6291
|
attempts: record.attempts,
|
|
6292
6292
|
duration: record.lastAttempt - record.firstAttempt,
|
|
6293
6293
|
errorPattern,
|
|
@@ -6299,8 +6299,8 @@ var init_loop_detector = __esm({
|
|
|
6299
6299
|
/**
|
|
6300
6300
|
* Mark a command as successful (resets tracking)
|
|
6301
6301
|
*/
|
|
6302
|
-
recordSuccess(command,
|
|
6303
|
-
const key = this._getKey(command,
|
|
6302
|
+
recordSuccess(command, context2 = "") {
|
|
6303
|
+
const key = this._getKey(command, context2);
|
|
6304
6304
|
const record = this._attempts.get(key);
|
|
6305
6305
|
if (record) {
|
|
6306
6306
|
record.success = true;
|
|
@@ -6312,8 +6312,8 @@ var init_loop_detector = __esm({
|
|
|
6312
6312
|
/**
|
|
6313
6313
|
* Clear all tracking for a command
|
|
6314
6314
|
*/
|
|
6315
|
-
clearTracking(command,
|
|
6316
|
-
const key = this._getKey(command,
|
|
6315
|
+
clearTracking(command, context2 = "") {
|
|
6316
|
+
const key = this._getKey(command, context2);
|
|
6317
6317
|
this._attempts.delete(key);
|
|
6318
6318
|
}
|
|
6319
6319
|
/**
|
|
@@ -6374,7 +6374,7 @@ var init_loop_detector = __esm({
|
|
|
6374
6374
|
function requiresReasoning(commandName) {
|
|
6375
6375
|
return REASONING_REQUIRED_COMMANDS.includes(commandName);
|
|
6376
6376
|
}
|
|
6377
|
-
async function reason(commandName,
|
|
6377
|
+
async function reason(commandName, context2, state) {
|
|
6378
6378
|
const steps = [];
|
|
6379
6379
|
const plan = [];
|
|
6380
6380
|
const criticalIssues = [];
|
|
@@ -6398,7 +6398,7 @@ async function reason(commandName, context, state) {
|
|
|
6398
6398
|
plan.push("Update metrics");
|
|
6399
6399
|
break;
|
|
6400
6400
|
case "feature":
|
|
6401
|
-
if (
|
|
6401
|
+
if (context2.params.description || context2.params.feature) {
|
|
6402
6402
|
steps.push({ step: "Has feature description", passed: true });
|
|
6403
6403
|
} else {
|
|
6404
6404
|
steps.push({ step: "Has feature description", passed: false, details: "No description provided" });
|
|
@@ -6416,7 +6416,7 @@ async function reason(commandName, context, state) {
|
|
|
6416
6416
|
plan.push("Suggest starting first task");
|
|
6417
6417
|
break;
|
|
6418
6418
|
case "spec":
|
|
6419
|
-
if (
|
|
6419
|
+
if (context2.params.feature || context2.params.name) {
|
|
6420
6420
|
steps.push({ step: "Has spec name", passed: true });
|
|
6421
6421
|
} else {
|
|
6422
6422
|
steps.push({ step: "Has spec name", passed: false, details: "No spec name provided" });
|
|
@@ -6885,7 +6885,7 @@ var init_memory_system = __esm({
|
|
|
6885
6885
|
async savePatterns(projectId) {
|
|
6886
6886
|
return this.save(projectId);
|
|
6887
6887
|
}
|
|
6888
|
-
async recordDecision(projectId, key, value,
|
|
6888
|
+
async recordDecision(projectId, key, value, context2 = "") {
|
|
6889
6889
|
const patterns = await this.load(projectId);
|
|
6890
6890
|
const now = getTimestamp();
|
|
6891
6891
|
if (!patterns.decisions[key]) {
|
|
@@ -6895,15 +6895,15 @@ var init_memory_system = __esm({
|
|
|
6895
6895
|
firstSeen: now,
|
|
6896
6896
|
lastSeen: now,
|
|
6897
6897
|
confidence: "low",
|
|
6898
|
-
contexts: [
|
|
6898
|
+
contexts: [context2].filter(Boolean)
|
|
6899
6899
|
};
|
|
6900
6900
|
} else {
|
|
6901
6901
|
const decision = patterns.decisions[key];
|
|
6902
6902
|
if (decision.value === value) {
|
|
6903
6903
|
decision.count++;
|
|
6904
6904
|
decision.lastSeen = now;
|
|
6905
|
-
if (
|
|
6906
|
-
decision.contexts.push(
|
|
6905
|
+
if (context2 && !decision.contexts.includes(context2)) {
|
|
6906
|
+
decision.contexts.push(context2);
|
|
6907
6907
|
}
|
|
6908
6908
|
if (decision.count >= 5) {
|
|
6909
6909
|
decision.confidence = "high";
|
|
@@ -7093,11 +7093,11 @@ var init_memory_system = __esm({
|
|
|
7093
7093
|
(m) => m.title.toLowerCase().includes(queryLower) || m.content.toLowerCase().includes(queryLower)
|
|
7094
7094
|
);
|
|
7095
7095
|
}
|
|
7096
|
-
async getRelevantMemories(projectId,
|
|
7096
|
+
async getRelevantMemories(projectId, context2, limit = 5) {
|
|
7097
7097
|
const db = await this.load(projectId);
|
|
7098
7098
|
const scored = db.memories.map((memory) => {
|
|
7099
7099
|
let score = 0;
|
|
7100
|
-
const contextTags = this._extractContextTags(
|
|
7100
|
+
const contextTags = this._extractContextTags(context2);
|
|
7101
7101
|
for (const tag of memory.tags || []) {
|
|
7102
7102
|
if (contextTags.includes(tag)) score += 10;
|
|
7103
7103
|
}
|
|
@@ -7105,7 +7105,7 @@ var init_memory_system = __esm({
|
|
|
7105
7105
|
const daysSinceUpdate = age / (1e3 * 60 * 60 * 24);
|
|
7106
7106
|
score += Math.max(0, 5 - daysSinceUpdate);
|
|
7107
7107
|
if (memory.userTriggered) score += 5;
|
|
7108
|
-
const keywords = this._extractKeywords(
|
|
7108
|
+
const keywords = this._extractKeywords(context2);
|
|
7109
7109
|
for (const keyword of keywords) {
|
|
7110
7110
|
if (memory.content.toLowerCase().includes(keyword)) score += 2;
|
|
7111
7111
|
if (memory.title.toLowerCase().includes(keyword)) score += 3;
|
|
@@ -7114,7 +7114,7 @@ var init_memory_system = __esm({
|
|
|
7114
7114
|
});
|
|
7115
7115
|
return scored.filter((m) => m._score > 0).sort((a, b) => b._score - a._score).slice(0, limit).map(({ _score, ...memory }) => memory);
|
|
7116
7116
|
}
|
|
7117
|
-
_extractContextTags(
|
|
7117
|
+
_extractContextTags(context2) {
|
|
7118
7118
|
const tags = [];
|
|
7119
7119
|
const commandTags = {
|
|
7120
7120
|
ship: [MEMORY_TAGS.COMMIT_STYLE, MEMORY_TAGS.SHIP_WORKFLOW, MEMORY_TAGS.TEST_BEHAVIOR],
|
|
@@ -7123,23 +7123,23 @@ var init_memory_system = __esm({
|
|
|
7123
7123
|
analyze: [MEMORY_TAGS.TECH_STACK, MEMORY_TAGS.ARCHITECTURE],
|
|
7124
7124
|
spec: [MEMORY_TAGS.ARCHITECTURE, MEMORY_TAGS.CODE_STYLE]
|
|
7125
7125
|
};
|
|
7126
|
-
if (
|
|
7127
|
-
tags.push(...commandTags[
|
|
7126
|
+
if (context2.commandName && commandTags[context2.commandName]) {
|
|
7127
|
+
tags.push(...commandTags[context2.commandName]);
|
|
7128
7128
|
}
|
|
7129
7129
|
return tags;
|
|
7130
7130
|
}
|
|
7131
|
-
_extractKeywords(
|
|
7131
|
+
_extractKeywords(context2) {
|
|
7132
7132
|
const keywords = [];
|
|
7133
|
-
if (
|
|
7134
|
-
keywords.push(...
|
|
7133
|
+
if (context2.params?.description) {
|
|
7134
|
+
keywords.push(...context2.params.description.toLowerCase().split(/\s+/));
|
|
7135
7135
|
}
|
|
7136
|
-
if (
|
|
7137
|
-
keywords.push(...
|
|
7136
|
+
if (context2.params?.feature) {
|
|
7137
|
+
keywords.push(...context2.params.feature.toLowerCase().split(/\s+/));
|
|
7138
7138
|
}
|
|
7139
7139
|
const stopWords = ["the", "a", "an", "is", "are", "to", "for", "and", "or", "in"];
|
|
7140
7140
|
return keywords.filter((k) => k.length > 2 && !stopWords.includes(k));
|
|
7141
7141
|
}
|
|
7142
|
-
async autoRemember(projectId, decisionType, value,
|
|
7142
|
+
async autoRemember(projectId, decisionType, value, context2 = "") {
|
|
7143
7143
|
const tagMap = {
|
|
7144
7144
|
commit_footer: [MEMORY_TAGS.COMMIT_STYLE],
|
|
7145
7145
|
branch_naming: [MEMORY_TAGS.BRANCH_NAMING],
|
|
@@ -7158,8 +7158,8 @@ var init_memory_system = __esm({
|
|
|
7158
7158
|
} else {
|
|
7159
7159
|
await this.createMemory(projectId, {
|
|
7160
7160
|
title: `Preference: ${decisionType}`,
|
|
7161
|
-
content: `${decisionType}: ${value}${
|
|
7162
|
-
Context: ${
|
|
7161
|
+
content: `${decisionType}: ${value}${context2 ? `
|
|
7162
|
+
Context: ${context2}` : ""}`,
|
|
7163
7163
|
tags,
|
|
7164
7164
|
userTriggered: true
|
|
7165
7165
|
});
|
|
@@ -7222,11 +7222,11 @@ Context: ${context}` : ""}`,
|
|
|
7222
7222
|
searchMemories(projectId, query) {
|
|
7223
7223
|
return this._semanticMemories.searchMemories(projectId, query);
|
|
7224
7224
|
}
|
|
7225
|
-
getRelevantMemories(projectId,
|
|
7226
|
-
return this._semanticMemories.getRelevantMemories(projectId,
|
|
7225
|
+
getRelevantMemories(projectId, context2, limit) {
|
|
7226
|
+
return this._semanticMemories.getRelevantMemories(projectId, context2, limit);
|
|
7227
7227
|
}
|
|
7228
|
-
autoRemember(projectId, decisionType, value,
|
|
7229
|
-
return this._semanticMemories.autoRemember(projectId, decisionType, value,
|
|
7228
|
+
autoRemember(projectId, decisionType, value, context2) {
|
|
7229
|
+
return this._semanticMemories.autoRemember(projectId, decisionType, value, context2);
|
|
7230
7230
|
}
|
|
7231
7231
|
getAllMemories(projectId) {
|
|
7232
7232
|
return this._semanticMemories.getAllMemories(projectId);
|
|
@@ -7255,8 +7255,8 @@ Context: ${context}` : ""}`,
|
|
|
7255
7255
|
savePatterns(projectId) {
|
|
7256
7256
|
return this._patternStore.savePatterns(projectId);
|
|
7257
7257
|
}
|
|
7258
|
-
recordDecision(projectId, key, value,
|
|
7259
|
-
return this._patternStore.recordDecision(projectId, key, value,
|
|
7258
|
+
recordDecision(projectId, key, value, context2) {
|
|
7259
|
+
return this._patternStore.recordDecision(projectId, key, value, context2);
|
|
7260
7260
|
}
|
|
7261
7261
|
getDecision(projectId, key) {
|
|
7262
7262
|
return this._patternStore.getDecision(projectId, key);
|
|
@@ -7298,10 +7298,10 @@ Context: ${context}` : ""}`,
|
|
|
7298
7298
|
if (pattern) return pattern.value;
|
|
7299
7299
|
return null;
|
|
7300
7300
|
}
|
|
7301
|
-
async learnDecision(projectId, key, value,
|
|
7301
|
+
async learnDecision(projectId, key, value, context2 = "") {
|
|
7302
7302
|
this.setSession(`decision:${key}`, value);
|
|
7303
|
-
await this.recordDecision(projectId, key, value,
|
|
7304
|
-
await this.appendHistory(projectId, { type: "decision", key, value, context });
|
|
7303
|
+
await this.recordDecision(projectId, key, value, context2);
|
|
7304
|
+
await this.appendHistory(projectId, { type: "decision", key, value, context: context2 });
|
|
7305
7305
|
}
|
|
7306
7306
|
/**
|
|
7307
7307
|
* Reset internal state (for testing)
|
|
@@ -7351,11 +7351,11 @@ function formatWarnings(result) {
|
|
|
7351
7351
|
}
|
|
7352
7352
|
return output;
|
|
7353
7353
|
}
|
|
7354
|
-
async function verifyDone(
|
|
7354
|
+
async function verifyDone(context2) {
|
|
7355
7355
|
const warnings = [];
|
|
7356
7356
|
const recommendations = [];
|
|
7357
7357
|
const actual = {};
|
|
7358
|
-
const nowPath =
|
|
7358
|
+
const nowPath = context2.paths.now;
|
|
7359
7359
|
try {
|
|
7360
7360
|
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
7361
7361
|
actual.nowExists = true;
|
|
@@ -7383,7 +7383,7 @@ async function verifyDone(context) {
|
|
|
7383
7383
|
throw error;
|
|
7384
7384
|
}
|
|
7385
7385
|
}
|
|
7386
|
-
const nextPath =
|
|
7386
|
+
const nextPath = context2.paths.next;
|
|
7387
7387
|
try {
|
|
7388
7388
|
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
7389
7389
|
actual.nextExists = true;
|
|
@@ -7397,7 +7397,7 @@ async function verifyDone(context) {
|
|
|
7397
7397
|
throw error;
|
|
7398
7398
|
}
|
|
7399
7399
|
}
|
|
7400
|
-
const metricsPath =
|
|
7400
|
+
const metricsPath = context2.paths.metrics;
|
|
7401
7401
|
try {
|
|
7402
7402
|
await fs18.access(path17.dirname(metricsPath), fs18.constants.W_OK);
|
|
7403
7403
|
actual.metricsWritable = true;
|
|
@@ -7416,13 +7416,13 @@ async function verifyDone(context) {
|
|
|
7416
7416
|
recommendations
|
|
7417
7417
|
};
|
|
7418
7418
|
}
|
|
7419
|
-
async function verifyShip(
|
|
7419
|
+
async function verifyShip(context2) {
|
|
7420
7420
|
const warnings = [];
|
|
7421
7421
|
const recommendations = [];
|
|
7422
7422
|
const actual = {};
|
|
7423
7423
|
try {
|
|
7424
7424
|
const gitStatus = execSync2("git status --porcelain", {
|
|
7425
|
-
cwd:
|
|
7425
|
+
cwd: context2.projectPath,
|
|
7426
7426
|
encoding: "utf-8"
|
|
7427
7427
|
});
|
|
7428
7428
|
actual.hasUncommittedChanges = gitStatus.trim().length > 0;
|
|
@@ -7434,7 +7434,7 @@ async function verifyShip(context) {
|
|
|
7434
7434
|
} catch (error) {
|
|
7435
7435
|
actual.gitAvailable = false;
|
|
7436
7436
|
}
|
|
7437
|
-
const pkgPath = path17.join(
|
|
7437
|
+
const pkgPath = path17.join(context2.projectPath, "package.json");
|
|
7438
7438
|
try {
|
|
7439
7439
|
const pkgContent = await fs18.readFile(pkgPath, "utf-8");
|
|
7440
7440
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -7450,11 +7450,11 @@ async function verifyShip(context) {
|
|
|
7450
7450
|
throw error;
|
|
7451
7451
|
}
|
|
7452
7452
|
}
|
|
7453
|
-
const shippedPath =
|
|
7453
|
+
const shippedPath = context2.paths.shipped;
|
|
7454
7454
|
try {
|
|
7455
7455
|
const shippedContent = await fs18.readFile(shippedPath, "utf-8");
|
|
7456
7456
|
actual.shippedExists = true;
|
|
7457
|
-
const featureName =
|
|
7457
|
+
const featureName = context2.params.feature || context2.params.description;
|
|
7458
7458
|
if (featureName) {
|
|
7459
7459
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
7460
7460
|
const todayPattern = new RegExp(`${today}.*${escapeRegex(featureName)}`, "i");
|
|
@@ -7490,11 +7490,11 @@ async function verifyShip(context) {
|
|
|
7490
7490
|
recommendations
|
|
7491
7491
|
};
|
|
7492
7492
|
}
|
|
7493
|
-
async function verifyFeature(
|
|
7493
|
+
async function verifyFeature(context2) {
|
|
7494
7494
|
const warnings = [];
|
|
7495
7495
|
const recommendations = [];
|
|
7496
7496
|
const actual = {};
|
|
7497
|
-
const nextPath =
|
|
7497
|
+
const nextPath = context2.paths.next;
|
|
7498
7498
|
try {
|
|
7499
7499
|
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
7500
7500
|
actual.nextExists = true;
|
|
@@ -7513,11 +7513,11 @@ async function verifyFeature(context) {
|
|
|
7513
7513
|
throw error;
|
|
7514
7514
|
}
|
|
7515
7515
|
}
|
|
7516
|
-
const roadmapPath =
|
|
7516
|
+
const roadmapPath = context2.paths.roadmap;
|
|
7517
7517
|
try {
|
|
7518
7518
|
const roadmapContent = await fs18.readFile(roadmapPath, "utf-8");
|
|
7519
7519
|
actual.roadmapExists = true;
|
|
7520
|
-
const featureName =
|
|
7520
|
+
const featureName = context2.params.description || context2.params.feature;
|
|
7521
7521
|
if (featureName) {
|
|
7522
7522
|
const featurePattern = new RegExp(escapeRegex(featureName), "i");
|
|
7523
7523
|
if (featurePattern.test(roadmapContent)) {
|
|
@@ -7532,7 +7532,7 @@ async function verifyFeature(context) {
|
|
|
7532
7532
|
throw error;
|
|
7533
7533
|
}
|
|
7534
7534
|
}
|
|
7535
|
-
const nowPath =
|
|
7535
|
+
const nowPath = context2.paths.now;
|
|
7536
7536
|
try {
|
|
7537
7537
|
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
7538
7538
|
actual.hasActiveTask = nowContent.trim().length > 0 && !nowContent.includes("No current task");
|
|
@@ -7553,18 +7553,18 @@ async function verifyFeature(context) {
|
|
|
7553
7553
|
recommendations
|
|
7554
7554
|
};
|
|
7555
7555
|
}
|
|
7556
|
-
async function verifyNow(
|
|
7556
|
+
async function verifyNow(context2) {
|
|
7557
7557
|
const warnings = [];
|
|
7558
7558
|
const recommendations = [];
|
|
7559
7559
|
const actual = {};
|
|
7560
|
-
const nowPath =
|
|
7560
|
+
const nowPath = context2.paths.now;
|
|
7561
7561
|
try {
|
|
7562
7562
|
const nowContent = await fs18.readFile(nowPath, "utf-8");
|
|
7563
7563
|
actual.nowExists = true;
|
|
7564
7564
|
actual.nowContent = nowContent.trim();
|
|
7565
7565
|
const hasRealTask = nowContent.trim().length > 0 && !nowContent.includes("No current task") && !nowContent.match(/^#\s*NOW\s*$/m);
|
|
7566
7566
|
actual.hasActiveTask = hasRealTask;
|
|
7567
|
-
if (hasRealTask &&
|
|
7567
|
+
if (hasRealTask && context2.params.task) {
|
|
7568
7568
|
const taskPreview = nowContent.substring(0, 50).replace(/\n/g, " ");
|
|
7569
7569
|
warnings.push(`Replacing existing task: "${taskPreview}..."`);
|
|
7570
7570
|
recommendations.push("Use /p:done first to track completion");
|
|
@@ -7577,12 +7577,12 @@ async function verifyNow(context) {
|
|
|
7577
7577
|
throw error;
|
|
7578
7578
|
}
|
|
7579
7579
|
}
|
|
7580
|
-
const nextPath =
|
|
7580
|
+
const nextPath = context2.paths.next;
|
|
7581
7581
|
try {
|
|
7582
7582
|
const nextContent = await fs18.readFile(nextPath, "utf-8");
|
|
7583
7583
|
const pendingTasks = (nextContent.match(/- \[ \]/g) || []).length;
|
|
7584
7584
|
actual.pendingTasks = pendingTasks;
|
|
7585
|
-
if (!
|
|
7585
|
+
if (!context2.params.task && pendingTasks > 0) {
|
|
7586
7586
|
recommendations.push(`${pendingTasks} tasks available in queue`);
|
|
7587
7587
|
}
|
|
7588
7588
|
} catch (error) {
|
|
@@ -7599,11 +7599,11 @@ async function verifyNow(context) {
|
|
|
7599
7599
|
recommendations
|
|
7600
7600
|
};
|
|
7601
7601
|
}
|
|
7602
|
-
async function verifyInit(
|
|
7602
|
+
async function verifyInit(context2) {
|
|
7603
7603
|
const warnings = [];
|
|
7604
7604
|
const recommendations = [];
|
|
7605
7605
|
const actual = {};
|
|
7606
|
-
const configPath = path17.join(
|
|
7606
|
+
const configPath = path17.join(context2.projectPath, ".prjct/prjct.config.json");
|
|
7607
7607
|
try {
|
|
7608
7608
|
const configContent = await fs18.readFile(configPath, "utf-8");
|
|
7609
7609
|
actual.alreadyInitialized = true;
|
|
@@ -7648,11 +7648,11 @@ async function verifyInit(context) {
|
|
|
7648
7648
|
recommendations
|
|
7649
7649
|
};
|
|
7650
7650
|
}
|
|
7651
|
-
async function verifySync(
|
|
7651
|
+
async function verifySync(context2) {
|
|
7652
7652
|
const warnings = [];
|
|
7653
7653
|
const recommendations = [];
|
|
7654
7654
|
const actual = {};
|
|
7655
|
-
const configPath = path17.join(
|
|
7655
|
+
const configPath = path17.join(context2.projectPath, ".prjct/prjct.config.json");
|
|
7656
7656
|
try {
|
|
7657
7657
|
const configContent = await fs18.readFile(configPath, "utf-8");
|
|
7658
7658
|
actual.hasConfig = true;
|
|
@@ -7693,7 +7693,7 @@ async function verifySync(context) {
|
|
|
7693
7693
|
recommendations
|
|
7694
7694
|
};
|
|
7695
7695
|
}
|
|
7696
|
-
async function verifyAnalyze(
|
|
7696
|
+
async function verifyAnalyze(context2) {
|
|
7697
7697
|
const warnings = [];
|
|
7698
7698
|
const recommendations = [];
|
|
7699
7699
|
const actual = {};
|
|
@@ -7701,7 +7701,7 @@ async function verifyAnalyze(context) {
|
|
|
7701
7701
|
actual.detectedFiles = [];
|
|
7702
7702
|
for (const file of files) {
|
|
7703
7703
|
try {
|
|
7704
|
-
await fs18.access(path17.join(
|
|
7704
|
+
await fs18.access(path17.join(context2.projectPath, file));
|
|
7705
7705
|
actual.detectedFiles.push(file);
|
|
7706
7706
|
} catch (error) {
|
|
7707
7707
|
if (!isNotFoundError(error)) {
|
|
@@ -7717,7 +7717,7 @@ async function verifyAnalyze(context) {
|
|
|
7717
7717
|
actual.detectedSrcDirs = [];
|
|
7718
7718
|
for (const dir of srcDirs) {
|
|
7719
7719
|
try {
|
|
7720
|
-
const stat = await fs18.stat(path17.join(
|
|
7720
|
+
const stat = await fs18.stat(path17.join(context2.projectPath, dir));
|
|
7721
7721
|
if (stat.isDirectory()) {
|
|
7722
7722
|
;
|
|
7723
7723
|
actual.detectedSrcDirs.push(dir);
|
|
@@ -7736,11 +7736,11 @@ async function verifyAnalyze(context) {
|
|
|
7736
7736
|
recommendations
|
|
7737
7737
|
};
|
|
7738
7738
|
}
|
|
7739
|
-
async function verifySpec(
|
|
7739
|
+
async function verifySpec(context2) {
|
|
7740
7740
|
const warnings = [];
|
|
7741
7741
|
const recommendations = [];
|
|
7742
7742
|
const actual = {};
|
|
7743
|
-
const specsPath =
|
|
7743
|
+
const specsPath = context2.paths.specs;
|
|
7744
7744
|
try {
|
|
7745
7745
|
await fs18.access(specsPath);
|
|
7746
7746
|
actual.specsExists = true;
|
|
@@ -7755,7 +7755,7 @@ async function verifySpec(context) {
|
|
|
7755
7755
|
throw error;
|
|
7756
7756
|
}
|
|
7757
7757
|
}
|
|
7758
|
-
const featureName =
|
|
7758
|
+
const featureName = context2.params.feature || context2.params.name || context2.params.description;
|
|
7759
7759
|
if (featureName && actual.existingSpecs) {
|
|
7760
7760
|
const slug = featureName.toLowerCase().replace(/\s+/g, "-");
|
|
7761
7761
|
if (actual.existingSpecs.includes(`${slug}.md`)) {
|
|
@@ -7770,7 +7770,7 @@ async function verifySpec(context) {
|
|
|
7770
7770
|
recommendations
|
|
7771
7771
|
};
|
|
7772
7772
|
}
|
|
7773
|
-
async function verify(commandName,
|
|
7773
|
+
async function verify(commandName, context2, state) {
|
|
7774
7774
|
const verifier = verifiers[commandName];
|
|
7775
7775
|
if (!verifier) {
|
|
7776
7776
|
return {
|
|
@@ -7781,7 +7781,7 @@ async function verify(commandName, context, state) {
|
|
|
7781
7781
|
};
|
|
7782
7782
|
}
|
|
7783
7783
|
try {
|
|
7784
|
-
return await verifier(
|
|
7784
|
+
return await verifier(context2, state);
|
|
7785
7785
|
} catch (error) {
|
|
7786
7786
|
return {
|
|
7787
7787
|
verified: false,
|
|
@@ -7791,10 +7791,10 @@ async function verify(commandName, context, state) {
|
|
|
7791
7791
|
};
|
|
7792
7792
|
}
|
|
7793
7793
|
}
|
|
7794
|
-
async function prepareCommand(commandName,
|
|
7795
|
-
const verification = await verify(commandName,
|
|
7794
|
+
async function prepareCommand(commandName, context2, state) {
|
|
7795
|
+
const verification = await verify(commandName, context2, state);
|
|
7796
7796
|
return {
|
|
7797
|
-
...
|
|
7797
|
+
...context2,
|
|
7798
7798
|
groundTruth: {
|
|
7799
7799
|
...verification,
|
|
7800
7800
|
verifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -7894,15 +7894,15 @@ var init_constants = __esm({
|
|
|
7894
7894
|
});
|
|
7895
7895
|
|
|
7896
7896
|
// core/agentic/plan-mode.ts
|
|
7897
|
-
function generateApprovalPrompt(commandName,
|
|
7897
|
+
function generateApprovalPrompt(commandName, context2) {
|
|
7898
7898
|
const prompts = {
|
|
7899
7899
|
ship: {
|
|
7900
7900
|
title: "Ship Confirmation",
|
|
7901
7901
|
message: "Ready to commit and push changes?",
|
|
7902
7902
|
details: [
|
|
7903
|
-
`Branch: ${
|
|
7904
|
-
`Files: ${
|
|
7905
|
-
`Commit: "${
|
|
7903
|
+
`Branch: ${context2.branch || "current"}`,
|
|
7904
|
+
`Files: ${context2.changedFiles?.length || 0} changed`,
|
|
7905
|
+
`Commit: "${context2.commitMessage || "No message"}"`
|
|
7906
7906
|
],
|
|
7907
7907
|
options: [
|
|
7908
7908
|
{ key: "y", label: "Yes, ship it", action: "approve" },
|
|
@@ -7913,7 +7913,7 @@ function generateApprovalPrompt(commandName, context) {
|
|
|
7913
7913
|
cleanup: {
|
|
7914
7914
|
title: "Cleanup Confirmation",
|
|
7915
7915
|
message: "This will delete files/code. Continue?",
|
|
7916
|
-
details: [`Files to delete: ${
|
|
7916
|
+
details: [`Files to delete: ${context2.filesToDelete?.length || 0}`, `Code to remove: ${context2.linesOfCode || 0} lines`],
|
|
7917
7917
|
options: [
|
|
7918
7918
|
{ key: "y", label: "Yes, cleanup", action: "approve" },
|
|
7919
7919
|
{ key: "n", label: "No, cancel", action: "reject" },
|
|
@@ -7922,8 +7922,8 @@ function generateApprovalPrompt(commandName, context) {
|
|
|
7922
7922
|
},
|
|
7923
7923
|
git: {
|
|
7924
7924
|
title: "Git Operation Confirmation",
|
|
7925
|
-
message: `Execute: ${
|
|
7926
|
-
details:
|
|
7925
|
+
message: `Execute: ${context2.operation || "git operation"}?`,
|
|
7926
|
+
details: context2.warnings || [],
|
|
7927
7927
|
options: [
|
|
7928
7928
|
{ key: "y", label: "Yes, execute", action: "approve" },
|
|
7929
7929
|
{ key: "n", label: "No, cancel", action: "reject" }
|
|
@@ -8234,8 +8234,8 @@ var init_plan_mode = __esm({
|
|
|
8234
8234
|
/**
|
|
8235
8235
|
* Generate approval prompt for destructive commands (class method wrapper)
|
|
8236
8236
|
*/
|
|
8237
|
-
generateApprovalPrompt(commandName,
|
|
8238
|
-
return generateApprovalPrompt(commandName,
|
|
8237
|
+
generateApprovalPrompt(commandName, context2) {
|
|
8238
|
+
return generateApprovalPrompt(commandName, context2);
|
|
8239
8239
|
}
|
|
8240
8240
|
/**
|
|
8241
8241
|
* Format plan status for display
|
|
@@ -8380,53 +8380,53 @@ var init_template_executor = __esm({
|
|
|
8380
8380
|
/**
|
|
8381
8381
|
* Build prompt that tells Claude to execute templates agentically
|
|
8382
8382
|
*/
|
|
8383
|
-
buildAgenticPrompt(
|
|
8384
|
-
const requiresOrchestration = this.requiresOrchestration(
|
|
8383
|
+
buildAgenticPrompt(context2) {
|
|
8384
|
+
const requiresOrchestration = this.requiresOrchestration(context2.command);
|
|
8385
8385
|
const prompt = `
|
|
8386
8386
|
## Agentic Execution Mode
|
|
8387
8387
|
|
|
8388
8388
|
You are executing a prjct command. Follow the template-first approach.
|
|
8389
8389
|
|
|
8390
8390
|
### Context
|
|
8391
|
-
- Command: ${
|
|
8392
|
-
- Args: ${
|
|
8393
|
-
- Project: ${
|
|
8394
|
-
- Project ID: ${
|
|
8391
|
+
- Command: ${context2.command}
|
|
8392
|
+
- Args: ${context2.args}
|
|
8393
|
+
- Project: ${context2.projectPath}
|
|
8394
|
+
- Project ID: ${context2.projectId}
|
|
8395
8395
|
|
|
8396
8396
|
### Paths (Read as needed)
|
|
8397
|
-
- Orchestrator: ${
|
|
8398
|
-
- Agent Routing: ${
|
|
8399
|
-
- Task Fragmentation: ${
|
|
8400
|
-
- Command Template: ${
|
|
8401
|
-
- Repo Analysis: ${
|
|
8402
|
-
- Agents Directory: ${
|
|
8403
|
-
- Skills Directory: ${
|
|
8404
|
-
- State JSON: ${
|
|
8397
|
+
- Orchestrator: ${context2.paths.orchestrator}
|
|
8398
|
+
- Agent Routing: ${context2.paths.agentRouting}
|
|
8399
|
+
- Task Fragmentation: ${context2.paths.taskFragmentation}
|
|
8400
|
+
- Command Template: ${context2.paths.commandTemplate}
|
|
8401
|
+
- Repo Analysis: ${context2.paths.repoAnalysis}
|
|
8402
|
+
- Agents Directory: ${context2.paths.agentsDir}
|
|
8403
|
+
- Skills Directory: ${context2.paths.skillsDir}
|
|
8404
|
+
- State JSON: ${context2.paths.stateJson}
|
|
8405
8405
|
|
|
8406
8406
|
### Instructions
|
|
8407
8407
|
|
|
8408
|
-
1. **Read the command template** (${
|
|
8408
|
+
1. **Read the command template** (${context2.paths.commandTemplate})
|
|
8409
8409
|
|
|
8410
8410
|
2. **Check if orchestration is needed**
|
|
8411
8411
|
- This command ${requiresOrchestration ? "REQUIRES" : "does NOT require"} orchestration
|
|
8412
8412
|
${requiresOrchestration ? `
|
|
8413
8413
|
3. **Orchestration steps:**
|
|
8414
|
-
- Read: ${
|
|
8415
|
-
- Read: ${
|
|
8416
|
-
- Analyze the task: "${
|
|
8414
|
+
- Read: ${context2.paths.orchestrator}
|
|
8415
|
+
- Read: ${context2.paths.repoAnalysis} to understand project technologies
|
|
8416
|
+
- Analyze the task: "${context2.args}"
|
|
8417
8417
|
- Determine which domains are ACTUALLY relevant based on:
|
|
8418
8418
|
a) What the task requires
|
|
8419
8419
|
b) What technologies exist in this project
|
|
8420
|
-
c) What agents are available in ${
|
|
8420
|
+
c) What agents are available in ${context2.paths.agentsDir}
|
|
8421
8421
|
|
|
8422
|
-
- **IMPORTANTE**: Los agentes en ${
|
|
8422
|
+
- **IMPORTANTE**: Los agentes en ${context2.paths.agentsDir} YA son espec\xEDficos del proyecto
|
|
8423
8423
|
(fueron generados durante p. sync con las tecnolog\xEDas reales)
|
|
8424
8424
|
|
|
8425
8425
|
- SIEMPRE usar el especialista si existe para el dominio
|
|
8426
8426
|
- Solo usar generalista si NO existe agente para ese dominio
|
|
8427
8427
|
|
|
8428
|
-
- Check if task should be fragmented (read: ${
|
|
8429
|
-
- If agents loaded, check their skills and load from ${
|
|
8428
|
+
- Check if task should be fragmented (read: ${context2.paths.taskFragmentation})
|
|
8429
|
+
- If agents loaded, check their skills and load from ${context2.paths.skillsDir}
|
|
8430
8430
|
` : `
|
|
8431
8431
|
3. **Simple execution:**
|
|
8432
8432
|
- Execute the command template directly
|
|
@@ -8466,7 +8466,7 @@ When fragmenting tasks:
|
|
|
8466
8466
|
`;
|
|
8467
8467
|
return {
|
|
8468
8468
|
prompt,
|
|
8469
|
-
context,
|
|
8469
|
+
context: context2,
|
|
8470
8470
|
requiresOrchestration
|
|
8471
8471
|
};
|
|
8472
8472
|
}
|
|
@@ -9049,7 +9049,7 @@ var init_command_executor = __esm({
|
|
|
9049
9049
|
console.warn(`\u26A0\uFE0F Orchestrator warning: ${error.message}`);
|
|
9050
9050
|
}
|
|
9051
9051
|
}
|
|
9052
|
-
const
|
|
9052
|
+
const context2 = {
|
|
9053
9053
|
...metadataContext,
|
|
9054
9054
|
agentsPath: agenticExecContext.paths.agentsDir,
|
|
9055
9055
|
agentRoutingPath: agenticExecContext.paths.agentRouting,
|
|
@@ -9085,7 +9085,7 @@ var init_command_executor = __esm({
|
|
|
9085
9085
|
};
|
|
9086
9086
|
const prompt = prompt_builder_default.build(
|
|
9087
9087
|
template,
|
|
9088
|
-
|
|
9088
|
+
context2,
|
|
9089
9089
|
state,
|
|
9090
9090
|
null,
|
|
9091
9091
|
learnedPatterns,
|
|
@@ -9103,7 +9103,7 @@ var init_command_executor = __esm({
|
|
|
9103
9103
|
return {
|
|
9104
9104
|
success: true,
|
|
9105
9105
|
template,
|
|
9106
|
-
context,
|
|
9106
|
+
context: context2,
|
|
9107
9107
|
state,
|
|
9108
9108
|
prompt,
|
|
9109
9109
|
agenticDelegation: true,
|
|
@@ -9111,8 +9111,8 @@ var init_command_executor = __esm({
|
|
|
9111
9111
|
agenticExecContext,
|
|
9112
9112
|
agenticPrompt: agenticInfo.prompt,
|
|
9113
9113
|
requiresOrchestration: agenticInfo.requiresOrchestration,
|
|
9114
|
-
agentsPath:
|
|
9115
|
-
agentRoutingPath:
|
|
9114
|
+
agentsPath: context2.agentsPath,
|
|
9115
|
+
agentRoutingPath: context2.agentRoutingPath,
|
|
9116
9116
|
orchestratorPath: agenticExecContext.paths.orchestrator,
|
|
9117
9117
|
taskFragmentationPath: agenticExecContext.paths.taskFragmentation,
|
|
9118
9118
|
reasoning,
|
|
@@ -9202,13 +9202,13 @@ var init_command_executor = __esm({
|
|
|
9202
9202
|
try {
|
|
9203
9203
|
const template = await template_loader_default.load(commandName);
|
|
9204
9204
|
const allowedTools = template.frontmatter["allowed-tools"] || [];
|
|
9205
|
-
const
|
|
9205
|
+
const context2 = await context_builder_default.build(projectPath);
|
|
9206
9206
|
const tools = {
|
|
9207
9207
|
read: /* @__PURE__ */ __name(async (filePath) => this.executeTool("Read", [filePath], allowedTools), "read"),
|
|
9208
9208
|
write: /* @__PURE__ */ __name(async (filePath, content) => this.executeTool("Write", [filePath, content], allowedTools), "write"),
|
|
9209
9209
|
bash: /* @__PURE__ */ __name(async (command) => this.executeTool("Bash", [command], allowedTools), "bash")
|
|
9210
9210
|
};
|
|
9211
|
-
const result = await executionFn(tools,
|
|
9211
|
+
const result = await executionFn(tools, context2);
|
|
9212
9212
|
return {
|
|
9213
9213
|
success: true,
|
|
9214
9214
|
result
|
|
@@ -10436,6 +10436,7 @@ var init_analysis2 = __esm({
|
|
|
10436
10436
|
init_analyzer2();
|
|
10437
10437
|
init_generator();
|
|
10438
10438
|
init_command_installer();
|
|
10439
|
+
init_services();
|
|
10439
10440
|
AnalysisCommands = class extends PrjctCommandsBase {
|
|
10440
10441
|
static {
|
|
10441
10442
|
__name(this, "AnalysisCommands");
|
|
@@ -10448,7 +10449,7 @@ var init_analysis2 = __esm({
|
|
|
10448
10449
|
await this.initializeAgent();
|
|
10449
10450
|
console.log("\u{1F50D} Analyzing repository...\n");
|
|
10450
10451
|
analyzer_default2.init(projectPath);
|
|
10451
|
-
const
|
|
10452
|
+
const context2 = await context_builder_default.build(projectPath, options);
|
|
10452
10453
|
const analysisData = {
|
|
10453
10454
|
packageJson: await analyzer_default2.readPackageJson(),
|
|
10454
10455
|
cargoToml: await analyzer_default2.readCargoToml(),
|
|
@@ -10467,7 +10468,7 @@ var init_analysis2 = __esm({
|
|
|
10467
10468
|
};
|
|
10468
10469
|
const summary = this._generateAnalysisSummary(analysisData, projectPath);
|
|
10469
10470
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
10470
|
-
const summaryPath =
|
|
10471
|
+
const summaryPath = context2.paths.analysis || path_manager_default.getFilePath(
|
|
10471
10472
|
projectId,
|
|
10472
10473
|
"analysis",
|
|
10473
10474
|
"repo-summary.md"
|
|
@@ -10579,43 +10580,71 @@ var init_analysis2 = __esm({
|
|
|
10579
10580
|
return lines.join("\n");
|
|
10580
10581
|
}
|
|
10581
10582
|
/**
|
|
10582
|
-
* /p:sync -
|
|
10583
|
+
* /p:sync - Comprehensive project sync
|
|
10584
|
+
*
|
|
10585
|
+
* Uses syncService to do ALL operations in one TypeScript execution:
|
|
10586
|
+
* - Git analysis
|
|
10587
|
+
* - Project stats
|
|
10588
|
+
* - Agent generation
|
|
10589
|
+
* - Context file generation
|
|
10590
|
+
* - Skill configuration
|
|
10591
|
+
* - State updates
|
|
10583
10592
|
*
|
|
10584
|
-
*
|
|
10585
|
-
* Claude then reads the data and decides what agents to create.
|
|
10586
|
-
* NO hardcoded if/else logic for technology detection.
|
|
10593
|
+
* This eliminates the need for Claude to make 50+ individual tool calls.
|
|
10587
10594
|
*/
|
|
10588
10595
|
async sync(projectPath = process.cwd()) {
|
|
10589
10596
|
try {
|
|
10590
10597
|
const initResult = await this.ensureProjectInit(projectPath);
|
|
10591
10598
|
if (!initResult.success) return initResult;
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
console.error("\u274C Analysis failed");
|
|
10598
|
-
return analysisResult;
|
|
10599
|
+
console.log("\u{1F504} Syncing project...\n");
|
|
10600
|
+
const result = await syncService.sync(projectPath);
|
|
10601
|
+
if (!result.success) {
|
|
10602
|
+
console.error("\u274C Sync failed:", result.error);
|
|
10603
|
+
return { success: false, error: result.error };
|
|
10599
10604
|
}
|
|
10600
|
-
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
10601
|
-
await generateContext(projectId, projectPath);
|
|
10602
10605
|
const globalConfigResult = await command_installer_default.installGlobalConfig();
|
|
10603
10606
|
if (globalConfigResult.success) {
|
|
10604
10607
|
console.log("\u{1F4DD} Updated ~/.claude/CLAUDE.md");
|
|
10605
10608
|
}
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
});
|
|
10610
|
-
console.log(
|
|
10611
|
-
console.log(
|
|
10612
|
-
console.log(
|
|
10613
|
-
|
|
10614
|
-
console.log("
|
|
10615
|
-
console.log(
|
|
10616
|
-
console.log(
|
|
10609
|
+
console.log(`\u{1F504} Project synced to prjct v${result.cliVersion}
|
|
10610
|
+
`);
|
|
10611
|
+
console.log("\u{1F4CA} Project Stats");
|
|
10612
|
+
console.log(`\u251C\u2500\u2500 Files: ~${result.stats.fileCount}`);
|
|
10613
|
+
console.log(`\u251C\u2500\u2500 Commits: ${result.git.commits}`);
|
|
10614
|
+
console.log(`\u251C\u2500\u2500 Version: ${result.stats.version}`);
|
|
10615
|
+
console.log(`\u2514\u2500\u2500 Stack: ${result.stats.ecosystem}
|
|
10616
|
+
`);
|
|
10617
|
+
console.log("\u{1F33F} Git Status");
|
|
10618
|
+
console.log(`\u251C\u2500\u2500 Branch: ${result.git.branch}`);
|
|
10619
|
+
console.log(`\u251C\u2500\u2500 Uncommitted: ${result.git.hasChanges ? "Yes" : "Clean"}`);
|
|
10620
|
+
console.log(`\u2514\u2500\u2500 Recent: ${result.git.weeklyCommits} commits this week
|
|
10621
|
+
`);
|
|
10622
|
+
console.log("\u{1F4C1} Context Updated");
|
|
10623
|
+
for (const file of result.contextFiles) {
|
|
10624
|
+
console.log(`\u251C\u2500\u2500 ${file}`);
|
|
10625
|
+
}
|
|
10626
|
+
console.log("");
|
|
10627
|
+
const workflowAgents = result.agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
10628
|
+
const domainAgents = result.agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
10629
|
+
console.log(`\u{1F916} Agents Regenerated (${result.agents.length})`);
|
|
10630
|
+
console.log(`\u251C\u2500\u2500 Workflow: ${workflowAgents.join(", ")}`);
|
|
10631
|
+
console.log(`\u2514\u2500\u2500 Domain: ${domainAgents.join(", ") || "none"}
|
|
10632
|
+
`);
|
|
10633
|
+
if (result.skills.length > 0) {
|
|
10634
|
+
console.log("\u{1F4E6} Skills Configured");
|
|
10635
|
+
for (const skill of result.skills) {
|
|
10636
|
+
console.log(`\u251C\u2500\u2500 ${skill.agent}.md \u2192 ${skill.skill}`);
|
|
10637
|
+
}
|
|
10638
|
+
console.log("");
|
|
10639
|
+
}
|
|
10640
|
+
if (result.git.hasChanges) {
|
|
10641
|
+
console.log("\u26A0\uFE0F You have uncommitted changes\n");
|
|
10642
|
+
} else {
|
|
10643
|
+
console.log("\u2728 Repository is clean!\n");
|
|
10644
|
+
}
|
|
10617
10645
|
return {
|
|
10618
|
-
success: true
|
|
10646
|
+
success: true,
|
|
10647
|
+
data: result
|
|
10619
10648
|
};
|
|
10620
10649
|
} catch (error) {
|
|
10621
10650
|
console.error("\u274C Error:", error.message);
|
|
@@ -10758,12 +10787,12 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10758
10787
|
return { success: false, error: "No project ID found" };
|
|
10759
10788
|
}
|
|
10760
10789
|
output_default.spin(`planning ${description}...`);
|
|
10761
|
-
const
|
|
10790
|
+
const context2 = await context_builder_default.build(projectPath, { description });
|
|
10762
10791
|
const tasks = this._breakdownFeatureTasks(description);
|
|
10763
10792
|
const featureId = generateUUID();
|
|
10764
10793
|
const tasksWithAgents = [];
|
|
10765
10794
|
for (const taskDesc of tasks) {
|
|
10766
|
-
const agentResult = await this._assignAgentForTask(taskDesc, projectPath,
|
|
10795
|
+
const agentResult = await this._assignAgentForTask(taskDesc, projectPath, context2);
|
|
10767
10796
|
const agent = agentResult.agent?.name || "generalist";
|
|
10768
10797
|
tasksWithAgents.push({ task: taskDesc, agent });
|
|
10769
10798
|
}
|
|
@@ -10812,9 +10841,9 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10812
10841
|
return { success: false, error: "No project ID found" };
|
|
10813
10842
|
}
|
|
10814
10843
|
output_default.spin("tracking bug...");
|
|
10815
|
-
const
|
|
10844
|
+
const context2 = await context_builder_default.build(projectPath, { description });
|
|
10816
10845
|
const severity = this._detectBugSeverity(description);
|
|
10817
|
-
const agentResult = await this._assignAgentForTask(`fix bug: ${description}`, projectPath,
|
|
10846
|
+
const agentResult = await this._assignAgentForTask(`fix bug: ${description}`, projectPath, context2);
|
|
10818
10847
|
const agent = agentResult.agent?.name || "generalist";
|
|
10819
10848
|
const priorityMap = {
|
|
10820
10849
|
"critical": "critical",
|
|
@@ -10990,8 +11019,8 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
10990
11019
|
const globalPath2 = path_manager_default.getGlobalProjectPath(projectId);
|
|
10991
11020
|
const specsPath2 = path27.join(globalPath2, "planning", "specs");
|
|
10992
11021
|
try {
|
|
10993
|
-
const
|
|
10994
|
-
const files = await
|
|
11022
|
+
const fs30 = await import("fs/promises");
|
|
11023
|
+
const files = await fs30.readdir(specsPath2);
|
|
10995
11024
|
const specs = files.filter((f) => f.endsWith(".md") && f !== ".gitkeep");
|
|
10996
11025
|
if (specs.length === 0) {
|
|
10997
11026
|
output_default.warn("no specs yet");
|
|
@@ -11376,6 +11405,790 @@ var init_breakdown_service = __esm({
|
|
|
11376
11405
|
}
|
|
11377
11406
|
});
|
|
11378
11407
|
|
|
11408
|
+
// core/services/sync-service.ts
|
|
11409
|
+
import fs27 from "fs/promises";
|
|
11410
|
+
import path28 from "path";
|
|
11411
|
+
import { exec as exec5 } from "child_process";
|
|
11412
|
+
import { promisify as promisify5 } from "util";
|
|
11413
|
+
var execAsync3, SyncService, syncService;
|
|
11414
|
+
var init_sync_service = __esm({
|
|
11415
|
+
"core/services/sync-service.ts"() {
|
|
11416
|
+
"use strict";
|
|
11417
|
+
init_path_manager();
|
|
11418
|
+
init_config_manager();
|
|
11419
|
+
init_date_helper();
|
|
11420
|
+
execAsync3 = promisify5(exec5);
|
|
11421
|
+
SyncService = class {
|
|
11422
|
+
static {
|
|
11423
|
+
__name(this, "SyncService");
|
|
11424
|
+
}
|
|
11425
|
+
projectPath;
|
|
11426
|
+
projectId = null;
|
|
11427
|
+
globalPath = "";
|
|
11428
|
+
cliVersion = "0.0.0";
|
|
11429
|
+
constructor() {
|
|
11430
|
+
this.projectPath = process.cwd();
|
|
11431
|
+
}
|
|
11432
|
+
/**
|
|
11433
|
+
* Main sync method - does everything in one call
|
|
11434
|
+
*/
|
|
11435
|
+
async sync(projectPath = process.cwd()) {
|
|
11436
|
+
this.projectPath = projectPath;
|
|
11437
|
+
try {
|
|
11438
|
+
this.projectId = await config_manager_default.getProjectId(projectPath);
|
|
11439
|
+
if (!this.projectId) {
|
|
11440
|
+
return {
|
|
11441
|
+
success: false,
|
|
11442
|
+
projectId: "",
|
|
11443
|
+
cliVersion: "",
|
|
11444
|
+
git: this.emptyGitData(),
|
|
11445
|
+
stats: this.emptyStats(),
|
|
11446
|
+
commands: this.emptyCommands(),
|
|
11447
|
+
stack: this.emptyStack(),
|
|
11448
|
+
agents: [],
|
|
11449
|
+
skills: [],
|
|
11450
|
+
contextFiles: [],
|
|
11451
|
+
error: "No prjct project. Run p. init first."
|
|
11452
|
+
};
|
|
11453
|
+
}
|
|
11454
|
+
this.globalPath = path_manager_default.getGlobalProjectPath(this.projectId);
|
|
11455
|
+
this.cliVersion = await this.getCliVersion();
|
|
11456
|
+
await this.ensureDirectories();
|
|
11457
|
+
const git = await this.analyzeGit();
|
|
11458
|
+
const stats = await this.gatherStats();
|
|
11459
|
+
const commands = await this.detectCommands();
|
|
11460
|
+
const stack = await this.detectStack();
|
|
11461
|
+
const agents = await this.generateAgents(stack, stats);
|
|
11462
|
+
const skills = this.configureSkills(agents);
|
|
11463
|
+
const contextFiles = await this.generateContextFiles(git, stats, commands, agents);
|
|
11464
|
+
await this.updateProjectJson(git, stats);
|
|
11465
|
+
await this.updateStateJson(stats, stack);
|
|
11466
|
+
await this.logToMemory(git, stats);
|
|
11467
|
+
return {
|
|
11468
|
+
success: true,
|
|
11469
|
+
projectId: this.projectId,
|
|
11470
|
+
cliVersion: this.cliVersion,
|
|
11471
|
+
git,
|
|
11472
|
+
stats,
|
|
11473
|
+
commands,
|
|
11474
|
+
stack,
|
|
11475
|
+
agents,
|
|
11476
|
+
skills,
|
|
11477
|
+
contextFiles
|
|
11478
|
+
};
|
|
11479
|
+
} catch (error) {
|
|
11480
|
+
return {
|
|
11481
|
+
success: false,
|
|
11482
|
+
projectId: this.projectId || "",
|
|
11483
|
+
cliVersion: this.cliVersion,
|
|
11484
|
+
git: this.emptyGitData(),
|
|
11485
|
+
stats: this.emptyStats(),
|
|
11486
|
+
commands: this.emptyCommands(),
|
|
11487
|
+
stack: this.emptyStack(),
|
|
11488
|
+
agents: [],
|
|
11489
|
+
skills: [],
|
|
11490
|
+
contextFiles: [],
|
|
11491
|
+
error: error.message
|
|
11492
|
+
};
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
// ==========================================================================
|
|
11496
|
+
// DIRECTORY SETUP
|
|
11497
|
+
// ==========================================================================
|
|
11498
|
+
async ensureDirectories() {
|
|
11499
|
+
const dirs = ["storage", "context", "agents", "memory", "analysis", "config", "sync"];
|
|
11500
|
+
for (const dir of dirs) {
|
|
11501
|
+
await fs27.mkdir(path28.join(this.globalPath, dir), { recursive: true });
|
|
11502
|
+
}
|
|
11503
|
+
}
|
|
11504
|
+
// ==========================================================================
|
|
11505
|
+
// GIT ANALYSIS
|
|
11506
|
+
// ==========================================================================
|
|
11507
|
+
async analyzeGit() {
|
|
11508
|
+
const data = {
|
|
11509
|
+
branch: "main",
|
|
11510
|
+
commits: 0,
|
|
11511
|
+
contributors: 0,
|
|
11512
|
+
hasChanges: false,
|
|
11513
|
+
stagedFiles: [],
|
|
11514
|
+
modifiedFiles: [],
|
|
11515
|
+
untrackedFiles: [],
|
|
11516
|
+
recentCommits: [],
|
|
11517
|
+
weeklyCommits: 0
|
|
11518
|
+
};
|
|
11519
|
+
try {
|
|
11520
|
+
const { stdout: branch } = await execAsync3("git branch --show-current", {
|
|
11521
|
+
cwd: this.projectPath
|
|
11522
|
+
});
|
|
11523
|
+
data.branch = branch.trim() || "main";
|
|
11524
|
+
const { stdout: commits } = await execAsync3("git rev-list --count HEAD", {
|
|
11525
|
+
cwd: this.projectPath
|
|
11526
|
+
});
|
|
11527
|
+
data.commits = parseInt(commits.trim()) || 0;
|
|
11528
|
+
const { stdout: contributors } = await execAsync3("git shortlog -sn --all | wc -l", {
|
|
11529
|
+
cwd: this.projectPath
|
|
11530
|
+
});
|
|
11531
|
+
data.contributors = parseInt(contributors.trim()) || 0;
|
|
11532
|
+
const { stdout: status } = await execAsync3("git status --porcelain", {
|
|
11533
|
+
cwd: this.projectPath
|
|
11534
|
+
});
|
|
11535
|
+
const lines = status.trim().split("\n").filter(Boolean);
|
|
11536
|
+
data.hasChanges = lines.length > 0;
|
|
11537
|
+
for (const line of lines) {
|
|
11538
|
+
const code = line.substring(0, 2);
|
|
11539
|
+
const file = line.substring(3);
|
|
11540
|
+
if (code.startsWith("A") || code.startsWith("M ")) {
|
|
11541
|
+
data.stagedFiles.push(file);
|
|
11542
|
+
} else if (code.includes("M")) {
|
|
11543
|
+
data.modifiedFiles.push(file);
|
|
11544
|
+
} else if (code.startsWith("??")) {
|
|
11545
|
+
data.untrackedFiles.push(file);
|
|
11546
|
+
}
|
|
11547
|
+
}
|
|
11548
|
+
const { stdout: log } = await execAsync3(
|
|
11549
|
+
'git log --oneline -20 --pretty=format:"%h|%s|%ad" --date=short',
|
|
11550
|
+
{ cwd: this.projectPath }
|
|
11551
|
+
);
|
|
11552
|
+
data.recentCommits = log.split("\n").filter(Boolean).map((line) => {
|
|
11553
|
+
const [hash, message, date] = line.split("|");
|
|
11554
|
+
return { hash, message, date };
|
|
11555
|
+
});
|
|
11556
|
+
const { stdout: weekly } = await execAsync3('git log --oneline --since="1 week ago" | wc -l', {
|
|
11557
|
+
cwd: this.projectPath
|
|
11558
|
+
});
|
|
11559
|
+
data.weeklyCommits = parseInt(weekly.trim()) || 0;
|
|
11560
|
+
} catch {
|
|
11561
|
+
}
|
|
11562
|
+
return data;
|
|
11563
|
+
}
|
|
11564
|
+
// ==========================================================================
|
|
11565
|
+
// PROJECT STATS
|
|
11566
|
+
// ==========================================================================
|
|
11567
|
+
async gatherStats() {
|
|
11568
|
+
const stats = {
|
|
11569
|
+
fileCount: 0,
|
|
11570
|
+
version: "0.0.0",
|
|
11571
|
+
name: path28.basename(this.projectPath),
|
|
11572
|
+
ecosystem: "unknown",
|
|
11573
|
+
projectType: "simple",
|
|
11574
|
+
languages: [],
|
|
11575
|
+
frameworks: []
|
|
11576
|
+
};
|
|
11577
|
+
try {
|
|
11578
|
+
const { stdout } = await execAsync3(
|
|
11579
|
+
'find . -type f \\( -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.py" -o -name "*.go" -o -name "*.rs" \\) -not -path "./node_modules/*" -not -path "./.git/*" | wc -l',
|
|
11580
|
+
{ cwd: this.projectPath }
|
|
11581
|
+
);
|
|
11582
|
+
stats.fileCount = parseInt(stdout.trim()) || 0;
|
|
11583
|
+
} catch {
|
|
11584
|
+
stats.fileCount = 0;
|
|
11585
|
+
}
|
|
11586
|
+
try {
|
|
11587
|
+
const pkgPath = path28.join(this.projectPath, "package.json");
|
|
11588
|
+
const pkg = JSON.parse(await fs27.readFile(pkgPath, "utf-8"));
|
|
11589
|
+
stats.version = pkg.version || "0.0.0";
|
|
11590
|
+
stats.name = pkg.name || stats.name;
|
|
11591
|
+
stats.ecosystem = "JavaScript";
|
|
11592
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
11593
|
+
if (deps.react || deps["react-dom"]) stats.frameworks.push("React");
|
|
11594
|
+
if (deps.next) stats.frameworks.push("Next.js");
|
|
11595
|
+
if (deps.vue) stats.frameworks.push("Vue");
|
|
11596
|
+
if (deps.express) stats.frameworks.push("Express");
|
|
11597
|
+
if (deps.hono) stats.frameworks.push("Hono");
|
|
11598
|
+
if (deps["@angular/core"]) stats.frameworks.push("Angular");
|
|
11599
|
+
if (deps.svelte) stats.frameworks.push("Svelte");
|
|
11600
|
+
if (pkg.devDependencies?.typescript || await this.fileExists("tsconfig.json")) {
|
|
11601
|
+
stats.languages.push("TypeScript");
|
|
11602
|
+
} else {
|
|
11603
|
+
stats.languages.push("JavaScript");
|
|
11604
|
+
}
|
|
11605
|
+
} catch {
|
|
11606
|
+
}
|
|
11607
|
+
if (await this.fileExists("Cargo.toml")) {
|
|
11608
|
+
stats.ecosystem = "Rust";
|
|
11609
|
+
stats.languages.push("Rust");
|
|
11610
|
+
}
|
|
11611
|
+
if (await this.fileExists("go.mod")) {
|
|
11612
|
+
stats.ecosystem = "Go";
|
|
11613
|
+
stats.languages.push("Go");
|
|
11614
|
+
}
|
|
11615
|
+
if (await this.fileExists("requirements.txt") || await this.fileExists("pyproject.toml")) {
|
|
11616
|
+
stats.ecosystem = "Python";
|
|
11617
|
+
stats.languages.push("Python");
|
|
11618
|
+
}
|
|
11619
|
+
if (stats.fileCount > 300 || stats.frameworks.length >= 3) {
|
|
11620
|
+
stats.projectType = "enterprise";
|
|
11621
|
+
} else if (stats.fileCount > 50 || stats.frameworks.length >= 2) {
|
|
11622
|
+
stats.projectType = "complex";
|
|
11623
|
+
}
|
|
11624
|
+
return stats;
|
|
11625
|
+
}
|
|
11626
|
+
// ==========================================================================
|
|
11627
|
+
// COMMAND DETECTION
|
|
11628
|
+
// ==========================================================================
|
|
11629
|
+
async detectCommands() {
|
|
11630
|
+
const commands = {
|
|
11631
|
+
install: "npm install",
|
|
11632
|
+
run: "npm run",
|
|
11633
|
+
test: "npm test",
|
|
11634
|
+
build: "npm run build",
|
|
11635
|
+
dev: "npm run dev",
|
|
11636
|
+
lint: "npm run lint",
|
|
11637
|
+
format: "npm run format"
|
|
11638
|
+
};
|
|
11639
|
+
if (await this.fileExists("bun.lockb")) {
|
|
11640
|
+
commands.install = "bun install";
|
|
11641
|
+
commands.run = "bun run";
|
|
11642
|
+
commands.test = "bun test";
|
|
11643
|
+
commands.build = "bun run build";
|
|
11644
|
+
commands.dev = "bun run dev";
|
|
11645
|
+
commands.lint = "bun run lint";
|
|
11646
|
+
commands.format = "bun run format";
|
|
11647
|
+
} else if (await this.fileExists("pnpm-lock.yaml")) {
|
|
11648
|
+
commands.install = "pnpm install";
|
|
11649
|
+
commands.run = "pnpm run";
|
|
11650
|
+
commands.test = "pnpm test";
|
|
11651
|
+
commands.build = "pnpm run build";
|
|
11652
|
+
commands.dev = "pnpm run dev";
|
|
11653
|
+
commands.lint = "pnpm run lint";
|
|
11654
|
+
commands.format = "pnpm run format";
|
|
11655
|
+
} else if (await this.fileExists("yarn.lock")) {
|
|
11656
|
+
commands.install = "yarn";
|
|
11657
|
+
commands.run = "yarn";
|
|
11658
|
+
commands.test = "yarn test";
|
|
11659
|
+
commands.build = "yarn build";
|
|
11660
|
+
commands.dev = "yarn dev";
|
|
11661
|
+
commands.lint = "yarn lint";
|
|
11662
|
+
commands.format = "yarn format";
|
|
11663
|
+
}
|
|
11664
|
+
if (await this.fileExists("Cargo.toml")) {
|
|
11665
|
+
commands.install = "cargo build";
|
|
11666
|
+
commands.run = "cargo run";
|
|
11667
|
+
commands.test = "cargo test";
|
|
11668
|
+
commands.build = "cargo build --release";
|
|
11669
|
+
commands.dev = "cargo run";
|
|
11670
|
+
commands.lint = "cargo clippy";
|
|
11671
|
+
commands.format = "cargo fmt";
|
|
11672
|
+
}
|
|
11673
|
+
if (await this.fileExists("go.mod")) {
|
|
11674
|
+
commands.install = "go mod download";
|
|
11675
|
+
commands.run = "go run .";
|
|
11676
|
+
commands.test = "go test ./...";
|
|
11677
|
+
commands.build = "go build";
|
|
11678
|
+
commands.dev = "go run .";
|
|
11679
|
+
commands.lint = "golangci-lint run";
|
|
11680
|
+
commands.format = "go fmt ./...";
|
|
11681
|
+
}
|
|
11682
|
+
return commands;
|
|
11683
|
+
}
|
|
11684
|
+
// ==========================================================================
|
|
11685
|
+
// STACK DETECTION
|
|
11686
|
+
// ==========================================================================
|
|
11687
|
+
async detectStack() {
|
|
11688
|
+
const stack = {
|
|
11689
|
+
hasFrontend: false,
|
|
11690
|
+
hasBackend: false,
|
|
11691
|
+
hasDatabase: false,
|
|
11692
|
+
hasDocker: false,
|
|
11693
|
+
hasTesting: false,
|
|
11694
|
+
frontendType: null,
|
|
11695
|
+
frameworks: []
|
|
11696
|
+
};
|
|
11697
|
+
try {
|
|
11698
|
+
const pkgPath = path28.join(this.projectPath, "package.json");
|
|
11699
|
+
const pkg = JSON.parse(await fs27.readFile(pkgPath, "utf-8"));
|
|
11700
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
11701
|
+
if (deps.react || deps.vue || deps.svelte || deps["@angular/core"]) {
|
|
11702
|
+
stack.hasFrontend = true;
|
|
11703
|
+
stack.frontendType = "web";
|
|
11704
|
+
}
|
|
11705
|
+
if (deps["react-native"] || deps.expo) {
|
|
11706
|
+
stack.hasFrontend = true;
|
|
11707
|
+
stack.frontendType = stack.frontendType === "web" ? "both" : "mobile";
|
|
11708
|
+
}
|
|
11709
|
+
if (deps.express || deps.fastify || deps.hono || deps.koa || deps.nest) {
|
|
11710
|
+
stack.hasBackend = true;
|
|
11711
|
+
}
|
|
11712
|
+
if (deps.prisma || deps.mongoose || deps.pg || deps.mysql2 || deps.sequelize) {
|
|
11713
|
+
stack.hasDatabase = true;
|
|
11714
|
+
}
|
|
11715
|
+
if (deps.jest || deps.vitest || deps.mocha || pkg.devDependencies?.["bun-types"]) {
|
|
11716
|
+
stack.hasTesting = true;
|
|
11717
|
+
}
|
|
11718
|
+
if (deps.react) stack.frameworks.push("React");
|
|
11719
|
+
if (deps.next) stack.frameworks.push("Next.js");
|
|
11720
|
+
if (deps.express) stack.frameworks.push("Express");
|
|
11721
|
+
if (deps.hono) stack.frameworks.push("Hono");
|
|
11722
|
+
} catch {
|
|
11723
|
+
}
|
|
11724
|
+
stack.hasDocker = await this.fileExists("Dockerfile") || await this.fileExists("docker-compose.yml");
|
|
11725
|
+
return stack;
|
|
11726
|
+
}
|
|
11727
|
+
// ==========================================================================
|
|
11728
|
+
// AGENT GENERATION
|
|
11729
|
+
// ==========================================================================
|
|
11730
|
+
async generateAgents(stack, stats) {
|
|
11731
|
+
const agents = [];
|
|
11732
|
+
const agentsPath = path28.join(this.globalPath, "agents");
|
|
11733
|
+
try {
|
|
11734
|
+
const files = await fs27.readdir(agentsPath);
|
|
11735
|
+
for (const file of files) {
|
|
11736
|
+
if (file.endsWith(".md")) {
|
|
11737
|
+
await fs27.unlink(path28.join(agentsPath, file));
|
|
11738
|
+
}
|
|
11739
|
+
}
|
|
11740
|
+
} catch {
|
|
11741
|
+
}
|
|
11742
|
+
const workflowAgents = ["prjct-workflow", "prjct-planner", "prjct-shipper"];
|
|
11743
|
+
for (const name of workflowAgents) {
|
|
11744
|
+
await this.generateWorkflowAgent(name, agentsPath);
|
|
11745
|
+
agents.push({ name, type: "workflow" });
|
|
11746
|
+
}
|
|
11747
|
+
if (stack.hasFrontend) {
|
|
11748
|
+
await this.generateDomainAgent("frontend", agentsPath, stats, stack);
|
|
11749
|
+
agents.push({ name: "frontend", type: "domain", skill: "javascript-typescript" });
|
|
11750
|
+
await this.generateDomainAgent("uxui", agentsPath, stats, stack);
|
|
11751
|
+
agents.push({ name: "uxui", type: "domain", skill: "frontend-design" });
|
|
11752
|
+
}
|
|
11753
|
+
if (stack.hasBackend) {
|
|
11754
|
+
await this.generateDomainAgent("backend", agentsPath, stats, stack);
|
|
11755
|
+
agents.push({ name: "backend", type: "domain", skill: "javascript-typescript" });
|
|
11756
|
+
}
|
|
11757
|
+
if (stack.hasDatabase) {
|
|
11758
|
+
await this.generateDomainAgent("database", agentsPath, stats, stack);
|
|
11759
|
+
agents.push({ name: "database", type: "domain" });
|
|
11760
|
+
}
|
|
11761
|
+
if (stack.hasTesting) {
|
|
11762
|
+
await this.generateDomainAgent("testing", agentsPath, stats, stack);
|
|
11763
|
+
agents.push({ name: "testing", type: "domain", skill: "developer-kit" });
|
|
11764
|
+
}
|
|
11765
|
+
if (stack.hasDocker) {
|
|
11766
|
+
await this.generateDomainAgent("devops", agentsPath, stats, stack);
|
|
11767
|
+
agents.push({ name: "devops", type: "domain", skill: "developer-kit" });
|
|
11768
|
+
}
|
|
11769
|
+
return agents;
|
|
11770
|
+
}
|
|
11771
|
+
async generateWorkflowAgent(name, agentsPath) {
|
|
11772
|
+
let content = "";
|
|
11773
|
+
try {
|
|
11774
|
+
const templatePath = path28.join(
|
|
11775
|
+
__dirname,
|
|
11776
|
+
"..",
|
|
11777
|
+
"..",
|
|
11778
|
+
"templates",
|
|
11779
|
+
"subagents",
|
|
11780
|
+
"workflow",
|
|
11781
|
+
`${name}.md`
|
|
11782
|
+
);
|
|
11783
|
+
content = await fs27.readFile(templatePath, "utf-8");
|
|
11784
|
+
} catch {
|
|
11785
|
+
content = this.generateMinimalWorkflowAgent(name);
|
|
11786
|
+
}
|
|
11787
|
+
await fs27.writeFile(path28.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
11788
|
+
}
|
|
11789
|
+
async generateDomainAgent(name, agentsPath, stats, stack) {
|
|
11790
|
+
let content = "";
|
|
11791
|
+
try {
|
|
11792
|
+
const templatePath = path28.join(
|
|
11793
|
+
__dirname,
|
|
11794
|
+
"..",
|
|
11795
|
+
"..",
|
|
11796
|
+
"templates",
|
|
11797
|
+
"subagents",
|
|
11798
|
+
"domain",
|
|
11799
|
+
`${name}.md`
|
|
11800
|
+
);
|
|
11801
|
+
content = await fs27.readFile(templatePath, "utf-8");
|
|
11802
|
+
content = content.replace("{projectName}", stats.name);
|
|
11803
|
+
content = content.replace("{frameworks}", stack.frameworks.join(", ") || "None detected");
|
|
11804
|
+
content = content.replace("{ecosystem}", stats.ecosystem);
|
|
11805
|
+
} catch {
|
|
11806
|
+
content = this.generateMinimalDomainAgent(name, stats, stack);
|
|
11807
|
+
}
|
|
11808
|
+
await fs27.writeFile(path28.join(agentsPath, `${name}.md`), content, "utf-8");
|
|
11809
|
+
}
|
|
11810
|
+
generateMinimalWorkflowAgent(name) {
|
|
11811
|
+
const descriptions = {
|
|
11812
|
+
"prjct-workflow": "Task lifecycle: now, done, pause, resume",
|
|
11813
|
+
"prjct-planner": "Planning: task, prd, spec, bug",
|
|
11814
|
+
"prjct-shipper": "Shipping: ship, merge, review"
|
|
11815
|
+
};
|
|
11816
|
+
return `---
|
|
11817
|
+
name: ${name}
|
|
11818
|
+
description: ${descriptions[name] || "Workflow agent"}
|
|
11819
|
+
tools: Read, Write, Glob
|
|
11820
|
+
---
|
|
11821
|
+
|
|
11822
|
+
# ${name.toUpperCase()}
|
|
11823
|
+
|
|
11824
|
+
Workflow agent for prjct operations.
|
|
11825
|
+
|
|
11826
|
+
## Project Context
|
|
11827
|
+
|
|
11828
|
+
When invoked:
|
|
11829
|
+
1. Read \`.prjct/prjct.config.json\` \u2192 extract \`projectId\`
|
|
11830
|
+
2. Read \`~/.prjct-cli/projects/{projectId}/storage/state.json\`
|
|
11831
|
+
3. Execute requested operation
|
|
11832
|
+
`;
|
|
11833
|
+
}
|
|
11834
|
+
generateMinimalDomainAgent(name, stats, stack) {
|
|
11835
|
+
return `---
|
|
11836
|
+
name: ${name}
|
|
11837
|
+
description: ${name.charAt(0).toUpperCase() + name.slice(1)} specialist for ${stats.name}
|
|
11838
|
+
tools: Read, Write, Glob, Grep
|
|
11839
|
+
skills: []
|
|
11840
|
+
---
|
|
11841
|
+
|
|
11842
|
+
# ${name.toUpperCase()} AGENT
|
|
11843
|
+
|
|
11844
|
+
Domain specialist for ${name} tasks.
|
|
11845
|
+
|
|
11846
|
+
## Project Context
|
|
11847
|
+
|
|
11848
|
+
- **Project**: ${stats.name}
|
|
11849
|
+
- **Ecosystem**: ${stats.ecosystem}
|
|
11850
|
+
- **Frameworks**: ${stack.frameworks.join(", ") || "None detected"}
|
|
11851
|
+
|
|
11852
|
+
## Your Role
|
|
11853
|
+
|
|
11854
|
+
You are the ${name} expert for this project. Apply best practices for the detected stack.
|
|
11855
|
+
`;
|
|
11856
|
+
}
|
|
11857
|
+
// ==========================================================================
|
|
11858
|
+
// SKILL CONFIGURATION
|
|
11859
|
+
// ==========================================================================
|
|
11860
|
+
configureSkills(agents) {
|
|
11861
|
+
const skills = [];
|
|
11862
|
+
for (const agent of agents) {
|
|
11863
|
+
if (agent.skill) {
|
|
11864
|
+
skills.push({ agent: agent.name, skill: agent.skill });
|
|
11865
|
+
}
|
|
11866
|
+
}
|
|
11867
|
+
const skillsConfig = {
|
|
11868
|
+
projectId: this.projectId,
|
|
11869
|
+
syncedAt: date_helper_default.getTimestamp(),
|
|
11870
|
+
skills: skills.map((s) => ({
|
|
11871
|
+
name: s.skill,
|
|
11872
|
+
linkedAgents: [s.agent]
|
|
11873
|
+
})),
|
|
11874
|
+
agentSkillMap: Object.fromEntries(skills.map((s) => [s.agent, s.skill]))
|
|
11875
|
+
};
|
|
11876
|
+
fs27.writeFile(
|
|
11877
|
+
path28.join(this.globalPath, "config", "skills.json"),
|
|
11878
|
+
JSON.stringify(skillsConfig, null, 2),
|
|
11879
|
+
"utf-8"
|
|
11880
|
+
).catch(() => {
|
|
11881
|
+
});
|
|
11882
|
+
return skills;
|
|
11883
|
+
}
|
|
11884
|
+
// ==========================================================================
|
|
11885
|
+
// CONTEXT FILE GENERATION
|
|
11886
|
+
// ==========================================================================
|
|
11887
|
+
async generateContextFiles(git, stats, commands, agents) {
|
|
11888
|
+
const contextPath = path28.join(this.globalPath, "context");
|
|
11889
|
+
const files = [];
|
|
11890
|
+
await this.generateClaudeMd(contextPath, git, stats, commands, agents);
|
|
11891
|
+
files.push("context/CLAUDE.md");
|
|
11892
|
+
await this.generateNowMd(contextPath);
|
|
11893
|
+
files.push("context/now.md");
|
|
11894
|
+
await this.generateNextMd(contextPath);
|
|
11895
|
+
files.push("context/next.md");
|
|
11896
|
+
await this.generateIdeasMd(contextPath);
|
|
11897
|
+
files.push("context/ideas.md");
|
|
11898
|
+
await this.generateShippedMd(contextPath);
|
|
11899
|
+
files.push("context/shipped.md");
|
|
11900
|
+
return files;
|
|
11901
|
+
}
|
|
11902
|
+
async generateClaudeMd(contextPath, git, stats, commands, agents) {
|
|
11903
|
+
const workflowAgents = agents.filter((a) => a.type === "workflow").map((a) => a.name);
|
|
11904
|
+
const domainAgents = agents.filter((a) => a.type === "domain").map((a) => a.name);
|
|
11905
|
+
const content = `# ${stats.name} - Project Rules
|
|
11906
|
+
<!-- projectId: ${this.projectId} -->
|
|
11907
|
+
<!-- Generated: ${date_helper_default.getTimestamp()} -->
|
|
11908
|
+
<!-- Ecosystem: ${stats.ecosystem} | Type: ${stats.projectType} -->
|
|
11909
|
+
|
|
11910
|
+
## THIS PROJECT (${stats.ecosystem})
|
|
11911
|
+
|
|
11912
|
+
**Type:** ${stats.projectType}
|
|
11913
|
+
**Path:** ${this.projectPath}
|
|
11914
|
+
|
|
11915
|
+
### Commands (USE THESE, NOT OTHERS)
|
|
11916
|
+
|
|
11917
|
+
| Action | Command |
|
|
11918
|
+
|--------|---------|
|
|
11919
|
+
| Install dependencies | \`${commands.install}\` |
|
|
11920
|
+
| Run dev server | \`${commands.dev}\` |
|
|
11921
|
+
| Run tests | \`${commands.test}\` |
|
|
11922
|
+
| Build | \`${commands.build}\` |
|
|
11923
|
+
| Lint | \`${commands.lint}\` |
|
|
11924
|
+
| Format | \`${commands.format}\` |
|
|
11925
|
+
|
|
11926
|
+
### Code Conventions
|
|
11927
|
+
|
|
11928
|
+
- **Languages**: ${stats.languages.join(", ") || "Not detected"}
|
|
11929
|
+
- **Frameworks**: ${stats.frameworks.join(", ") || "Not detected"}
|
|
11930
|
+
|
|
11931
|
+
---
|
|
11932
|
+
|
|
11933
|
+
## PRJCT RULES
|
|
11934
|
+
|
|
11935
|
+
### Path Resolution
|
|
11936
|
+
**ALL prjct writes go to**: \`~/.prjct-cli/projects/${this.projectId}/\`
|
|
11937
|
+
- NEVER write to \`.prjct/\`
|
|
11938
|
+
- NEVER write to \`./\` for prjct data
|
|
11939
|
+
|
|
11940
|
+
### Workflow
|
|
11941
|
+
\`\`\`
|
|
11942
|
+
p. sync \u2192 p. task "desc" \u2192 [work] \u2192 p. done \u2192 p. ship
|
|
11943
|
+
\`\`\`
|
|
11944
|
+
|
|
11945
|
+
| Command | Action |
|
|
11946
|
+
|---------|--------|
|
|
11947
|
+
| \`p. sync\` | Re-analyze project |
|
|
11948
|
+
| \`p. task X\` | Start task |
|
|
11949
|
+
| \`p. done\` | Complete subtask |
|
|
11950
|
+
| \`p. ship X\` | Ship feature |
|
|
11951
|
+
|
|
11952
|
+
---
|
|
11953
|
+
|
|
11954
|
+
## PROJECT STATE
|
|
11955
|
+
|
|
11956
|
+
| Field | Value |
|
|
11957
|
+
|-------|-------|
|
|
11958
|
+
| Name | ${stats.name} |
|
|
11959
|
+
| Version | ${stats.version} |
|
|
11960
|
+
| Ecosystem | ${stats.ecosystem} |
|
|
11961
|
+
| Branch | ${git.branch} |
|
|
11962
|
+
| Files | ~${stats.fileCount} |
|
|
11963
|
+
| Commits | ${git.commits} |
|
|
11964
|
+
|
|
11965
|
+
---
|
|
11966
|
+
|
|
11967
|
+
## AGENTS
|
|
11968
|
+
|
|
11969
|
+
Load from \`~/.prjct-cli/projects/${this.projectId}/agents/\`:
|
|
11970
|
+
|
|
11971
|
+
**Workflow**: ${workflowAgents.join(", ")}
|
|
11972
|
+
**Domain**: ${domainAgents.join(", ") || "none"}
|
|
11973
|
+
`;
|
|
11974
|
+
await fs27.writeFile(path28.join(contextPath, "CLAUDE.md"), content, "utf-8");
|
|
11975
|
+
}
|
|
11976
|
+
async generateNowMd(contextPath) {
|
|
11977
|
+
let currentTask = null;
|
|
11978
|
+
try {
|
|
11979
|
+
const statePath = path28.join(this.globalPath, "storage", "state.json");
|
|
11980
|
+
const state = JSON.parse(await fs27.readFile(statePath, "utf-8"));
|
|
11981
|
+
currentTask = state.currentTask;
|
|
11982
|
+
} catch {
|
|
11983
|
+
}
|
|
11984
|
+
const content = currentTask ? `# NOW
|
|
11985
|
+
|
|
11986
|
+
**${currentTask.description}**
|
|
11987
|
+
|
|
11988
|
+
Started: ${currentTask.startedAt}
|
|
11989
|
+
${currentTask.branch ? `Branch: ${currentTask.branch.name}` : ""}
|
|
11990
|
+
` : `# NOW
|
|
11991
|
+
|
|
11992
|
+
_No active task_
|
|
11993
|
+
|
|
11994
|
+
Use \`p. task "description"\` to start working.
|
|
11995
|
+
`;
|
|
11996
|
+
await fs27.writeFile(path28.join(contextPath, "now.md"), content, "utf-8");
|
|
11997
|
+
}
|
|
11998
|
+
async generateNextMd(contextPath) {
|
|
11999
|
+
let queue = { tasks: [] };
|
|
12000
|
+
try {
|
|
12001
|
+
const queuePath = path28.join(this.globalPath, "storage", "queue.json");
|
|
12002
|
+
queue = JSON.parse(await fs27.readFile(queuePath, "utf-8"));
|
|
12003
|
+
} catch {
|
|
12004
|
+
}
|
|
12005
|
+
const content = `# NEXT
|
|
12006
|
+
|
|
12007
|
+
${queue.tasks.length > 0 ? queue.tasks.map((t, i) => `${i + 1}. ${t.description}${t.priority ? ` [${t.priority}]` : ""}`).join("\n") : "_Empty queue_"}
|
|
12008
|
+
`;
|
|
12009
|
+
await fs27.writeFile(path28.join(contextPath, "next.md"), content, "utf-8");
|
|
12010
|
+
}
|
|
12011
|
+
async generateIdeasMd(contextPath) {
|
|
12012
|
+
let ideas = { ideas: [] };
|
|
12013
|
+
try {
|
|
12014
|
+
const ideasPath = path28.join(this.globalPath, "storage", "ideas.json");
|
|
12015
|
+
ideas = JSON.parse(await fs27.readFile(ideasPath, "utf-8"));
|
|
12016
|
+
} catch {
|
|
12017
|
+
}
|
|
12018
|
+
const content = `# IDEAS
|
|
12019
|
+
|
|
12020
|
+
${ideas.ideas.length > 0 ? ideas.ideas.map((i) => `- ${i.text}${i.priority ? ` [${i.priority}]` : ""}`).join("\n") : "_No ideas captured yet_"}
|
|
12021
|
+
`;
|
|
12022
|
+
await fs27.writeFile(path28.join(contextPath, "ideas.md"), content, "utf-8");
|
|
12023
|
+
}
|
|
12024
|
+
async generateShippedMd(contextPath) {
|
|
12025
|
+
let shipped = {
|
|
12026
|
+
shipped: []
|
|
12027
|
+
};
|
|
12028
|
+
try {
|
|
12029
|
+
const shippedPath = path28.join(this.globalPath, "storage", "shipped.json");
|
|
12030
|
+
shipped = JSON.parse(await fs27.readFile(shippedPath, "utf-8"));
|
|
12031
|
+
} catch {
|
|
12032
|
+
}
|
|
12033
|
+
const content = `# SHIPPED \u{1F680}
|
|
12034
|
+
|
|
12035
|
+
${shipped.shipped.length > 0 ? shipped.shipped.slice(-10).map((s) => `- **${s.name}**${s.version ? ` v${s.version}` : ""} - ${s.shippedAt}`).join("\n") : "_Nothing shipped yet_"}
|
|
12036
|
+
|
|
12037
|
+
**Total shipped:** ${shipped.shipped.length}
|
|
12038
|
+
`;
|
|
12039
|
+
await fs27.writeFile(path28.join(contextPath, "shipped.md"), content, "utf-8");
|
|
12040
|
+
}
|
|
12041
|
+
// ==========================================================================
|
|
12042
|
+
// PROJECT.JSON UPDATE
|
|
12043
|
+
// ==========================================================================
|
|
12044
|
+
async updateProjectJson(git, stats) {
|
|
12045
|
+
const projectJsonPath = path28.join(this.globalPath, "project.json");
|
|
12046
|
+
let existing = {};
|
|
12047
|
+
try {
|
|
12048
|
+
existing = JSON.parse(await fs27.readFile(projectJsonPath, "utf-8"));
|
|
12049
|
+
} catch {
|
|
12050
|
+
}
|
|
12051
|
+
const updated = {
|
|
12052
|
+
...existing,
|
|
12053
|
+
projectId: this.projectId,
|
|
12054
|
+
repoPath: this.projectPath,
|
|
12055
|
+
name: stats.name,
|
|
12056
|
+
version: stats.version,
|
|
12057
|
+
cliVersion: this.cliVersion,
|
|
12058
|
+
techStack: stats.frameworks,
|
|
12059
|
+
fileCount: stats.fileCount,
|
|
12060
|
+
commitCount: git.commits,
|
|
12061
|
+
stack: stats.ecosystem,
|
|
12062
|
+
currentBranch: git.branch,
|
|
12063
|
+
hasUncommittedChanges: git.hasChanges,
|
|
12064
|
+
createdAt: existing.createdAt || date_helper_default.getTimestamp(),
|
|
12065
|
+
lastSync: date_helper_default.getTimestamp()
|
|
12066
|
+
};
|
|
12067
|
+
await fs27.writeFile(projectJsonPath, JSON.stringify(updated, null, 2), "utf-8");
|
|
12068
|
+
}
|
|
12069
|
+
// ==========================================================================
|
|
12070
|
+
// STATE.JSON UPDATE
|
|
12071
|
+
// ==========================================================================
|
|
12072
|
+
async updateStateJson(stats, stack) {
|
|
12073
|
+
const statePath = path28.join(this.globalPath, "storage", "state.json");
|
|
12074
|
+
let state = {};
|
|
12075
|
+
try {
|
|
12076
|
+
state = JSON.parse(await fs27.readFile(statePath, "utf-8"));
|
|
12077
|
+
} catch {
|
|
12078
|
+
}
|
|
12079
|
+
state.projectId = this.projectId;
|
|
12080
|
+
state.stack = {
|
|
12081
|
+
language: stats.languages[0] || "Unknown",
|
|
12082
|
+
framework: stats.frameworks[0] || null
|
|
12083
|
+
};
|
|
12084
|
+
state.domains = {
|
|
12085
|
+
hasFrontend: stack.hasFrontend,
|
|
12086
|
+
hasBackend: stack.hasBackend,
|
|
12087
|
+
hasDatabase: stack.hasDatabase,
|
|
12088
|
+
hasTesting: stack.hasTesting,
|
|
12089
|
+
hasDocker: stack.hasDocker
|
|
12090
|
+
};
|
|
12091
|
+
state.projectType = stats.projectType;
|
|
12092
|
+
state.metrics = {
|
|
12093
|
+
totalFiles: stats.fileCount
|
|
12094
|
+
};
|
|
12095
|
+
state.lastSync = date_helper_default.getTimestamp();
|
|
12096
|
+
state.lastUpdated = date_helper_default.getTimestamp();
|
|
12097
|
+
state.context = {
|
|
12098
|
+
...state.context || {},
|
|
12099
|
+
lastSession: date_helper_default.getTimestamp(),
|
|
12100
|
+
lastAction: "Synced project",
|
|
12101
|
+
nextAction: 'Run `p. task "description"` to start working'
|
|
12102
|
+
};
|
|
12103
|
+
await fs27.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
|
|
12104
|
+
}
|
|
12105
|
+
// ==========================================================================
|
|
12106
|
+
// MEMORY LOGGING
|
|
12107
|
+
// ==========================================================================
|
|
12108
|
+
async logToMemory(git, stats) {
|
|
12109
|
+
const memoryPath = path28.join(this.globalPath, "memory", "events.jsonl");
|
|
12110
|
+
const event = {
|
|
12111
|
+
ts: date_helper_default.getTimestamp(),
|
|
12112
|
+
action: "sync",
|
|
12113
|
+
branch: git.branch,
|
|
12114
|
+
uncommitted: git.hasChanges,
|
|
12115
|
+
fileCount: stats.fileCount,
|
|
12116
|
+
commitCount: git.commits
|
|
12117
|
+
};
|
|
12118
|
+
await fs27.appendFile(memoryPath, JSON.stringify(event) + "\n", "utf-8");
|
|
12119
|
+
}
|
|
12120
|
+
// ==========================================================================
|
|
12121
|
+
// HELPERS
|
|
12122
|
+
// ==========================================================================
|
|
12123
|
+
async fileExists(filename) {
|
|
12124
|
+
try {
|
|
12125
|
+
await fs27.access(path28.join(this.projectPath, filename));
|
|
12126
|
+
return true;
|
|
12127
|
+
} catch {
|
|
12128
|
+
return false;
|
|
12129
|
+
}
|
|
12130
|
+
}
|
|
12131
|
+
async getCliVersion() {
|
|
12132
|
+
try {
|
|
12133
|
+
const pkgPath = path28.join(__dirname, "..", "..", "package.json");
|
|
12134
|
+
const pkg = JSON.parse(await fs27.readFile(pkgPath, "utf-8"));
|
|
12135
|
+
return pkg.version || "0.0.0";
|
|
12136
|
+
} catch {
|
|
12137
|
+
return "0.0.0";
|
|
12138
|
+
}
|
|
12139
|
+
}
|
|
12140
|
+
// Empty data structures for error cases
|
|
12141
|
+
emptyGitData() {
|
|
12142
|
+
return {
|
|
12143
|
+
branch: "main",
|
|
12144
|
+
commits: 0,
|
|
12145
|
+
contributors: 0,
|
|
12146
|
+
hasChanges: false,
|
|
12147
|
+
stagedFiles: [],
|
|
12148
|
+
modifiedFiles: [],
|
|
12149
|
+
untrackedFiles: [],
|
|
12150
|
+
recentCommits: [],
|
|
12151
|
+
weeklyCommits: 0
|
|
12152
|
+
};
|
|
12153
|
+
}
|
|
12154
|
+
emptyStats() {
|
|
12155
|
+
return {
|
|
12156
|
+
fileCount: 0,
|
|
12157
|
+
version: "0.0.0",
|
|
12158
|
+
name: "unknown",
|
|
12159
|
+
ecosystem: "unknown",
|
|
12160
|
+
projectType: "simple",
|
|
12161
|
+
languages: [],
|
|
12162
|
+
frameworks: []
|
|
12163
|
+
};
|
|
12164
|
+
}
|
|
12165
|
+
emptyCommands() {
|
|
12166
|
+
return {
|
|
12167
|
+
install: "npm install",
|
|
12168
|
+
run: "npm run",
|
|
12169
|
+
test: "npm test",
|
|
12170
|
+
build: "npm run build",
|
|
12171
|
+
dev: "npm run dev",
|
|
12172
|
+
lint: "npm run lint",
|
|
12173
|
+
format: "npm run format"
|
|
12174
|
+
};
|
|
12175
|
+
}
|
|
12176
|
+
emptyStack() {
|
|
12177
|
+
return {
|
|
12178
|
+
hasFrontend: false,
|
|
12179
|
+
hasBackend: false,
|
|
12180
|
+
hasDatabase: false,
|
|
12181
|
+
hasDocker: false,
|
|
12182
|
+
hasTesting: false,
|
|
12183
|
+
frontendType: null,
|
|
12184
|
+
frameworks: []
|
|
12185
|
+
};
|
|
12186
|
+
}
|
|
12187
|
+
};
|
|
12188
|
+
syncService = new SyncService();
|
|
12189
|
+
}
|
|
12190
|
+
});
|
|
12191
|
+
|
|
11379
12192
|
// core/services/index.ts
|
|
11380
12193
|
var init_services = __esm({
|
|
11381
12194
|
"core/services/index.ts"() {
|
|
@@ -11384,6 +12197,7 @@ var init_services = __esm({
|
|
|
11384
12197
|
init_project_service();
|
|
11385
12198
|
init_memory_service();
|
|
11386
12199
|
init_breakdown_service();
|
|
12200
|
+
init_sync_service();
|
|
11387
12201
|
}
|
|
11388
12202
|
});
|
|
11389
12203
|
|
|
@@ -11455,8 +12269,8 @@ var init_base = __esm({
|
|
|
11455
12269
|
_detectBugSeverity(description) {
|
|
11456
12270
|
return breakdownService.detectBugSeverity(description);
|
|
11457
12271
|
}
|
|
11458
|
-
async _assignAgentForTask(task, projectPath,
|
|
11459
|
-
return agentService.assignForTask(task, projectPath,
|
|
12272
|
+
async _assignAgentForTask(task, projectPath, context2) {
|
|
12273
|
+
return agentService.assignForTask(task, projectPath, context2);
|
|
11460
12274
|
}
|
|
11461
12275
|
};
|
|
11462
12276
|
}
|
|
@@ -11670,18 +12484,18 @@ var init_workflow = __esm({
|
|
|
11670
12484
|
});
|
|
11671
12485
|
|
|
11672
12486
|
// core/utils/project-commands.ts
|
|
11673
|
-
import
|
|
12487
|
+
import path29 from "path";
|
|
11674
12488
|
async function detectPackageManager(projectPath, pkg) {
|
|
11675
12489
|
const declared = pkg?.packageManager?.trim().toLowerCase();
|
|
11676
12490
|
if (declared?.startsWith("pnpm@")) return "pnpm";
|
|
11677
12491
|
if (declared?.startsWith("yarn@")) return "yarn";
|
|
11678
12492
|
if (declared?.startsWith("bun@")) return "bun";
|
|
11679
12493
|
if (declared?.startsWith("npm@")) return "npm";
|
|
11680
|
-
if (await fileExists(
|
|
11681
|
-
if (await fileExists(
|
|
11682
|
-
if (await fileExists(
|
|
11683
|
-
if (await fileExists(
|
|
11684
|
-
if (await fileExists(
|
|
12494
|
+
if (await fileExists(path29.join(projectPath, "pnpm-lock.yaml"))) return "pnpm";
|
|
12495
|
+
if (await fileExists(path29.join(projectPath, "yarn.lock"))) return "yarn";
|
|
12496
|
+
if (await fileExists(path29.join(projectPath, "bun.lockb"))) return "bun";
|
|
12497
|
+
if (await fileExists(path29.join(projectPath, "bun.lock"))) return "bun";
|
|
12498
|
+
if (await fileExists(path29.join(projectPath, "package-lock.json"))) return "npm";
|
|
11685
12499
|
return "npm";
|
|
11686
12500
|
}
|
|
11687
12501
|
function pmRun(pm, scriptName) {
|
|
@@ -11697,7 +12511,7 @@ function pmTest(pm) {
|
|
|
11697
12511
|
return "npm test";
|
|
11698
12512
|
}
|
|
11699
12513
|
async function detectProjectCommands(projectPath) {
|
|
11700
|
-
const pkgPath =
|
|
12514
|
+
const pkgPath = path29.join(projectPath, "package.json");
|
|
11701
12515
|
const pkg = await readJson(pkgPath, null);
|
|
11702
12516
|
if (pkg) {
|
|
11703
12517
|
const pm = await detectPackageManager(projectPath, pkg);
|
|
@@ -11714,27 +12528,27 @@ async function detectProjectCommands(projectPath) {
|
|
|
11714
12528
|
}
|
|
11715
12529
|
return result;
|
|
11716
12530
|
}
|
|
11717
|
-
if (await fileExists(
|
|
12531
|
+
if (await fileExists(path29.join(projectPath, "pytest.ini"))) {
|
|
11718
12532
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
11719
12533
|
}
|
|
11720
|
-
const pyproject = await readFile(
|
|
12534
|
+
const pyproject = await readFile(path29.join(projectPath, "pyproject.toml"), "");
|
|
11721
12535
|
if (pyproject.includes("[tool.pytest") || pyproject.includes("pytest")) {
|
|
11722
12536
|
return { stack: "python", test: { tool: "pytest", command: "pytest" } };
|
|
11723
12537
|
}
|
|
11724
|
-
if (await fileExists(
|
|
12538
|
+
if (await fileExists(path29.join(projectPath, "Cargo.toml"))) {
|
|
11725
12539
|
return { stack: "rust", test: { tool: "cargo", command: "cargo test" } };
|
|
11726
12540
|
}
|
|
11727
|
-
if (await fileExists(
|
|
12541
|
+
if (await fileExists(path29.join(projectPath, "go.mod"))) {
|
|
11728
12542
|
return { stack: "go", test: { tool: "go", command: "go test ./..." } };
|
|
11729
12543
|
}
|
|
11730
12544
|
const files = await listFiles(projectPath);
|
|
11731
12545
|
if (files.some((f) => f.endsWith(".sln") || f.endsWith(".csproj") || f.endsWith(".fsproj"))) {
|
|
11732
12546
|
return { stack: "dotnet", test: { tool: "dotnet", command: "dotnet test" } };
|
|
11733
12547
|
}
|
|
11734
|
-
if (await fileExists(
|
|
12548
|
+
if (await fileExists(path29.join(projectPath, "pom.xml"))) {
|
|
11735
12549
|
return { stack: "java", test: { tool: "maven", command: "mvn test" } };
|
|
11736
12550
|
}
|
|
11737
|
-
if (await fileExists(
|
|
12551
|
+
if (await fileExists(path29.join(projectPath, "gradlew")) && (await fileExists(path29.join(projectPath, "build.gradle")) || await fileExists(path29.join(projectPath, "build.gradle.kts")))) {
|
|
11738
12552
|
return { stack: "java", test: { tool: "gradle", command: "./gradlew test" } };
|
|
11739
12553
|
}
|
|
11740
12554
|
return { stack: "unknown" };
|
|
@@ -11751,7 +12565,7 @@ var init_project_commands = __esm({
|
|
|
11751
12565
|
});
|
|
11752
12566
|
|
|
11753
12567
|
// core/commands/shipping.ts
|
|
11754
|
-
import
|
|
12568
|
+
import path30 from "path";
|
|
11755
12569
|
var ShippingCommands;
|
|
11756
12570
|
var init_shipping = __esm({
|
|
11757
12571
|
"core/commands/shipping.ts"() {
|
|
@@ -11880,7 +12694,7 @@ ${result.stderr}`.trim();
|
|
|
11880
12694
|
*/
|
|
11881
12695
|
async _bumpVersion(projectPath) {
|
|
11882
12696
|
try {
|
|
11883
|
-
const pkgPath =
|
|
12697
|
+
const pkgPath = path30.join(projectPath, "package.json");
|
|
11884
12698
|
const pkg = await file_helper_exports.readJson(pkgPath, { version: "0.0.0" });
|
|
11885
12699
|
const oldVersion = pkg?.version || "0.0.0";
|
|
11886
12700
|
const [major, minor, patch] = oldVersion.split(".").map(Number);
|
|
@@ -11902,7 +12716,7 @@ ${result.stderr}`.trim();
|
|
|
11902
12716
|
*/
|
|
11903
12717
|
async _updateChangelog(feature, version, projectPath) {
|
|
11904
12718
|
try {
|
|
11905
|
-
const changelogPath =
|
|
12719
|
+
const changelogPath = path30.join(projectPath, "CHANGELOG.md");
|
|
11906
12720
|
const changelog = await file_helper_exports.readFile(changelogPath, "# Changelog\n\n");
|
|
11907
12721
|
const entry = `## [${version}] - ${date_helper_default.formatDate(/* @__PURE__ */ new Date())}
|
|
11908
12722
|
|
|
@@ -12026,11 +12840,11 @@ var init_registry = __esm({
|
|
|
12026
12840
|
if (typeof method !== "function") {
|
|
12027
12841
|
throw new Error(`${String(methodName)} is not a function`);
|
|
12028
12842
|
}
|
|
12029
|
-
const wrapper = /* @__PURE__ */ __name(async (params,
|
|
12843
|
+
const wrapper = /* @__PURE__ */ __name(async (params, context2) => {
|
|
12030
12844
|
if (params !== void 0 && params !== null) {
|
|
12031
|
-
return method.call(instance2, params,
|
|
12845
|
+
return method.call(instance2, params, context2.projectPath);
|
|
12032
12846
|
}
|
|
12033
|
-
return method.call(instance2,
|
|
12847
|
+
return method.call(instance2, context2.projectPath);
|
|
12034
12848
|
}, "wrapper");
|
|
12035
12849
|
this.handlerFns.set(name, wrapper);
|
|
12036
12850
|
this.setMeta(name, meta);
|
|
@@ -12222,9 +13036,9 @@ var init_registry = __esm({
|
|
|
12222
13036
|
*/
|
|
12223
13037
|
async execute(name, params, projectPath = process.cwd()) {
|
|
12224
13038
|
const meta = this.metadata.get(name);
|
|
12225
|
-
let
|
|
13039
|
+
let context2;
|
|
12226
13040
|
if (meta?.requiresProject === false) {
|
|
12227
|
-
|
|
13041
|
+
context2 = {
|
|
12228
13042
|
projectId: "",
|
|
12229
13043
|
projectPath,
|
|
12230
13044
|
globalPath: "",
|
|
@@ -12232,7 +13046,7 @@ var init_registry = __esm({
|
|
|
12232
13046
|
};
|
|
12233
13047
|
} else {
|
|
12234
13048
|
try {
|
|
12235
|
-
|
|
13049
|
+
context2 = await this.buildContext(projectPath);
|
|
12236
13050
|
} catch (error) {
|
|
12237
13051
|
return {
|
|
12238
13052
|
success: false,
|
|
@@ -12242,11 +13056,11 @@ var init_registry = __esm({
|
|
|
12242
13056
|
}
|
|
12243
13057
|
const handler = this.handlers.get(name);
|
|
12244
13058
|
if (handler) {
|
|
12245
|
-
return handler.execute(params,
|
|
13059
|
+
return handler.execute(params, context2);
|
|
12246
13060
|
}
|
|
12247
13061
|
const handlerFn = this.handlerFns.get(name);
|
|
12248
13062
|
if (handlerFn) {
|
|
12249
|
-
return handlerFn(params,
|
|
13063
|
+
return handlerFn(params, context2);
|
|
12250
13064
|
}
|
|
12251
13065
|
return {
|
|
12252
13066
|
success: false,
|
|
@@ -12260,23 +13074,23 @@ var init_registry = __esm({
|
|
|
12260
13074
|
async executeWithoutProject(name, params, projectPath = process.cwd()) {
|
|
12261
13075
|
const handler = this.handlers.get(name);
|
|
12262
13076
|
if (handler) {
|
|
12263
|
-
const
|
|
13077
|
+
const context2 = {
|
|
12264
13078
|
projectId: "",
|
|
12265
13079
|
projectPath,
|
|
12266
13080
|
globalPath: "",
|
|
12267
13081
|
timestamp: getTimestamp()
|
|
12268
13082
|
};
|
|
12269
|
-
return handler.execute(params,
|
|
13083
|
+
return handler.execute(params, context2);
|
|
12270
13084
|
}
|
|
12271
13085
|
const handlerFn = this.handlerFns.get(name);
|
|
12272
13086
|
if (handlerFn) {
|
|
12273
|
-
const
|
|
13087
|
+
const context2 = {
|
|
12274
13088
|
projectId: "",
|
|
12275
13089
|
projectPath,
|
|
12276
13090
|
globalPath: "",
|
|
12277
13091
|
timestamp: getTimestamp()
|
|
12278
13092
|
};
|
|
12279
|
-
return handlerFn(params,
|
|
13093
|
+
return handlerFn(params, context2);
|
|
12280
13094
|
}
|
|
12281
13095
|
return {
|
|
12282
13096
|
success: false,
|
|
@@ -12298,7 +13112,7 @@ var init_registry = __esm({
|
|
|
12298
13112
|
});
|
|
12299
13113
|
|
|
12300
13114
|
// core/commands/analytics.ts
|
|
12301
|
-
import
|
|
13115
|
+
import path31 from "path";
|
|
12302
13116
|
var AnalyticsCommands;
|
|
12303
13117
|
var init_analytics = __esm({
|
|
12304
13118
|
"core/commands/analytics.ts"() {
|
|
@@ -12323,7 +13137,7 @@ var init_analytics = __esm({
|
|
|
12323
13137
|
output_default.fail("no project ID");
|
|
12324
13138
|
return { success: false, error: "No project ID found" };
|
|
12325
13139
|
}
|
|
12326
|
-
const projectName =
|
|
13140
|
+
const projectName = path31.basename(projectPath);
|
|
12327
13141
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
12328
13142
|
const queueTasks = await queueStorage.getActiveTasks(projectId);
|
|
12329
13143
|
const shipped = await shippedStorage.getRecent(projectId, 5);
|
|
@@ -12366,8 +13180,8 @@ var init_analytics = __esm({
|
|
|
12366
13180
|
return { success: true, view, metrics };
|
|
12367
13181
|
}
|
|
12368
13182
|
if (view === "roadmap") {
|
|
12369
|
-
const
|
|
12370
|
-
const roadmapContent = await tool_registry_default.get("Read")(
|
|
13183
|
+
const context2 = await context_builder_default.build(projectPath);
|
|
13184
|
+
const roadmapContent = await tool_registry_default.get("Read")(context2.paths.roadmap);
|
|
12371
13185
|
console.log(`
|
|
12372
13186
|
\u{1F5FA}\uFE0F ROADMAP - ${projectName}
|
|
12373
13187
|
`);
|
|
@@ -12561,7 +13375,7 @@ ${catInfo?.title || cat}:`);
|
|
|
12561
13375
|
});
|
|
12562
13376
|
|
|
12563
13377
|
// core/commands/cleanup.ts
|
|
12564
|
-
import
|
|
13378
|
+
import path32 from "path";
|
|
12565
13379
|
async function cleanupMemory(projectPath) {
|
|
12566
13380
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
12567
13381
|
const results = { rotated: [], totalSize: 0, freedSpace: 0 };
|
|
@@ -12577,7 +13391,7 @@ async function cleanupMemory(projectPath) {
|
|
|
12577
13391
|
results.totalSize += sizeMB;
|
|
12578
13392
|
const rotated = await jsonl_helper_default.rotateJsonLinesIfNeeded(filePath, 10);
|
|
12579
13393
|
if (rotated) {
|
|
12580
|
-
results.rotated.push(
|
|
13394
|
+
results.rotated.push(path32.basename(filePath));
|
|
12581
13395
|
results.freedSpace += sizeMB;
|
|
12582
13396
|
}
|
|
12583
13397
|
}
|
|
@@ -12684,7 +13498,7 @@ var init_cleanup = __esm({
|
|
|
12684
13498
|
});
|
|
12685
13499
|
|
|
12686
13500
|
// core/commands/design.ts
|
|
12687
|
-
import
|
|
13501
|
+
import path33 from "path";
|
|
12688
13502
|
async function design(target = null, options = {}, projectPath = process.cwd()) {
|
|
12689
13503
|
try {
|
|
12690
13504
|
const designType = options.type || "architecture";
|
|
@@ -12696,7 +13510,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
12696
13510
|
const designTarget = target || "system";
|
|
12697
13511
|
output_default.spin(`designing ${designType}...`);
|
|
12698
13512
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
12699
|
-
const designsPath =
|
|
13513
|
+
const designsPath = path33.join(
|
|
12700
13514
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12701
13515
|
"planning",
|
|
12702
13516
|
"designs"
|
|
@@ -12736,7 +13550,7 @@ async function design(target = null, options = {}, projectPath = process.cwd())
|
|
|
12736
13550
|
break;
|
|
12737
13551
|
}
|
|
12738
13552
|
const designFileName = `${designType}-${designTarget.toLowerCase().replace(/\s+/g, "-")}.md`;
|
|
12739
|
-
const designFilePath =
|
|
13553
|
+
const designFilePath = path33.join(designsPath, designFileName);
|
|
12740
13554
|
await file_helper_exports.writeFile(designFilePath, designContent);
|
|
12741
13555
|
await memoryService.log(projectPath, "design_created", {
|
|
12742
13556
|
type: designType,
|
|
@@ -12760,7 +13574,7 @@ var init_design = __esm({
|
|
|
12760
13574
|
});
|
|
12761
13575
|
|
|
12762
13576
|
// core/commands/snapshots.ts
|
|
12763
|
-
import
|
|
13577
|
+
import path34 from "path";
|
|
12764
13578
|
async function recover(projectPath = process.cwd()) {
|
|
12765
13579
|
try {
|
|
12766
13580
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
@@ -12812,7 +13626,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
12812
13626
|
output_default.fail("no project ID");
|
|
12813
13627
|
return { success: false, error: "No project ID found" };
|
|
12814
13628
|
}
|
|
12815
|
-
const snapshotsPath =
|
|
13629
|
+
const snapshotsPath = path34.join(
|
|
12816
13630
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12817
13631
|
"snapshots"
|
|
12818
13632
|
);
|
|
@@ -12833,7 +13647,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
12833
13647
|
cwd: projectPath,
|
|
12834
13648
|
encoding: "utf-8"
|
|
12835
13649
|
});
|
|
12836
|
-
const snapshotFile =
|
|
13650
|
+
const snapshotFile = path34.join(snapshotsPath, "history.json");
|
|
12837
13651
|
let history2 = { snapshots: [], current: -1 };
|
|
12838
13652
|
try {
|
|
12839
13653
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -12873,11 +13687,11 @@ async function redo(projectPath = process.cwd()) {
|
|
|
12873
13687
|
output_default.fail("no project ID");
|
|
12874
13688
|
return { success: false, error: "No project ID found" };
|
|
12875
13689
|
}
|
|
12876
|
-
const snapshotsPath =
|
|
13690
|
+
const snapshotsPath = path34.join(
|
|
12877
13691
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12878
13692
|
"snapshots"
|
|
12879
13693
|
);
|
|
12880
|
-
const snapshotFile =
|
|
13694
|
+
const snapshotFile = path34.join(snapshotsPath, "history.json");
|
|
12881
13695
|
let history2;
|
|
12882
13696
|
try {
|
|
12883
13697
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -12936,11 +13750,11 @@ async function history(projectPath = process.cwd()) {
|
|
|
12936
13750
|
output_default.fail("no project ID");
|
|
12937
13751
|
return { success: false, error: "No project ID found" };
|
|
12938
13752
|
}
|
|
12939
|
-
const snapshotsPath =
|
|
13753
|
+
const snapshotsPath = path34.join(
|
|
12940
13754
|
path_manager_default.getGlobalProjectPath(projectId),
|
|
12941
13755
|
"snapshots"
|
|
12942
13756
|
);
|
|
12943
|
-
const snapshotFile =
|
|
13757
|
+
const snapshotFile = path34.join(snapshotsPath, "history.json");
|
|
12944
13758
|
let snapshotHistory;
|
|
12945
13759
|
try {
|
|
12946
13760
|
const content = await file_helper_exports.readFile(snapshotFile);
|
|
@@ -13046,8 +13860,8 @@ var init_maintenance = __esm({
|
|
|
13046
13860
|
});
|
|
13047
13861
|
|
|
13048
13862
|
// core/commands/setup.ts
|
|
13049
|
-
import
|
|
13050
|
-
import
|
|
13863
|
+
import path35 from "path";
|
|
13864
|
+
import fs28 from "fs";
|
|
13051
13865
|
import chalk4 from "chalk";
|
|
13052
13866
|
var SetupCommands;
|
|
13053
13867
|
var init_setup2 = __esm({
|
|
@@ -13157,7 +13971,7 @@ var init_setup2 = __esm({
|
|
|
13157
13971
|
try {
|
|
13158
13972
|
const claudeDir = path_manager_default.getClaudeDir();
|
|
13159
13973
|
const settingsPath = path_manager_default.getClaudeSettingsPath();
|
|
13160
|
-
const statusLinePath =
|
|
13974
|
+
const statusLinePath = path35.join(claudeDir, "prjct-statusline.sh");
|
|
13161
13975
|
const scriptContent = `#!/bin/bash
|
|
13162
13976
|
# prjct Status Line for Claude Code
|
|
13163
13977
|
# Shows version update notifications and current task
|
|
@@ -13215,11 +14029,11 @@ fi
|
|
|
13215
14029
|
# Default: show prjct branding
|
|
13216
14030
|
echo "\u26A1 prjct"
|
|
13217
14031
|
`;
|
|
13218
|
-
|
|
14032
|
+
fs28.writeFileSync(statusLinePath, scriptContent, { mode: 493 });
|
|
13219
14033
|
let settings = {};
|
|
13220
|
-
if (
|
|
14034
|
+
if (fs28.existsSync(settingsPath)) {
|
|
13221
14035
|
try {
|
|
13222
|
-
settings = JSON.parse(
|
|
14036
|
+
settings = JSON.parse(fs28.readFileSync(settingsPath, "utf8"));
|
|
13223
14037
|
} catch (_error) {
|
|
13224
14038
|
}
|
|
13225
14039
|
}
|
|
@@ -13227,7 +14041,7 @@ echo "\u26A1 prjct"
|
|
|
13227
14041
|
type: "command",
|
|
13228
14042
|
command: statusLinePath
|
|
13229
14043
|
};
|
|
13230
|
-
|
|
14044
|
+
fs28.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
13231
14045
|
return { success: true };
|
|
13232
14046
|
} catch (error) {
|
|
13233
14047
|
return { success: false, error: error.message };
|
|
@@ -13274,18 +14088,155 @@ echo "\u26A1 prjct"
|
|
|
13274
14088
|
console.log(chalk4.bold.magenta("Happy shipping! \u{1F680}"));
|
|
13275
14089
|
console.log("");
|
|
13276
14090
|
}
|
|
14091
|
+
};
|
|
14092
|
+
}
|
|
14093
|
+
});
|
|
14094
|
+
|
|
14095
|
+
// core/commands/context.ts
|
|
14096
|
+
import fs29 from "fs/promises";
|
|
14097
|
+
import path36 from "path";
|
|
14098
|
+
var ContextCommands, contextCommands;
|
|
14099
|
+
var init_context = __esm({
|
|
14100
|
+
"core/commands/context.ts"() {
|
|
14101
|
+
"use strict";
|
|
14102
|
+
init_config_manager();
|
|
14103
|
+
init_path_manager();
|
|
14104
|
+
init_storage2();
|
|
14105
|
+
init_orchestrator_executor();
|
|
14106
|
+
init_fs();
|
|
14107
|
+
ContextCommands = class {
|
|
14108
|
+
static {
|
|
14109
|
+
__name(this, "ContextCommands");
|
|
14110
|
+
}
|
|
13277
14111
|
/**
|
|
13278
|
-
*
|
|
14112
|
+
* Get full project context for Claude
|
|
14113
|
+
*
|
|
14114
|
+
* Usage:
|
|
14115
|
+
* prjct context task "add user auth"
|
|
14116
|
+
* prjct context done
|
|
14117
|
+
* prjct context ship
|
|
14118
|
+
*
|
|
14119
|
+
* Returns JSON with all orchestrator data.
|
|
13279
14120
|
*/
|
|
13280
|
-
async
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
13286
|
-
|
|
14121
|
+
async context(input = null, projectPath = process.cwd()) {
|
|
14122
|
+
try {
|
|
14123
|
+
const parts = (input || "").trim().split(/\s+/);
|
|
14124
|
+
const command = parts[0] || "task";
|
|
14125
|
+
const taskDescription = parts.slice(1).join(" ");
|
|
14126
|
+
const config = await config_manager_default.readConfig(projectPath);
|
|
14127
|
+
if (!config || !config.projectId) {
|
|
14128
|
+
const output2 = {
|
|
14129
|
+
projectId: "",
|
|
14130
|
+
globalPath: "",
|
|
14131
|
+
currentTask: null,
|
|
14132
|
+
domains: [],
|
|
14133
|
+
primaryDomain: null,
|
|
14134
|
+
agents: [],
|
|
14135
|
+
subtasks: null,
|
|
14136
|
+
repoAnalysis: {
|
|
14137
|
+
ecosystem: "unknown",
|
|
14138
|
+
frameworks: [],
|
|
14139
|
+
hasTests: false,
|
|
14140
|
+
technologies: []
|
|
14141
|
+
}
|
|
14142
|
+
};
|
|
14143
|
+
console.log(JSON.stringify(output2, null, 2));
|
|
14144
|
+
return {
|
|
14145
|
+
success: false,
|
|
14146
|
+
message: "No prjct project. Run `p. init` first."
|
|
14147
|
+
};
|
|
14148
|
+
}
|
|
14149
|
+
const projectId = config.projectId;
|
|
14150
|
+
const globalPath = path_manager_default.getGlobalProjectPath(projectId);
|
|
14151
|
+
const state = await stateStorage.read(projectId);
|
|
14152
|
+
const currentTask = state?.currentTask ? {
|
|
14153
|
+
id: state.currentTask.id,
|
|
14154
|
+
description: state.currentTask.description,
|
|
14155
|
+
type: state.currentTask.type || "task",
|
|
14156
|
+
status: state.currentTask.status || "active",
|
|
14157
|
+
branch: state.currentTask.branch,
|
|
14158
|
+
subtasks: state.currentTask.subtasks?.map((st) => ({
|
|
14159
|
+
id: st.id,
|
|
14160
|
+
description: st.description,
|
|
14161
|
+
status: st.status || "pending"
|
|
14162
|
+
})),
|
|
14163
|
+
currentSubtaskIndex: state.currentTask.currentSubtaskIndex
|
|
14164
|
+
} : null;
|
|
14165
|
+
let orchestratorContext = null;
|
|
14166
|
+
if (taskDescription) {
|
|
14167
|
+
try {
|
|
14168
|
+
orchestratorContext = await orchestrator_executor_default.execute(
|
|
14169
|
+
command,
|
|
14170
|
+
taskDescription,
|
|
14171
|
+
projectPath
|
|
14172
|
+
);
|
|
14173
|
+
} catch (error) {
|
|
14174
|
+
console.error(`Warning: Orchestrator failed: ${error.message}`);
|
|
14175
|
+
}
|
|
14176
|
+
}
|
|
14177
|
+
const repoAnalysis = await this.loadRepoAnalysis(globalPath);
|
|
14178
|
+
const output = {
|
|
14179
|
+
projectId,
|
|
14180
|
+
globalPath,
|
|
14181
|
+
currentTask,
|
|
14182
|
+
domains: orchestratorContext?.detectedDomains || [],
|
|
14183
|
+
primaryDomain: orchestratorContext?.primaryDomain || null,
|
|
14184
|
+
agents: orchestratorContext?.agents.map((a) => ({
|
|
14185
|
+
name: a.name,
|
|
14186
|
+
domain: a.domain,
|
|
14187
|
+
filePath: a.filePath,
|
|
14188
|
+
skills: a.skills,
|
|
14189
|
+
preview: a.content.substring(0, 500)
|
|
14190
|
+
})) || [],
|
|
14191
|
+
subtasks: orchestratorContext?.subtasks?.map((st) => ({
|
|
14192
|
+
id: st.id,
|
|
14193
|
+
description: st.description,
|
|
14194
|
+
domain: st.domain,
|
|
14195
|
+
agent: st.agent,
|
|
14196
|
+
status: st.status,
|
|
14197
|
+
order: st.order
|
|
14198
|
+
})) || null,
|
|
14199
|
+
repoAnalysis: {
|
|
14200
|
+
ecosystem: repoAnalysis?.ecosystem || "unknown",
|
|
14201
|
+
frameworks: repoAnalysis?.frameworks || [],
|
|
14202
|
+
hasTests: repoAnalysis?.hasTests || false,
|
|
14203
|
+
technologies: repoAnalysis?.technologies || []
|
|
14204
|
+
}
|
|
14205
|
+
};
|
|
14206
|
+
console.log(JSON.stringify(output, null, 2));
|
|
14207
|
+
return {
|
|
14208
|
+
success: true,
|
|
14209
|
+
message: ""
|
|
14210
|
+
// Empty message - JSON output is the result
|
|
14211
|
+
};
|
|
14212
|
+
} catch (error) {
|
|
14213
|
+
return {
|
|
14214
|
+
success: false,
|
|
14215
|
+
message: `Context error: ${error.message}`
|
|
14216
|
+
};
|
|
14217
|
+
}
|
|
14218
|
+
}
|
|
14219
|
+
/**
|
|
14220
|
+
* Load repo analysis from analysis/repo-analysis.json
|
|
14221
|
+
*/
|
|
14222
|
+
async loadRepoAnalysis(globalPath) {
|
|
14223
|
+
try {
|
|
14224
|
+
const analysisPath = path36.join(globalPath, "analysis", "repo-analysis.json");
|
|
14225
|
+
const content = await fs29.readFile(analysisPath, "utf-8");
|
|
14226
|
+
const data = JSON.parse(content);
|
|
14227
|
+
return {
|
|
14228
|
+
ecosystem: data.ecosystem || "unknown",
|
|
14229
|
+
frameworks: data.frameworks || [],
|
|
14230
|
+
hasTests: data.hasTests ?? false,
|
|
14231
|
+
technologies: data.technologies || []
|
|
14232
|
+
};
|
|
14233
|
+
} catch (error) {
|
|
14234
|
+
if (isNotFoundError(error)) return null;
|
|
14235
|
+
return null;
|
|
14236
|
+
}
|
|
13287
14237
|
}
|
|
13288
14238
|
};
|
|
14239
|
+
contextCommands = new ContextCommands();
|
|
13289
14240
|
}
|
|
13290
14241
|
});
|
|
13291
14242
|
|
|
@@ -13301,6 +14252,7 @@ var init_commands = __esm({
|
|
|
13301
14252
|
init_maintenance();
|
|
13302
14253
|
init_analysis2();
|
|
13303
14254
|
init_setup2();
|
|
14255
|
+
init_context();
|
|
13304
14256
|
PrjctCommands = class {
|
|
13305
14257
|
static {
|
|
13306
14258
|
__name(this, "PrjctCommands");
|
|
@@ -13313,6 +14265,7 @@ var init_commands = __esm({
|
|
|
13313
14265
|
maintenance;
|
|
13314
14266
|
analysis;
|
|
13315
14267
|
setupCmds;
|
|
14268
|
+
contextCmds;
|
|
13316
14269
|
// Shared state
|
|
13317
14270
|
agent;
|
|
13318
14271
|
agentInfo;
|
|
@@ -13326,15 +14279,13 @@ var init_commands = __esm({
|
|
|
13326
14279
|
this.maintenance = new MaintenanceCommands();
|
|
13327
14280
|
this.analysis = new AnalysisCommands();
|
|
13328
14281
|
this.setupCmds = new SetupCommands();
|
|
14282
|
+
this.contextCmds = new ContextCommands();
|
|
13329
14283
|
this.agent = null;
|
|
13330
14284
|
this.agentInfo = null;
|
|
13331
14285
|
this.currentAuthor = null;
|
|
13332
14286
|
this.prjctDir = ".prjct";
|
|
13333
14287
|
}
|
|
13334
14288
|
// ========== Workflow Commands ==========
|
|
13335
|
-
async work(task = null, projectPath = process.cwd()) {
|
|
13336
|
-
return this.workflow.now(task, projectPath);
|
|
13337
|
-
}
|
|
13338
14289
|
async done(projectPath = process.cwd()) {
|
|
13339
14290
|
return this.workflow.done(projectPath);
|
|
13340
14291
|
}
|
|
@@ -13351,9 +14302,6 @@ var init_commands = __esm({
|
|
|
13351
14302
|
async init(idea = null, projectPath = process.cwd()) {
|
|
13352
14303
|
return this.planning.init(idea, projectPath);
|
|
13353
14304
|
}
|
|
13354
|
-
async feature(description, projectPath = process.cwd()) {
|
|
13355
|
-
return this.planning.feature(description, projectPath);
|
|
13356
|
-
}
|
|
13357
14305
|
async bug(description, projectPath = process.cwd()) {
|
|
13358
14306
|
return this.planning.bug(description, projectPath);
|
|
13359
14307
|
}
|
|
@@ -13400,6 +14348,10 @@ var init_commands = __esm({
|
|
|
13400
14348
|
async sync(projectPath = process.cwd()) {
|
|
13401
14349
|
return this.analysis.sync(projectPath);
|
|
13402
14350
|
}
|
|
14351
|
+
// ========== Context Commands ==========
|
|
14352
|
+
async context(input = null, projectPath = process.cwd()) {
|
|
14353
|
+
return this.contextCmds.context(input, projectPath);
|
|
14354
|
+
}
|
|
13403
14355
|
// ========== Setup Commands ==========
|
|
13404
14356
|
async start() {
|
|
13405
14357
|
return this.setupCmds.start();
|
|
@@ -13407,9 +14359,6 @@ var init_commands = __esm({
|
|
|
13407
14359
|
async setup(options = {}) {
|
|
13408
14360
|
return this.setupCmds.setup(options);
|
|
13409
14361
|
}
|
|
13410
|
-
async migrateAll(options = {}) {
|
|
13411
|
-
return this.setupCmds.migrateAll(options);
|
|
13412
|
-
}
|
|
13413
14362
|
async installStatusLine() {
|
|
13414
14363
|
return this.setupCmds.installStatusLine();
|
|
13415
14364
|
}
|
|
@@ -13494,17 +14443,6 @@ var init_command_data = __esm({
|
|
|
13494
14443
|
requiresProject: true,
|
|
13495
14444
|
features: ["Agentic type classification", "7-phase workflow", "Git branch management", "Task breakdown"]
|
|
13496
14445
|
},
|
|
13497
|
-
{
|
|
13498
|
-
name: "feature",
|
|
13499
|
-
group: "core",
|
|
13500
|
-
description: "DEPRECATED - Use /p:task instead",
|
|
13501
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
13502
|
-
params: "<description>",
|
|
13503
|
-
implemented: true,
|
|
13504
|
-
hasTemplate: true,
|
|
13505
|
-
requiresProject: true,
|
|
13506
|
-
deprecated: true
|
|
13507
|
-
},
|
|
13508
14446
|
{
|
|
13509
14447
|
name: "spec",
|
|
13510
14448
|
group: "core",
|
|
@@ -13515,28 +14453,6 @@ var init_command_data = __esm({
|
|
|
13515
14453
|
hasTemplate: true,
|
|
13516
14454
|
requiresProject: true
|
|
13517
14455
|
},
|
|
13518
|
-
{
|
|
13519
|
-
name: "now",
|
|
13520
|
-
group: "core",
|
|
13521
|
-
description: "DEPRECATED - Use /p:task instead",
|
|
13522
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
13523
|
-
params: "[task]",
|
|
13524
|
-
implemented: true,
|
|
13525
|
-
hasTemplate: true,
|
|
13526
|
-
requiresProject: true,
|
|
13527
|
-
deprecated: true
|
|
13528
|
-
},
|
|
13529
|
-
{
|
|
13530
|
-
name: "work",
|
|
13531
|
-
group: "core",
|
|
13532
|
-
description: "DEPRECATED - Use /p:task instead",
|
|
13533
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
13534
|
-
params: "[task]",
|
|
13535
|
-
implemented: true,
|
|
13536
|
-
hasTemplate: true,
|
|
13537
|
-
requiresProject: true,
|
|
13538
|
-
deprecated: true
|
|
13539
|
-
},
|
|
13540
14456
|
{
|
|
13541
14457
|
name: "pause",
|
|
13542
14458
|
group: "core",
|
|
@@ -13758,16 +14674,6 @@ var init_command_data = __esm({
|
|
|
13758
14674
|
hasTemplate: true,
|
|
13759
14675
|
requiresProject: true
|
|
13760
14676
|
},
|
|
13761
|
-
{
|
|
13762
|
-
name: "migrate-all",
|
|
13763
|
-
group: "setup",
|
|
13764
|
-
description: "Migrate all legacy projects to UUID format",
|
|
13765
|
-
usage: { claude: "/p:migrate-all", terminal: "prjct migrate-all" },
|
|
13766
|
-
params: "[--deep-scan] [--dry-run]",
|
|
13767
|
-
implemented: true,
|
|
13768
|
-
hasTemplate: true,
|
|
13769
|
-
requiresProject: false
|
|
13770
|
-
},
|
|
13771
14677
|
{
|
|
13772
14678
|
name: "auth",
|
|
13773
14679
|
group: "setup",
|
|
@@ -13777,6 +14683,17 @@ var init_command_data = __esm({
|
|
|
13777
14683
|
implemented: true,
|
|
13778
14684
|
hasTemplate: true,
|
|
13779
14685
|
requiresProject: false
|
|
14686
|
+
},
|
|
14687
|
+
{
|
|
14688
|
+
name: "context",
|
|
14689
|
+
group: "setup",
|
|
14690
|
+
description: "Get project context as JSON for Claude templates",
|
|
14691
|
+
usage: { claude: null, terminal: "prjct context <command> [args]" },
|
|
14692
|
+
params: "<command> [args]",
|
|
14693
|
+
implemented: true,
|
|
14694
|
+
hasTemplate: false,
|
|
14695
|
+
requiresProject: true,
|
|
14696
|
+
features: ["Returns JSON with project context", "Runs orchestrator", "Loads agents and skills"]
|
|
13780
14697
|
}
|
|
13781
14698
|
];
|
|
13782
14699
|
}
|
|
@@ -13792,14 +14709,11 @@ function registerAllCommands() {
|
|
|
13792
14709
|
if (commandRegistry.has("work")) return;
|
|
13793
14710
|
registerCategories();
|
|
13794
14711
|
const getMeta = /* @__PURE__ */ __name((name) => COMMANDS.find((c) => c.name === name), "getMeta");
|
|
13795
|
-
commandRegistry.registerMethod("work", workflow, "now", getMeta("work"));
|
|
13796
|
-
commandRegistry.registerMethod("now", workflow, "now", getMeta("now"));
|
|
13797
14712
|
commandRegistry.registerMethod("done", workflow, "done", getMeta("done"));
|
|
13798
14713
|
commandRegistry.registerMethod("next", workflow, "next", getMeta("next"));
|
|
13799
14714
|
commandRegistry.registerMethod("pause", workflow, "pause", getMeta("pause"));
|
|
13800
14715
|
commandRegistry.registerMethod("resume", workflow, "resume", getMeta("resume"));
|
|
13801
14716
|
commandRegistry.registerMethod("init", planning, "init", getMeta("init"));
|
|
13802
|
-
commandRegistry.registerMethod("feature", planning, "feature", getMeta("feature"));
|
|
13803
14717
|
commandRegistry.registerMethod("bug", planning, "bug", getMeta("bug"));
|
|
13804
14718
|
commandRegistry.registerMethod("idea", planning, "idea", getMeta("idea"));
|
|
13805
14719
|
commandRegistry.registerMethod("spec", planning, "spec", getMeta("spec"));
|
|
@@ -13816,9 +14730,9 @@ function registerAllCommands() {
|
|
|
13816
14730
|
commandRegistry.registerMethod("sync", analysis, "sync", getMeta("sync"));
|
|
13817
14731
|
commandRegistry.registerMethod("start", setup, "start", getMeta("start"));
|
|
13818
14732
|
commandRegistry.registerMethod("setup", setup, "setup", getMeta("setup"));
|
|
13819
|
-
commandRegistry.registerMethod("
|
|
14733
|
+
commandRegistry.registerMethod("context", context, "context", getMeta("context"));
|
|
13820
14734
|
}
|
|
13821
|
-
var workflow, planning, shipping, analytics, maintenance, analysis, setup;
|
|
14735
|
+
var workflow, planning, shipping, analytics, maintenance, analysis, setup, context;
|
|
13822
14736
|
var init_register = __esm({
|
|
13823
14737
|
"core/commands/register.ts"() {
|
|
13824
14738
|
"use strict";
|
|
@@ -13831,6 +14745,7 @@ var init_register = __esm({
|
|
|
13831
14745
|
init_maintenance();
|
|
13832
14746
|
init_analysis2();
|
|
13833
14747
|
init_setup2();
|
|
14748
|
+
init_context();
|
|
13834
14749
|
workflow = new WorkflowCommands();
|
|
13835
14750
|
planning = new PlanningCommands();
|
|
13836
14751
|
shipping = new ShippingCommands();
|
|
@@ -13838,6 +14753,7 @@ var init_register = __esm({
|
|
|
13838
14753
|
maintenance = new MaintenanceCommands();
|
|
13839
14754
|
analysis = new AnalysisCommands();
|
|
13840
14755
|
setup = new SetupCommands();
|
|
14756
|
+
context = new ContextCommands();
|
|
13841
14757
|
__name(registerCategories, "registerCategories");
|
|
13842
14758
|
__name(registerAllCommands, "registerAllCommands");
|
|
13843
14759
|
registerAllCommands();
|
|
@@ -13860,22 +14776,18 @@ var require_package = __commonJS({
|
|
|
13860
14776
|
"package.json"(exports, module) {
|
|
13861
14777
|
module.exports = {
|
|
13862
14778
|
name: "prjct-cli",
|
|
13863
|
-
version: "0.35.
|
|
14779
|
+
version: "0.35.3",
|
|
13864
14780
|
description: "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
|
|
13865
14781
|
main: "core/index.ts",
|
|
13866
14782
|
bin: {
|
|
13867
14783
|
prjct: "bin/prjct"
|
|
13868
14784
|
},
|
|
13869
|
-
workspaces: [
|
|
13870
|
-
"packages/*"
|
|
13871
|
-
],
|
|
13872
14785
|
publishConfig: {
|
|
13873
14786
|
access: "public",
|
|
13874
14787
|
registry: "https://registry.npmjs.org"
|
|
13875
14788
|
},
|
|
13876
14789
|
scripts: {
|
|
13877
14790
|
build: "node scripts/build.js",
|
|
13878
|
-
"build:shared": "bun run --filter '@prjct/shared' build",
|
|
13879
14791
|
"build:node": "node scripts/build.js",
|
|
13880
14792
|
release: "node scripts/release.js",
|
|
13881
14793
|
"release:patch": "node scripts/release.js patch",
|
|
@@ -13951,15 +14863,13 @@ var require_package = __commonJS({
|
|
|
13951
14863
|
"bin/",
|
|
13952
14864
|
"core/",
|
|
13953
14865
|
"dist/",
|
|
13954
|
-
"packages/shared/",
|
|
13955
14866
|
"templates/",
|
|
13956
14867
|
"scripts/postinstall.js",
|
|
13957
14868
|
"scripts/build.js",
|
|
13958
14869
|
"scripts/install.sh",
|
|
13959
14870
|
"LICENSE",
|
|
13960
14871
|
"README.md",
|
|
13961
|
-
"CHANGELOG.md"
|
|
13962
|
-
"CLAUDE.md"
|
|
14872
|
+
"CHANGELOG.md"
|
|
13963
14873
|
],
|
|
13964
14874
|
trustedDependencies: [
|
|
13965
14875
|
"chalk",
|
|
@@ -14020,20 +14930,16 @@ Use 'prjct --help' to see available commands.`);
|
|
|
14020
14930
|
result = await commands.cleanup(options);
|
|
14021
14931
|
} else if (commandName === "setup") {
|
|
14022
14932
|
result = await commands.setup(options);
|
|
14023
|
-
} else if (commandName === "migrate-all") {
|
|
14024
|
-
result = await commands.migrateAll(options);
|
|
14025
14933
|
} else {
|
|
14026
14934
|
const param = parsedArgs.join(" ") || null;
|
|
14027
14935
|
const standardCommands = {
|
|
14028
14936
|
// Core workflow
|
|
14029
|
-
work: /* @__PURE__ */ __name((p) => commands.work(p), "work"),
|
|
14030
14937
|
done: /* @__PURE__ */ __name(() => commands.done(), "done"),
|
|
14031
14938
|
next: /* @__PURE__ */ __name(() => commands.next(), "next"),
|
|
14032
14939
|
pause: /* @__PURE__ */ __name((p) => commands.pause(p || ""), "pause"),
|
|
14033
14940
|
resume: /* @__PURE__ */ __name((p) => commands.resume(p), "resume"),
|
|
14034
14941
|
// Planning
|
|
14035
14942
|
init: /* @__PURE__ */ __name((p) => commands.init(p), "init"),
|
|
14036
|
-
feature: /* @__PURE__ */ __name((p) => commands.feature(p || ""), "feature"),
|
|
14037
14943
|
bug: /* @__PURE__ */ __name((p) => commands.bug(p || ""), "bug"),
|
|
14038
14944
|
idea: /* @__PURE__ */ __name((p) => commands.idea(p || ""), "idea"),
|
|
14039
14945
|
spec: /* @__PURE__ */ __name((p) => commands.spec(p), "spec"),
|
|
@@ -14048,7 +14954,9 @@ Use 'prjct --help' to see available commands.`);
|
|
|
14048
14954
|
history: /* @__PURE__ */ __name(() => commands.history(), "history"),
|
|
14049
14955
|
// Setup
|
|
14050
14956
|
sync: /* @__PURE__ */ __name(() => commands.sync(), "sync"),
|
|
14051
|
-
start: /* @__PURE__ */ __name(() => commands.start(), "start")
|
|
14957
|
+
start: /* @__PURE__ */ __name(() => commands.start(), "start"),
|
|
14958
|
+
// Context (for Claude templates)
|
|
14959
|
+
context: /* @__PURE__ */ __name((p) => commands.context(p), "context")
|
|
14052
14960
|
};
|
|
14053
14961
|
const handler = standardCommands[commandName];
|
|
14054
14962
|
if (handler) {
|