@aman_asmuei/aman-agent 0.32.0 → 0.33.1
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 +637 -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,476 @@ 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
|
+
if (typeof item !== "string" || !item) continue;
|
|
813
|
+
const tokens = estimateTokens(item);
|
|
814
|
+
if (total + tokens > maxTokens) break;
|
|
815
|
+
result.push(item);
|
|
816
|
+
total += tokens;
|
|
817
|
+
}
|
|
818
|
+
return result;
|
|
819
|
+
}
|
|
820
|
+
async function buildContext2(stack, opts) {
|
|
821
|
+
const conventions = [];
|
|
822
|
+
const decisions = [];
|
|
823
|
+
const corrections = [];
|
|
824
|
+
const preferences = [];
|
|
825
|
+
const rules = [];
|
|
826
|
+
let memoriesUsed = 0;
|
|
827
|
+
try {
|
|
828
|
+
const amemDir = process.env.AMEM_DIR ?? path25.join(os22.homedir(), ".amem");
|
|
829
|
+
const dbPath = process.env.AMEM_DB ?? path25.join(amemDir, "memory.db");
|
|
830
|
+
const db2 = createDatabase2(dbPath);
|
|
831
|
+
const query = [stack.projectName, ...stack.languages, ...stack.frameworks].join(" ");
|
|
832
|
+
const result = await recall2(db2, { query, limit: 20 });
|
|
833
|
+
for (const mem of result.memories) {
|
|
834
|
+
const content = mem.content;
|
|
835
|
+
if (typeof content !== "string" || !content) continue;
|
|
836
|
+
switch (mem.type) {
|
|
837
|
+
case "pattern":
|
|
838
|
+
conventions.push(content);
|
|
839
|
+
break;
|
|
840
|
+
case "decision":
|
|
841
|
+
decisions.push(content);
|
|
842
|
+
break;
|
|
843
|
+
case "correction":
|
|
844
|
+
corrections.push(content);
|
|
845
|
+
break;
|
|
846
|
+
case "preference":
|
|
847
|
+
preferences.push(content);
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
memoriesUsed++;
|
|
851
|
+
}
|
|
852
|
+
} catch {
|
|
853
|
+
}
|
|
854
|
+
try {
|
|
855
|
+
const identity = await acoreGetIdentity2(AGENT_SCOPE2);
|
|
856
|
+
if (identity?.content) {
|
|
857
|
+
const lines = identity.content.split("\n").filter(
|
|
858
|
+
(l) => l.startsWith("- ") && (l.toLowerCase().includes("prefer") || l.toLowerCase().includes("style") || l.toLowerCase().includes("convention"))
|
|
859
|
+
);
|
|
860
|
+
for (const line of lines) {
|
|
861
|
+
const text3 = line.replace(/^-\s*/, "").trim();
|
|
862
|
+
if (text3 && !preferences.includes(text3)) preferences.push(text3);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
} catch {
|
|
866
|
+
}
|
|
867
|
+
try {
|
|
868
|
+
const categories = await arulesListCategories2(AGENT_SCOPE2);
|
|
869
|
+
for (const cat of categories) {
|
|
870
|
+
for (const ruleText of cat.rules) {
|
|
871
|
+
rules.push(ruleText);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
} catch {
|
|
875
|
+
}
|
|
876
|
+
if (opts?.smart && opts.llmClient) {
|
|
877
|
+
try {
|
|
878
|
+
const client = opts.llmClient;
|
|
879
|
+
const rawData = [
|
|
880
|
+
`Project: ${stack.projectName}`,
|
|
881
|
+
`Stack: ${stack.languages.join(", ")} + ${stack.frameworks.join(", ")}`,
|
|
882
|
+
`Databases: ${stack.databases.join(", ") || "none detected"}`,
|
|
883
|
+
"",
|
|
884
|
+
conventions.length > 0 ? `Conventions:
|
|
885
|
+
${conventions.map((c) => `- ${c}`).join("\n")}` : "",
|
|
886
|
+
decisions.length > 0 ? `Decisions:
|
|
887
|
+
${decisions.map((d) => `- ${d}`).join("\n")}` : "",
|
|
888
|
+
corrections.length > 0 ? `Corrections:
|
|
889
|
+
${corrections.map((c) => `- ${c}`).join("\n")}` : "",
|
|
890
|
+
preferences.length > 0 ? `Preferences:
|
|
891
|
+
${preferences.map((p5) => `- ${p5}`).join("\n")}` : "",
|
|
892
|
+
rules.length > 0 ? `Rules:
|
|
893
|
+
${rules.map((r) => `- ${r}`).join("\n")}` : ""
|
|
894
|
+
].filter(Boolean).join("\n\n");
|
|
895
|
+
const response = await client.chat(
|
|
896
|
+
"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.",
|
|
897
|
+
[{ role: "user", content: rawData }],
|
|
898
|
+
() => {
|
|
899
|
+
}
|
|
900
|
+
);
|
|
901
|
+
const text3 = typeof response.message.content === "string" ? response.message.content : response.message.content.map((b) => b.text ?? "").join("");
|
|
902
|
+
const extractSection = (sectionName) => {
|
|
903
|
+
const regex = new RegExp(`##?\\s*${sectionName}[\\s\\S]*?(?=##|$)`, "i");
|
|
904
|
+
const match = text3.match(regex);
|
|
905
|
+
if (!match) return [];
|
|
906
|
+
return match[0].split("\n").filter((l) => l.startsWith("- ")).map((l) => l.replace(/^-\s*/, "").trim());
|
|
907
|
+
};
|
|
908
|
+
const smartConventions = extractSection("Conventions");
|
|
909
|
+
const smartDecisions = extractSection("Decisions");
|
|
910
|
+
const smartCorrections = extractSection("Corrections");
|
|
911
|
+
const smartPreferences = extractSection("Preferences");
|
|
912
|
+
const smartRules = extractSection("Rules");
|
|
913
|
+
return {
|
|
914
|
+
stack,
|
|
915
|
+
conventions: trimToTokenBudget(smartConventions.length > 0 ? smartConventions : conventions, TOKEN_LIMITS.conventions),
|
|
916
|
+
decisions: trimToTokenBudget(smartDecisions.length > 0 ? smartDecisions : decisions, TOKEN_LIMITS.decisions),
|
|
917
|
+
corrections: trimToTokenBudget(smartCorrections.length > 0 ? smartCorrections : corrections, TOKEN_LIMITS.corrections),
|
|
918
|
+
preferences: trimToTokenBudget(smartPreferences.length > 0 ? smartPreferences : preferences, TOKEN_LIMITS.preferences),
|
|
919
|
+
rules: trimToTokenBudget(smartRules.length > 0 ? smartRules : rules, TOKEN_LIMITS.rules),
|
|
920
|
+
metadata: {
|
|
921
|
+
generatedAt: Date.now(),
|
|
922
|
+
mode: "smart",
|
|
923
|
+
memoriesUsed
|
|
924
|
+
}
|
|
925
|
+
};
|
|
926
|
+
} catch {
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
return {
|
|
930
|
+
stack,
|
|
931
|
+
conventions: trimToTokenBudget(conventions, TOKEN_LIMITS.conventions),
|
|
932
|
+
decisions: trimToTokenBudget(decisions, TOKEN_LIMITS.decisions),
|
|
933
|
+
corrections: trimToTokenBudget(corrections, TOKEN_LIMITS.corrections),
|
|
934
|
+
preferences: trimToTokenBudget(preferences, TOKEN_LIMITS.preferences),
|
|
935
|
+
rules: trimToTokenBudget(rules, TOKEN_LIMITS.rules),
|
|
936
|
+
metadata: {
|
|
937
|
+
generatedAt: Date.now(),
|
|
938
|
+
mode: "template",
|
|
939
|
+
memoriesUsed
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
var AGENT_SCOPE2, TOKEN_LIMITS;
|
|
944
|
+
var init_context_builder = __esm({
|
|
945
|
+
"src/dev/context-builder.ts"() {
|
|
946
|
+
"use strict";
|
|
947
|
+
init_token_budget();
|
|
948
|
+
AGENT_SCOPE2 = process.env.AMAN_AGENT_SCOPE ?? "dev:agent";
|
|
949
|
+
TOKEN_LIMITS = {
|
|
950
|
+
conventions: 1500,
|
|
951
|
+
decisions: 1200,
|
|
952
|
+
corrections: 800,
|
|
953
|
+
preferences: 500,
|
|
954
|
+
rules: 800
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
// src/dev/claude-md-writer.ts
|
|
960
|
+
import fs25 from "fs";
|
|
961
|
+
import path26 from "path";
|
|
962
|
+
function formatStack(stack) {
|
|
963
|
+
const parts = [];
|
|
964
|
+
const goFrameworks = ["fiber", "gin", "chi", "echo"];
|
|
965
|
+
const jsFrameworks = ["next", "react", "remix", "express", "fastify", "hono", "nestjs", "vue", "svelte", "nuxt"];
|
|
966
|
+
const pyFrameworks = ["django", "fastapi", "flask"];
|
|
967
|
+
for (const lang of stack.languages) {
|
|
968
|
+
const fw = stack.frameworks.filter((f) => {
|
|
969
|
+
if (lang === "go" && goFrameworks.includes(f)) return true;
|
|
970
|
+
if ((lang === "typescript" || lang === "javascript") && jsFrameworks.includes(f)) return true;
|
|
971
|
+
if (lang === "python" && pyFrameworks.includes(f)) return true;
|
|
972
|
+
if (lang === "dart" && f === "flutter") return true;
|
|
973
|
+
return false;
|
|
974
|
+
});
|
|
975
|
+
const name = lang.charAt(0).toUpperCase() + lang.slice(1);
|
|
976
|
+
if (fw.length > 0) {
|
|
977
|
+
parts.push(`${name} (${fw.map((f) => f.charAt(0).toUpperCase() + f.slice(1)).join(", ")})`);
|
|
978
|
+
} else {
|
|
979
|
+
parts.push(name);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
if (stack.databases.length > 0) {
|
|
983
|
+
parts.push(...stack.databases.map((d) => d.charAt(0).toUpperCase() + d.slice(1)));
|
|
984
|
+
}
|
|
985
|
+
return parts.join(" + ");
|
|
986
|
+
}
|
|
987
|
+
function renderToString(ctx) {
|
|
988
|
+
const lines = [];
|
|
989
|
+
const ts = new Date(ctx.metadata.generatedAt).toISOString();
|
|
990
|
+
lines.push(`# Project: ${ctx.stack.projectName}`);
|
|
991
|
+
lines.push(`<!-- aman-agent:dev generated=${ts} memories=${ctx.metadata.memoriesUsed} mode=${ctx.metadata.mode} -->`);
|
|
992
|
+
lines.push("");
|
|
993
|
+
const stackLine = formatStack(ctx.stack);
|
|
994
|
+
if (stackLine || ctx.stack.infra.length > 0) {
|
|
995
|
+
lines.push("## Stack");
|
|
996
|
+
if (stackLine) lines.push(`- ${stackLine}`);
|
|
997
|
+
if (ctx.stack.infra.length > 0) {
|
|
998
|
+
lines.push(`- Infra: ${ctx.stack.infra.join(", ")}`);
|
|
999
|
+
}
|
|
1000
|
+
if (ctx.stack.isMonorepo) {
|
|
1001
|
+
lines.push("- Monorepo");
|
|
1002
|
+
}
|
|
1003
|
+
lines.push("");
|
|
1004
|
+
}
|
|
1005
|
+
if (ctx.conventions.length > 0) {
|
|
1006
|
+
lines.push("## Conventions");
|
|
1007
|
+
for (const c of ctx.conventions) lines.push(`- ${c}`);
|
|
1008
|
+
lines.push("");
|
|
1009
|
+
}
|
|
1010
|
+
if (ctx.decisions.length > 0) {
|
|
1011
|
+
lines.push("## Past Decisions");
|
|
1012
|
+
for (const d of ctx.decisions) lines.push(`- ${d}`);
|
|
1013
|
+
lines.push("");
|
|
1014
|
+
}
|
|
1015
|
+
if (ctx.corrections.length > 0) {
|
|
1016
|
+
lines.push("## Corrections");
|
|
1017
|
+
for (const c of ctx.corrections) lines.push(`- ${c}`);
|
|
1018
|
+
lines.push("");
|
|
1019
|
+
}
|
|
1020
|
+
if (ctx.preferences.length > 0) {
|
|
1021
|
+
lines.push("## Developer Preferences");
|
|
1022
|
+
for (const p5 of ctx.preferences) lines.push(`- ${p5}`);
|
|
1023
|
+
lines.push("");
|
|
1024
|
+
}
|
|
1025
|
+
if (ctx.rules.length > 0) {
|
|
1026
|
+
lines.push("## Rules");
|
|
1027
|
+
for (const r of ctx.rules) lines.push(`- ${r}`);
|
|
1028
|
+
lines.push("");
|
|
1029
|
+
}
|
|
1030
|
+
return lines.join("\n");
|
|
1031
|
+
}
|
|
1032
|
+
function parseMarker(content) {
|
|
1033
|
+
const match = content.match(
|
|
1034
|
+
/<!--\s*aman-agent:dev\s+generated=(\S+)\s+memories=(\d+)\s+mode=(\S+)\s*-->/
|
|
1035
|
+
);
|
|
1036
|
+
if (!match) return null;
|
|
1037
|
+
return {
|
|
1038
|
+
generatedAt: new Date(match[1]),
|
|
1039
|
+
memories: parseInt(match[2], 10),
|
|
1040
|
+
mode: match[3]
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function checkStaleness(projectPath) {
|
|
1044
|
+
const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
|
|
1045
|
+
if (!fs25.existsSync(claudeMdPath)) {
|
|
1046
|
+
return { status: "missing" };
|
|
1047
|
+
}
|
|
1048
|
+
const content = fs25.readFileSync(claudeMdPath, "utf-8");
|
|
1049
|
+
const marker = parseMarker(content);
|
|
1050
|
+
if (!marker) {
|
|
1051
|
+
return { status: "no-marker" };
|
|
1052
|
+
}
|
|
1053
|
+
return { status: "fresh", generatedAt: marker.generatedAt };
|
|
1054
|
+
}
|
|
1055
|
+
function writeClaudeMd(ctx, projectPath) {
|
|
1056
|
+
const claudeMdPath = path26.join(projectPath, "CLAUDE.md");
|
|
1057
|
+
let backedUp = false;
|
|
1058
|
+
if (fs25.existsSync(claudeMdPath)) {
|
|
1059
|
+
const content = fs25.readFileSync(claudeMdPath, "utf-8");
|
|
1060
|
+
const marker = parseMarker(content);
|
|
1061
|
+
if (!marker) {
|
|
1062
|
+
fs25.copyFileSync(claudeMdPath, `${claudeMdPath}.bak`);
|
|
1063
|
+
backedUp = true;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
const md = renderToString(ctx);
|
|
1067
|
+
fs25.writeFileSync(claudeMdPath, md, "utf-8");
|
|
1068
|
+
return { written: true, backedUp, path: claudeMdPath };
|
|
1069
|
+
}
|
|
1070
|
+
var init_claude_md_writer = __esm({
|
|
1071
|
+
"src/dev/claude-md-writer.ts"() {
|
|
1072
|
+
"use strict";
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
// src/dev/dev-command.ts
|
|
1077
|
+
var dev_command_exports = {};
|
|
1078
|
+
__export(dev_command_exports, {
|
|
1079
|
+
runDev: () => runDev
|
|
1080
|
+
});
|
|
1081
|
+
import fs26 from "fs";
|
|
1082
|
+
import path27 from "path";
|
|
1083
|
+
function ensureGitignore(projectPath) {
|
|
1084
|
+
const gitignorePath = path27.join(projectPath, ".gitignore");
|
|
1085
|
+
if (!fs26.existsSync(gitignorePath)) return;
|
|
1086
|
+
const content = fs26.readFileSync(gitignorePath, "utf-8");
|
|
1087
|
+
if (content.includes("CLAUDE.md")) return;
|
|
1088
|
+
fs26.appendFileSync(gitignorePath, "\n# Generated by aman-agent dev\nCLAUDE.md\n");
|
|
1089
|
+
}
|
|
1090
|
+
async function runDev(projectPath, flags = {}, precomputedStack) {
|
|
1091
|
+
const resolved = path27.resolve(projectPath);
|
|
1092
|
+
if (!fs26.existsSync(resolved)) {
|
|
1093
|
+
return { success: false, generated: false, error: `Directory not found: ${resolved}` };
|
|
1094
|
+
}
|
|
1095
|
+
const stack = precomputedStack ?? scanStack(resolved);
|
|
1096
|
+
if (flags.diff) {
|
|
1097
|
+
const ctx2 = await buildContext2(stack, { smart: flags.smart });
|
|
1098
|
+
const newContent = renderToString(ctx2);
|
|
1099
|
+
const existingPath = path27.join(resolved, "CLAUDE.md");
|
|
1100
|
+
const existing = fs26.existsSync(existingPath) ? fs26.readFileSync(existingPath, "utf-8") : "";
|
|
1101
|
+
return {
|
|
1102
|
+
success: true,
|
|
1103
|
+
generated: false,
|
|
1104
|
+
diff: existing === newContent ? "(no changes)" : newContent,
|
|
1105
|
+
context: ctx2
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
if (!flags.force) {
|
|
1109
|
+
const staleness = checkStaleness(resolved);
|
|
1110
|
+
if (staleness.status === "fresh") {
|
|
1111
|
+
return { success: true, generated: false, skippedReason: "fresh" };
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
const ctx = await buildContext2(stack, { smart: flags.smart });
|
|
1115
|
+
const writeResult = writeClaudeMd(ctx, resolved);
|
|
1116
|
+
ensureGitignore(resolved);
|
|
1117
|
+
return {
|
|
1118
|
+
success: true,
|
|
1119
|
+
generated: writeResult.written,
|
|
1120
|
+
context: ctx
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
var init_dev_command = __esm({
|
|
1124
|
+
"src/dev/dev-command.ts"() {
|
|
1125
|
+
"use strict";
|
|
1126
|
+
init_stack_detector();
|
|
1127
|
+
init_context_builder();
|
|
1128
|
+
init_claude_md_writer();
|
|
1129
|
+
}
|
|
1130
|
+
});
|
|
1131
|
+
|
|
603
1132
|
// src/index.ts
|
|
604
1133
|
import { Command } from "commander";
|
|
605
1134
|
import * as p4 from "@clack/prompts";
|
|
@@ -696,63 +1225,11 @@ function migrateIfNeeded() {
|
|
|
696
1225
|
}
|
|
697
1226
|
|
|
698
1227
|
// src/prompt.ts
|
|
1228
|
+
init_token_budget();
|
|
699
1229
|
import fs4 from "fs";
|
|
700
1230
|
import path4 from "path";
|
|
701
1231
|
import os3 from "os";
|
|
702
1232
|
|
|
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
1233
|
// src/user-identity.ts
|
|
757
1234
|
import fs3 from "fs";
|
|
758
1235
|
import path3 from "path";
|
|
@@ -4574,12 +5051,12 @@ You are being delegated a specific task by the primary agent. Complete this task
|
|
|
4574
5051
|
</delegation>`;
|
|
4575
5052
|
let finalDelegationPrompt = delegationPrompt;
|
|
4576
5053
|
try {
|
|
4577
|
-
const
|
|
4578
|
-
if (
|
|
5054
|
+
const recall3 = await memoryRecall(task, { limit: 3, compact: true });
|
|
5055
|
+
if (recall3.total > 0) {
|
|
4579
5056
|
finalDelegationPrompt += `
|
|
4580
5057
|
|
|
4581
5058
|
<relevant-memories>
|
|
4582
|
-
${
|
|
5059
|
+
${recall3.text}
|
|
4583
5060
|
</relevant-memories>`;
|
|
4584
5061
|
}
|
|
4585
5062
|
} catch {
|
|
@@ -6604,7 +7081,7 @@ function handleReset(action) {
|
|
|
6604
7081
|
function handleUpdate() {
|
|
6605
7082
|
try {
|
|
6606
7083
|
const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
|
|
6607
|
-
const local = true ? "0.
|
|
7084
|
+
const local = true ? "0.33.1" : "unknown";
|
|
6608
7085
|
if (current === local) {
|
|
6609
7086
|
return { handled: true, output: `${pc6.green("Up to date")} \u2014 v${local}` };
|
|
6610
7087
|
}
|
|
@@ -8381,6 +8858,9 @@ Assistant: ${assistantResponse.slice(0, 2e3)}`;
|
|
|
8381
8858
|
}
|
|
8382
8859
|
}
|
|
8383
8860
|
|
|
8861
|
+
// src/agent.ts
|
|
8862
|
+
init_token_budget();
|
|
8863
|
+
|
|
8384
8864
|
// src/errors.ts
|
|
8385
8865
|
var ERROR_MAPPINGS = [
|
|
8386
8866
|
{ pattern: /rate.?limit|429/i, message: "Rate limited. I'll retry automatically." },
|
|
@@ -8988,10 +9468,10 @@ ${converted}
|
|
|
8988
9468
|
let augmentedSystemPrompt = activeSystemPrompt;
|
|
8989
9469
|
let memoryTokens = 0;
|
|
8990
9470
|
{
|
|
8991
|
-
const
|
|
8992
|
-
if (
|
|
8993
|
-
augmentedSystemPrompt = activeSystemPrompt +
|
|
8994
|
-
memoryTokens =
|
|
9471
|
+
const recall3 = await recallForMessage(input);
|
|
9472
|
+
if (recall3) {
|
|
9473
|
+
augmentedSystemPrompt = activeSystemPrompt + recall3.text;
|
|
9474
|
+
memoryTokens = recall3.tokenEstimate;
|
|
8995
9475
|
}
|
|
8996
9476
|
}
|
|
8997
9477
|
const userTurnCount = messages.filter((m) => m.role === "user").length;
|
|
@@ -9370,8 +9850,8 @@ async function saveConversationToMemory(messages, sessionId) {
|
|
|
9370
9850
|
}
|
|
9371
9851
|
|
|
9372
9852
|
// src/index.ts
|
|
9373
|
-
import
|
|
9374
|
-
import
|
|
9853
|
+
import fs27 from "fs";
|
|
9854
|
+
import path28 from "path";
|
|
9375
9855
|
|
|
9376
9856
|
// src/presets.ts
|
|
9377
9857
|
var PRESETS = {
|
|
@@ -9585,7 +10065,7 @@ var Inbox = class {
|
|
|
9585
10065
|
// package.json
|
|
9586
10066
|
var package_default = {
|
|
9587
10067
|
name: "@aman_asmuei/aman-agent",
|
|
9588
|
-
version: "0.
|
|
10068
|
+
version: "0.33.1",
|
|
9589
10069
|
description: "Your AI companion, running locally \u2014 powered by the aman ecosystem",
|
|
9590
10070
|
type: "module",
|
|
9591
10071
|
engines: {
|
|
@@ -9878,9 +10358,9 @@ async function runServe(opts) {
|
|
|
9878
10358
|
|
|
9879
10359
|
// src/index.ts
|
|
9880
10360
|
async function autoDetectConfig() {
|
|
9881
|
-
const reconfigMarker =
|
|
9882
|
-
if (
|
|
9883
|
-
|
|
10361
|
+
const reconfigMarker = path28.join(homeDir(), ".reconfig");
|
|
10362
|
+
if (fs27.existsSync(reconfigMarker)) {
|
|
10363
|
+
fs27.unlinkSync(reconfigMarker);
|
|
9884
10364
|
return null;
|
|
9885
10365
|
}
|
|
9886
10366
|
const anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
@@ -9909,10 +10389,10 @@ async function autoDetectConfig() {
|
|
|
9909
10389
|
return null;
|
|
9910
10390
|
}
|
|
9911
10391
|
function bootstrapEcosystem() {
|
|
9912
|
-
const corePath =
|
|
9913
|
-
if (
|
|
9914
|
-
|
|
9915
|
-
|
|
10392
|
+
const corePath = path28.join(identityDir(), "core.md");
|
|
10393
|
+
if (fs27.existsSync(corePath)) return false;
|
|
10394
|
+
fs27.mkdirSync(identityDir(), { recursive: true });
|
|
10395
|
+
fs27.writeFileSync(corePath, [
|
|
9916
10396
|
"# Aman",
|
|
9917
10397
|
"",
|
|
9918
10398
|
"## Personality",
|
|
@@ -9924,10 +10404,10 @@ function bootstrapEcosystem() {
|
|
|
9924
10404
|
"## Session",
|
|
9925
10405
|
"_New companion \u2014 no prior sessions._"
|
|
9926
10406
|
].join("\n"), "utf-8");
|
|
9927
|
-
const rulesPath =
|
|
9928
|
-
if (!
|
|
9929
|
-
|
|
9930
|
-
|
|
10407
|
+
const rulesPath = path28.join(rulesDir(), "rules.md");
|
|
10408
|
+
if (!fs27.existsSync(rulesPath)) {
|
|
10409
|
+
fs27.mkdirSync(rulesDir(), { recursive: true });
|
|
10410
|
+
fs27.writeFileSync(rulesPath, [
|
|
9931
10411
|
"# Guardrails",
|
|
9932
10412
|
"",
|
|
9933
10413
|
"## safety",
|
|
@@ -9939,20 +10419,20 @@ function bootstrapEcosystem() {
|
|
|
9939
10419
|
"- Respect the user's preferences stored in memory"
|
|
9940
10420
|
].join("\n"), "utf-8");
|
|
9941
10421
|
}
|
|
9942
|
-
const flowPath =
|
|
9943
|
-
if (!
|
|
9944
|
-
|
|
9945
|
-
|
|
10422
|
+
const flowPath = path28.join(workflowsDir(), "flow.md");
|
|
10423
|
+
if (!fs27.existsSync(flowPath)) {
|
|
10424
|
+
fs27.mkdirSync(workflowsDir(), { recursive: true });
|
|
10425
|
+
fs27.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
|
|
9946
10426
|
}
|
|
9947
|
-
const skillPath =
|
|
9948
|
-
if (!
|
|
9949
|
-
|
|
9950
|
-
|
|
10427
|
+
const skillPath = path28.join(skillsDir(), "skills.md");
|
|
10428
|
+
if (!fs27.existsSync(skillPath)) {
|
|
10429
|
+
fs27.mkdirSync(skillsDir(), { recursive: true });
|
|
10430
|
+
fs27.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
|
|
9951
10431
|
}
|
|
9952
10432
|
return true;
|
|
9953
10433
|
}
|
|
9954
10434
|
var program = new Command();
|
|
9955
|
-
program.name("aman-agent").description("Your AI companion, running locally").version("0.
|
|
10435
|
+
program.name("aman-agent").description("Your AI companion, running locally").version("0.33.1").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
10436
|
p4.intro(pc9.bold("aman agent") + pc9.dim(" \u2014 your AI companion"));
|
|
9957
10437
|
let config = loadConfig();
|
|
9958
10438
|
if (!config) {
|
|
@@ -10307,18 +10787,18 @@ program.command("init").description("Set up your AI companion with a guided wiza
|
|
|
10307
10787
|
});
|
|
10308
10788
|
if (p4.isCancel(preset)) process.exit(0);
|
|
10309
10789
|
const result = applyPreset(preset, name || "Aman");
|
|
10310
|
-
|
|
10311
|
-
|
|
10790
|
+
fs27.mkdirSync(identityDir(), { recursive: true });
|
|
10791
|
+
fs27.writeFileSync(path28.join(identityDir(), "core.md"), result.coreMd, "utf-8");
|
|
10312
10792
|
p4.log.success(`Identity created \u2014 ${PRESETS[preset].identity.personality.split(".")[0].toLowerCase()}`);
|
|
10313
10793
|
if (result.rulesMd) {
|
|
10314
|
-
|
|
10315
|
-
|
|
10794
|
+
fs27.mkdirSync(rulesDir(), { recursive: true });
|
|
10795
|
+
fs27.writeFileSync(path28.join(rulesDir(), "rules.md"), result.rulesMd, "utf-8");
|
|
10316
10796
|
const ruleCount = (result.rulesMd.match(/^- /gm) || []).length;
|
|
10317
10797
|
p4.log.success(`${ruleCount} rules set`);
|
|
10318
10798
|
}
|
|
10319
10799
|
if (result.flowMd) {
|
|
10320
|
-
|
|
10321
|
-
|
|
10800
|
+
fs27.mkdirSync(workflowsDir(), { recursive: true });
|
|
10801
|
+
fs27.writeFileSync(path28.join(workflowsDir(), "flow.md"), result.flowMd, "utf-8");
|
|
10322
10802
|
const wfCount = (result.flowMd.match(/^## /gm) || []).length;
|
|
10323
10803
|
p4.log.success(`${wfCount} workflow${wfCount > 1 ? "s" : ""} added`);
|
|
10324
10804
|
}
|
|
@@ -10347,18 +10827,78 @@ program.command("serve").description("Run aman-agent as a local MCP server other
|
|
|
10347
10827
|
process.exit(1);
|
|
10348
10828
|
}
|
|
10349
10829
|
});
|
|
10830
|
+
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) => {
|
|
10831
|
+
const { runDev: runDev2 } = await Promise.resolve().then(() => (init_dev_command(), dev_command_exports));
|
|
10832
|
+
const { scanStack: scanStack2 } = await Promise.resolve().then(() => (init_stack_detector(), stack_detector_exports));
|
|
10833
|
+
const targetPath = projectPath ?? process.cwd();
|
|
10834
|
+
const stack = scanStack2(targetPath);
|
|
10835
|
+
const stackParts = stack.languages.map((l) => l.charAt(0).toUpperCase() + l.slice(1));
|
|
10836
|
+
if (stack.frameworks.length > 0) {
|
|
10837
|
+
stackParts.push(`(${stack.frameworks.map((f) => f.charAt(0).toUpperCase() + f.slice(1)).join(", ")})`);
|
|
10838
|
+
}
|
|
10839
|
+
if (stack.databases.length > 0) {
|
|
10840
|
+
stackParts.push(...stack.databases.map((d) => d.charAt(0).toUpperCase() + d.slice(1)));
|
|
10841
|
+
}
|
|
10842
|
+
if (stack.infra.length > 0) {
|
|
10843
|
+
stackParts.push(...stack.infra.map((i) => i.charAt(0).toUpperCase() + i.slice(1)));
|
|
10844
|
+
}
|
|
10845
|
+
if (stack.languages.length > 0) {
|
|
10846
|
+
console.log(`
|
|
10847
|
+
${pc9.cyan("Detected:")} ${stackParts.join(" + ")}`);
|
|
10848
|
+
} else {
|
|
10849
|
+
console.log(`
|
|
10850
|
+
${pc9.dim("No stack detected \u2014 generating minimal CLAUDE.md")}`);
|
|
10851
|
+
}
|
|
10852
|
+
const result = await runDev2(targetPath, {
|
|
10853
|
+
smart: opts.smart,
|
|
10854
|
+
noLaunch: opts.launch === false,
|
|
10855
|
+
force: opts.force,
|
|
10856
|
+
diff: opts.diff
|
|
10857
|
+
}, stack);
|
|
10858
|
+
if (!result.success) {
|
|
10859
|
+
console.error(` ${pc9.red("Error:")} ${result.error}`);
|
|
10860
|
+
process.exit(1);
|
|
10861
|
+
}
|
|
10862
|
+
if (result.diff) {
|
|
10863
|
+
console.log(`
|
|
10864
|
+
${result.diff}`);
|
|
10865
|
+
return;
|
|
10866
|
+
}
|
|
10867
|
+
if (result.generated) {
|
|
10868
|
+
const mode = opts.smart ? "smart" : "template";
|
|
10869
|
+
const memCount = result.context?.metadata.memoriesUsed ?? 0;
|
|
10870
|
+
console.log(` ${pc9.cyan("Recalled:")} ${memCount} memories`);
|
|
10871
|
+
console.log(` ${pc9.green("\u2713")} CLAUDE.md written (${mode} mode)
|
|
10872
|
+
`);
|
|
10873
|
+
} else if (result.skippedReason === "fresh") {
|
|
10874
|
+
console.log(` ${pc9.green("\u2713")} CLAUDE.md is up to date
|
|
10875
|
+
`);
|
|
10876
|
+
}
|
|
10877
|
+
if (opts.launch !== false && !opts.diff) {
|
|
10878
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
10879
|
+
try {
|
|
10880
|
+
execFileSync4("which", ["claude"], { stdio: "ignore" });
|
|
10881
|
+
} catch {
|
|
10882
|
+
console.log(` ${pc9.yellow("Claude Code not found.")} Install: npm install -g @anthropic-ai/claude-code`);
|
|
10883
|
+
process.exit(1);
|
|
10884
|
+
}
|
|
10885
|
+
console.log(` ${pc9.cyan("Launching Claude Code...")}
|
|
10886
|
+
`);
|
|
10887
|
+
execFileSync4("claude", [], { cwd: targetPath, stdio: "inherit" });
|
|
10888
|
+
}
|
|
10889
|
+
});
|
|
10350
10890
|
program.command("setup").description("Run the full configuration wizard (provider, identity, presets)").action(async () => {
|
|
10351
10891
|
p4.intro(pc9.bold("aman agent setup") + pc9.dim(" \u2014 full configuration wizard"));
|
|
10352
|
-
const reconfigPath =
|
|
10353
|
-
|
|
10354
|
-
|
|
10892
|
+
const reconfigPath = path28.join(homeDir(), ".reconfig");
|
|
10893
|
+
fs27.mkdirSync(homeDir(), { recursive: true });
|
|
10894
|
+
fs27.writeFileSync(reconfigPath, "", "utf-8");
|
|
10355
10895
|
p4.log.info("Configuration reset. Restart aman-agent to complete setup.");
|
|
10356
10896
|
});
|
|
10357
10897
|
program.command("update").description("Update aman-agent to the latest version").action(async () => {
|
|
10358
10898
|
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
10359
|
-
const isVendored = process.execPath.includes(
|
|
10899
|
+
const isVendored = process.execPath.includes(path28.join(".aman-agent", "node"));
|
|
10360
10900
|
if (isVendored) {
|
|
10361
|
-
const npmPath =
|
|
10901
|
+
const npmPath = path28.join(homeDir(), "node", "bin", "npm");
|
|
10362
10902
|
console.log("Updating aman-agent...");
|
|
10363
10903
|
try {
|
|
10364
10904
|
execFileSync4(npmPath, ["install", "-g", "@aman_asmuei/aman-agent@latest"], {
|
|
@@ -10386,7 +10926,7 @@ program.command("update").description("Update aman-agent to the latest version")
|
|
|
10386
10926
|
program.command("uninstall").description("Remove aman-agent and all its data").action(async () => {
|
|
10387
10927
|
const home2 = homeDir();
|
|
10388
10928
|
if (!process.stdin.isTTY) {
|
|
10389
|
-
|
|
10929
|
+
fs27.rmSync(home2, { recursive: true, force: true });
|
|
10390
10930
|
console.log("\u2713 Removed " + home2);
|
|
10391
10931
|
return;
|
|
10392
10932
|
}
|
|
@@ -10397,7 +10937,7 @@ program.command("uninstall").description("Remove aman-agent and all its data").a
|
|
|
10397
10937
|
console.log("Cancelled.");
|
|
10398
10938
|
return;
|
|
10399
10939
|
}
|
|
10400
|
-
|
|
10940
|
+
fs27.rmSync(home2, { recursive: true, force: true });
|
|
10401
10941
|
console.log("\u2713 Removed " + home2);
|
|
10402
10942
|
console.log("");
|
|
10403
10943
|
console.log("To complete uninstall, remove the PATH line from your shell config:");
|