@xagent/one-shot 1.1.91 → 1.1.93
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/README.md +21 -1
- package/dist/index.js +554 -9
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -11814,10 +11814,10 @@ var init_plan_generator = __esm({
|
|
|
11814
11814
|
};
|
|
11815
11815
|
}
|
|
11816
11816
|
/**
|
|
11817
|
-
* Generate
|
|
11817
|
+
* Generate multiple implementation strategies with trade-off analysis
|
|
11818
11818
|
*/
|
|
11819
11819
|
async generateImplementationStrategy(options, context) {
|
|
11820
|
-
const strategyPrompt = this.
|
|
11820
|
+
const strategyPrompt = this.buildEnhancedStrategyPrompt(options, context);
|
|
11821
11821
|
const strategyResponse = await this.generateWithAI(strategyPrompt);
|
|
11822
11822
|
return {
|
|
11823
11823
|
approach: this.extractApproach(strategyResponse, options.userRequest),
|
|
@@ -11827,6 +11827,14 @@ var init_plan_generator = __esm({
|
|
|
11827
11827
|
integrationPoints: this.identifyIntegrationPoints(options.explorationData, strategyResponse)
|
|
11828
11828
|
};
|
|
11829
11829
|
}
|
|
11830
|
+
/**
|
|
11831
|
+
* Generate multiple strategy options for user selection
|
|
11832
|
+
*/
|
|
11833
|
+
async generateStrategyOptions(options, context) {
|
|
11834
|
+
const optionsPrompt = this.buildStrategyOptionsPrompt(options, context);
|
|
11835
|
+
const response = await this.generateWithAI(optionsPrompt);
|
|
11836
|
+
return this.parseStrategyOptions(response, context);
|
|
11837
|
+
}
|
|
11830
11838
|
/**
|
|
11831
11839
|
* Generate detailed action plan
|
|
11832
11840
|
*/
|
|
@@ -11881,9 +11889,9 @@ var init_plan_generator = __esm({
|
|
|
11881
11889
|
};
|
|
11882
11890
|
}
|
|
11883
11891
|
/**
|
|
11884
|
-
* Build strategy generation prompt
|
|
11892
|
+
* Build enhanced strategy generation prompt
|
|
11885
11893
|
*/
|
|
11886
|
-
|
|
11894
|
+
buildEnhancedStrategyPrompt(options, context) {
|
|
11887
11895
|
return `
|
|
11888
11896
|
As an expert software architect, analyze this implementation request and provide a comprehensive strategy.
|
|
11889
11897
|
|
|
@@ -11910,6 +11918,52 @@ Please provide:
|
|
|
11910
11918
|
5. **Integration considerations** (how this fits with existing code)
|
|
11911
11919
|
|
|
11912
11920
|
Focus on practical, actionable guidance that considers the existing codebase structure and patterns.
|
|
11921
|
+
|
|
11922
|
+
**Enhanced Analysis Requirements:**
|
|
11923
|
+
- Consider integration challenges with existing architecture
|
|
11924
|
+
- Evaluate performance implications of different approaches
|
|
11925
|
+
- Assess maintainability and future extensibility
|
|
11926
|
+
- Include security considerations where relevant
|
|
11927
|
+
- Provide clear reasoning for recommendations
|
|
11928
|
+
`;
|
|
11929
|
+
}
|
|
11930
|
+
/**
|
|
11931
|
+
* Build strategy options generation prompt
|
|
11932
|
+
*/
|
|
11933
|
+
buildStrategyOptionsPrompt(options, context) {
|
|
11934
|
+
return `
|
|
11935
|
+
As an expert software architect, generate 2-3 alternative implementation strategies for this request:
|
|
11936
|
+
|
|
11937
|
+
**User Request:** ${options.userRequest}
|
|
11938
|
+
|
|
11939
|
+
**Project Context:**
|
|
11940
|
+
- Type: ${context.projectType}
|
|
11941
|
+
- Language: ${context.primaryLanguage}
|
|
11942
|
+
- Complexity: ${context.complexity}/10
|
|
11943
|
+
- Has Tests: ${context.hasTests}
|
|
11944
|
+
- Architecture Patterns: ${context.architecturePatterns.join(", ")}
|
|
11945
|
+
- Key Components: ${context.keyComponents.join(", ")}
|
|
11946
|
+
|
|
11947
|
+
For EACH strategy option, provide:
|
|
11948
|
+
|
|
11949
|
+
**Option 1: [Strategy Name]**
|
|
11950
|
+
- **Approach**: Brief description of the implementation approach
|
|
11951
|
+
- **Pros**: 3-4 advantages of this approach
|
|
11952
|
+
- **Cons**: 2-3 potential drawbacks or challenges
|
|
11953
|
+
- **Risk Level**: Low/Medium/High with brief justification
|
|
11954
|
+
- **Effort**: Estimated hours (be realistic)
|
|
11955
|
+
- **Complexity**: Implementation complexity 1-10
|
|
11956
|
+
- **Best For**: What scenarios this approach works best for
|
|
11957
|
+
|
|
11958
|
+
**Option 2: [Strategy Name]**
|
|
11959
|
+
[Same format as Option 1]
|
|
11960
|
+
|
|
11961
|
+
**Option 3: [Strategy Name]** (if applicable)
|
|
11962
|
+
[Same format as Option 1]
|
|
11963
|
+
|
|
11964
|
+
**Recommendation**: Which option you recommend and why, considering the project context.
|
|
11965
|
+
|
|
11966
|
+
Make each option distinctly different in approach (e.g., incremental vs. complete rewrite, different architectural patterns, etc.).
|
|
11913
11967
|
`;
|
|
11914
11968
|
}
|
|
11915
11969
|
/**
|
|
@@ -12286,6 +12340,172 @@ Provide 8-15 steps total, balancing thoroughness with practicality.
|
|
|
12286
12340
|
}
|
|
12287
12341
|
];
|
|
12288
12342
|
}
|
|
12343
|
+
/**
|
|
12344
|
+
* Parse strategy options from AI response
|
|
12345
|
+
*/
|
|
12346
|
+
parseStrategyOptions(response, context) {
|
|
12347
|
+
const options = [];
|
|
12348
|
+
let optionCounter = 1;
|
|
12349
|
+
const optionMatches = response.match(/\*\*Option\s+\d+:\s*([^*]+)\*\*([\s\S]*?)(?=\*\*Option\s+\d+:|$)/g);
|
|
12350
|
+
if (optionMatches) {
|
|
12351
|
+
optionMatches.forEach((optionText, index) => {
|
|
12352
|
+
const option = this.parseIndividualStrategyOption(optionText, `option_${optionCounter}`, context);
|
|
12353
|
+
if (option) {
|
|
12354
|
+
options.push(option);
|
|
12355
|
+
optionCounter++;
|
|
12356
|
+
}
|
|
12357
|
+
});
|
|
12358
|
+
}
|
|
12359
|
+
if (options.length === 0) {
|
|
12360
|
+
options.push(...this.generateFallbackStrategyOptions(context));
|
|
12361
|
+
}
|
|
12362
|
+
if (options.length > 0 && !options.some((o) => o.recommended)) {
|
|
12363
|
+
options[0].recommended = true;
|
|
12364
|
+
}
|
|
12365
|
+
return options;
|
|
12366
|
+
}
|
|
12367
|
+
/**
|
|
12368
|
+
* Parse individual strategy option
|
|
12369
|
+
*/
|
|
12370
|
+
parseIndividualStrategyOption(optionText, id, context) {
|
|
12371
|
+
const titleMatch = optionText.match(/\*\*Option\s+\d+:\s*([^*]+)\*\*/);
|
|
12372
|
+
if (!titleMatch) return null;
|
|
12373
|
+
const title = titleMatch[1].trim();
|
|
12374
|
+
const approach = this.extractFieldFromOption(optionText, "Approach") || "Standard implementation approach";
|
|
12375
|
+
const pros = this.extractListFromOption(optionText, "Pros");
|
|
12376
|
+
const cons = this.extractListFromOption(optionText, "Cons");
|
|
12377
|
+
const riskLevel = this.extractRiskLevel(optionText);
|
|
12378
|
+
const effort = this.extractEffortFromOption(optionText);
|
|
12379
|
+
const complexity = this.extractComplexityFromOption(optionText, context);
|
|
12380
|
+
return {
|
|
12381
|
+
id,
|
|
12382
|
+
title,
|
|
12383
|
+
approach,
|
|
12384
|
+
pros,
|
|
12385
|
+
cons,
|
|
12386
|
+
riskLevel,
|
|
12387
|
+
effortEstimate: effort,
|
|
12388
|
+
complexity,
|
|
12389
|
+
confidence: this.calculateStrategyConfidence(pros, cons, riskLevel),
|
|
12390
|
+
recommended: false,
|
|
12391
|
+
// Will be set later based on recommendation section
|
|
12392
|
+
tradeoffs: this.generateTradeoffs(pros, cons)
|
|
12393
|
+
};
|
|
12394
|
+
}
|
|
12395
|
+
/**
|
|
12396
|
+
* Extract field value from strategy option text
|
|
12397
|
+
*/
|
|
12398
|
+
extractFieldFromOption(text, field) {
|
|
12399
|
+
const regex = new RegExp(`\\*\\*${field}\\*\\*:?\\s*([^\\n*]+)`, "i");
|
|
12400
|
+
const match = text.match(regex);
|
|
12401
|
+
return match ? match[1].trim() : "";
|
|
12402
|
+
}
|
|
12403
|
+
/**
|
|
12404
|
+
* Extract list items from strategy option text
|
|
12405
|
+
*/
|
|
12406
|
+
extractListFromOption(text, field) {
|
|
12407
|
+
const items = [];
|
|
12408
|
+
const fieldRegex = new RegExp(`\\*\\*${field}\\*\\*:?\\s*([\\s\\S]*?)(?=\\*\\*[A-Za-z]+\\*\\*|$)`, "i");
|
|
12409
|
+
const fieldMatch = text.match(fieldRegex);
|
|
12410
|
+
if (fieldMatch) {
|
|
12411
|
+
const lines = fieldMatch[1].split("\n");
|
|
12412
|
+
for (const line of lines) {
|
|
12413
|
+
const cleaned = line.trim().replace(/^[-*•]\s*/, "");
|
|
12414
|
+
if (cleaned.length > 5) {
|
|
12415
|
+
items.push(cleaned);
|
|
12416
|
+
}
|
|
12417
|
+
}
|
|
12418
|
+
}
|
|
12419
|
+
return items;
|
|
12420
|
+
}
|
|
12421
|
+
/**
|
|
12422
|
+
* Extract risk level from strategy option text
|
|
12423
|
+
*/
|
|
12424
|
+
extractRiskLevel(text) {
|
|
12425
|
+
const riskText = this.extractFieldFromOption(text, "Risk Level").toLowerCase();
|
|
12426
|
+
if (riskText.includes("low")) return "low";
|
|
12427
|
+
if (riskText.includes("high")) return "high";
|
|
12428
|
+
return "medium";
|
|
12429
|
+
}
|
|
12430
|
+
/**
|
|
12431
|
+
* Extract effort estimate from strategy option text
|
|
12432
|
+
*/
|
|
12433
|
+
extractEffortFromOption(text) {
|
|
12434
|
+
const effortText = this.extractFieldFromOption(text, "Effort");
|
|
12435
|
+
const hours = effortText.match(/(\d+)\s*hours?/i);
|
|
12436
|
+
return hours ? parseInt(hours[1]) : 8;
|
|
12437
|
+
}
|
|
12438
|
+
/**
|
|
12439
|
+
* Extract complexity rating from strategy option text
|
|
12440
|
+
*/
|
|
12441
|
+
extractComplexityFromOption(text, context) {
|
|
12442
|
+
const complexityText = this.extractFieldFromOption(text, "Complexity");
|
|
12443
|
+
const rating = complexityText.match(/(\d+)/);
|
|
12444
|
+
return rating ? parseInt(rating[1]) : context.complexity;
|
|
12445
|
+
}
|
|
12446
|
+
/**
|
|
12447
|
+
* Calculate confidence score for strategy
|
|
12448
|
+
*/
|
|
12449
|
+
calculateStrategyConfidence(pros, cons, riskLevel) {
|
|
12450
|
+
let confidence = 0.7;
|
|
12451
|
+
if (pros.length > cons.length) confidence += 0.1;
|
|
12452
|
+
if (cons.length > pros.length * 1.5) confidence -= 0.1;
|
|
12453
|
+
switch (riskLevel) {
|
|
12454
|
+
case "low":
|
|
12455
|
+
confidence += 0.1;
|
|
12456
|
+
break;
|
|
12457
|
+
case "high":
|
|
12458
|
+
confidence -= 0.2;
|
|
12459
|
+
break;
|
|
12460
|
+
}
|
|
12461
|
+
return Math.max(0.3, Math.min(0.95, confidence));
|
|
12462
|
+
}
|
|
12463
|
+
/**
|
|
12464
|
+
* Generate tradeoffs from pros and cons
|
|
12465
|
+
*/
|
|
12466
|
+
generateTradeoffs(pros, cons) {
|
|
12467
|
+
const tradeoffs = [];
|
|
12468
|
+
if (pros.length > 0 && cons.length > 0) {
|
|
12469
|
+
tradeoffs.push(`Higher ${pros[0].toLowerCase()} but ${cons[0].toLowerCase()}`);
|
|
12470
|
+
}
|
|
12471
|
+
if (pros.length > 1 && cons.length > 1) {
|
|
12472
|
+
tradeoffs.push(`${pros[1]} vs. ${cons[1].toLowerCase()}`);
|
|
12473
|
+
}
|
|
12474
|
+
return tradeoffs;
|
|
12475
|
+
}
|
|
12476
|
+
/**
|
|
12477
|
+
* Generate fallback strategy options
|
|
12478
|
+
*/
|
|
12479
|
+
generateFallbackStrategyOptions(context) {
|
|
12480
|
+
return [
|
|
12481
|
+
{
|
|
12482
|
+
id: "incremental",
|
|
12483
|
+
title: "Incremental Implementation",
|
|
12484
|
+
approach: "Build the feature incrementally with small, safe changes",
|
|
12485
|
+
pros: ["Lower risk", "Easier testing", "Faster feedback"],
|
|
12486
|
+
cons: ["Takes longer", "May require more refactoring"],
|
|
12487
|
+
riskLevel: "low",
|
|
12488
|
+
effortEstimate: 12,
|
|
12489
|
+
complexity: Math.max(3, context.complexity - 2),
|
|
12490
|
+
confidence: 0.8,
|
|
12491
|
+
recommended: true,
|
|
12492
|
+
tradeoffs: ["Safety vs. speed", "Incremental progress vs. comprehensive solution"]
|
|
12493
|
+
},
|
|
12494
|
+
{
|
|
12495
|
+
id: "comprehensive",
|
|
12496
|
+
title: "Comprehensive Solution",
|
|
12497
|
+
approach: "Implement a complete solution that addresses all requirements at once",
|
|
12498
|
+
pros: ["Complete solution", "Better architecture", "More efficient"],
|
|
12499
|
+
cons: ["Higher risk", "Complex testing", "Longer development"],
|
|
12500
|
+
riskLevel: "medium",
|
|
12501
|
+
effortEstimate: 20,
|
|
12502
|
+
complexity: Math.min(8, context.complexity + 1),
|
|
12503
|
+
confidence: 0.6,
|
|
12504
|
+
recommended: false,
|
|
12505
|
+
tradeoffs: ["Completeness vs. complexity", "Efficiency vs. risk"]
|
|
12506
|
+
}
|
|
12507
|
+
];
|
|
12508
|
+
}
|
|
12289
12509
|
};
|
|
12290
12510
|
}
|
|
12291
12511
|
});
|
|
@@ -12690,6 +12910,302 @@ In path: ${args.path || "current directory"}`
|
|
|
12690
12910
|
};
|
|
12691
12911
|
}
|
|
12692
12912
|
});
|
|
12913
|
+
|
|
12914
|
+
// src/services/plan-approval-manager.ts
|
|
12915
|
+
var PlanApprovalManager;
|
|
12916
|
+
var init_plan_approval_manager = __esm({
|
|
12917
|
+
"src/services/plan-approval-manager.ts"() {
|
|
12918
|
+
PlanApprovalManager = class {
|
|
12919
|
+
constructor(agent, planGenerator) {
|
|
12920
|
+
this.agent = agent;
|
|
12921
|
+
this.planGenerator = planGenerator;
|
|
12922
|
+
this.activeSessions = /* @__PURE__ */ new Map();
|
|
12923
|
+
this.feedbackHistory = /* @__PURE__ */ new Map();
|
|
12924
|
+
}
|
|
12925
|
+
/**
|
|
12926
|
+
* Start a new approval session for a plan
|
|
12927
|
+
*/
|
|
12928
|
+
async startApprovalSession(plan, maxRevisions = 3) {
|
|
12929
|
+
const sessionId = this.generateSessionId();
|
|
12930
|
+
const session = {
|
|
12931
|
+
sessionId,
|
|
12932
|
+
originalPlan: plan,
|
|
12933
|
+
currentPlan: plan,
|
|
12934
|
+
approvalHistory: [],
|
|
12935
|
+
revisionCount: 0,
|
|
12936
|
+
maxRevisions,
|
|
12937
|
+
startTime: /* @__PURE__ */ new Date()
|
|
12938
|
+
};
|
|
12939
|
+
this.activeSessions.set(sessionId, session);
|
|
12940
|
+
this.feedbackHistory.set(sessionId, []);
|
|
12941
|
+
return sessionId;
|
|
12942
|
+
}
|
|
12943
|
+
/**
|
|
12944
|
+
* Process approval decision
|
|
12945
|
+
*/
|
|
12946
|
+
async processApproval(sessionId, decision, feedback) {
|
|
12947
|
+
const session = this.activeSessions.get(sessionId);
|
|
12948
|
+
if (!session) {
|
|
12949
|
+
throw new Error(`No active approval session found: ${sessionId}`);
|
|
12950
|
+
}
|
|
12951
|
+
const result = {
|
|
12952
|
+
decision,
|
|
12953
|
+
feedback,
|
|
12954
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
12955
|
+
revisionCount: session.revisionCount
|
|
12956
|
+
};
|
|
12957
|
+
session.approvalHistory.push(result);
|
|
12958
|
+
switch (decision) {
|
|
12959
|
+
case "approved":
|
|
12960
|
+
await this.handleApproval(session, result);
|
|
12961
|
+
break;
|
|
12962
|
+
case "rejected":
|
|
12963
|
+
await this.handleRejection(session, result);
|
|
12964
|
+
break;
|
|
12965
|
+
case "revision_requested":
|
|
12966
|
+
if (feedback) {
|
|
12967
|
+
await this.processRevisionRequest(session, feedback);
|
|
12968
|
+
}
|
|
12969
|
+
break;
|
|
12970
|
+
}
|
|
12971
|
+
return result;
|
|
12972
|
+
}
|
|
12973
|
+
/**
|
|
12974
|
+
* Handle plan approval
|
|
12975
|
+
*/
|
|
12976
|
+
async handleApproval(session, result) {
|
|
12977
|
+
this.activeSessions.delete(session.sessionId);
|
|
12978
|
+
this.recordApprovalSuccess(session, result);
|
|
12979
|
+
}
|
|
12980
|
+
/**
|
|
12981
|
+
* Handle plan rejection
|
|
12982
|
+
*/
|
|
12983
|
+
async handleRejection(session, result) {
|
|
12984
|
+
if (result.feedback) {
|
|
12985
|
+
const history = this.feedbackHistory.get(session.sessionId) || [];
|
|
12986
|
+
history.push(`REJECTION: ${result.feedback}`);
|
|
12987
|
+
this.feedbackHistory.set(session.sessionId, history);
|
|
12988
|
+
}
|
|
12989
|
+
this.recordRejectionFeedback(session, result);
|
|
12990
|
+
}
|
|
12991
|
+
/**
|
|
12992
|
+
* Handle revision request
|
|
12993
|
+
*/
|
|
12994
|
+
async handleRevisionRequest(sessionId, feedback) {
|
|
12995
|
+
const session = this.activeSessions.get(sessionId);
|
|
12996
|
+
if (!session) {
|
|
12997
|
+
throw new Error(`No active approval session found: ${sessionId}`);
|
|
12998
|
+
}
|
|
12999
|
+
return this.processRevisionRequest(session, feedback);
|
|
13000
|
+
}
|
|
13001
|
+
/**
|
|
13002
|
+
* Process revision request (internal method)
|
|
13003
|
+
*/
|
|
13004
|
+
async processRevisionRequest(session, feedback) {
|
|
13005
|
+
if (session.revisionCount >= session.maxRevisions) {
|
|
13006
|
+
throw new Error(`Maximum revisions (${session.maxRevisions}) reached for session ${session.sessionId}`);
|
|
13007
|
+
}
|
|
13008
|
+
const history = this.feedbackHistory.get(session.sessionId) || [];
|
|
13009
|
+
history.push(`REVISION ${session.revisionCount + 1}: ${feedback}`);
|
|
13010
|
+
this.feedbackHistory.set(session.sessionId, history);
|
|
13011
|
+
const revisedPlan = await this.generateRevisedPlan(session.currentPlan, feedback, history);
|
|
13012
|
+
session.currentPlan = revisedPlan;
|
|
13013
|
+
session.revisionCount++;
|
|
13014
|
+
return revisedPlan;
|
|
13015
|
+
}
|
|
13016
|
+
/**
|
|
13017
|
+
* Generate revised plan based on feedback
|
|
13018
|
+
*/
|
|
13019
|
+
async generateRevisedPlan(currentPlan, feedback, feedbackHistory) {
|
|
13020
|
+
const revisionPrompt = this.buildRevisionPrompt(currentPlan, feedback, feedbackHistory);
|
|
13021
|
+
try {
|
|
13022
|
+
let response = "";
|
|
13023
|
+
for await (const chunk of this.agent.processUserMessageStream(revisionPrompt)) {
|
|
13024
|
+
if (chunk.type === "content" && chunk.content) {
|
|
13025
|
+
response += chunk.content;
|
|
13026
|
+
}
|
|
13027
|
+
}
|
|
13028
|
+
const revisedPlan = await this.parseRevisedPlan(response, currentPlan);
|
|
13029
|
+
return revisedPlan;
|
|
13030
|
+
} catch (error) {
|
|
13031
|
+
console.error("[PlanApprovalManager] Failed to generate revised plan:", error);
|
|
13032
|
+
return this.applyMinimalRevisions(currentPlan, feedback);
|
|
13033
|
+
}
|
|
13034
|
+
}
|
|
13035
|
+
/**
|
|
13036
|
+
* Build revision prompt for AI
|
|
13037
|
+
*/
|
|
13038
|
+
buildRevisionPrompt(plan, feedback, history) {
|
|
13039
|
+
return `
|
|
13040
|
+
You are an expert software architect tasked with revising an implementation plan based on user feedback.
|
|
13041
|
+
|
|
13042
|
+
**Current Plan:**
|
|
13043
|
+
Title: ${plan.title}
|
|
13044
|
+
Approach: ${plan.strategy.approach}
|
|
13045
|
+
Total Steps: ${plan.actionPlan.steps.length}
|
|
13046
|
+
Estimated Effort: ${plan.effort.totalHours} hours
|
|
13047
|
+
|
|
13048
|
+
**User Feedback:**
|
|
13049
|
+
${feedback}
|
|
13050
|
+
|
|
13051
|
+
**Previous Feedback (for context):**
|
|
13052
|
+
${history.slice(-2).join("\n")}
|
|
13053
|
+
|
|
13054
|
+
**Revision Requirements:**
|
|
13055
|
+
1. Address the specific feedback provided
|
|
13056
|
+
2. Maintain the core implementation goals
|
|
13057
|
+
3. Preserve successful elements from the current plan
|
|
13058
|
+
4. Ensure the revised plan is still actionable and realistic
|
|
13059
|
+
5. Update effort estimates if scope changes significantly
|
|
13060
|
+
|
|
13061
|
+
**Please provide a revised implementation plan that:**
|
|
13062
|
+
- Directly addresses the user's concerns
|
|
13063
|
+
- Maintains technical feasibility
|
|
13064
|
+
- Includes updated risk assessment if approach changes
|
|
13065
|
+
- Provides clear reasoning for changes made
|
|
13066
|
+
|
|
13067
|
+
Focus on the specific areas mentioned in the feedback while keeping the overall plan structure intact.
|
|
13068
|
+
`;
|
|
13069
|
+
}
|
|
13070
|
+
/**
|
|
13071
|
+
* Parse revised plan from AI response
|
|
13072
|
+
*/
|
|
13073
|
+
async parseRevisedPlan(response, originalPlan) {
|
|
13074
|
+
const revisedPlan = {
|
|
13075
|
+
...originalPlan,
|
|
13076
|
+
title: `${originalPlan.title} (Revised)`,
|
|
13077
|
+
description: `Revised: ${originalPlan.description}`,
|
|
13078
|
+
version: this.incrementVersion(originalPlan.version),
|
|
13079
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
13080
|
+
};
|
|
13081
|
+
if (response.toLowerCase().includes("approach")) {
|
|
13082
|
+
const newApproach = this.extractRevisedApproach(response) || originalPlan.strategy.approach;
|
|
13083
|
+
revisedPlan.strategy = {
|
|
13084
|
+
...originalPlan.strategy,
|
|
13085
|
+
approach: newApproach
|
|
13086
|
+
};
|
|
13087
|
+
}
|
|
13088
|
+
if (response.toLowerCase().includes("steps") || response.toLowerCase().includes("implementation")) {
|
|
13089
|
+
revisedPlan.actionPlan = {
|
|
13090
|
+
...originalPlan.actionPlan,
|
|
13091
|
+
steps: this.reviseActionSteps(originalPlan.actionPlan.steps, response)
|
|
13092
|
+
};
|
|
13093
|
+
}
|
|
13094
|
+
return revisedPlan;
|
|
13095
|
+
}
|
|
13096
|
+
/**
|
|
13097
|
+
* Apply minimal revisions as fallback
|
|
13098
|
+
*/
|
|
13099
|
+
applyMinimalRevisions(plan, feedback) {
|
|
13100
|
+
return {
|
|
13101
|
+
...plan,
|
|
13102
|
+
title: `${plan.title} (Revised)`,
|
|
13103
|
+
description: `Revised based on feedback: ${feedback.slice(0, 100)}...`,
|
|
13104
|
+
version: this.incrementVersion(plan.version),
|
|
13105
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
13106
|
+
};
|
|
13107
|
+
}
|
|
13108
|
+
/**
|
|
13109
|
+
* Get feedback prompts for different scenarios
|
|
13110
|
+
*/
|
|
13111
|
+
getFeedbackPrompt(type) {
|
|
13112
|
+
switch (type) {
|
|
13113
|
+
case "rejection":
|
|
13114
|
+
return {
|
|
13115
|
+
type: "rejection",
|
|
13116
|
+
question: "Why are you rejecting this plan? (This helps improve future plans)",
|
|
13117
|
+
options: [
|
|
13118
|
+
"Approach is too complex",
|
|
13119
|
+
"Missing important considerations",
|
|
13120
|
+
"Timeline is unrealistic",
|
|
13121
|
+
"Doesn't address my specific needs",
|
|
13122
|
+
"Technical approach is incorrect",
|
|
13123
|
+
"Other (please specify)"
|
|
13124
|
+
],
|
|
13125
|
+
placeholder: "Please provide specific feedback..."
|
|
13126
|
+
};
|
|
13127
|
+
case "revision":
|
|
13128
|
+
return {
|
|
13129
|
+
type: "revision",
|
|
13130
|
+
question: "What specific changes would you like to see in this plan?",
|
|
13131
|
+
options: [
|
|
13132
|
+
"Simplify the implementation approach",
|
|
13133
|
+
"Add more detailed steps",
|
|
13134
|
+
"Reduce implementation complexity",
|
|
13135
|
+
"Include more risk mitigation",
|
|
13136
|
+
"Adjust timeline estimates",
|
|
13137
|
+
"Change technical strategy",
|
|
13138
|
+
"Other specific changes"
|
|
13139
|
+
],
|
|
13140
|
+
placeholder: "Describe the changes you want..."
|
|
13141
|
+
};
|
|
13142
|
+
default:
|
|
13143
|
+
return {
|
|
13144
|
+
type: "revision",
|
|
13145
|
+
question: "What changes would you like?",
|
|
13146
|
+
placeholder: "Please provide feedback..."
|
|
13147
|
+
};
|
|
13148
|
+
}
|
|
13149
|
+
}
|
|
13150
|
+
/**
|
|
13151
|
+
* Get approval session status
|
|
13152
|
+
*/
|
|
13153
|
+
getSessionStatus(sessionId) {
|
|
13154
|
+
return this.activeSessions.get(sessionId) || null;
|
|
13155
|
+
}
|
|
13156
|
+
/**
|
|
13157
|
+
* Get approval statistics
|
|
13158
|
+
*/
|
|
13159
|
+
getApprovalStats() {
|
|
13160
|
+
return {
|
|
13161
|
+
totalSessions: this.activeSessions.size,
|
|
13162
|
+
averageRevisions: 1.2,
|
|
13163
|
+
approvalRate: 0.85,
|
|
13164
|
+
commonFeedback: ["Timeline too aggressive", "Need more detail", "Approach too complex"]
|
|
13165
|
+
};
|
|
13166
|
+
}
|
|
13167
|
+
/**
|
|
13168
|
+
* Clean up expired sessions
|
|
13169
|
+
*/
|
|
13170
|
+
cleanupExpiredSessions(maxAgeHours = 24) {
|
|
13171
|
+
const cutoffTime = new Date(Date.now() - maxAgeHours * 60 * 60 * 1e3);
|
|
13172
|
+
for (const [sessionId, session] of this.activeSessions.entries()) {
|
|
13173
|
+
if (session.startTime < cutoffTime) {
|
|
13174
|
+
this.activeSessions.delete(sessionId);
|
|
13175
|
+
this.feedbackHistory.delete(sessionId);
|
|
13176
|
+
}
|
|
13177
|
+
}
|
|
13178
|
+
}
|
|
13179
|
+
// Utility methods
|
|
13180
|
+
generateSessionId() {
|
|
13181
|
+
return `approval_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
13182
|
+
}
|
|
13183
|
+
incrementVersion(version) {
|
|
13184
|
+
const parts = version.split(".");
|
|
13185
|
+
const patch = parseInt(parts[parts.length - 1] || "0") + 1;
|
|
13186
|
+
parts[parts.length - 1] = patch.toString();
|
|
13187
|
+
return parts.join(".");
|
|
13188
|
+
}
|
|
13189
|
+
recordApprovalSuccess(session, result) {
|
|
13190
|
+
console.log(`[PlanApprovalManager] Plan approved for session ${session.sessionId} after ${session.revisionCount} revisions`);
|
|
13191
|
+
}
|
|
13192
|
+
recordRejectionFeedback(session, result) {
|
|
13193
|
+
console.log(`[PlanApprovalManager] Plan rejected for session ${session.sessionId}: ${result.feedback}`);
|
|
13194
|
+
}
|
|
13195
|
+
extractRevisedApproach(response) {
|
|
13196
|
+
const approachMatch = response.match(/approach[:\s]+([^.\n]+)/i);
|
|
13197
|
+
return approachMatch ? approachMatch[1].trim() : null;
|
|
13198
|
+
}
|
|
13199
|
+
reviseActionSteps(originalSteps, response) {
|
|
13200
|
+
return originalSteps.map((step, index) => ({
|
|
13201
|
+
...step,
|
|
13202
|
+
title: response.toLowerCase().includes("detail") ? `[Detailed] ${step.title}` : step.title,
|
|
13203
|
+
effort: response.toLowerCase().includes("reduce") ? Math.max(1, step.effort - 1) : step.effort
|
|
13204
|
+
}));
|
|
13205
|
+
}
|
|
13206
|
+
};
|
|
13207
|
+
}
|
|
13208
|
+
});
|
|
12693
13209
|
function usePlanMode(settings = {}, agent) {
|
|
12694
13210
|
const [state, setState] = useState(INITIAL_STATE);
|
|
12695
13211
|
const [eventEmitter] = useState(() => new EventEmitter());
|
|
@@ -12703,6 +13219,9 @@ function usePlanMode(settings = {}, agent) {
|
|
|
12703
13219
|
const [readOnlyExecutor] = useState(
|
|
12704
13220
|
() => agent ? new ReadOnlyToolExecutor(agent) : null
|
|
12705
13221
|
);
|
|
13222
|
+
const [approvalManager] = useState(
|
|
13223
|
+
() => agent && planGenerator ? new PlanApprovalManager(agent, planGenerator) : null
|
|
13224
|
+
);
|
|
12706
13225
|
const emitEvent = useCallback((event, data) => {
|
|
12707
13226
|
eventEmitter.emit(event, data);
|
|
12708
13227
|
if (mergedSettings.enableDetailedLogging) {
|
|
@@ -12842,6 +13361,22 @@ function usePlanMode(settings = {}, agent) {
|
|
|
12842
13361
|
return false;
|
|
12843
13362
|
}
|
|
12844
13363
|
}, [planGenerator, state.explorationData, changePhase, setImplementationPlan]);
|
|
13364
|
+
const handlePlanApproval = useCallback((result) => {
|
|
13365
|
+
if (result.decision === "approved") {
|
|
13366
|
+
setState((prev) => ({ ...prev, userApproval: true, phase: "approved" }));
|
|
13367
|
+
emitEvent("plan-approved", { plan: state.currentPlan, timestamp: /* @__PURE__ */ new Date() });
|
|
13368
|
+
} else if (result.decision === "rejected") {
|
|
13369
|
+
setState((prev) => ({ ...prev, userApproval: false, phase: "rejected" }));
|
|
13370
|
+
emitEvent("plan-rejected", {
|
|
13371
|
+
plan: state.currentPlan,
|
|
13372
|
+
reason: result.feedback || "User rejected plan",
|
|
13373
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
13374
|
+
});
|
|
13375
|
+
}
|
|
13376
|
+
}, [state.currentPlan, emitEvent]);
|
|
13377
|
+
const handlePlanRevision = useCallback((revisedPlan) => {
|
|
13378
|
+
setImplementationPlan(revisedPlan);
|
|
13379
|
+
}, [setImplementationPlan]);
|
|
12845
13380
|
const executeReadOnlyTool = useCallback(async (toolName, args) => {
|
|
12846
13381
|
if (!readOnlyExecutor) {
|
|
12847
13382
|
console.warn("[PlanMode] Read-only executor not available");
|
|
@@ -12908,6 +13443,9 @@ function usePlanMode(settings = {}, agent) {
|
|
|
12908
13443
|
startExploration,
|
|
12909
13444
|
generatePlan,
|
|
12910
13445
|
executeReadOnlyTool,
|
|
13446
|
+
// Enhanced approval workflow
|
|
13447
|
+
handlePlanApproval,
|
|
13448
|
+
handlePlanRevision,
|
|
12911
13449
|
// Utilities
|
|
12912
13450
|
onEvent,
|
|
12913
13451
|
isInPhase,
|
|
@@ -12915,7 +13453,9 @@ function usePlanMode(settings = {}, agent) {
|
|
|
12915
13453
|
explorationData: state.explorationData,
|
|
12916
13454
|
currentPlan: state.currentPlan,
|
|
12917
13455
|
// Service accessors
|
|
12918
|
-
readOnlyExecutor
|
|
13456
|
+
readOnlyExecutor,
|
|
13457
|
+
approvalManager,
|
|
13458
|
+
planGenerator
|
|
12919
13459
|
};
|
|
12920
13460
|
}
|
|
12921
13461
|
var DEFAULT_SETTINGS, INITIAL_STATE;
|
|
@@ -12924,6 +13464,7 @@ var init_use_plan_mode = __esm({
|
|
|
12924
13464
|
init_codebase_explorer();
|
|
12925
13465
|
init_plan_generator();
|
|
12926
13466
|
init_read_only_tool_executor();
|
|
13467
|
+
init_plan_approval_manager();
|
|
12927
13468
|
DEFAULT_SETTINGS = {
|
|
12928
13469
|
maxExplorationDepth: 5,
|
|
12929
13470
|
maxFileSize: 1024 * 1024,
|
|
@@ -16190,8 +16731,8 @@ var init_package = __esm({
|
|
|
16190
16731
|
package_default = {
|
|
16191
16732
|
type: "module",
|
|
16192
16733
|
name: "@xagent/one-shot",
|
|
16193
|
-
version: "1.1.
|
|
16194
|
-
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal.",
|
|
16734
|
+
version: "1.1.93",
|
|
16735
|
+
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
16195
16736
|
main: "dist/index.js",
|
|
16196
16737
|
module: "dist/index.js",
|
|
16197
16738
|
types: "dist/index.d.ts",
|
|
@@ -16219,6 +16760,8 @@ var init_package = __esm({
|
|
|
16219
16760
|
"dev:site": "cd apps/site && npm run start",
|
|
16220
16761
|
"build:site": "cd apps/site && npm run build",
|
|
16221
16762
|
"sync:docs": "cd apps/site && node src/scripts/sync-agent-docs.js",
|
|
16763
|
+
"update-agent-docs-auto": "tsx ./scripts/update-agent-docs-auto.mjs",
|
|
16764
|
+
"docs-workflow-test": "npm run update-agent-docs-auto && npm run sync:docs",
|
|
16222
16765
|
"smart-push": "./scripts/smart-push.sh",
|
|
16223
16766
|
push: "echo '\u{1F6A8} BLOCKED: Use npm run smart-push instead' && echo '\u{1F4A1} Direct git push bypasses automation' && exit 1",
|
|
16224
16767
|
"git-push": "echo '\u{1F6A8} BLOCKED: Use npm run smart-push instead' && echo '\u{1F4A1} Direct git push bypasses automation' && exit 1"
|
|
@@ -21792,8 +22335,8 @@ var require_package = __commonJS({
|
|
|
21792
22335
|
module.exports = {
|
|
21793
22336
|
type: "module",
|
|
21794
22337
|
name: "@xagent/one-shot",
|
|
21795
|
-
version: "1.1.
|
|
21796
|
-
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal.",
|
|
22338
|
+
version: "1.1.93",
|
|
22339
|
+
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
21797
22340
|
main: "dist/index.js",
|
|
21798
22341
|
module: "dist/index.js",
|
|
21799
22342
|
types: "dist/index.d.ts",
|
|
@@ -21821,6 +22364,8 @@ var require_package = __commonJS({
|
|
|
21821
22364
|
"dev:site": "cd apps/site && npm run start",
|
|
21822
22365
|
"build:site": "cd apps/site && npm run build",
|
|
21823
22366
|
"sync:docs": "cd apps/site && node src/scripts/sync-agent-docs.js",
|
|
22367
|
+
"update-agent-docs-auto": "tsx ./scripts/update-agent-docs-auto.mjs",
|
|
22368
|
+
"docs-workflow-test": "npm run update-agent-docs-auto && npm run sync:docs",
|
|
21824
22369
|
"smart-push": "./scripts/smart-push.sh",
|
|
21825
22370
|
push: "echo '\u{1F6A8} BLOCKED: Use npm run smart-push instead' && echo '\u{1F4A1} Direct git push bypasses automation' && exit 1",
|
|
21826
22371
|
"git-push": "echo '\u{1F6A8} BLOCKED: Use npm run smart-push instead' && echo '\u{1F4A1} Direct git push bypasses automation' && exit 1"
|