MCPcopy Create free account
hub / github.com/IAmUnbounded/devctx / saveCommand

Function saveCommand

devctx/src/commands/save.ts:28–183  ·  view source on GitHub ↗
(message?: string, options?: SaveOptions)

Source from the content-addressed store, hash-verified

26}
27
28export async function saveCommand(message?: string, options?: SaveOptions) {
29 if (!(await isInitialized())) {
30 console.log(chalk.red("✗ DevContext not initialized. Run `devctx init` first."));
31 return;
32 }
33
34 try {
35 const [branch, repo, filesChanged, filesStaged, recentCommits, author] = await Promise.all([
36 getCurrentBranch(),
37 getRepoName(),
38 getChangedFiles(),
39 getStagedFiles(),
40 getRecentCommits(),
41 getAuthor(),
42 ]);
43
44 let task = message || "";
45 let approaches: string[] = [];
46 let decisions: string[] = [];
47 let currentState = "";
48 let nextSteps: string[] = [];
49 let blockers: string[] = [];
50
51 // Check if structured flags were provided (AI agent mode)
52 const hasStructuredInput =
53 options?.approaches || options?.decisions || options?.state || options?.nextSteps;
54
55 if (options?.auto) {
56 // Auto-extract mode — read from editor session data
57 console.log(chalk.gray(" Scanning editor sessions for context..."));
58 const cwd = process.cwd();
59 const extracted = await extractFromEditorSessions(cwd);
60
61 if (extracted) {
62 task = message || extracted.task;
63 approaches = extracted.approaches;
64 decisions = extracted.decisions;
65 currentState = extracted.currentState;
66 nextSteps = extracted.nextSteps;
67 blockers = extracted.blockers;
68 console.log(chalk.gray(` Found context from: ${extracted.source}`));
69 } else {
70 console.log(chalk.yellow("⚠ No editor session data found. Using message only."));
71 task = message || "Session (auto-extract found nothing)";
72 currentState = message || "";
73 }
74 } else if (hasStructuredInput && message) {
75 // Programmatic mode — AI agent is passing structured context
76 task = message;
77 approaches = options?.approaches
78 ? options.approaches.split(";;").map((s) => s.trim()).filter(Boolean)
79 : [];
80 decisions = options?.decisions
81 ? options.decisions.split(";;").map((s) => s.trim()).filter(Boolean)
82 : [];
83 currentState = options?.state || message;
84 nextSteps = options?.nextSteps
85 ? options.nextSteps.split(";;").map((s) => s.trim()).filter(Boolean)

Callers

nothing calls this directly

Calls 9

isInitializedFunction · 0.90
getCurrentBranchFunction · 0.90
getRepoNameFunction · 0.90
getChangedFilesFunction · 0.90
getStagedFilesFunction · 0.90
getRecentCommitsFunction · 0.90
getAuthorFunction · 0.90
saveContextFunction · 0.90

Tested by

no test coverage detected