@lazyingart/agintiflow 0.12.5 → 0.12.6

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 CHANGED
@@ -67,7 +67,7 @@ aginti
67
67
  aginti chat
68
68
  ```
69
69
 
70
- Inside chat, type normal requests such as `write a small Python CLI app with tests`. The default is Docker workspace mode with approved package installs, so coding, plotting, and LaTeX tasks can set up project-local tools without touching the host. Use `/help` for commands, `/login` or `/auth` to paste a provider key, `/instructions` to inspect `AGINTI.md`, `/latex on` for PDF work, `/docker off` only when you intentionally want host mode, `/sessions` to list project runs, and `/resume latest` or `/resume <session-id>` to continue work. Type `/` then Tab for command completion. `Ctrl+J` inserts a new line in the colored input panel, Enter sends, arrow keys move through wrapped multiline input, and `Ctrl+A`/`Ctrl+E` jump to the current line start/end. During an active run, Enter sends the draft as an ASAP pipe message (`→`) and Tab queues it for after the run (`↳`); ASAP messages are consumed first, Alt+Up edits the last piped message, and Shift+Left edits the last after-finish queued message. The input panel always shows the current `cwd` footer. Assistant responses start on a fresh line after the `aginti>` header and render common Markdown, including headings, inline code, bold text, lists, quotes, code fences, and tables. Esc or Ctrl+C stops the active run cleanly and prints the resume command.
70
+ Inside chat, type normal requests such as `write a small Python CLI app with tests`. The default is Docker workspace mode with approved package installs, so coding, plotting, and LaTeX tasks can set up project-local tools without touching the host. Use `/help` for commands, `/login` or `/auth` to paste a provider key, `/instructions` to inspect `AGINTI.md`, `/latex on` for PDF work, `/docker off` only when you intentionally want host mode, `/sessions` to list project runs, and `/resume latest` or `/resume <session-id>` to continue work. Type `/` then Tab for command completion. `Ctrl+J` inserts a new line in the colored input panel, Enter sends, arrow keys move through wrapped multiline input, and `Ctrl+A`/`Ctrl+E` jump to the current line start/end. During an active run, Enter sends the draft as an ASAP pipe message (`→`) and Tab queues it for after the run (`↳`); ASAP messages are consumed first, Alt+Up edits the last piped message, and Shift+Left edits the last after-finish queued message. The input panel always shows the current `cwd` footer. Assistant responses start on a fresh line after the `aginti>` header with a colored response gutter and render common Markdown, including headings, inline code, bold text, lists, quotes, code fences, and tables. Resuming a session prints a compact recent-chat preview before the prompt. Esc or Ctrl+C stops the active run cleanly and prints the resume command.
71
71
 
72
72
  `aginti init` creates `AGINTI.md` at the project root. This is the editable project-instruction file for both CLI and web runs, similar to `AGENTS.md` or project memory in other agents. Keep durable preferences, commands, and constraints there, but never secrets. You can edit it manually or ask in chat, for example: `update AGINTI.md to remember that this project uses pytest and npm run check`.
73
73
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.12.5",
3
+ "version": "0.12.6",
4
4
  "type": "module",
5
5
  "description": "AgInTiFlow is a resumable Playwright website-control agent with OpenAI-compatible tool calling.",
6
6
  "license": "Apache-2.0",
@@ -122,21 +122,24 @@ try {
122
122
  if (!result.stdout.includes("status=running workingOn=") || !result.stdout.includes("status=idle session=")) {
123
123
  throw new Error("interactive chat did not print simple run status updates");
124
124
  }
125
- if (!/aginti>\s+\|\r?\nMock run complete\./.test(result.stdout)) {
126
- throw new Error("assistant response did not start on a fresh line after the aginti header");
125
+ if (!/aginti>\s*\r?\n\s*\|\s+Mock run complete\./.test(result.stdout)) {
126
+ throw new Error("assistant response did not render with a fresh-line response gutter");
127
127
  }
128
128
 
129
129
  const latest = await runCli(["resume"], "/exit\n");
130
130
  if (!latest.stdout.includes("session=") || !latest.stdout.includes("Interactive agent chat")) {
131
131
  throw new Error("bare aginti resume did not open the latest session interactively");
132
132
  }
133
+ if (!latest.stdout.includes("resume history") || !latest.stdout.includes("Mock run complete")) {
134
+ throw new Error("bare aginti resume did not preview saved chat history");
135
+ }
133
136
 
134
137
  console.log(
135
138
  JSON.stringify(
136
139
  {
137
140
  ok: true,
138
141
  projectRoot: tempRoot,
139
- checks: ["markdown-render", "prompt-layout", "live-input-layout", "agent-response-newline", "aginti-md", "instructions-command", "instructions-chat-edit", "interactive-chat", "mock-file-write", "run-status", "resume-latest"],
142
+ checks: ["markdown-render", "prompt-layout", "live-input-layout", "agent-response-gutter", "aginti-md", "instructions-command", "instructions-chat-edit", "interactive-chat", "mock-file-write", "run-status", "resume-latest", "resume-history-preview"],
140
143
  },
141
144
  null,
142
145
  2
@@ -3,7 +3,7 @@ import { emitKeypressEvents } from "node:readline";
3
3
  import { stdin as input, stdout as output } from "node:process";
4
4
  import { runAgent } from "./agent-runner.js";
5
5
  import { loadConfig } from "./config.js";
6
- import { initProject, listProjectSessions, providerKeyStatus, readProjectInstructions, setProviderKey } from "./project.js";
6
+ import { initProject, listProjectSessions, projectPaths, providerKeyStatus, readProjectInstructions, setProviderKey } from "./project.js";
7
7
  import { normalizePackageInstallPolicy, normalizeSandboxMode } from "./command-policy.js";
8
8
  import { defaultMaxStepsForProfile, normalizeTaskProfile } from "./task-profiles.js";
9
9
  import { recommendedMaxStepsForTask } from "./engineering-guidance.js";
@@ -27,6 +27,7 @@ const ansi = {
27
27
  cursorShow: "\x1b[?25h",
28
28
  userBg: "\x1b[48;5;24m\x1b[38;5;231m",
29
29
  agentBg: "\x1b[48;5;29m\x1b[38;5;231m",
30
+ responseBg: "\x1b[48;5;25m\x1b[38;5;231m",
30
31
  systemBg: "\x1b[48;5;236m\x1b[38;5;245m",
31
32
  };
32
33
  const brandPalette = ["\x1b[38;5;45m", "\x1b[38;5;81m", "\x1b[38;5;86m", "\x1b[38;5;118m", "\x1b[38;5;226m"];
@@ -275,6 +276,10 @@ function rolePrefix(name, bgCode) {
275
276
  return `${label(name, bgCode)} ${color("|", bgCode)} `;
276
277
  }
277
278
 
279
+ function responsePrefix() {
280
+ return `${color(" | ", ansi.responseBg)} `;
281
+ }
282
+
278
283
  function printWrapped(prefix, text, { stripCode = "" } = {}) {
279
284
  const rendered = stripMarkdown(text);
280
285
  const lines = rendered.split("\n");
@@ -287,10 +292,10 @@ function printWrapped(prefix, text, { stripCode = "" } = {}) {
287
292
  }
288
293
 
289
294
  function printAgentMessage(text) {
290
- outputLine(rolePrefix("aginti>", ansi.agentBg).trimEnd());
295
+ outputLine(label("aginti>", ansi.agentBg).trimEnd());
291
296
  const rendered = stripMarkdown(text);
292
297
  const lines = rendered.split("\n");
293
- for (const line of lines) outputLine(line);
298
+ for (const line of lines) outputLine(`${responsePrefix()}${line}`);
294
299
  }
295
300
 
296
301
  function printSystemLine(text) {
@@ -1181,6 +1186,34 @@ async function latestSession() {
1181
1186
  return sessions[0] || null;
1182
1187
  }
1183
1188
 
1189
+ function compactHistoryText(content = "", limit = 170) {
1190
+ const rendered = stripAnsi(stripMarkdown(String(content || "")));
1191
+ return compactLine(rendered.replace(/\s+/g, " "), limit);
1192
+ }
1193
+
1194
+ function printHistoryEntry(entry) {
1195
+ const role = entry.role === "assistant" ? "aginti" : entry.role === "user" ? "user" : String(entry.role || "note");
1196
+ const bg = role === "aginti" ? ansi.agentBg : role === "user" ? ansi.userBg : ansi.systemBg;
1197
+ const time = entry.at ? new Date(entry.at).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) : "";
1198
+ const suffix = time ? ` ${color(time, ansi.dim)}` : "";
1199
+ outputLine(`${label(role, bg)} ${color("|", bg)} ${compactHistoryText(entry.content)}${suffix}`);
1200
+ }
1201
+
1202
+ async function printResumeHistory(state, { limit = 8 } = {}) {
1203
+ if (!state.sessionId) return;
1204
+ const store = new SessionStore(projectPaths(process.cwd()).sessionsDir, state.sessionId);
1205
+ const saved = await store.loadState().catch(() => null);
1206
+ const chat = Array.isArray(saved?.chat) ? saved.chat.filter((entry) => entry?.content) : [];
1207
+ if (chat.length === 0) {
1208
+ printSystemLine(`resume history session=${state.sessionId} messages=0`);
1209
+ return;
1210
+ }
1211
+
1212
+ const shown = chat.slice(-limit);
1213
+ printSystemLine(`resume history session=${state.sessionId} showing=${shown.length}/${chat.length}`);
1214
+ for (const entry of shown) printHistoryEntry(entry);
1215
+ }
1216
+
1184
1217
  function printStatusEvent(state, label, details = "") {
1185
1218
  state.lastEvent = details ? `${label}: ${details}` : label;
1186
1219
  printSystemLine(`status=${state.status || "running"} ${state.lastEvent}`);
@@ -1404,10 +1437,12 @@ async function handleCommand(line, state, packageDir) {
1404
1437
  } else {
1405
1438
  state.sessionId = latest.sessionId;
1406
1439
  printAgentMessage(`Resuming latest ${formatSessionLine(latest)}`);
1440
+ await printResumeHistory(state);
1407
1441
  }
1408
1442
  } else {
1409
1443
  state.sessionId = value;
1410
1444
  printAgentMessage(`Resuming ${state.sessionId}`);
1445
+ await printResumeHistory(state);
1411
1446
  }
1412
1447
  return true;
1413
1448
  }
@@ -1643,6 +1678,7 @@ export async function startInteractiveCli(args = {}, { packageDir, packageVersio
1643
1678
  await maybeOnboardDeepSeekKey(state);
1644
1679
  printAgentMessage("Interactive agent chat. Type /help for commands, /exit to quit.");
1645
1680
  printStatus(state);
1681
+ await printResumeHistory(state);
1646
1682
 
1647
1683
  try {
1648
1684
  while (true) {