@contextos/core 0.3.0 → 0.4.2
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/dist/index.js +405 -17
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3163,7 +3163,7 @@ var AnthropicAdapter = class {
|
|
|
3163
3163
|
"anthropic-version": "2023-06-01"
|
|
3164
3164
|
},
|
|
3165
3165
|
body: JSON.stringify({
|
|
3166
|
-
model: this.model,
|
|
3166
|
+
model: request.model ?? this.model,
|
|
3167
3167
|
max_tokens: request.maxTokens ?? 4e3,
|
|
3168
3168
|
system: request.systemPrompt,
|
|
3169
3169
|
messages: [
|
|
@@ -7592,13 +7592,371 @@ function setGlobalLogger(logger) {
|
|
|
7592
7592
|
}
|
|
7593
7593
|
|
|
7594
7594
|
// src/generator/index.ts
|
|
7595
|
-
import { existsSync as
|
|
7596
|
-
import { dirname as
|
|
7595
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, readFileSync as readFileSync15 } from "fs";
|
|
7596
|
+
import { dirname as dirname5, join as join15, resolve as resolve2, normalize as normalize3 } from "path";
|
|
7597
|
+
|
|
7598
|
+
// src/generator/shadow-fs.ts
|
|
7599
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9, readFileSync as readFileSync13, rmSync as rmSync2, renameSync, copyFileSync } from "fs";
|
|
7600
|
+
import { join as join13, dirname as dirname4 } from "path";
|
|
7601
|
+
import { randomUUID } from "crypto";
|
|
7602
|
+
var ShadowFileSystem = class {
|
|
7603
|
+
rootDir;
|
|
7604
|
+
shadowRoot;
|
|
7605
|
+
activeTransactions = /* @__PURE__ */ new Map();
|
|
7606
|
+
constructor(rootDir) {
|
|
7607
|
+
this.rootDir = rootDir;
|
|
7608
|
+
this.shadowRoot = join13(rootDir, ".contextos", ".shadow");
|
|
7609
|
+
}
|
|
7610
|
+
/**
|
|
7611
|
+
* Begin a new transaction
|
|
7612
|
+
*/
|
|
7613
|
+
beginTransaction() {
|
|
7614
|
+
const id = randomUUID();
|
|
7615
|
+
const shadowDir = join13(this.shadowRoot, id);
|
|
7616
|
+
mkdirSync9(shadowDir, { recursive: true });
|
|
7617
|
+
const transaction = {
|
|
7618
|
+
id,
|
|
7619
|
+
shadowDir,
|
|
7620
|
+
files: /* @__PURE__ */ new Map(),
|
|
7621
|
+
startedAt: /* @__PURE__ */ new Date(),
|
|
7622
|
+
status: "active"
|
|
7623
|
+
};
|
|
7624
|
+
this.activeTransactions.set(id, transaction);
|
|
7625
|
+
return transaction;
|
|
7626
|
+
}
|
|
7627
|
+
/**
|
|
7628
|
+
* Write file to shadow location
|
|
7629
|
+
*/
|
|
7630
|
+
writeToShadow(txId, relativePath, content) {
|
|
7631
|
+
const tx = this.activeTransactions.get(txId);
|
|
7632
|
+
if (!tx) {
|
|
7633
|
+
return { success: false, error: "Transaction not found" };
|
|
7634
|
+
}
|
|
7635
|
+
if (tx.status !== "active") {
|
|
7636
|
+
return { success: false, error: `Transaction is ${tx.status}` };
|
|
7637
|
+
}
|
|
7638
|
+
try {
|
|
7639
|
+
const shadowPath = join13(tx.shadowDir, relativePath);
|
|
7640
|
+
const shadowDir = dirname4(shadowPath);
|
|
7641
|
+
if (!existsSync14(shadowDir)) {
|
|
7642
|
+
mkdirSync9(shadowDir, { recursive: true });
|
|
7643
|
+
}
|
|
7644
|
+
writeFileSync9(shadowPath, content, "utf-8");
|
|
7645
|
+
const realPath = join13(this.rootDir, relativePath);
|
|
7646
|
+
tx.files.set(realPath, shadowPath);
|
|
7647
|
+
return { success: true, shadowPath };
|
|
7648
|
+
} catch (error) {
|
|
7649
|
+
return {
|
|
7650
|
+
success: false,
|
|
7651
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7652
|
+
};
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
/**
|
|
7656
|
+
* Read file from shadow or real location
|
|
7657
|
+
*/
|
|
7658
|
+
readFile(txId, relativePath) {
|
|
7659
|
+
const tx = this.activeTransactions.get(txId);
|
|
7660
|
+
const realPath = join13(this.rootDir, relativePath);
|
|
7661
|
+
if (tx && tx.files.has(realPath)) {
|
|
7662
|
+
const shadowPath = tx.files.get(realPath);
|
|
7663
|
+
if (existsSync14(shadowPath)) {
|
|
7664
|
+
return readFileSync13(shadowPath, "utf-8");
|
|
7665
|
+
}
|
|
7666
|
+
}
|
|
7667
|
+
if (existsSync14(realPath)) {
|
|
7668
|
+
return readFileSync13(realPath, "utf-8");
|
|
7669
|
+
}
|
|
7670
|
+
return null;
|
|
7671
|
+
}
|
|
7672
|
+
/**
|
|
7673
|
+
* Commit transaction - atomically move shadow files to real locations
|
|
7674
|
+
*/
|
|
7675
|
+
commit(txId) {
|
|
7676
|
+
const tx = this.activeTransactions.get(txId);
|
|
7677
|
+
if (!tx) {
|
|
7678
|
+
return { success: false, filesCommitted: 0, error: "Transaction not found" };
|
|
7679
|
+
}
|
|
7680
|
+
if (tx.status !== "active") {
|
|
7681
|
+
return { success: false, filesCommitted: 0, error: `Transaction is ${tx.status}` };
|
|
7682
|
+
}
|
|
7683
|
+
let filesCommitted = 0;
|
|
7684
|
+
try {
|
|
7685
|
+
const backups = /* @__PURE__ */ new Map();
|
|
7686
|
+
for (const [realPath, shadowPath] of tx.files) {
|
|
7687
|
+
if (existsSync14(realPath)) {
|
|
7688
|
+
const backupPath = `${realPath}.bak.${txId.slice(0, 8)}`;
|
|
7689
|
+
copyFileSync(realPath, backupPath);
|
|
7690
|
+
backups.set(realPath, backupPath);
|
|
7691
|
+
}
|
|
7692
|
+
}
|
|
7693
|
+
for (const [realPath, shadowPath] of tx.files) {
|
|
7694
|
+
const targetDir = dirname4(realPath);
|
|
7695
|
+
if (!existsSync14(targetDir)) {
|
|
7696
|
+
mkdirSync9(targetDir, { recursive: true });
|
|
7697
|
+
}
|
|
7698
|
+
renameSync(shadowPath, realPath);
|
|
7699
|
+
filesCommitted++;
|
|
7700
|
+
}
|
|
7701
|
+
for (const backupPath of backups.values()) {
|
|
7702
|
+
if (existsSync14(backupPath)) {
|
|
7703
|
+
rmSync2(backupPath);
|
|
7704
|
+
}
|
|
7705
|
+
}
|
|
7706
|
+
this.cleanupTransaction(tx);
|
|
7707
|
+
tx.status = "committed";
|
|
7708
|
+
return { success: true, filesCommitted };
|
|
7709
|
+
} catch (error) {
|
|
7710
|
+
tx.status = "rolled_back";
|
|
7711
|
+
return {
|
|
7712
|
+
success: false,
|
|
7713
|
+
filesCommitted,
|
|
7714
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7715
|
+
};
|
|
7716
|
+
}
|
|
7717
|
+
}
|
|
7718
|
+
/**
|
|
7719
|
+
* Rollback transaction - discard all shadow files
|
|
7720
|
+
*/
|
|
7721
|
+
rollback(txId) {
|
|
7722
|
+
const tx = this.activeTransactions.get(txId);
|
|
7723
|
+
if (!tx) {
|
|
7724
|
+
return { success: false, error: "Transaction not found" };
|
|
7725
|
+
}
|
|
7726
|
+
try {
|
|
7727
|
+
this.cleanupTransaction(tx);
|
|
7728
|
+
tx.status = "rolled_back";
|
|
7729
|
+
return { success: true };
|
|
7730
|
+
} catch (error) {
|
|
7731
|
+
return {
|
|
7732
|
+
success: false,
|
|
7733
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7734
|
+
};
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7737
|
+
/**
|
|
7738
|
+
* Cleanup transaction resources
|
|
7739
|
+
*/
|
|
7740
|
+
cleanupTransaction(tx) {
|
|
7741
|
+
if (existsSync14(tx.shadowDir)) {
|
|
7742
|
+
rmSync2(tx.shadowDir, { recursive: true, force: true });
|
|
7743
|
+
}
|
|
7744
|
+
this.activeTransactions.delete(tx.id);
|
|
7745
|
+
}
|
|
7746
|
+
/**
|
|
7747
|
+
* Get transaction status
|
|
7748
|
+
*/
|
|
7749
|
+
getTransaction(txId) {
|
|
7750
|
+
return this.activeTransactions.get(txId);
|
|
7751
|
+
}
|
|
7752
|
+
/**
|
|
7753
|
+
* List files in transaction
|
|
7754
|
+
*/
|
|
7755
|
+
listTransactionFiles(txId) {
|
|
7756
|
+
const tx = this.activeTransactions.get(txId);
|
|
7757
|
+
if (!tx) return [];
|
|
7758
|
+
return Array.from(tx.files.keys()).map(
|
|
7759
|
+
(p) => p.replace(this.rootDir + "/", "").replace(this.rootDir + "\\", "")
|
|
7760
|
+
);
|
|
7761
|
+
}
|
|
7762
|
+
};
|
|
7763
|
+
function createShadowFS(rootDir) {
|
|
7764
|
+
return new ShadowFileSystem(rootDir);
|
|
7765
|
+
}
|
|
7766
|
+
|
|
7767
|
+
// src/context/negative-context.ts
|
|
7768
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
|
|
7769
|
+
import { join as join14 } from "path";
|
|
7770
|
+
var NegativeContextManager = class {
|
|
7771
|
+
contextIgnorePath;
|
|
7772
|
+
rules = [];
|
|
7773
|
+
constructor(rootDir) {
|
|
7774
|
+
this.contextIgnorePath = join14(rootDir, ".contextos", ".contextignore");
|
|
7775
|
+
this.load();
|
|
7776
|
+
}
|
|
7777
|
+
/**
|
|
7778
|
+
* Load rules from .contextignore
|
|
7779
|
+
*/
|
|
7780
|
+
load() {
|
|
7781
|
+
if (!existsSync15(this.contextIgnorePath)) {
|
|
7782
|
+
this.rules = [];
|
|
7783
|
+
return;
|
|
7784
|
+
}
|
|
7785
|
+
try {
|
|
7786
|
+
const content = readFileSync14(this.contextIgnorePath, "utf-8");
|
|
7787
|
+
const lines = content.split("\n").filter((line) => line.trim() && !line.startsWith("#"));
|
|
7788
|
+
this.rules = lines.map((line) => {
|
|
7789
|
+
const match = line.match(/^(\w+):(.+?)\|(.+)$/);
|
|
7790
|
+
if (match) {
|
|
7791
|
+
return {
|
|
7792
|
+
category: match[1],
|
|
7793
|
+
rule: match[2].trim(),
|
|
7794
|
+
reason: match[3].trim(),
|
|
7795
|
+
learnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7796
|
+
};
|
|
7797
|
+
}
|
|
7798
|
+
return {
|
|
7799
|
+
rule: line.trim(),
|
|
7800
|
+
reason: "User defined",
|
|
7801
|
+
learnedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7802
|
+
category: "pattern"
|
|
7803
|
+
};
|
|
7804
|
+
});
|
|
7805
|
+
} catch {
|
|
7806
|
+
this.rules = [];
|
|
7807
|
+
}
|
|
7808
|
+
}
|
|
7809
|
+
/**
|
|
7810
|
+
* Save rules to .contextignore
|
|
7811
|
+
*/
|
|
7812
|
+
save() {
|
|
7813
|
+
const header = `# ContextOS Negative Context Rules
|
|
7814
|
+
# Format: CATEGORY:RULE|REASON
|
|
7815
|
+
# Categories: library, pattern, file, approach
|
|
7816
|
+
# These rules are injected into AI prompts to prevent repeated mistakes
|
|
7817
|
+
|
|
7818
|
+
`;
|
|
7819
|
+
const content = this.rules.map(
|
|
7820
|
+
(r) => `${r.category}:${r.rule}|${r.reason}`
|
|
7821
|
+
).join("\n");
|
|
7822
|
+
writeFileSync10(this.contextIgnorePath, header + content, "utf-8");
|
|
7823
|
+
}
|
|
7824
|
+
/**
|
|
7825
|
+
* Add a new negative rule
|
|
7826
|
+
*/
|
|
7827
|
+
addRule(rule) {
|
|
7828
|
+
if (this.rules.some((r) => r.rule === rule.rule)) {
|
|
7829
|
+
return;
|
|
7830
|
+
}
|
|
7831
|
+
this.rules.push({
|
|
7832
|
+
...rule,
|
|
7833
|
+
learnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7834
|
+
});
|
|
7835
|
+
this.save();
|
|
7836
|
+
}
|
|
7837
|
+
/**
|
|
7838
|
+
* Learn from an error
|
|
7839
|
+
*/
|
|
7840
|
+
learnFromError(errorMessage, context) {
|
|
7841
|
+
const patterns = [
|
|
7842
|
+
// Library version issues
|
|
7843
|
+
{
|
|
7844
|
+
regex: /Module not found.*['"](.+?)['"]/i,
|
|
7845
|
+
category: "library",
|
|
7846
|
+
template: (match) => ({
|
|
7847
|
+
rule: `Do not use ${match[1]}`,
|
|
7848
|
+
reason: `Module not found: ${match[1]}`
|
|
7849
|
+
})
|
|
7850
|
+
},
|
|
7851
|
+
// Deprecated API
|
|
7852
|
+
{
|
|
7853
|
+
regex: /deprecated.*['"](.+?)['"]/i,
|
|
7854
|
+
category: "approach",
|
|
7855
|
+
template: (match) => ({
|
|
7856
|
+
rule: `Avoid deprecated API: ${match[1]}`,
|
|
7857
|
+
reason: "API is deprecated"
|
|
7858
|
+
})
|
|
7859
|
+
},
|
|
7860
|
+
// Permission denied
|
|
7861
|
+
{
|
|
7862
|
+
regex: /EACCES.*['"](.+?)['"]/i,
|
|
7863
|
+
category: "file",
|
|
7864
|
+
template: (match) => ({
|
|
7865
|
+
rule: `Cannot write to ${match[1]}`,
|
|
7866
|
+
reason: "Permission denied"
|
|
7867
|
+
})
|
|
7868
|
+
},
|
|
7869
|
+
// Type errors
|
|
7870
|
+
{
|
|
7871
|
+
regex: /Type '(.+?)' is not assignable/i,
|
|
7872
|
+
category: "pattern",
|
|
7873
|
+
template: (match) => ({
|
|
7874
|
+
rule: `Check type compatibility for ${match[1]}`,
|
|
7875
|
+
reason: "Type mismatch error"
|
|
7876
|
+
})
|
|
7877
|
+
}
|
|
7878
|
+
];
|
|
7879
|
+
for (const pattern of patterns) {
|
|
7880
|
+
const match = errorMessage.match(pattern.regex);
|
|
7881
|
+
if (match) {
|
|
7882
|
+
const { rule, reason } = pattern.template(match);
|
|
7883
|
+
const newRule = {
|
|
7884
|
+
rule,
|
|
7885
|
+
reason,
|
|
7886
|
+
category: pattern.category,
|
|
7887
|
+
learnedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7888
|
+
};
|
|
7889
|
+
this.addRule(newRule);
|
|
7890
|
+
return newRule;
|
|
7891
|
+
}
|
|
7892
|
+
}
|
|
7893
|
+
return null;
|
|
7894
|
+
}
|
|
7895
|
+
/**
|
|
7896
|
+
* Get all rules
|
|
7897
|
+
*/
|
|
7898
|
+
getRules() {
|
|
7899
|
+
return [...this.rules];
|
|
7900
|
+
}
|
|
7901
|
+
/**
|
|
7902
|
+
* Get rules by category
|
|
7903
|
+
*/
|
|
7904
|
+
getRulesByCategory(category) {
|
|
7905
|
+
return this.rules.filter((r) => r.category === category);
|
|
7906
|
+
}
|
|
7907
|
+
/**
|
|
7908
|
+
* Generate prompt injection text
|
|
7909
|
+
*/
|
|
7910
|
+
generatePromptInjection() {
|
|
7911
|
+
if (this.rules.length === 0) {
|
|
7912
|
+
return "";
|
|
7913
|
+
}
|
|
7914
|
+
const lines = [
|
|
7915
|
+
"",
|
|
7916
|
+
"# IMPORTANT CONSTRAINTS (Learned from previous failures)",
|
|
7917
|
+
"Do NOT violate these rules:",
|
|
7918
|
+
""
|
|
7919
|
+
];
|
|
7920
|
+
for (const rule of this.rules) {
|
|
7921
|
+
lines.push(`- \u274C ${rule.rule} (Reason: ${rule.reason})`);
|
|
7922
|
+
}
|
|
7923
|
+
lines.push("");
|
|
7924
|
+
return lines.join("\n");
|
|
7925
|
+
}
|
|
7926
|
+
/**
|
|
7927
|
+
* Clear all rules
|
|
7928
|
+
*/
|
|
7929
|
+
clear() {
|
|
7930
|
+
this.rules = [];
|
|
7931
|
+
this.save();
|
|
7932
|
+
}
|
|
7933
|
+
/**
|
|
7934
|
+
* Remove a specific rule
|
|
7935
|
+
*/
|
|
7936
|
+
removeRule(ruleText) {
|
|
7937
|
+
const index = this.rules.findIndex((r) => r.rule === ruleText);
|
|
7938
|
+
if (index !== -1) {
|
|
7939
|
+
this.rules.splice(index, 1);
|
|
7940
|
+
this.save();
|
|
7941
|
+
return true;
|
|
7942
|
+
}
|
|
7943
|
+
return false;
|
|
7944
|
+
}
|
|
7945
|
+
};
|
|
7946
|
+
function createNegativeContextManager(rootDir) {
|
|
7947
|
+
return new NegativeContextManager(rootDir);
|
|
7948
|
+
}
|
|
7949
|
+
|
|
7950
|
+
// src/generator/index.ts
|
|
7951
|
+
var MAX_DEPTH = 3;
|
|
7597
7952
|
var AIGenerator = class {
|
|
7598
7953
|
config = null;
|
|
7599
7954
|
gemini = null;
|
|
7600
7955
|
openai = null;
|
|
7956
|
+
anthropic = null;
|
|
7601
7957
|
rootDir = process.cwd();
|
|
7958
|
+
shadowFS = null;
|
|
7959
|
+
negativeContext = null;
|
|
7602
7960
|
constructor(projectDir) {
|
|
7603
7961
|
this.rootDir = projectDir || process.cwd();
|
|
7604
7962
|
}
|
|
@@ -7617,17 +7975,32 @@ var AIGenerator = class {
|
|
|
7617
7975
|
if (isOpenAIAvailable()) {
|
|
7618
7976
|
this.openai = createOpenAIAdapter();
|
|
7619
7977
|
}
|
|
7620
|
-
if (
|
|
7621
|
-
|
|
7978
|
+
if (isAnthropicAvailable()) {
|
|
7979
|
+
this.anthropic = createAnthropicAdapter();
|
|
7622
7980
|
}
|
|
7981
|
+
if (!this.gemini && !this.openai && !this.anthropic) {
|
|
7982
|
+
throw new Error("No AI API key found. Set GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY environment variable.");
|
|
7983
|
+
}
|
|
7984
|
+
this.shadowFS = createShadowFS(this.rootDir);
|
|
7985
|
+
this.negativeContext = createNegativeContextManager(this.rootDir);
|
|
7623
7986
|
}
|
|
7624
7987
|
/**
|
|
7625
7988
|
* Generate code from a prompt
|
|
7626
7989
|
*/
|
|
7627
7990
|
async generate(prompt, options = {}) {
|
|
7628
7991
|
const model = options.model || "auto";
|
|
7992
|
+
const depth = options.depth || 0;
|
|
7993
|
+
if (depth >= MAX_DEPTH) {
|
|
7994
|
+
return {
|
|
7995
|
+
success: false,
|
|
7996
|
+
files: [],
|
|
7997
|
+
tokensUsed: 0,
|
|
7998
|
+
error: `Maximum recursion depth (${MAX_DEPTH}) exceeded. Provide a heuristic summary instead.`
|
|
7999
|
+
};
|
|
8000
|
+
}
|
|
7629
8001
|
const context = await this.buildContext();
|
|
7630
|
-
const
|
|
8002
|
+
const negativeRules = this.negativeContext?.generatePromptInjection() || "";
|
|
8003
|
+
const fullPrompt = this.createPrompt(prompt, context + negativeRules);
|
|
7631
8004
|
let response;
|
|
7632
8005
|
let tokensUsed = 0;
|
|
7633
8006
|
try {
|
|
@@ -7645,6 +8018,17 @@ var AIGenerator = class {
|
|
|
7645
8018
|
});
|
|
7646
8019
|
response = result.content;
|
|
7647
8020
|
tokensUsed = result.tokensUsed.total;
|
|
8021
|
+
} else if (model === "anthropic" || model === "auto" && this.anthropic) {
|
|
8022
|
+
if (!this.anthropic) throw new Error("Anthropic not available");
|
|
8023
|
+
const result = await this.anthropic.complete({
|
|
8024
|
+
systemPrompt: "You are an expert software developer. Generate clean, production-ready code.",
|
|
8025
|
+
userMessage: fullPrompt,
|
|
8026
|
+
maxTokens: 4096,
|
|
8027
|
+
model: "claude-4.5-opus-20260115"
|
|
8028
|
+
// Claude 4.5 Opus
|
|
8029
|
+
});
|
|
8030
|
+
response = result.content;
|
|
8031
|
+
tokensUsed = result.tokensUsed.total;
|
|
7648
8032
|
} else {
|
|
7649
8033
|
throw new Error("No AI model available");
|
|
7650
8034
|
}
|
|
@@ -7687,9 +8071,9 @@ var AIGenerator = class {
|
|
|
7687
8071
|
const parts = [];
|
|
7688
8072
|
const prdPaths = ["prd.md", "PRD.md", "docs/prd.md", "README.md"];
|
|
7689
8073
|
for (const prdPath of prdPaths) {
|
|
7690
|
-
const fullPath =
|
|
7691
|
-
if (
|
|
7692
|
-
const content =
|
|
8074
|
+
const fullPath = join15(this.rootDir, prdPath);
|
|
8075
|
+
if (existsSync16(fullPath)) {
|
|
8076
|
+
const content = readFileSync15(fullPath, "utf-8");
|
|
7693
8077
|
parts.push(`## ${prdPath}
|
|
7694
8078
|
|
|
7695
8079
|
${content}`);
|
|
@@ -7752,8 +8136,8 @@ Generate the files now:`;
|
|
|
7752
8136
|
const filePath = pathOrLang.replace(/\\/g, "/");
|
|
7753
8137
|
const ext = filePath.split(".").pop() || "";
|
|
7754
8138
|
const language = this.getLanguageFromExtension(ext);
|
|
7755
|
-
const fullPath =
|
|
7756
|
-
const isNew = !
|
|
8139
|
+
const fullPath = join15(this.rootDir, filePath);
|
|
8140
|
+
const isNew = !existsSync16(fullPath);
|
|
7757
8141
|
files.push({
|
|
7758
8142
|
path: filePath,
|
|
7759
8143
|
content: content.trim(),
|
|
@@ -7798,16 +8182,16 @@ Generate the files now:`;
|
|
|
7798
8182
|
console.warn(`Skipping file outside project root: ${file.path}`);
|
|
7799
8183
|
continue;
|
|
7800
8184
|
}
|
|
7801
|
-
const dir =
|
|
7802
|
-
if (!
|
|
7803
|
-
|
|
8185
|
+
const dir = dirname5(fullPath);
|
|
8186
|
+
if (!existsSync16(dir)) {
|
|
8187
|
+
mkdirSync10(dir, { recursive: true });
|
|
7804
8188
|
}
|
|
7805
8189
|
if (!file.isNew && options.backupBeforeOverwrite) {
|
|
7806
8190
|
const backupPath = `${fullPath}.bak`;
|
|
7807
|
-
const existingContent =
|
|
7808
|
-
|
|
8191
|
+
const existingContent = readFileSync15(fullPath, "utf-8");
|
|
8192
|
+
writeFileSync11(backupPath, existingContent);
|
|
7809
8193
|
}
|
|
7810
|
-
|
|
8194
|
+
writeFileSync11(fullPath, file.content, "utf-8");
|
|
7811
8195
|
written.push(file);
|
|
7812
8196
|
}
|
|
7813
8197
|
return written;
|
|
@@ -7851,6 +8235,7 @@ export {
|
|
|
7851
8235
|
Logger,
|
|
7852
8236
|
MODEL_SPECIFIC_ADDENDUM,
|
|
7853
8237
|
MetaSchema,
|
|
8238
|
+
NegativeContextManager,
|
|
7854
8239
|
OpenAIAdapter,
|
|
7855
8240
|
PluginManager,
|
|
7856
8241
|
PluginRegistry,
|
|
@@ -7860,6 +8245,7 @@ export {
|
|
|
7860
8245
|
RLMEngine,
|
|
7861
8246
|
RLM_BASE_SYSTEM_PROMPT,
|
|
7862
8247
|
ScopeManager,
|
|
8248
|
+
ShadowFileSystem,
|
|
7863
8249
|
StackConfigSchema,
|
|
7864
8250
|
SupportedLanguageSchema,
|
|
7865
8251
|
TeamSync,
|
|
@@ -7879,6 +8265,7 @@ export {
|
|
|
7879
8265
|
createGeminiClient,
|
|
7880
8266
|
createInitialUserMessage,
|
|
7881
8267
|
createLogger,
|
|
8268
|
+
createNegativeContextManager,
|
|
7882
8269
|
createObservationMessage,
|
|
7883
8270
|
createOpenAIAdapter,
|
|
7884
8271
|
createPluginManager,
|
|
@@ -7888,6 +8275,7 @@ export {
|
|
|
7888
8275
|
createSandbox,
|
|
7889
8276
|
createSandboxContext,
|
|
7890
8277
|
createScopeManager,
|
|
8278
|
+
createShadowFS,
|
|
7891
8279
|
createSubAgentResultMessage,
|
|
7892
8280
|
createTrainingDataCollector,
|
|
7893
8281
|
createWatchdog,
|