@lazyingart/agintiflow 0.20.41 → 0.20.43
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 +3 -0
- package/demos/README.md +1 -0
- package/demos/agintiflow-cli-launch.jpg +0 -0
- package/package.json +1 -1
- package/scripts/smoke-cli-chat.js +5 -0
- package/scripts/smoke-inbox.js +22 -1
- package/src/cli.js +71 -18
- package/src/project.js +27 -3
- package/src/session-index.js +13 -3
package/README.md
CHANGED
|
@@ -140,6 +140,7 @@ aginti sessions show <session-id>
|
|
|
140
140
|
aginti sessions rename <session-id> "friendly title"
|
|
141
141
|
aginti storage migrate
|
|
142
142
|
aginti resume
|
|
143
|
+
aginti resume --all-sessions
|
|
143
144
|
aginti resume latest
|
|
144
145
|
aginti resume <session-id> "continue with a short follow-up"
|
|
145
146
|
aginti queue <session-id> "extra instruction for the running agent"
|
|
@@ -148,6 +149,8 @@ aginti --latex "draw a figure, write a short LaTeX report, and compile the PDF"
|
|
|
148
149
|
aginti "set up this project and run the tests"
|
|
149
150
|
```
|
|
150
151
|
|
|
152
|
+
Bare `aginti resume` lists sessions for the current cwd by default. Use `--all-sessions` to browse the global session index; in the interactive selector, type a number to resume, `q` to quit, `/text` to filter the visible list, or `/` to clear the filter.
|
|
153
|
+
|
|
151
154
|
Run from a source checkout:
|
|
152
155
|
|
|
153
156
|
```bash
|
package/demos/README.md
CHANGED
|
@@ -4,3 +4,4 @@ This folder stores shareable screenshots and visual demos used by the repository
|
|
|
4
4
|
|
|
5
5
|
- `agintiflow-cli-launch.png`: interactive CLI launch screen with the AgInTi Flow terminal banner, Docker workspace status, and input panel.
|
|
6
6
|
- `agintiflow-cli-launch.jpg`: optimized README/web preview derived from the same screenshot.
|
|
7
|
+
- `archive/`: previous CLI launch screenshots kept before replacing the active README preview.
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a web-first coding agent and CLI with DeepSeek routing, sandboxed tools, model providers, canvas artifacts, and optional wrappers.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -235,6 +235,11 @@ try {
|
|
|
235
235
|
if (classifyEscapeAction({ active: true, pendingAsap: [] }) !== "abort") {
|
|
236
236
|
throw new Error("active Esc should abort when no ASAP pipe messages are pending");
|
|
237
237
|
}
|
|
238
|
+
await runChat("/exit\n");
|
|
239
|
+
const idleSessionEntries = await fs.readdir(path.join(agintiflowHome, "sessions"), { withFileTypes: true }).catch(() => []);
|
|
240
|
+
if (idleSessionEntries.some((entry) => entry.isDirectory())) {
|
|
241
|
+
throw new Error("idle interactive chat created a session before any user task");
|
|
242
|
+
}
|
|
238
243
|
if (
|
|
239
244
|
canonicalSlashPromptBuffer("/ve") !== "/venice" ||
|
|
240
245
|
canonicalSlashPromptBuffer("/v") !== "/venice" ||
|
package/scripts/smoke-inbox.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { ensureProjectSessionStorage, listProjectSessions } from "../src/project.js";
|
|
5
|
+
import { ensureProjectSessionStorage, listProjectSessions, sessionStoreOptions } from "../src/project.js";
|
|
6
6
|
import { SessionStore } from "../src/session-store.js";
|
|
7
7
|
|
|
8
8
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-inbox-"));
|
|
@@ -58,6 +58,25 @@ try {
|
|
|
58
58
|
"project session pointer was not created"
|
|
59
59
|
);
|
|
60
60
|
|
|
61
|
+
const nestedCwd = path.join(legacyProject, "nested");
|
|
62
|
+
await fs.mkdir(nestedCwd, { recursive: true });
|
|
63
|
+
const otherCwdStore = new SessionStore(paths.globalSessionsDir, "other-cwd-smoke", sessionStoreOptions(legacyProject, "other-cwd-smoke"));
|
|
64
|
+
await otherCwdStore.saveState({
|
|
65
|
+
sessionId: "other-cwd-smoke",
|
|
66
|
+
createdAt: "2026-01-01T00:02:00.000Z",
|
|
67
|
+
updatedAt: "2026-01-01T00:03:00.000Z",
|
|
68
|
+
provider: "mock",
|
|
69
|
+
model: "mock-agent",
|
|
70
|
+
goal: "nested cwd smoke",
|
|
71
|
+
projectRoot: legacyProject,
|
|
72
|
+
commandCwd: nestedCwd,
|
|
73
|
+
chat: [],
|
|
74
|
+
});
|
|
75
|
+
const cwdFiltered = await listProjectSessions(legacyProject, { limit: 10, commandCwd: legacyProject });
|
|
76
|
+
assert(!cwdFiltered.some((session) => session.sessionId === "other-cwd-smoke"), "default cwd filtering included a different cwd session");
|
|
77
|
+
const allSessions = await listProjectSessions(legacyProject, { limit: 10, allSessions: true });
|
|
78
|
+
assert(allSessions.some((session) => session.sessionId === "other-cwd-smoke"), "--all-sessions mode did not include a different cwd session");
|
|
79
|
+
|
|
61
80
|
console.log(
|
|
62
81
|
JSON.stringify(
|
|
63
82
|
{
|
|
@@ -68,6 +87,8 @@ try {
|
|
|
68
87
|
"session-inbox-asap-priority",
|
|
69
88
|
"legacy-session-migration",
|
|
70
89
|
"global-session-store",
|
|
90
|
+
"cwd-session-filter",
|
|
91
|
+
"all-sessions-list",
|
|
71
92
|
],
|
|
72
93
|
},
|
|
73
94
|
null,
|
package/src/cli.js
CHANGED
|
@@ -378,7 +378,7 @@ export function parseArgs(argv) {
|
|
|
378
378
|
|
|
379
379
|
function printUsage() {
|
|
380
380
|
console.log(
|
|
381
|
-
'Usage: aginti [chat] OR aginti web [--port 3210] OR aginti update OR aginti models OR aginti skills [query] OR aginti auth [deepseek|openai|qwen|venice|grsai] OR aginti resume [latest|<session-id>] ["prompt"] OR aginti queue <session-id> "message" OR aginti [--no-auto-update] [--language en|ja|zh-Hans|zh-Hant|ko|fr|es|ar|vi|de|ru] [--image] [--latex] [--routing smart|fast|complex|manual] [--provider deepseek|openai|qwen|venice|mock] [--model MODEL] [--route-model MODEL] [--main-model MODEL] [--spare-model MODEL --spare-reasoning medium] [--aux-provider grsai|venice --aux-model MODEL] [--sandbox-mode host|docker-readonly|docker-workspace] [--package-install-policy block|prompt|allow] [--approve-package-installs] [--allow-shell|--no-shell] [--allow-file-tools|--no-file-tools] [--web-search|--no-web-search] [--parallel-scouts|--no-parallel-scouts --scout-count 1..10] [--allow-auxiliary-tools|--no-auxiliary-tools] [--allow-wrappers --wrapper codex --wrapper-model gpt-5.5] [--list-models|--list-routes] "your task"'
|
|
381
|
+
'Usage: aginti [chat] OR aginti web [--port 3210] OR aginti update OR aginti models OR aginti skills [query] OR aginti auth [deepseek|openai|qwen|venice|grsai] OR aginti resume [--all-sessions] [latest|<session-id>] ["prompt"] OR aginti queue <session-id> "message" OR aginti [--no-auto-update] [--language en|ja|zh-Hans|zh-Hant|ko|fr|es|ar|vi|de|ru] [--image] [--latex] [--routing smart|fast|complex|manual] [--provider deepseek|openai|qwen|venice|mock] [--model MODEL] [--route-model MODEL] [--main-model MODEL] [--spare-model MODEL --spare-reasoning medium] [--aux-provider grsai|venice --aux-model MODEL] [--sandbox-mode host|docker-readonly|docker-workspace] [--package-install-policy block|prompt|allow] [--approve-package-installs] [--allow-shell|--no-shell] [--allow-file-tools|--no-file-tools] [--web-search|--no-web-search] [--parallel-scouts|--no-parallel-scouts --scout-count 1..10] [--allow-auxiliary-tools|--no-auxiliary-tools] [--allow-wrappers --wrapper codex --wrapper-model gpt-5.5] [--list-models|--list-routes] "your task"'
|
|
382
382
|
);
|
|
383
383
|
console.log(`Languages: ${["en", "ja", "zh-Hans", "zh-Hant", "ko", "fr", "es", "ar", "vi", "de", "ru"].map((code) => `${code}=${languageLabel(code)}`).join(", ")}`);
|
|
384
384
|
}
|
|
@@ -601,11 +601,13 @@ function printAuthWizardResult(result) {
|
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
async function handleSessionsCommand(argv) {
|
|
604
|
-
const
|
|
604
|
+
const normalizedArgv = argv[0] === "--all-sessions" ? ["list", ...argv] : argv;
|
|
605
|
+
const [verb = "list", sessionId = "", ...rest] = normalizedArgv;
|
|
605
606
|
if (verb === "list") {
|
|
606
|
-
const
|
|
607
|
+
const allSessions = normalizedArgv.includes("--all-sessions");
|
|
608
|
+
const sessions = await listProjectSessions(process.cwd(), { limit: 80, allSessions });
|
|
607
609
|
if (sessions.length === 0) {
|
|
608
|
-
console.log("No
|
|
610
|
+
console.log(allSessions ? "No sessions found." : "No sessions found for this cwd.");
|
|
609
611
|
return;
|
|
610
612
|
}
|
|
611
613
|
for (const session of sessions) {
|
|
@@ -640,35 +642,82 @@ async function handleSessionsCommand(argv) {
|
|
|
640
642
|
process.exit(1);
|
|
641
643
|
}
|
|
642
644
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
645
|
+
function sessionSearchText(session) {
|
|
646
|
+
return [
|
|
647
|
+
session.sessionId,
|
|
648
|
+
session.provider,
|
|
649
|
+
session.model,
|
|
650
|
+
session.updatedAt,
|
|
651
|
+
session.title,
|
|
652
|
+
session.goal,
|
|
653
|
+
session.projectRoot,
|
|
654
|
+
session.commandCwd,
|
|
655
|
+
]
|
|
656
|
+
.filter(Boolean)
|
|
657
|
+
.join(" ")
|
|
658
|
+
.toLowerCase();
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function filterSessions(sessions, filterText = "") {
|
|
662
|
+
const needle = String(filterText || "").trim().toLowerCase();
|
|
663
|
+
if (!needle) return sessions;
|
|
664
|
+
return sessions.filter((session) => sessionSearchText(session).includes(needle));
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
function printSessionChoices(sessions, { filterText = "", allSessions = false, maxShown = 20 } = {}) {
|
|
668
|
+
const scope = allSessions ? "all sessions" : `cwd ${process.cwd()}`;
|
|
669
|
+
const shown = sessions.slice(0, maxShown);
|
|
670
|
+
console.log(`Select a session to resume (${scope}${filterText ? `, filter="${filterText}"` : ""}):`);
|
|
671
|
+
if (shown.length === 0) {
|
|
672
|
+
console.log("No matching sessions. Type /text to change the filter, / to clear it, or q to quit.");
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
shown.forEach((session, index) => {
|
|
647
676
|
const title = session.title || session.goal || "(untitled)";
|
|
648
677
|
console.log(
|
|
649
678
|
`${index + 1}. ${session.sessionId} ${session.provider || "unknown"}/${session.model || "unknown"} ${session.updatedAt || ""} ${title.slice(0, 90)}`
|
|
650
679
|
);
|
|
651
680
|
});
|
|
681
|
+
if (sessions.length > shown.length) console.log(`... ${sessions.length - shown.length} more hidden by display limit; type /text to narrow.`);
|
|
682
|
+
console.log("Type a number to select, /text to filter, / to clear, or q to quit.");
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
async function promptSelectSession(sessions, { allSessions = false } = {}) {
|
|
686
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) return sessions[0]?.sessionId || "";
|
|
652
687
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
688
|
+
let filterText = "";
|
|
653
689
|
try {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
690
|
+
while (true) {
|
|
691
|
+
const filtered = filterSessions(sessions, filterText);
|
|
692
|
+
printSessionChoices(filtered, { filterText, allSessions });
|
|
693
|
+
const answer = (await rl.question("Session number/filter: ")).trim();
|
|
694
|
+
if (!answer || answer.toLowerCase() === "q" || answer.toLowerCase() === "quit") return "";
|
|
695
|
+
if (answer.startsWith("/")) {
|
|
696
|
+
filterText = answer.slice(1).trim();
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
const index = Number(answer) - 1;
|
|
700
|
+
if (Number.isInteger(index) && index >= 0 && index < Math.min(filtered.length, 20)) {
|
|
701
|
+
return filtered[index]?.sessionId || "";
|
|
702
|
+
}
|
|
703
|
+
console.log("Invalid selection. Type a shown number, /text to filter, or q to quit.");
|
|
704
|
+
}
|
|
657
705
|
} finally {
|
|
658
706
|
rl.close();
|
|
659
707
|
}
|
|
660
708
|
}
|
|
661
709
|
|
|
662
|
-
async function resolveResumeSessionId(sessionId) {
|
|
710
|
+
async function resolveResumeSessionId(sessionId, { allSessions = false } = {}) {
|
|
663
711
|
if (sessionId && sessionId !== "latest") return sessionId;
|
|
664
|
-
const sessions = await listProjectSessions(process.cwd(),
|
|
712
|
+
const sessions = await listProjectSessions(process.cwd(), { limit: 1000, allSessions });
|
|
665
713
|
if (sessionId === "latest" || sessions.length <= 1 || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
666
714
|
if (sessions[0]?.sessionId) return sessions[0].sessionId;
|
|
667
715
|
} else {
|
|
668
|
-
const selected = await promptSelectSession(sessions);
|
|
716
|
+
const selected = await promptSelectSession(sessions, { allSessions });
|
|
669
717
|
if (selected) return selected;
|
|
718
|
+
return "";
|
|
670
719
|
}
|
|
671
|
-
throw new Error("No
|
|
720
|
+
throw new Error(allSessions ? "No sessions found." : "No sessions found for this cwd. Use `aginti resume --all-sessions` to browse all sessions.");
|
|
672
721
|
}
|
|
673
722
|
|
|
674
723
|
async function handleQueueCommand(argv) {
|
|
@@ -837,14 +886,18 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
837
886
|
}
|
|
838
887
|
|
|
839
888
|
if (argv[0] === "resume") {
|
|
840
|
-
|
|
841
|
-
const
|
|
889
|
+
const resumeArgv = argv.slice(1);
|
|
890
|
+
const allSessions = resumeArgv.includes("--all-sessions");
|
|
891
|
+
const positional = resumeArgv.filter((arg) => arg !== "--all-sessions");
|
|
892
|
+
let sessionId = positional[0] || "";
|
|
893
|
+
const prompt = positional.slice(1).join(" ").trim();
|
|
842
894
|
try {
|
|
843
|
-
sessionId = await resolveResumeSessionId(sessionId);
|
|
895
|
+
sessionId = await resolveResumeSessionId(sessionId, { allSessions });
|
|
844
896
|
} catch (error) {
|
|
845
897
|
console.error(error instanceof Error ? error.message : String(error));
|
|
846
898
|
process.exit(1);
|
|
847
899
|
}
|
|
900
|
+
if (!sessionId) return;
|
|
848
901
|
if (!prompt) {
|
|
849
902
|
await startInteractiveCli(agentDefaults({ ...parseArgs([]), resume: sessionId }), {
|
|
850
903
|
packageDir,
|
package/src/project.js
CHANGED
|
@@ -484,11 +484,34 @@ export async function setProviderKey(projectRoot, provider, value) {
|
|
|
484
484
|
};
|
|
485
485
|
}
|
|
486
486
|
|
|
487
|
-
|
|
487
|
+
function normalizeSessionListOptions(projectRoot, limitOrOptions = 50) {
|
|
488
|
+
const options = typeof limitOrOptions === "object" && limitOrOptions !== null ? limitOrOptions : { limit: limitOrOptions };
|
|
489
|
+
const root = resolveProjectRoot(projectRoot);
|
|
490
|
+
const commandCwd = options.commandCwd === false ? "" : path.resolve(options.commandCwd || root);
|
|
491
|
+
return {
|
|
492
|
+
limit: Math.min(Math.max(Number(options.limit) || 50, 1), 1000),
|
|
493
|
+
commandCwd,
|
|
494
|
+
allSessions: Boolean(options.allSessions),
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function sessionMatchesCommandCwd(session, commandCwd = "") {
|
|
499
|
+
if (!commandCwd) return true;
|
|
500
|
+
const value = session.commandCwd || session.projectRoot || "";
|
|
501
|
+
if (!value) return false;
|
|
502
|
+
return path.resolve(value) === path.resolve(commandCwd);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export async function listProjectSessions(projectRoot = process.cwd(), limitOrOptions = 50) {
|
|
506
|
+
const options = normalizeSessionListOptions(projectRoot, limitOrOptions);
|
|
488
507
|
const paths = await ensureProjectSessionStorage(projectRoot);
|
|
489
508
|
const indexed = (() => {
|
|
490
509
|
try {
|
|
491
|
-
return listSessionIndex({
|
|
510
|
+
return listSessionIndex({
|
|
511
|
+
projectRoot: options.allSessions ? "" : paths.root,
|
|
512
|
+
commandCwd: options.allSessions ? "" : options.commandCwd,
|
|
513
|
+
limit: Math.max(options.limit, 100),
|
|
514
|
+
});
|
|
492
515
|
} catch {
|
|
493
516
|
return [];
|
|
494
517
|
}
|
|
@@ -521,6 +544,7 @@ export async function listProjectSessions(projectRoot = process.cwd(), limit = 5
|
|
|
521
544
|
updatedAt: state?.updatedAt || pointer.updatedAt || byId.get(sessionId)?.updatedAt || state?.createdAt || "",
|
|
522
545
|
stepsCompleted: state?.stepsCompleted || 0,
|
|
523
546
|
};
|
|
547
|
+
if (!options.allSessions && !sessionMatchesCommandCwd(record, options.commandCwd)) continue;
|
|
524
548
|
byId.set(sessionId, record);
|
|
525
549
|
try {
|
|
526
550
|
upsertSessionIndex({
|
|
@@ -534,7 +558,7 @@ export async function listProjectSessions(projectRoot = process.cwd(), limit = 5
|
|
|
534
558
|
}
|
|
535
559
|
|
|
536
560
|
const sessions = [...byId.values()];
|
|
537
|
-
return sessions.sort((a, b) => String(b.updatedAt).localeCompare(String(a.updatedAt))).slice(0, limit);
|
|
561
|
+
return sessions.sort((a, b) => String(b.updatedAt).localeCompare(String(a.updatedAt))).slice(0, options.limit);
|
|
538
562
|
}
|
|
539
563
|
|
|
540
564
|
export async function showProjectSession(projectRoot, sessionId) {
|
package/src/session-index.js
CHANGED
|
@@ -120,16 +120,26 @@ export function deleteSessionIndex(sessionId) {
|
|
|
120
120
|
return result.changes > 0;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
export function listSessionIndex({ projectRoot = "", limit = 100 } = {}) {
|
|
123
|
+
export function listSessionIndex({ projectRoot = "", commandCwd = "", limit = 100 } = {}) {
|
|
124
124
|
const db = ensureIndexDb();
|
|
125
125
|
const maxRows = Math.min(Math.max(Number(limit) || 100, 1), 1000);
|
|
126
126
|
const columns = `session_id AS sessionId, project_root AS projectRoot, command_cwd AS commandCwd, project_sessions_dir AS projectSessionsDir,
|
|
127
127
|
session_dir AS sessionDir, provider, model, goal, title, status,
|
|
128
128
|
created_at AS createdAt, updated_at AS updatedAt, ended_at AS endedAt, result, error`;
|
|
129
|
+
const clauses = [];
|
|
130
|
+
const params = [];
|
|
129
131
|
if (projectRoot) {
|
|
132
|
+
clauses.push("project_root = ?");
|
|
133
|
+
params.push(path.resolve(projectRoot));
|
|
134
|
+
}
|
|
135
|
+
if (commandCwd) {
|
|
136
|
+
clauses.push("command_cwd = ?");
|
|
137
|
+
params.push(path.resolve(commandCwd));
|
|
138
|
+
}
|
|
139
|
+
if (clauses.length > 0) {
|
|
130
140
|
return db
|
|
131
|
-
.prepare(`SELECT ${columns} FROM sessions WHERE
|
|
132
|
-
.all(
|
|
141
|
+
.prepare(`SELECT ${columns} FROM sessions WHERE ${clauses.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`)
|
|
142
|
+
.all(...params, maxRows);
|
|
133
143
|
}
|
|
134
144
|
return db.prepare(`SELECT ${columns} FROM sessions ORDER BY updated_at DESC LIMIT ?`).all(maxRows);
|
|
135
145
|
}
|