@aman_asmuei/aman-agent 0.32.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -30
- package/dist/index.js +634 -97
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,65 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// src/token-budget.ts
|
|
12
|
+
function estimateTokens(text3) {
|
|
13
|
+
return Math.round(text3.split(/\s+/).filter(Boolean).length * 1.3);
|
|
14
|
+
}
|
|
15
|
+
function buildBudgetedPrompt(components, maxTokens = 8e3) {
|
|
16
|
+
const included = [];
|
|
17
|
+
const truncated = [];
|
|
18
|
+
const parts = [];
|
|
19
|
+
let totalTokens = 0;
|
|
20
|
+
const sorted = [...components].sort((a, b) => {
|
|
21
|
+
const aPri = PRIORITIES.indexOf(a.name);
|
|
22
|
+
const bPri = PRIORITIES.indexOf(b.name);
|
|
23
|
+
return (aPri === -1 ? 99 : aPri) - (bPri === -1 ? 99 : bPri);
|
|
24
|
+
});
|
|
25
|
+
for (const comp of sorted) {
|
|
26
|
+
if (totalTokens + comp.tokens <= maxTokens) {
|
|
27
|
+
parts.push(comp.content);
|
|
28
|
+
included.push(comp.name);
|
|
29
|
+
totalTokens += comp.tokens;
|
|
30
|
+
} else {
|
|
31
|
+
const halfContent = comp.content.slice(0, Math.floor(comp.content.length / 2));
|
|
32
|
+
const halfTokens = estimateTokens(halfContent);
|
|
33
|
+
if (totalTokens + halfTokens <= maxTokens) {
|
|
34
|
+
parts.push(halfContent + "\n\n[... truncated for context budget ...]");
|
|
35
|
+
included.push(comp.name + " (partial)");
|
|
36
|
+
totalTokens += halfTokens;
|
|
37
|
+
} else {
|
|
38
|
+
truncated.push(comp.name);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
prompt: parts.join("\n\n---\n\n"),
|
|
44
|
+
included,
|
|
45
|
+
truncated,
|
|
46
|
+
totalTokens
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
var PRIORITIES;
|
|
50
|
+
var init_token_budget = __esm({
|
|
51
|
+
"src/token-budget.ts"() {
|
|
52
|
+
"use strict";
|
|
53
|
+
PRIORITIES = [
|
|
54
|
+
"identity",
|
|
55
|
+
// core.md — always include
|
|
56
|
+
"user",
|
|
57
|
+
// user.md — user profile, always include
|
|
58
|
+
"guardrails",
|
|
59
|
+
// rules.md — safety critical
|
|
60
|
+
"workflows",
|
|
61
|
+
// flow.md — behavioral
|
|
62
|
+
"tools",
|
|
63
|
+
// kit.md — capabilities
|
|
64
|
+
"skills"
|
|
65
|
+
// skills.md — can be truncated
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
11
70
|
// src/logger.ts
|
|
12
71
|
import fs5 from "fs";
|
|
13
72
|
import path5 from "path";
|
|
@@ -600,6 +659,473 @@ var init_delegate_remote = __esm({
|
|
|
600
659
|
}
|
|
601
660
|
});
|
|
602
661
|
|
|
662
|
+
// src/dev/stack-detector.ts
|
|
663
|
+
var stack_detector_exports = {};
|
|
664
|
+
__export(stack_detector_exports, {
|
|
665
|
+
scanStack: () => scanStack
|
|
666
|
+
});
|
|
667
|
+
import fs24 from "fs";
|
|
668
|
+
import path24 from "path";
|
|
669
|
+
function scanStack(projectPath) {
|
|
670
|
+
const languages = [];
|
|
671
|
+
const frameworks = [];
|
|
672
|
+
const databases = [];
|
|
673
|
+
const infra = [];
|
|
674
|
+
let isMonorepo = false;
|
|
675
|
+
let projectName = path24.basename(projectPath);
|
|
676
|
+
const goModPath = path24.join(projectPath, "go.mod");
|
|
677
|
+
if (fs24.existsSync(goModPath)) {
|
|
678
|
+
languages.push("go");
|
|
679
|
+
const content = fs24.readFileSync(goModPath, "utf-8");
|
|
680
|
+
const moduleMatch = content.match(/^module\s+(.+)$/m);
|
|
681
|
+
if (moduleMatch) {
|
|
682
|
+
const parts = moduleMatch[1].trim().split("/");
|
|
683
|
+
projectName = parts[parts.length - 1];
|
|
684
|
+
}
|
|
685
|
+
if (content.includes("gofiber/fiber")) frameworks.push("fiber");
|
|
686
|
+
if (content.includes("gin-gonic/gin")) frameworks.push("gin");
|
|
687
|
+
if (content.includes("go-chi/chi")) frameworks.push("chi");
|
|
688
|
+
if (content.includes("labstack/echo")) frameworks.push("echo");
|
|
689
|
+
}
|
|
690
|
+
const pkgPath = path24.join(projectPath, "package.json");
|
|
691
|
+
const hasTsConfig = fs24.existsSync(path24.join(projectPath, "tsconfig.json"));
|
|
692
|
+
if (fs24.existsSync(pkgPath)) {
|
|
693
|
+
try {
|
|
694
|
+
const pkg = JSON.parse(fs24.readFileSync(pkgPath, "utf-8"));
|
|
695
|
+
if (pkg.name) projectName = pkg.name;
|
|
696
|
+
if (hasTsConfig) {
|
|
697
|
+
languages.push("typescript");
|
|
698
|
+
} else {
|
|
699
|
+
languages.push("javascript");
|
|
700
|
+
}
|
|
701
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
702
|
+
for (const [dep, fwName] of Object.entries(FRAMEWORK_MAP)) {
|
|
703
|
+
if (allDeps?.[dep]) frameworks.push(fwName);
|
|
704
|
+
}
|
|
705
|
+
if (pkg.workspaces) isMonorepo = true;
|
|
706
|
+
} catch {
|
|
707
|
+
if (hasTsConfig) languages.push("typescript");
|
|
708
|
+
}
|
|
709
|
+
} else if (hasTsConfig) {
|
|
710
|
+
languages.push("typescript");
|
|
711
|
+
}
|
|
712
|
+
const cargoPath = path24.join(projectPath, "Cargo.toml");
|
|
713
|
+
if (fs24.existsSync(cargoPath)) {
|
|
714
|
+
languages.push("rust");
|
|
715
|
+
const content = fs24.readFileSync(cargoPath, "utf-8");
|
|
716
|
+
if (content.includes("[workspace]")) isMonorepo = true;
|
|
717
|
+
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
718
|
+
if (nameMatch && !isMonorepo) projectName = nameMatch[1];
|
|
719
|
+
}
|
|
720
|
+
const pyprojectPath = path24.join(projectPath, "pyproject.toml");
|
|
721
|
+
if (fs24.existsSync(pyprojectPath)) {
|
|
722
|
+
languages.push("python");
|
|
723
|
+
const content = fs24.readFileSync(pyprojectPath, "utf-8");
|
|
724
|
+
if (content.includes("django")) frameworks.push("django");
|
|
725
|
+
if (content.includes("fastapi")) frameworks.push("fastapi");
|
|
726
|
+
if (content.includes("flask")) frameworks.push("flask");
|
|
727
|
+
}
|
|
728
|
+
if (fs24.existsSync(path24.join(projectPath, "pubspec.yaml"))) {
|
|
729
|
+
languages.push("dart");
|
|
730
|
+
frameworks.push("flutter");
|
|
731
|
+
}
|
|
732
|
+
if (fs24.existsSync(path24.join(projectPath, "Dockerfile"))) {
|
|
733
|
+
infra.push("docker");
|
|
734
|
+
}
|
|
735
|
+
const composeNames = ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"];
|
|
736
|
+
for (const name of composeNames) {
|
|
737
|
+
const composePath = path24.join(projectPath, name);
|
|
738
|
+
if (fs24.existsSync(composePath)) {
|
|
739
|
+
if (!infra.includes("docker")) infra.push("docker");
|
|
740
|
+
const content = fs24.readFileSync(composePath, "utf-8");
|
|
741
|
+
for (const [pattern, dbName] of Object.entries(DB_IMAGE_MAP)) {
|
|
742
|
+
if (content.includes(pattern) && !databases.includes(dbName)) {
|
|
743
|
+
databases.push(dbName);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
if (fs24.existsSync(path24.join(projectPath, ".github", "workflows"))) {
|
|
750
|
+
infra.push("github-actions");
|
|
751
|
+
}
|
|
752
|
+
for (const dir of ["k3s", "k8s", "deploy"]) {
|
|
753
|
+
if (fs24.existsSync(path24.join(projectPath, dir))) {
|
|
754
|
+
infra.push("kubernetes");
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
if (fs24.existsSync(path24.join(projectPath, "Makefile"))) {
|
|
759
|
+
infra.push("make");
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
projectName,
|
|
763
|
+
languages,
|
|
764
|
+
frameworks,
|
|
765
|
+
databases,
|
|
766
|
+
infra,
|
|
767
|
+
isMonorepo,
|
|
768
|
+
detectedAt: Date.now()
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
var FRAMEWORK_MAP, DB_IMAGE_MAP;
|
|
772
|
+
var init_stack_detector = __esm({
|
|
773
|
+
"src/dev/stack-detector.ts"() {
|
|
774
|
+
"use strict";
|
|
775
|
+
FRAMEWORK_MAP = {
|
|
776
|
+
next: "next",
|
|
777
|
+
react: "react",
|
|
778
|
+
remix: "remix",
|
|
779
|
+
express: "express",
|
|
780
|
+
fastify: "fastify",
|
|
781
|
+
hono: "hono",
|
|
782
|
+
"@nestjs/core": "nestjs",
|
|
783
|
+
vue: "vue",
|
|
784
|
+
svelte: "svelte",
|
|
785
|
+
nuxt: "nuxt"
|
|
786
|
+
};
|
|
787
|
+
DB_IMAGE_MAP = {
|
|
788
|
+
postgres: "postgresql",
|
|
789
|
+
mysql: "mysql",
|
|
790
|
+
mariadb: "mariadb",
|
|
791
|
+
mongo: "mongodb",
|
|
792
|
+
redis: "redis",
|
|
793
|
+
timescaledb: "timescaledb"
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
// src/dev/context-builder.ts
|
|
799
|
+
import path25 from "path";
|
|
800
|
+
import os22 from "os";
|
|
801
|
+
import { createDatabase as createDatabase2, recall as recall2 } from "@aman_asmuei/amem-core";
|
|
802
|
+
import {
|
|
803
|
+
getIdentity as acoreGetIdentity2
|
|
804
|
+
} from "@aman_asmuei/acore-core";
|
|
805
|
+
import {
|
|
806
|
+
listRuleCategories as arulesListCategories2
|
|
807
|
+
} from "@aman_asmuei/arules-core";
|
|
808
|
+
function trimToTokenBudget(items, maxTokens) {
|
|
809
|
+
const result = [];
|
|
810
|
+
let total = 0;
|
|
811
|
+
for (const item of items) {
|
|
812
|
+
const tokens = estimateTokens(item);
|
|
813
|
+
if (total + tokens > maxTokens) break;
|
|
814
|
+
result.push(item);
|
|
815
|
+
total += tokens;
|
|
816
|
+
}
|
|
817
|
+
return result;
|
|
818
|
+
}
|
|
819
|
+
async function buildContext2(stack, opts) {
|
|
820
|
+
const conventions = [];
|
|
821
|
+
const decisions = [];
|
|
822
|
+
const corrections = [];
|
|
823
|
+
const preferences = [];
|
|
824
|
+
const rules = [];
|
|
825
|
+
let memoriesUsed = 0;
|
|
826
|
+
try {
|
|
827
|
+
const amemDir = process.env.AMEM_DIR ?? path25.join(os22.homedir(), ".amem");
|
|
828
|
+
const dbPath = process.env.AMEM_DB ?? path25.join(amemDir, "memory.db");
|
|
829
|
+
const db2 = createDatabase2(dbPath);
|
|
830
|
+
const query = [stack.projectName, ...stack.languages, ...stack.frameworks].join(" ");
|
|
831
|
+
const result = await recall2(db2, { query, limit: 20 });
|
|
832
|
+
for (const mem of result.memories) {
|
|
833
|
+
switch (mem.type) {
|
|
834
|
+
case "pattern":
|
|
835
|
+
conventions.push(mem.content);
|
|
836
|
+
break;
|
|
837
|
+
case "decision":
|
|
838
|
+
decisions.push(mem.content);
|
|
839
|
+
break;
|
|
840
|
+
case "correction":
|
|
841
|
+
corrections.push(mem.content);
|
|
842
|
+
break;
|
|
843
|
+
case "preference":
|
|
844
|
+
preferences.push(mem.content);
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
memoriesUsed++;
|
|
848
|
+
}
|
|
849
|
+
} catch {
|
|
850
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
const identity = await acoreGetIdentity2(AGENT_SCOPE2);
|
|
853
|
+
if (identity?.content) {
|
|
854
|
+
const lines = identity.content.split("\n").filter(
|
|
855
|
+
(l) => l.startsWith("- ") && (l.toLowerCase().includes("prefer") || l.toLowerCase().includes("style") || l.toLowerCase().includes("convention"))
|
|
856
|
+
);
|
|
857
|
+
for (const line of lines) {
|
|
858
|
+
const text3 = line.replace(/^-\s*/, "").trim();
|
|
859
|
+
if (text3 && !preferences.includes(text3)) preferences.push(text3);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
} catch {
|
|
863
|
+
}
|
|
864
|
+
try {
|
|
865
|
+
const categories = await arulesListCategories2(AGENT_SCOPE2);
|
|
866
|
+
for (const cat of categories) {
|
|
867
|
+
for (const ruleText of cat.rules) {
|
|
868
|
+
rules.push(ruleText);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
} catch {
|
|
872
|
+
}
|
|
873
|
+
if (opts?.smart && opts.llmClient) {
|
|
874
|
+
try {
|
|
875
|
+
const client = opts.llmClient;
|
|
876
|
+
const rawData = [
|
|
877
|
+
`Project: ${stack.projectName}`,
|
|
878
|
+
`Stack: ${stack.languages.join(", ")} + ${stack.frameworks.join(", ")}`,
|
|
879
|
+
`Databases: ${stack.databases.join(", ") || "none detected"}`,
|
|
880
|
+
"",
|
|
881
|
+
conventions.length > 0 ? `Conventions:
|
|
882
|
+
${conventions.map((c) => `- ${c}`).join("\n")}` : "",
|
|
883
|
+
decisions.length > 0 ? `Decisions:
|
|
884
|
+
${decisions.map((d) => `- ${d}`).join("\n")}` : "",
|
|
885
|
+
corrections.length > 0 ? `Corrections:
|
|
886
|
+
${corrections.map((c) => `- ${c}`).join("\n")}` : "",
|
|
887
|
+
preferences.length > 0 ? `Preferences:
|
|
888
|
+
${preferences.map((p5) => `- ${p5}`).join("\n")}` : "",
|
|
889
|
+
rules.length > 0 ? `Rules:
|
|
890
|
+
${rules.map((r) => `- ${r}`).join("\n")}` : ""
|
|
891
|
+
].filter(Boolean).join("\n\n");
|
|
892
|
+
const response = await client.chat(
|
|
893
|
+
"You are a developer context assembler. Given raw developer history, output a merged, deduplicated set of conventions and decisions as markdown bullet lists. Group by: Conventions, Decisions, Corrections, Preferences, Rules. Be specific, not generic. Max 3000 tokens.",
|
|
894
|
+
[{ role: "user", content: rawData }],
|
|
895
|
+
() => {
|
|
896
|
+
}
|
|
897
|
+
);
|
|
898
|
+
const text3 = typeof response.message.content === "string" ? response.message.content : response.message.content.map((b) => b.text ?? "").join("");
|
|
899
|
+
const extractSection = (sectionName) => {
|
|
900
|
+
const regex = new RegExp(`##?\\s*${sectionName}[\\s\\S]*?(?=##|$)`, "i");
|
|
901
|
+
const match = text3.match(regex);
|
|
902
|
+
if (!match) return [];
|
|
903
|
+
return match[0].split("\n").filter((l) => l.startsWith("- ")).map((l) => l.replace(/^-\s*/, "").trim());
|
|
904
|
+
};
|
|
905
|
+
const smartConventions = extractSection("Conventions");
|
|
906
|
+
const smartDecisions = extractSection("Decisions");
|
|
907
|
+
const smartCorrections = extractSection("Corrections");
|
|
908
|
+
const smartPreferences = extractSection("Preferences");
|
|
909
|
+
const smartRules = extractSection("Rules");
|
|
910
|
+
return {
|
|
911
|
+
stack,
|
|
912
|
+
conventions: trimToTokenBudget(smartConventions.length > 0 ? smartConventions : conventions, TOKEN_LIMITS.conventions),
|
|
913
|
+
decisions: trimToTokenBudget(smartDecisions.length > 0 ? smartDecisions : decisions, TOKEN_LIMITS.decisions),
|
|
914
|
+
corrections: trimToTokenBudget(smartCorrections.length > 0 ? smartCorrections : corrections, TOKEN_LIMITS.corrections),
|
|
915
|
+
preferences: trimToTokenBudget(smartPreferences.length > 0 ? smartPreferences : preferences, TOKEN_LIMITS.preferences),
|
|
916
|
+
rules: trimToTokenBudget(smartRules.length > 0 ? smartRules : rules, TOKEN_LIMITS.rules),
|
|
917
|
+
metadata: {
|
|
918
|
+
generatedAt: Date.now(),
|
|
919
|
+
mode: "smart",
|
|
920
|
+
memoriesUsed
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
} catch {
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
return {
|
|
927
|
+
stack,
|
|
928
|
+
conventions: trimToTokenBudget(conventions, TOKEN_LIMITS.conventions),
|
|
929
|
+
decisions: trimToTokenBudget(decisions, TOKEN_LIMITS.decisions),
|
|
930
|
+
corrections: trimToTokenBudget(corrections, TOKEN_LIMITS.corrections),
|
|
931
|
+
preferences: trimToTokenBudget(preferences, TOKEN_LIMITS.preferences),
|
|
932
|
+
rules: trimToTokenBudget(rules, TOKEN_LIMITS.rules),
|
|
933
|
+
metadata: {
|
|
934
|
+
generatedAt: Date.now(),
|
|
935
|
+
mode: "template",
|
|
936
|
+
memoriesUsed
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
var AGENT_SCOPE2, TOKEN_LIMITS;
|
|
941
|
+
var init_context_builder = __esm({
|
|
942
|
+
"src/dev/context-builder.ts"() {
|
|
943
|
+
"use strict";
|
|
944
|
+
init_token_budget();
|
|
945
|
+
AGENT_SCOPE2 = process.env.AMAN_AGENT_SCOPE ?? "dev:agent";
|
|
946
|
+
TOKEN_LIMITS = {
|
|
947
|
+
conventions: 1500,
|
|
948
|
+
decisions: 1200,
|
|
949
|
+
corrections: 800,
|
|
950
|
+
preferences: 500,
|
|
951
|
+
rules: 800
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// src/dev/claude-md-writer.ts
|
|
957
|
+
import fs25 from "fs";
|
|
958
|
+
import path26 from "path";
|
|
959
|
+
function formatStack(stack) {
|
|
960
|
+
const parts = [];
|
|
961
|
+
const goFrameworks = ["fiber", "gin", "chi", "echo"];
|
|
962
|
+
const jsFrameworks = ["next", "react", "remix", "express", "fastify", "hono", "nestjs", "vue", "svelte", "nuxt"];
|
|
963
|
+
const pyFrameworks = ["django", "fastapi", "flask"];
|
|
964
|
+
for (const lang of stack.languages) {
|
|
965
|
+
const fw = stack.frameworks.filter((f) => {
|
|
966
|
+
if (lang === "go" && goFrameworks.includes(f)) return true;
|
|
967
|
+
if ((lang === "typescript" || lang === "javascript") && jsFrameworks.includes(f)) return true;
|
|
968
|
+
if (lang === "python" && pyFrameworks.includes(f)) return true;
|
|
969
|
+
if (lang === "dart" && f === "flutter") return true;
|
|
970
|
+
return false;
|
|
971
|
+
});
|
|
972
|
+
const name = lang.charAt(0).toUpperCase() + lang.slice(1);
|
|
973
|
+
if (fw.length > 0) {
|
|
974
|
+
parts.push(`${name} (${fw.map((f) => f.charAt(0).toUpperCase() + f.slice(1)).join(", ")})`);
|
|
975
|
+
} else {
|
|
976
|
+
parts.push(name);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
if (stack.databases.length > 0) {
|
|
980
|
+
parts.push(...stack.databases.map((d) => d.charAt(0).toUpperCase() + d.slice(1)));
|
|
981
|
+
}
|
|
982
|
+
return parts.join(" + ");
|
|
983
|
+
}
|
|
984
|
+
function renderToString(ctx) {
|
|
985
|
+
const lines = [];
|
|
986
|
+
const ts = new Date(ctx.metadata.generatedAt).toISOString();
|
|
987
|
+
lines.push(`# Project: ${ctx.stack.projectName}`);
|
|
988
|
+
lines.push(`<!-- aman-agent:dev generated=${ts} memories=${ctx.metadata.memoriesUsed} mode=${ctx.metadata.mode} -->`);
|
|
989
|
+
lines.push("");
|
|
990
|
+
const stackLine = formatStack(ctx.stack);
|
|
991
|
+
if (stackLine || ctx.stack.infra.length > 0) {
|
|
992
|
+
lines.push("## Stack");
|
|
993
|
+
if (stackLine) lines.push(`- ${stackLine}`);
|
|
994
|
+
if (ctx.stack.infra.length > 0) {
|
|
995
|
+
lines.push(`- Infra: ${ctx.stack.infra.join(", ")}`);
|
|
996
|
+
}
|
|
997
|
+
if (ctx.stack.isMonorepo) {
|
|
998
|
+
lines.push("- Monorepo");
|
|
999
|
+
}
|
|
1000
|
+
lines.push("");
|
|
1001
|
+
}
|
|
1002
|
+
if (ctx.conventions.length > 0) {
|
|
1003
|
+
lines.push("## Conventions");
|
|
1004
|
+
for (const c of ctx.conventions) lines.push(`- ${c}`);
|
|
1005
|
+
lines.push("");
|
|
1006
|
+
}
|
|
1007
|
+
if (ctx.decisions.length > 0) {
|
|
1008
|
+
lines.push("## Past Decisions");
|
|
1009
|
+
for (const d of ctx.decisions) lines.push(`- ${d}`);
|
|
1010
|
+
lines.push("");
|
|
1011
|
+
}
|
|
1012
|
+
if (ctx.corrections.length > 0) {
|
|
1013
|
+
lines.push("## Corrections");
|
|
1014
|
+
for (const c of ctx.corrections) lines.push(`- ${c}`);
|
|
1015
|
+
lines.push("");
|
|
1016
|
+
}
|
|
1017
|
+
if (ctx.preferences.length > 0) {
|
|
1018
|
+
lines.push("## Developer Preferences");
|
|
1019
|
+
for (const p5 of ctx.preferences) lines.push(`- ${p5}`);
|
|
1020
|
+
lines.push("");
|
|
1021
|
+
}
|
|
1022
|
+
if (ctx.rules.length > 0) {
|
|
1023
|
+
lines.push("## Rules");
|
|
1024
|
+
for (const r of ctx.rules) lines.push(`- ${r}`);
|
|
1025
|
+
lines.push("");
|
|
1026
|
+
}
|
|
1027
|
+
return lines.join("\n");
|
|
1028
|
+
}
|
|
1029
|
+
function parseMarker(content) {
|
|
1030
|
+
const match = content.match(
|
|
1031
|
+
/<!--\s*aman-agent:dev\s+generated=(\S+)\s+memories=(\d+)\s+mode=(\S+)\s*-->/
|
|
1032
|
+
);
|
|
1033
|
+
if (!match) return null;
|
|
1034
|
+
return {
|
|
1035
|
+
generatedAt: new Date(match[1]),
|
|
1036
|
+
memories: parseInt(match[2], 10),
|
|
1037
|
+
mode: match[3]
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
function checkStaleness(projectPath) {
|
|
1041
|
+
const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
|
|
1042
|
+
if (!fs25.existsSync(claudeMdPath)) {
|
|
1043
|
+
return { status: "missing" };
|
|
1044
|
+
}
|
|
1045
|
+
const content = fs25.readFileSync(claudeMdPath, "utf-8");
|
|
1046
|
+
const marker = parseMarker(content);
|
|
1047
|
+
if (!marker) {
|
|
1048
|
+
return { status: "no-marker" };
|
|
1049
|
+
}
|
|
1050
|
+
return { status: "fresh", generatedAt: marker.generatedAt };
|
|
1051
|
+
}
|
|
1052
|
+
function writeClaudeMd(ctx, projectPath) {
|
|
1053
|
+
const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
|
|
1054
|
+
let backedUp = false;
|
|
1055
|
+
if (fs25.existsSync(claudeMdPath)) {
|
|
1056
|
+
const content = fs25.readFileSync(claudeMdPath, "utf-8");
|
|
1057
|
+
const marker = parseMarker(content);
|
|
1058
|
+
if (!marker) {
|
|
1059
|
+
fs25.copyFileSync(claudeMdPath, `${claudeMdPath}.bak`);
|
|
1060
|
+
backedUp = true;
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
const md = renderToString(ctx);
|
|
1064
|
+
fs25.writeFileSync(claudeMdPath, md, "utf-8");
|
|
1065
|
+
return { written: true, backedUp, path: claudeMdPath };
|
|
1066
|
+
}
|
|
1067
|
+
var init_claude_md_writer = __esm({
|
|
1068
|
+
"src/dev/claude-md-writer.ts"() {
|
|
1069
|
+
"use strict";
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
// src/dev/dev-command.ts
|
|
1074
|
+
var dev_command_exports = {};
|
|
1075
|
+
__export(dev_command_exports, {
|
|
1076
|
+
runDev: () => runDev
|
|
1077
|
+
});
|
|
1078
|
+
import fs26 from "fs";
|
|
1079
|
+
import path27 from "path";
|
|
1080
|
+
function ensureGitignore(projectPath) {
|
|
1081
|
+
const gitignorePath = path27.join(projectPath, ".gitignore");
|
|
1082
|
+
if (!fs26.existsSync(gitignorePath)) return;
|
|
1083
|
+
const content = fs26.readFileSync(gitignorePath, "utf-8");
|
|
1084
|
+
if (content.includes("CLAUDE.md")) return;
|
|
1085
|
+
fs26.appendFileSync(gitignorePath, "\n# Generated by aman-agent dev\nCLAUDE.md\n");
|
|
1086
|
+
}
|
|
1087
|
+
async function runDev(projectPath, flags = {}, precomputedStack) {
|
|
1088
|
+
const resolved = path27.resolve(projectPath);
|
|
1089
|
+
if (!fs26.existsSync(resolved)) {
|
|
1090
|
+
return { success: false, generated: false, error: `Directory not found: ${resolved}` };
|
|
1091
|
+
}
|
|
1092
|
+
const stack = precomputedStack ?? scanStack(resolved);
|
|
1093
|
+
if (flags.diff) {
|
|
1094
|
+
const ctx2 = await buildContext2(stack, { smart: flags.smart });
|
|
1095
|
+
const newContent = renderToString(ctx2);
|
|
1096
|
+
const existingPath = path27.join(resolved, "CLAUDE.md");
|
|
1097
|
+
const existing = fs26.existsSync(existingPath) ? fs26.readFileSync(existingPath, "utf-8") : "";
|
|
1098
|
+
return {
|
|
1099
|
+
success: true,
|
|
1100
|
+
generated: false,
|
|
1101
|
+
diff: existing === newContent ? "(no changes)" : newContent,
|
|
1102
|
+
context: ctx2
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
if (!flags.force) {
|
|
1106
|
+
const staleness = checkStaleness(resolved);
|
|
1107
|
+
if (staleness.status === "fresh") {
|
|
1108
|
+
return { success: true, generated: false, skippedReason: "fresh" };
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
const ctx = await buildContext2(stack, { smart: flags.smart });
|
|
1112
|
+
const writeResult = writeClaudeMd(ctx, resolved);
|
|
1113
|
+
ensureGitignore(resolved);
|
|
1114
|
+
return {
|
|
1115
|
+
success: true,
|
|
1116
|
+
generated: writeResult.written,
|
|
1117
|
+
context: ctx
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
var init_dev_command = __esm({
|
|
1121
|
+
"src/dev/dev-command.ts"() {
|
|
1122
|
+
"use strict";
|
|
1123
|
+
init_stack_detector();
|
|
1124
|
+
init_context_builder();
|
|
1125
|
+
init_claude_md_writer();
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
|
|
603
1129
|
// src/index.ts
|
|
604
1130
|
import { Command } from "commander";
|
|
605
1131
|
import * as p4 from "@clack/prompts";
|
|
@@ -696,63 +1222,11 @@ function migrateIfNeeded() {
|
|
|
696
1222
|
}
|
|
697
1223
|
|
|
698
1224
|
// src/prompt.ts
|
|
1225
|
+
init_token_budget();
|
|
699
1226
|
import fs4 from "fs";
|
|
700
1227
|
import path4 from "path";
|
|
701
1228
|
import os3 from "os";
|
|
702
1229
|
|
|
703
|
-
// src/token-budget.ts
|
|
704
|
-
function estimateTokens(text3) {
|
|
705
|
-
return Math.round(text3.split(/\s+/).filter(Boolean).length * 1.3);
|
|
706
|
-
}
|
|
707
|
-
var PRIORITIES = [
|
|
708
|
-
"identity",
|
|
709
|
-
// core.md — always include
|
|
710
|
-
"user",
|
|
711
|
-
// user.md — user profile, always include
|
|
712
|
-
"guardrails",
|
|
713
|
-
// rules.md — safety critical
|
|
714
|
-
"workflows",
|
|
715
|
-
// flow.md — behavioral
|
|
716
|
-
"tools",
|
|
717
|
-
// kit.md — capabilities
|
|
718
|
-
"skills"
|
|
719
|
-
// skills.md — can be truncated
|
|
720
|
-
];
|
|
721
|
-
function buildBudgetedPrompt(components, maxTokens = 8e3) {
|
|
722
|
-
const included = [];
|
|
723
|
-
const truncated = [];
|
|
724
|
-
const parts = [];
|
|
725
|
-
let totalTokens = 0;
|
|
726
|
-
const sorted = [...components].sort((a, b) => {
|
|
727
|
-
const aPri = PRIORITIES.indexOf(a.name);
|
|
728
|
-
const bPri = PRIORITIES.indexOf(b.name);
|
|
729
|
-
return (aPri === -1 ? 99 : aPri) - (bPri === -1 ? 99 : bPri);
|
|
730
|
-
});
|
|
731
|
-
for (const comp of sorted) {
|
|
732
|
-
if (totalTokens + comp.tokens <= maxTokens) {
|
|
733
|
-
parts.push(comp.content);
|
|
734
|
-
included.push(comp.name);
|
|
735
|
-
totalTokens += comp.tokens;
|
|
736
|
-
} else {
|
|
737
|
-
const halfContent = comp.content.slice(0, Math.floor(comp.content.length / 2));
|
|
738
|
-
const halfTokens = estimateTokens(halfContent);
|
|
739
|
-
if (totalTokens + halfTokens <= maxTokens) {
|
|
740
|
-
parts.push(halfContent + "\n\n[... truncated for context budget ...]");
|
|
741
|
-
included.push(comp.name + " (partial)");
|
|
742
|
-
totalTokens += halfTokens;
|
|
743
|
-
} else {
|
|
744
|
-
truncated.push(comp.name);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
return {
|
|
749
|
-
prompt: parts.join("\n\n---\n\n"),
|
|
750
|
-
included,
|
|
751
|
-
truncated,
|
|
752
|
-
totalTokens
|
|
753
|
-
};
|
|
754
|
-
}
|
|
755
|
-
|
|
756
1230
|
// src/user-identity.ts
|
|
757
1231
|
import fs3 from "fs";
|
|
758
1232
|
import path3 from "path";
|
|
@@ -4574,12 +5048,12 @@ You are being delegated a specific task by the primary agent. Complete this task
|
|
|
4574
5048
|
</delegation>`;
|
|
4575
5049
|
let finalDelegationPrompt = delegationPrompt;
|
|
4576
5050
|
try {
|
|
4577
|
-
const
|
|
4578
|
-
if (
|
|
5051
|
+
const recall3 = await memoryRecall(task, { limit: 3, compact: true });
|
|
5052
|
+
if (recall3.total > 0) {
|
|
4579
5053
|
finalDelegationPrompt += `
|
|
4580
5054
|
|
|
4581
5055
|
<relevant-memories>
|
|
4582
|
-
${
|
|
5056
|
+
${recall3.text}
|
|
4583
5057
|
</relevant-memories>`;
|
|
4584
5058
|
}
|
|
4585
5059
|
} catch {
|
|
@@ -6604,7 +7078,7 @@ function handleReset(action) {
|
|
|
6604
7078
|
function handleUpdate() {
|
|
6605
7079
|
try {
|
|
6606
7080
|
const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
|
|
6607
|
-
const local = true ? "0.
|
|
7081
|
+
const local = true ? "0.33.0" : "unknown";
|
|
6608
7082
|
if (current === local) {
|
|
6609
7083
|
return { handled: true, output: `${pc6.green("Up to date")} \u2014 v${local}` };
|
|
6610
7084
|
}
|
|
@@ -8381,6 +8855,9 @@ Assistant: ${assistantResponse.slice(0, 2e3)}`;
|
|
|
8381
8855
|
}
|
|
8382
8856
|
}
|
|
8383
8857
|
|
|
8858
|
+
// src/agent.ts
|
|
8859
|
+
init_token_budget();
|
|
8860
|
+
|
|
8384
8861
|
// src/errors.ts
|
|
8385
8862
|
var ERROR_MAPPINGS = [
|
|
8386
8863
|
{ pattern: /rate.?limit|429/i, message: "Rate limited. I'll retry automatically." },
|
|
@@ -8988,10 +9465,10 @@ ${converted}
|
|
|
8988
9465
|
let augmentedSystemPrompt = activeSystemPrompt;
|
|
8989
9466
|
let memoryTokens = 0;
|
|
8990
9467
|
{
|
|
8991
|
-
const
|
|
8992
|
-
if (
|
|
8993
|
-
augmentedSystemPrompt = activeSystemPrompt +
|
|
8994
|
-
memoryTokens =
|
|
9468
|
+
const recall3 = await recallForMessage(input);
|
|
9469
|
+
if (recall3) {
|
|
9470
|
+
augmentedSystemPrompt = activeSystemPrompt + recall3.text;
|
|
9471
|
+
memoryTokens = recall3.tokenEstimate;
|
|
8995
9472
|
}
|
|
8996
9473
|
}
|
|
8997
9474
|
const userTurnCount = messages.filter((m) => m.role === "user").length;
|
|
@@ -9370,8 +9847,8 @@ async function saveConversationToMemory(messages, sessionId) {
|
|
|
9370
9847
|
}
|
|
9371
9848
|
|
|
9372
9849
|
// src/index.ts
|
|
9373
|
-
import
|
|
9374
|
-
import
|
|
9850
|
+
import fs27 from "fs";
|
|
9851
|
+
import path28 from "path";
|
|
9375
9852
|
|
|
9376
9853
|
// src/presets.ts
|
|
9377
9854
|
var PRESETS = {
|
|
@@ -9585,7 +10062,7 @@ var Inbox = class {
|
|
|
9585
10062
|
// package.json
|
|
9586
10063
|
var package_default = {
|
|
9587
10064
|
name: "@aman_asmuei/aman-agent",
|
|
9588
|
-
version: "0.
|
|
10065
|
+
version: "0.33.0",
|
|
9589
10066
|
description: "Your AI companion, running locally \u2014 powered by the aman ecosystem",
|
|
9590
10067
|
type: "module",
|
|
9591
10068
|
engines: {
|
|
@@ -9878,9 +10355,9 @@ async function runServe(opts) {
|
|
|
9878
10355
|
|
|
9879
10356
|
// src/index.ts
|
|
9880
10357
|
async function autoDetectConfig() {
|
|
9881
|
-
const reconfigMarker =
|
|
9882
|
-
if (
|
|
9883
|
-
|
|
10358
|
+
const reconfigMarker = path28.join(homeDir(), ".reconfig");
|
|
10359
|
+
if (fs27.existsSync(reconfigMarker)) {
|
|
10360
|
+
fs27.unlinkSync(reconfigMarker);
|
|
9884
10361
|
return null;
|
|
9885
10362
|
}
|
|
9886
10363
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
@@ -9909,10 +10386,10 @@ async function autoDetectConfig() {
|
|
|
9909
10386
|
return null;
|
|
9910
10387
|
}
|
|
9911
10388
|
function bootstrapEcosystem() {
|
|
9912
|
-
const corePath =
|
|
9913
|
-
if (
|
|
9914
|
-
|
|
9915
|
-
|
|
10389
|
+
const corePath = path28.join(identityDir(), "core.md");
|
|
10390
|
+
if (fs27.existsSync(corePath)) return false;
|
|
10391
|
+
fs27.mkdirSync(identityDir(), { recursive: true });
|
|
10392
|
+
fs27.writeFileSync(corePath, [
|
|
9916
10393
|
"# Aman",
|
|
9917
10394
|
"",
|
|
9918
10395
|
"## Personality",
|
|
@@ -9924,10 +10401,10 @@ function bootstrapEcosystem() {
|
|
|
9924
10401
|
"## Session",
|
|
9925
10402
|
"_New companion \u2014 no prior sessions._"
|
|
9926
10403
|
].join("\n"), "utf-8");
|
|
9927
|
-
const rulesPath =
|
|
9928
|
-
if (!
|
|
9929
|
-
|
|
9930
|
-
|
|
10404
|
+
const rulesPath = path28.join(rulesDir(), "rules.md");
|
|
10405
|
+
if (!fs27.existsSync(rulesPath)) {
|
|
10406
|
+
fs27.mkdirSync(rulesDir(), { recursive: true });
|
|
10407
|
+
fs27.writeFileSync(rulesPath, [
|
|
9931
10408
|
"# Guardrails",
|
|
9932
10409
|
"",
|
|
9933
10410
|
"## safety",
|
|
@@ -9939,20 +10416,20 @@ function bootstrapEcosystem() {
|
|
|
9939
10416
|
"- Respect the user's preferences stored in memory"
|
|
9940
10417
|
].join("\n"), "utf-8");
|
|
9941
10418
|
}
|
|
9942
|
-
const flowPath =
|
|
9943
|
-
if (!
|
|
9944
|
-
|
|
9945
|
-
|
|
10419
|
+
const flowPath = path28.join(workflowsDir(), "flow.md");
|
|
10420
|
+
if (!fs27.existsSync(flowPath)) {
|
|
10421
|
+
fs27.mkdirSync(workflowsDir(), { recursive: true });
|
|
10422
|
+
fs27.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
|
|
9946
10423
|
}
|
|
9947
|
-
const skillPath =
|
|
9948
|
-
if (!
|
|
9949
|
-
|
|
9950
|
-
|
|
10424
|
+
const skillPath = path28.join(skillsDir(), "skills.md");
|
|
10425
|
+
if (!fs27.existsSync(skillPath)) {
|
|
10426
|
+
fs27.mkdirSync(skillsDir(), { recursive: true });
|
|
10427
|
+
fs27.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
|
|
9951
10428
|
}
|
|
9952
10429
|
return true;
|
|
9953
10430
|
}
|
|
9954
10431
|
var program = new Command();
|
|
9955
|
-
program.name("aman-agent").description("Your AI companion, running locally").version("0.
|
|
10432
|
+
program.name("aman-agent").description("Your AI companion, running locally").version("0.33.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
|
|
9956
10433
|
p4.intro(pc9.bold("aman agent") + pc9.dim(" \u2014 your AI companion"));
|
|
9957
10434
|
let config = loadConfig();
|
|
9958
10435
|
if (!config) {
|
|
@@ -10307,18 +10784,18 @@ program.command("init").description("Set up your AI companion with a guided wiza
|
|
|
10307
10784
|
});
|
|
10308
10785
|
if (p4.isCancel(preset)) process.exit(0);
|
|
10309
10786
|
const result = applyPreset(preset, name || "Aman");
|
|
10310
|
-
|
|
10311
|
-
|
|
10787
|
+
fs27.mkdirSync(identityDir(), { recursive: true });
|
|
10788
|
+
fs27.writeFileSync(path28.join(identityDir(), "core.md"), result.coreMd, "utf-8");
|
|
10312
10789
|
p4.log.success(`Identity created \u2014 ${PRESETS[preset].identity.personality.split(".")[0].toLowerCase()}`);
|
|
10313
10790
|
if (result.rulesMd) {
|
|
10314
|
-
|
|
10315
|
-
|
|
10791
|
+
fs27.mkdirSync(rulesDir(), { recursive: true });
|
|
10792
|
+
fs27.writeFileSync(path28.join(rulesDir(), "rules.md"), result.rulesMd, "utf-8");
|
|
10316
10793
|
const ruleCount = (result.rulesMd.match(/^- /gm) || []).length;
|
|
10317
10794
|
p4.log.success(`${ruleCount} rules set`);
|
|
10318
10795
|
}
|
|
10319
10796
|
if (result.flowMd) {
|
|
10320
|
-
|
|
10321
|
-
|
|
10797
|
+
fs27.mkdirSync(workflowsDir(), { recursive: true });
|
|
10798
|
+
fs27.writeFileSync(path28.join(workflowsDir(), "flow.md"), result.flowMd, "utf-8");
|
|
10322
10799
|
const wfCount = (result.flowMd.match(/^## /gm) || []).length;
|
|
10323
10800
|
p4.log.success(`${wfCount} workflow${wfCount > 1 ? "s" : ""} added`);
|
|
10324
10801
|
}
|
|
@@ -10347,18 +10824,78 @@ program.command("serve").description("Run aman-agent as a local MCP server other
|
|
|
10347
10824
|
process.exit(1);
|
|
10348
10825
|
}
|
|
10349
10826
|
});
|
|
10827
|
+
program.command("dev [path]").description("Set up project context and start Claude Code").option("--smart", "Use LLM to generate CLAUDE.md").option("--no-launch", "Generate CLAUDE.md only, don't start claude").option("--force", "Regenerate even if CLAUDE.md is fresh").option("--diff", "Show what would change without writing").action(async (projectPath, opts) => {
|
|
10828
|
+
const { runDev: runDev2 } = await Promise.resolve().then(() => (init_dev_command(), dev_command_exports));
|
|
10829
|
+
const { scanStack: scanStack2 } = await Promise.resolve().then(() => (init_stack_detector(), stack_detector_exports));
|
|
10830
|
+
const targetPath = projectPath ?? process.cwd();
|
|
10831
|
+
const stack = scanStack2(targetPath);
|
|
10832
|
+
const stackParts = stack.languages.map((l) => l.charAt(0).toUpperCase() + l.slice(1));
|
|
10833
|
+
if (stack.frameworks.length > 0) {
|
|
10834
|
+
stackParts.push(`(${stack.frameworks.map((f) => f.charAt(0).toUpperCase() + f.slice(1)).join(", ")})`);
|
|
10835
|
+
}
|
|
10836
|
+
if (stack.databases.length > 0) {
|
|
10837
|
+
stackParts.push(...stack.databases.map((d) => d.charAt(0).toUpperCase() + d.slice(1)));
|
|
10838
|
+
}
|
|
10839
|
+
if (stack.infra.length > 0) {
|
|
10840
|
+
stackParts.push(...stack.infra.map((i) => i.charAt(0).toUpperCase() + i.slice(1)));
|
|
10841
|
+
}
|
|
10842
|
+
if (stack.languages.length > 0) {
|
|
10843
|
+
console.log(`
|
|
10844
|
+
${pc9.cyan("Detected:")} ${stackParts.join(" + ")}`);
|
|
10845
|
+
} else {
|
|
10846
|
+
console.log(`
|
|
10847
|
+
${pc9.dim("No stack detected \u2014 generating minimal CLAUDE.md")}`);
|
|
10848
|
+
}
|
|
10849
|
+
const result = await runDev2(targetPath, {
|
|
10850
|
+
smart: opts.smart,
|
|
10851
|
+
noLaunch: opts.launch === false,
|
|
10852
|
+
force: opts.force,
|
|
10853
|
+
diff: opts.diff
|
|
10854
|
+
}, stack);
|
|
10855
|
+
if (!result.success) {
|
|
10856
|
+
console.error(` ${pc9.red("Error:")} ${result.error}`);
|
|
10857
|
+
process.exit(1);
|
|
10858
|
+
}
|
|
10859
|
+
if (result.diff) {
|
|
10860
|
+
console.log(`
|
|
10861
|
+
${result.diff}`);
|
|
10862
|
+
return;
|
|
10863
|
+
}
|
|
10864
|
+
if (result.generated) {
|
|
10865
|
+
const mode = opts.smart ? "smart" : "template";
|
|
10866
|
+
const memCount = result.context?.metadata.memoriesUsed ?? 0;
|
|
10867
|
+
console.log(` ${pc9.cyan("Recalled:")} ${memCount} memories`);
|
|
10868
|
+
console.log(` ${pc9.green("\u2713")} CLAUDE.md written (${mode} mode)
|
|
10869
|
+
`);
|
|
10870
|
+
} else if (result.skippedReason === "fresh") {
|
|
10871
|
+
console.log(` ${pc9.green("\u2713")} CLAUDE.md is up to date
|
|
10872
|
+
`);
|
|
10873
|
+
}
|
|
10874
|
+
if (opts.launch !== false && !opts.diff) {
|
|
10875
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
10876
|
+
try {
|
|
10877
|
+
execFileSync4("which", ["claude"], { stdio: "ignore" });
|
|
10878
|
+
} catch {
|
|
10879
|
+
console.log(` ${pc9.yellow("Claude Code not found.")} Install: npm install -g @anthropic-ai/claude-code`);
|
|
10880
|
+
process.exit(1);
|
|
10881
|
+
}
|
|
10882
|
+
console.log(` ${pc9.cyan("Launching Claude Code...")}
|
|
10883
|
+
`);
|
|
10884
|
+
execFileSync4("claude", [], { cwd: targetPath, stdio: "inherit" });
|
|
10885
|
+
}
|
|
10886
|
+
});
|
|
10350
10887
|
program.command("setup").description("Run the full configuration wizard (provider, identity, presets)").action(async () => {
|
|
10351
10888
|
p4.intro(pc9.bold("aman agent setup") + pc9.dim(" \u2014 full configuration wizard"));
|
|
10352
|
-
const reconfigPath =
|
|
10353
|
-
|
|
10354
|
-
|
|
10889
|
+
const reconfigPath = path28.join(homeDir(), ".reconfig");
|
|
10890
|
+
fs27.mkdirSync(homeDir(), { recursive: true });
|
|
10891
|
+
fs27.writeFileSync(reconfigPath, "", "utf-8");
|
|
10355
10892
|
p4.log.info("Configuration reset. Restart aman-agent to complete setup.");
|
|
10356
10893
|
});
|
|
10357
10894
|
program.command("update").description("Update aman-agent to the latest version").action(async () => {
|
|
10358
10895
|
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
10359
|
-
const isVendored = process.execPath.includes(
|
|
10896
|
+
const isVendored = process.execPath.includes(path28.join(".aman-agent", "node"));
|
|
10360
10897
|
if (isVendored) {
|
|
10361
|
-
const npmPath =
|
|
10898
|
+
const npmPath = path28.join(homeDir(), "node", "bin", "npm");
|
|
10362
10899
|
console.log("Updating aman-agent...");
|
|
10363
10900
|
try {
|
|
10364
10901
|
execFileSync4(npmPath, ["install", "-g", "@aman_asmuei/aman-agent@latest"], {
|
|
@@ -10386,7 +10923,7 @@ program.command("update").description("Update aman-agent to the latest version")
|
|
|
10386
10923
|
program.command("uninstall").description("Remove aman-agent and all its data").action(async () => {
|
|
10387
10924
|
const home2 = homeDir();
|
|
10388
10925
|
if (!process.stdin.isTTY) {
|
|
10389
|
-
|
|
10926
|
+
fs27.rmSync(home2, { recursive: true, force: true });
|
|
10390
10927
|
console.log("\u2713 Removed " + home2);
|
|
10391
10928
|
return;
|
|
10392
10929
|
}
|
|
@@ -10397,7 +10934,7 @@ program.command("uninstall").description("Remove aman-agent and all its data").a
|
|
|
10397
10934
|
console.log("Cancelled.");
|
|
10398
10935
|
return;
|
|
10399
10936
|
}
|
|
10400
|
-
|
|
10937
|
+
fs27.rmSync(home2, { recursive: true, force: true });
|
|
10401
10938
|
console.log("\u2713 Removed " + home2);
|
|
10402
10939
|
console.log("");
|
|
10403
10940
|
console.log("To complete uninstall, remove the PATH line from your shell config:");
|