@lazyingart/agintiflow 0.20.25 → 0.20.39

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.
Files changed (63) hide show
  1. package/README.md +9 -4
  2. package/docs/agent-runtime-pipe.md +5 -4
  3. package/docs/cli-i18n.md +1 -1
  4. package/docs/project-agent-lessons.md +1 -1
  5. package/docs/real-deepseek-capabilities.md +1 -1
  6. package/docs/self-development-supervision.md +1 -2
  7. package/docs/skills-and-tools.md +1 -1
  8. package/docs/supervised-capability-curriculum.md +111 -0
  9. package/package.json +9 -3
  10. package/public/app.js +4 -0
  11. package/references/backend-frontend-artifact-tunnel.md +3 -3
  12. package/references/general-task-capability-taxonomy.md +109 -0
  13. package/references/supervision-student-recursive-training.md +116 -0
  14. package/scripts/smoke-auto-update.js +96 -0
  15. package/scripts/smoke-auxiliary-tools.js +1 -0
  16. package/scripts/smoke-canvas-artifacts.js +67 -0
  17. package/scripts/smoke-capabilities.js +51 -2
  18. package/scripts/smoke-cli-chat.js +2 -0
  19. package/scripts/smoke-coding-tools.js +41 -0
  20. package/scripts/smoke-inbox.js +40 -1
  21. package/scripts/smoke-skills.js +53 -1
  22. package/scripts/smoke-toolchain-docker.js +1 -0
  23. package/scripts/smoke-web-api.js +6 -1
  24. package/skills/android/SKILL.md +2 -1
  25. package/skills/code-review/SKILL.md +24 -0
  26. package/skills/data-analysis/SKILL.md +29 -0
  27. package/skills/database/SKILL.md +27 -0
  28. package/skills/devops-deployment/SKILL.md +29 -0
  29. package/skills/docs-knowledge/SKILL.md +28 -0
  30. package/skills/dotnet-csharp/SKILL.md +24 -0
  31. package/skills/education-tutorial/SKILL.md +26 -0
  32. package/skills/go/SKILL.md +23 -0
  33. package/skills/ios-swift/SKILL.md +26 -0
  34. package/skills/java-jvm/SKILL.md +25 -0
  35. package/skills/php/SKILL.md +24 -0
  36. package/skills/presentation-slides/SKILL.md +26 -0
  37. package/skills/qa-testing/SKILL.md +27 -0
  38. package/skills/ruby/SKILL.md +24 -0
  39. package/skills/rust/SKILL.md +23 -0
  40. package/skills/security-review/SKILL.md +28 -0
  41. package/skills/supervision-student/SKILL.md +67 -0
  42. package/skills/writing-editing/SKILL.md +28 -0
  43. package/src/agent-runner.js +49 -7
  44. package/src/artifact-tunnel.js +75 -4
  45. package/src/auto-update.js +389 -0
  46. package/src/capabilities.js +6 -1
  47. package/src/cli.js +129 -14
  48. package/src/config.js +6 -2
  49. package/src/engineering-guidance.js +12 -2
  50. package/src/interactive-cli.js +42 -5
  51. package/src/model-client.js +2 -2
  52. package/src/model-routing.js +3 -1
  53. package/src/parallel-scouts.js +17 -1
  54. package/src/project.js +200 -20
  55. package/src/session-index.js +135 -0
  56. package/src/session-store.js +67 -3
  57. package/src/skill-library.js +16 -2
  58. package/src/sqlite.js +19 -0
  59. package/src/static-preview-server.js +8 -1
  60. package/src/task-profiles.js +318 -5
  61. package/src/web-db.js +58 -6
  62. package/src/workspace-tools.js +1 -0
  63. package/web.js +37 -11
@@ -3,14 +3,14 @@ export const TASK_PROFILES = {
3
3
  id: "auto",
4
4
  label: "Auto",
5
5
  prompt:
6
- "Act as the general-purpose AgInTiFlow agent. Infer the task type from the request, then choose the right mix of browser, shell, files, web search, canvas, and sandbox tools. For short tasks, use the smallest safe tool sequence that completes the work. For codebase, writing, website, LaTeX, system, debugging, migration, or multi-language tasks, automatically borrow the relevant specialized profile habits without becoming narrowly constrained.",
6
+ "Act as the general-purpose AgInTiFlow agent. Infer the task type from the request, then choose the right mix of browser, shell, files, web search, canvas, and sandbox tools. For short tasks, use the smallest safe tool sequence that completes the work. For codebase, writing, website, LaTeX, system, debugging, migration, data cleanup, reporting, or multi-language tasks, automatically borrow the relevant specialized profile habits without becoming narrowly constrained. When you create or repair a deliverable, verify the produced output and polish obvious noise, duplicates, broken formatting, stale filenames, or misleading summaries before finalizing.",
7
7
  tools: ["browser", "shell", "files", "canvas", "inspect_project"],
8
8
  },
9
9
  code: {
10
10
  id: "code",
11
11
  label: "Code writing",
12
12
  prompt:
13
- "Bias toward coding-agent behavior across languages, but remain a general assistant when the task needs docs, shell, web, or design work. Inspect project instructions/manifests/conventions, edit workspace files with patches, run useful focused checks, iterate on failures, and report changed files plus residual risks.",
13
+ "Bias toward coding-agent behavior across languages, but remain a general assistant when the task needs docs, shell, web, or design work. Inspect project instructions/manifests/conventions, edit workspace files with patches, run useful focused checks, iterate on failures, clean or ignore agent/build artifacts appropriately, and report changed files plus residual risks. If optional lint/style cleanup starts to expand beyond the requested fix, prioritize functional checks and explicitly report the remaining style scope instead of exhausting the run.",
14
14
  tools: ["inspect_project", "files", "shell", "sandbox"],
15
15
  },
16
16
  "large-codebase": {
@@ -27,6 +27,34 @@ export const TASK_PROFILES = {
27
27
  "Bias toward long-form writing quality without refusing adjacent research, code, or formatting tasks. Create structured drafts with outlines, sections, revision notes, and saved files for durable output. Use web search when current sources matter and canvas for important drafts.",
28
28
  tools: ["files", "canvas"],
29
29
  },
30
+ research: {
31
+ id: "research",
32
+ label: "Research",
33
+ prompt:
34
+ "Bias toward careful research while remaining able to write, code, plot, or format results. Clarify the research question, gather current sources when needed with web_search, distinguish evidence from inference, save durable notes or summaries with citations, and surface important artifacts through canvas.",
35
+ tools: ["web_search", "files", "canvas", "shell"],
36
+ },
37
+ paper: {
38
+ id: "paper",
39
+ label: "Academic paper",
40
+ prompt:
41
+ "Bias toward academic paper and manuscript production while still handling code, figures, literature, and LaTeX. Build an outline, define claims and contributions, keep sources traceable, create or update durable manuscript files, compile/check outputs when possible, and save PDFs/figures with descriptive paths.",
42
+ tools: ["files", "shell", "web_search", "canvas", "sandbox"],
43
+ },
44
+ book: {
45
+ id: "book",
46
+ label: "Book writing",
47
+ prompt:
48
+ "Bias toward book-scale structure while staying useful for research, code snippets, figures, and publication tooling. Maintain a chapter map, outline before drafting, write durable chapter files, preserve voice/style notes, and produce revision checklists instead of one-off chat-only prose.",
49
+ tools: ["files", "web_search", "canvas"],
50
+ },
51
+ novel: {
52
+ id: "novel",
53
+ label: "Novel writing",
54
+ prompt:
55
+ "Bias toward fiction craft while still supporting research and formatting. Track premise, characters, arcs, scenes, continuity, tone, and chapter files; draft in durable files and use canvas for important scenes or outlines.",
56
+ tools: ["files", "web_search", "canvas"],
57
+ },
30
58
  design: {
31
59
  id: "design",
32
60
  label: "Design docs",
@@ -34,6 +62,76 @@ export const TASK_PROFILES = {
34
62
  "Bias toward clear product/engineering design while remaining able to implement or test when asked. Produce concise design documents with goals, constraints, options, tradeoffs, implementation steps, verification criteria, and decision records.",
35
63
  tools: ["files", "canvas"],
36
64
  },
65
+ docs: {
66
+ id: "docs",
67
+ label: "Documentation",
68
+ prompt:
69
+ "Bias toward documentation work across README, API references, tutorials, changelogs, architecture notes, and user guides while still inspecting code when accuracy depends on it. Read the relevant source/config first, write durable markdown or docs-site files, include runnable examples when useful, verify links/commands where practical, and keep the docs structured for future maintenance.",
70
+ tools: ["inspect_project", "search_files", "read_file", "write_file", "apply_patch", "shell", "canvas"],
71
+ },
72
+ data: {
73
+ id: "data",
74
+ label: "Data analysis",
75
+ prompt:
76
+ "Bias toward reproducible data analysis, cleanup, ETL, visualization, and report generation while staying able to write scripts or docs. Inspect data shape and schema first, preserve raw inputs, create cleaned outputs with descriptive filenames, run deterministic scripts/notebooks where available, save plots/reports as durable artifacts, and explain assumptions and data quality issues.",
77
+ tools: ["inspect_project", "files", "shell", "canvas", "sandbox"],
78
+ },
79
+ qa: {
80
+ id: "qa",
81
+ label: "QA and testing",
82
+ prompt:
83
+ "Bias toward quality assurance, failing-test repair, regression reproduction, CI debugging, and test design. When a real failure exists, reproduce it first, minimize the failing case, patch the smallest cause, add or update tests when useful, run focused checks before broad suites, and report exact commands plus remaining coverage gaps. When asked to create a testing project from scratch, produce a clean runnable project with meaningful tests; do not stage fake bugs, misleading tests, or artificial failures unless the user explicitly asks for a bug-reproduction exercise. Before finalizing, remove stale interrupted drafts, generated caches, and contradictory comments or README text.",
84
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
85
+ },
86
+ database: {
87
+ id: "database",
88
+ label: "Database",
89
+ prompt:
90
+ "Bias toward database, SQL, schema, migration, seed data, query, and persistence work while still handling application code. Inspect existing migrations/models/schema first, back up or use disposable fixtures before destructive changes, prefer reversible migrations, run syntax or smoke checks when tools exist, and stop on ambiguous data-loss choices.",
91
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
92
+ },
93
+ devops: {
94
+ id: "devops",
95
+ label: "DevOps and deployment",
96
+ prompt:
97
+ "Bias toward Docker, CI/CD, deployment, services, environment setup, logs, ports, and runtime operations. Diagnose with read-only commands first, prefer project-local or containerized changes, make setup scripts idempotent, avoid host sudo unless explicitly approved, verify with build/health/log checks, and provide rollback or manual steps when automation is unsafe.",
98
+ tools: ["inspect_project", "files", "shell", "web_search", "sandbox"],
99
+ },
100
+ security: {
101
+ id: "security",
102
+ label: "Security review",
103
+ prompt:
104
+ "Bias toward security review, threat modeling, secrets hygiene, dependency risks, auth/session logic, input validation, and safe automation. Gather evidence before changing code, never print secrets, distinguish exploitable risk from style concern, patch minimal high-impact issues, run relevant scanners/tests when available, and stop before destructive or credential-sensitive actions.",
105
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "web_search", "sandbox"],
106
+ },
107
+ slides: {
108
+ id: "slides",
109
+ label: "Slides and presentations",
110
+ prompt:
111
+ "Bias toward presentation, pitch deck, poster, lecture, and slide-style communication. Clarify audience and purpose from available context, create a durable outline and slide files or markdown deck, keep each slide visually focused, include speaker notes when useful, and export/preview when local tools support it.",
112
+ tools: ["files", "shell", "canvas", "web_search"],
113
+ },
114
+ education: {
115
+ id: "education",
116
+ label: "Education and tutorials",
117
+ prompt:
118
+ "Bias toward teaching, tutorials, courses, exercises, examples, and explanatory walkthroughs. Identify learner level, build from objectives to examples to checks, create durable lesson files, include exercises/solutions when useful, and verify code/math examples where possible.",
119
+ tools: ["files", "shell", "web_search", "canvas"],
120
+ },
121
+ supervision: {
122
+ id: "supervision",
123
+ label: "Supervision",
124
+ prompt:
125
+ "Bias toward supervising another agent or long-running task instead of doing the target work directly. Define acceptance criteria, give the student agent normal user-level prompts, monitor progress through tmux/session logs/artifacts, independently verify claims, record evidence, and convert repeated failures into reusable AgInTiFlow skills, tools, policies, tests, or profile improvements.",
126
+ tools: ["shell", "files", "canvas", "inspect_project", "tmux"],
127
+ },
128
+ app: {
129
+ id: "app",
130
+ label: "App builder",
131
+ prompt:
132
+ "Bias toward end-to-end app delivery across web, desktop, mobile, and local tools. Inspect the existing stack first, choose the smallest coherent architecture, implement real files, run build/test/preview/install checks when available, save artifacts with good names, and keep git status explicit.",
133
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox", "canvas"],
134
+ },
37
135
  python: {
38
136
  id: "python",
39
137
  label: "Python",
@@ -55,11 +153,74 @@ export const TASK_PROFILES = {
55
153
  "Bias toward Node/JavaScript/TypeScript workflows without excluding frontend, backend, docs, or deployment work. Inspect package.json/lockfiles, respect the package manager, add tests when useful, and run safe npm/node checks when available.",
56
154
  tools: ["files", "shell", "sandbox"],
57
155
  },
156
+ java: {
157
+ id: "java",
158
+ label: "Java/JVM",
159
+ prompt:
160
+ "Bias toward Java, Kotlin JVM, Maven, Gradle, Spring, and JUnit work while staying useful for docs, shell, and deployment tasks. Inspect pom.xml, build.gradle, settings.gradle, wrapper files, source sets, and test layout before editing. Prefer project-local Maven/Gradle wrappers, run focused compile/test tasks, and avoid global JDK/toolchain mutation unless explicitly approved.",
161
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
162
+ },
163
+ ios: {
164
+ id: "ios",
165
+ label: "iOS/Swift",
166
+ prompt:
167
+ "Bias toward iOS, Swift, SwiftUI, Xcode, Swift Package Manager, simulator, and Apple-platform work while staying useful for design/docs. Inspect Package.swift, .xcodeproj/.xcworkspace, schemes, Info.plist, signing constraints, xcodebuild availability, and simulator devices before editing. Prefer build/test with project-local settings, save screenshots when a simulator is available, and stop cleanly on signing or missing-Xcode blockers.",
168
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "canvas"],
169
+ },
170
+ go: {
171
+ id: "go",
172
+ label: "Go",
173
+ prompt:
174
+ "Bias toward Go modules, CLIs, servers, tests, and tooling. Inspect go.mod, packages, commands, and tests before editing. Use gofmt, go test ./... when practical, keep module changes intentional, and report environment blockers such as missing Go or private modules.",
175
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
176
+ },
177
+ rust: {
178
+ id: "rust",
179
+ label: "Rust",
180
+ prompt:
181
+ "Bias toward Rust crates, Cargo workspaces, CLIs, services, tests, and safety-oriented fixes. Inspect Cargo.toml, workspace members, features, source modules, and tests before editing. Use cargo fmt/check/test when available, avoid broad dependency churn, and explain borrow/lifetime or unsafe tradeoffs clearly.",
182
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
183
+ },
184
+ dotnet: {
185
+ id: "dotnet",
186
+ label: ".NET/C#",
187
+ prompt:
188
+ "Bias toward .NET, C#, F#, ASP.NET, console apps, tests, and NuGet projects. Inspect .sln, .csproj, Program.cs, appsettings, and test projects before editing. Use dotnet restore/build/test when available, keep generated bin/obj out of commits, and stop on SDK or credential blockers.",
189
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
190
+ },
191
+ php: {
192
+ id: "php",
193
+ label: "PHP",
194
+ prompt:
195
+ "Bias toward PHP, Composer, Laravel/Symfony, WordPress-style projects, CLIs, and tests. Inspect composer.json, framework config, routes, migrations, and tests before editing. Use composer scripts, php -l, and PHPUnit/Pest when available; avoid changing global PHP extensions unless explicitly approved.",
196
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
197
+ },
198
+ ruby: {
199
+ id: "ruby",
200
+ label: "Ruby",
201
+ prompt:
202
+ "Bias toward Ruby, Rails, Bundler, gems, Rake tasks, and tests. Inspect Gemfile, gemspec, config/routes.rb, migrations, and tests before editing. Use bundle exec rake/test/rspec when available, keep bundle/vendor artifacts out of commits, and stop on native gem or credential blockers.",
203
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
204
+ },
205
+ "c-cpp": {
206
+ id: "c-cpp",
207
+ label: "C/C++",
208
+ prompt:
209
+ "Bias toward C and C++ development while still handling docs, scripts, and system setup. Inspect CMake/Make/build files, patch source carefully, prefer out-of-tree builds, run focused compile/test checks, and use sanitizers/debuggers only when available and safe.",
210
+ tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox"],
211
+ },
212
+ "r-stan": {
213
+ id: "r-stan",
214
+ label: "R/Stan",
215
+ prompt:
216
+ "Bias toward R, Stan, statistics, reproducible analysis, and research code. Inspect renv/DESCRIPTION/scripts/data layout, keep outputs reproducible, prefer project-local libraries or Docker, run Rscript/CmdStan checks when available, and save plots/reports as durable artifacts.",
217
+ tools: ["inspect_project", "files", "shell", "web_search", "canvas", "sandbox"],
218
+ },
58
219
  android: {
59
220
  id: "android",
60
221
  label: "Android",
61
222
  prompt:
62
- "Bias toward end-to-end Android app delivery while still handling normal project work. Inspect git status, existing Gradle files, AndroidManifest, SDK paths, Java/Kotlin versions, adb devices, and emulator/AVD availability before editing. Do not use host sudo, apt, dnf, yum, brew, winget, or global host installs during Android tasks; prefer the existing Android SDK, project-local Gradle wrapper, user-writable caches, or a clear setup report. Create missing wrapper directories before downloads, avoid repeated failing install attempts, build with focused Gradle tasks, install and launch with adb when a device/emulator exists, verify with am/logcat/screencap when possible, and commit the finished app only after checks.",
223
+ "Bias toward end-to-end Android app delivery while still handling normal project work. Inspect git status, existing Gradle files, AndroidManifest, SDK paths, Java/Kotlin versions, adb devices, and emulator/AVD availability before editing. Do not use host sudo, apt, dnf, yum, brew, winget, or global host installs during Android tasks; prefer the existing Android SDK, project-local Gradle wrapper, user-writable caches, or a clear setup report. Create missing wrapper directories before downloads, avoid repeated failing install attempts, build with focused Gradle tasks, install and launch with adb when a device/emulator exists, verify with am/logcat/screencap when possible, save screenshots under durable workspace paths, and commit the finished app only after checks.",
63
224
  tools: ["inspect_project", "search_files", "read_file", "apply_patch", "shell", "sandbox", "canvas"],
64
225
  },
65
226
  website: {
@@ -83,6 +244,20 @@ export const TASK_PROFILES = {
83
244
  "Bias toward AAPS workflows while still handling normal project work. Recognize .aaps folders and @lazyingart/aaps conventions, keep work project-local, document assumptions, and avoid secrets or publishing unless explicitly requested.",
84
245
  tools: ["files", "shell", "sandbox"],
85
246
  },
247
+ github: {
248
+ id: "github",
249
+ label: "GitHub maintenance",
250
+ prompt:
251
+ "Bias toward safe git and GitHub maintenance while still fixing code/docs when asked. Always inspect git status and remotes first, separate unrelated changes, run relevant checks before commits, use gh when available for PR/issues/releases, prefer fast-forward pulls, and stop on conflicts or ambiguous history.",
252
+ tools: ["shell", "files", "web_search", "inspect_project"],
253
+ },
254
+ word: {
255
+ id: "word",
256
+ label: "Word documents",
257
+ prompt:
258
+ "Bias toward Word/docx/document workflows while still using writing, conversion, LaTeX, or scripts when useful. Preserve originals, create clear output filenames, use available local tools such as pandoc/libreoffice/python packages when present, and verify generated documents exist before reporting success.",
259
+ tools: ["files", "shell", "canvas", "sandbox"],
260
+ },
86
261
  latex: {
87
262
  id: "latex",
88
263
  label: "LaTeX",
@@ -100,17 +275,124 @@ export const TASK_PROFILES = {
100
275
  };
101
276
 
102
277
  const PROFILE_ALIASES = {
278
+ default: "auto",
279
+ general: "auto",
103
280
  large: "large-codebase",
104
281
  codebase: "large-codebase",
105
282
  repo: "large-codebase",
106
283
  repository: "large-codebase",
107
284
  engineering: "large-codebase",
108
285
  engineer: "large-codebase",
286
+ application: "app",
287
+ apps: "app",
109
288
  mobile: "android",
110
289
  apk: "android",
111
290
  gradle: "android",
112
- kotlin: "android",
113
- java: "android",
291
+ kotlin: "java",
292
+ jvm: "java",
293
+ java: "java",
294
+ maven: "java",
295
+ spring: "java",
296
+ ios: "ios",
297
+ iphone: "ios",
298
+ ipad: "ios",
299
+ swift: "ios",
300
+ swiftui: "ios",
301
+ xcode: "ios",
302
+ go: "go",
303
+ golang: "go",
304
+ rust: "rust",
305
+ cargo: "rust",
306
+ dotnet: "dotnet",
307
+ ".net": "dotnet",
308
+ csharp: "dotnet",
309
+ "c#": "dotnet",
310
+ aspnet: "dotnet",
311
+ php: "php",
312
+ composer: "php",
313
+ laravel: "php",
314
+ symfony: "php",
315
+ ruby: "ruby",
316
+ rails: "ruby",
317
+ bundler: "ruby",
318
+ frontend: "website",
319
+ web: "website",
320
+ site: "website",
321
+ documentation: "docs",
322
+ docs: "docs",
323
+ readme: "docs",
324
+ tutorial: "docs",
325
+ changelog: "docs",
326
+ manual: "docs",
327
+ data: "data",
328
+ analysis: "data",
329
+ analytics: "data",
330
+ csv: "data",
331
+ etl: "data",
332
+ dataframe: "data",
333
+ qa: "qa",
334
+ test: "qa",
335
+ testing: "qa",
336
+ ci: "qa",
337
+ regression: "qa",
338
+ database: "database",
339
+ db: "database",
340
+ sql: "database",
341
+ sqlite: "database",
342
+ postgres: "database",
343
+ devops: "devops",
344
+ deploy: "devops",
345
+ deployment: "devops",
346
+ docker: "devops",
347
+ k8s: "devops",
348
+ kubernetes: "devops",
349
+ security: "security",
350
+ sec: "security",
351
+ audit: "security",
352
+ secrets: "security",
353
+ auth: "security",
354
+ slides: "slides",
355
+ slide: "slides",
356
+ presentation: "slides",
357
+ deck: "slides",
358
+ powerpoint: "slides",
359
+ pptx: "slides",
360
+ education: "education",
361
+ teach: "education",
362
+ course: "education",
363
+ lesson: "education",
364
+ manuscript: "paper",
365
+ academic: "paper",
366
+ article: "paper",
367
+ report: "paper",
368
+ literature: "research",
369
+ sources: "research",
370
+ chapter: "book",
371
+ fiction: "novel",
372
+ story: "novel",
373
+ supervise: "supervision",
374
+ supervisor: "supervision",
375
+ student: "supervision",
376
+ training: "supervision",
377
+ homework: "supervision",
378
+ curriculum: "supervision",
379
+ selfsupervision: "supervision",
380
+ "self-supervision": "supervision",
381
+ cpp: "c-cpp",
382
+ "c++": "c-cpp",
383
+ clang: "c-cpp",
384
+ cmake: "c-cpp",
385
+ r: "r-stan",
386
+ stan: "r-stan",
387
+ statistics: "r-stan",
388
+ git: "github",
389
+ gh: "github",
390
+ release: "github",
391
+ docx: "word",
392
+ office: "word",
393
+ system: "maintenance",
394
+ sysadmin: "maintenance",
395
+ computer: "maintenance",
114
396
  };
115
397
 
116
398
  export function listTaskProfiles() {
@@ -129,8 +411,39 @@ export function getTaskProfile(value = "auto") {
129
411
 
130
412
  export function defaultMaxStepsForProfile(value = "auto") {
131
413
  const profile = normalizeTaskProfile(value);
414
+ if (profile === "code") return 36;
132
415
  if (profile === "large-codebase") return 36;
416
+ if (profile === "qa") return 40;
417
+ if (profile === "app") return 40;
133
418
  if (profile === "android") return 60;
134
419
  if (profile === "latex") return 30;
420
+ if (profile === "supervision") return 40;
421
+ if (["devops", "security"].includes(profile)) return 36;
422
+ if (
423
+ [
424
+ "paper",
425
+ "research",
426
+ "book",
427
+ "novel",
428
+ "docs",
429
+ "data",
430
+ "database",
431
+ "slides",
432
+ "education",
433
+ "java",
434
+ "ios",
435
+ "go",
436
+ "rust",
437
+ "dotnet",
438
+ "php",
439
+ "ruby",
440
+ "c-cpp",
441
+ "r-stan",
442
+ "github",
443
+ "word",
444
+ "maintenance",
445
+ ].includes(profile)
446
+ )
447
+ return 30;
135
448
  return 24;
136
449
  }
package/src/web-db.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { DatabaseSync } from "node:sqlite";
4
3
  import { getModelPresets, getModelRoleDefaults } from "./model-routing.js";
5
4
  import { resolveLanguage } from "./i18n.js";
5
+ import { projectPaths } from "./project.js";
6
+ import { deleteSessionIndex, renameSessionIndex, upsertSessionIndex } from "./session-index.js";
7
+ import { loadDatabaseSync } from "./sqlite.js";
6
8
 
7
9
  const PREFERENCES_SCHEMA_VERSION = 7;
8
10
 
@@ -52,10 +54,12 @@ function defaultPreferences(baseDir) {
52
54
 
53
55
  export class WebDatabase {
54
56
  constructor(baseDir) {
55
- this.baseDir = baseDir;
56
- this.dbDir = path.join(baseDir, ".sessions");
57
- this.dbPath = path.join(this.dbDir, "web-state.sqlite");
57
+ this.baseDir = path.resolve(baseDir);
58
+ this.paths = projectPaths(this.baseDir);
59
+ this.dbDir = this.paths.sessionsDir;
60
+ this.dbPath = this.paths.sessionDbPath;
58
61
  fs.mkdirSync(this.dbDir, { recursive: true });
62
+ const DatabaseSync = loadDatabaseSync();
59
63
  this.db = new DatabaseSync(this.dbPath);
60
64
  this.db.exec(`
61
65
  CREATE TABLE IF NOT EXISTS preferences (
@@ -85,6 +89,18 @@ export class WebDatabase {
85
89
  if (!sessionColumns.some((column) => column.name === "title")) {
86
90
  this.db.exec("ALTER TABLE sessions ADD COLUMN title TEXT NOT NULL DEFAULT ''");
87
91
  }
92
+ if (!sessionColumns.some((column) => column.name === "project_root")) {
93
+ this.db.exec("ALTER TABLE sessions ADD COLUMN project_root TEXT NOT NULL DEFAULT ''");
94
+ }
95
+ if (!sessionColumns.some((column) => column.name === "command_cwd")) {
96
+ this.db.exec("ALTER TABLE sessions ADD COLUMN command_cwd TEXT NOT NULL DEFAULT ''");
97
+ }
98
+ if (!sessionColumns.some((column) => column.name === "project_sessions_dir")) {
99
+ this.db.exec("ALTER TABLE sessions ADD COLUMN project_sessions_dir TEXT NOT NULL DEFAULT ''");
100
+ }
101
+ if (!sessionColumns.some((column) => column.name === "session_dir")) {
102
+ this.db.exec("ALTER TABLE sessions ADD COLUMN session_dir TEXT NOT NULL DEFAULT ''");
103
+ }
88
104
  }
89
105
 
90
106
  getPreferences() {
@@ -156,12 +172,21 @@ export class WebDatabase {
156
172
 
157
173
  upsertSession(session) {
158
174
  const updatedAt = session.updatedAt || new Date().toISOString();
175
+ const projectRoot = session.projectRoot || this.baseDir;
176
+ const commandCwd = session.commandCwd || projectRoot;
177
+ const projectSessionsDir = session.projectSessionsDir || this.paths.sessionsDir;
178
+ const sessionDir = session.sessionDir || path.join(this.paths.globalSessionsDir, session.sessionId);
159
179
  this.db
160
180
  .prepare(
161
181
  `INSERT INTO sessions (
162
- session_id, provider, model, goal, title, status, started_at, updated_at, ended_at, result, error
163
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
182
+ session_id, project_root, command_cwd, project_sessions_dir, session_dir,
183
+ provider, model, goal, title, status, started_at, updated_at, ended_at, result, error
184
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
164
185
  ON CONFLICT(session_id) DO UPDATE SET
186
+ project_root = excluded.project_root,
187
+ command_cwd = excluded.command_cwd,
188
+ project_sessions_dir = excluded.project_sessions_dir,
189
+ session_dir = excluded.session_dir,
165
190
  provider = excluded.provider,
166
191
  model = excluded.model,
167
192
  goal = excluded.goal,
@@ -174,6 +199,10 @@ export class WebDatabase {
174
199
  )
175
200
  .run(
176
201
  session.sessionId,
202
+ projectRoot,
203
+ commandCwd,
204
+ projectSessionsDir,
205
+ sessionDir,
177
206
  session.provider,
178
207
  session.model,
179
208
  session.goal,
@@ -185,6 +214,19 @@ export class WebDatabase {
185
214
  session.result || "",
186
215
  session.error || ""
187
216
  );
217
+ try {
218
+ upsertSessionIndex({
219
+ ...session,
220
+ projectRoot,
221
+ commandCwd,
222
+ projectSessionsDir,
223
+ sessionDir,
224
+ createdAt: session.startedAt,
225
+ updatedAt,
226
+ });
227
+ } catch {
228
+ // The project-local database remains the fallback if the global index cannot be updated.
229
+ }
188
230
  }
189
231
 
190
232
  getSession(sessionId) {
@@ -193,6 +235,10 @@ export class WebDatabase {
193
235
  .prepare(
194
236
  `SELECT
195
237
  session_id AS sessionId,
238
+ project_root AS projectRoot,
239
+ command_cwd AS commandCwd,
240
+ project_sessions_dir AS projectSessionsDir,
241
+ session_dir AS sessionDir,
196
242
  provider,
197
243
  model,
198
244
  goal,
@@ -215,6 +261,10 @@ export class WebDatabase {
215
261
  .prepare(
216
262
  `SELECT
217
263
  session_id AS sessionId,
264
+ project_root AS projectRoot,
265
+ command_cwd AS commandCwd,
266
+ project_sessions_dir AS projectSessionsDir,
267
+ session_dir AS sessionDir,
218
268
  provider,
219
269
  model,
220
270
  goal,
@@ -237,11 +287,13 @@ export class WebDatabase {
237
287
  const result = this.db
238
288
  .prepare("UPDATE sessions SET title = ?, updated_at = ? WHERE session_id = ?")
239
289
  .run(title, updatedAt, sessionId);
290
+ if (result.changes > 0) renameSessionIndex(sessionId, title);
240
291
  return result.changes > 0;
241
292
  }
242
293
 
243
294
  deleteSession(sessionId) {
244
295
  const result = this.db.prepare("DELETE FROM sessions WHERE session_id = ?").run(sessionId);
296
+ if (result.changes > 0) deleteSessionIndex(sessionId);
245
297
  return result.changes > 0;
246
298
  }
247
299
  }
@@ -16,6 +16,7 @@ const DEFAULT_MAX_DEPTH = 4;
16
16
  const SKIP_DIRS = new Set([
17
17
  ".git",
18
18
  ".sessions",
19
+ ".aginti-sessions",
19
20
  ".aginti",
20
21
  "node_modules",
21
22
  "dist",
package/web.js CHANGED
@@ -20,7 +20,15 @@ import { getDockerSandboxStatus, getSandboxLogs, runDockerPreflight } from "./sr
20
20
  import { normalizePackageInstallPolicy, normalizeSandboxMode } from "./src/command-policy.js";
21
21
  import { summarizeWorkspaceTools, WORKSPACE_TOOL_NAMES } from "./src/workspace-tools.js";
22
22
  import { listTaskProfiles, normalizeTaskProfile } from "./src/task-profiles.js";
23
- import { loadProjectEnv, projectPaths, providerKeyStatus, setProviderKey } from "./src/project.js";
23
+ import {
24
+ ensureProjectSessionStorage,
25
+ listProjectSessions,
26
+ loadProjectEnv,
27
+ projectPaths,
28
+ providerKeyStatus,
29
+ renameProjectSession,
30
+ setProviderKey,
31
+ } from "./src/project.js";
24
32
  import { buildCapabilityReport } from "./src/capabilities.js";
25
33
  import { listSkills } from "./src/skill-library.js";
26
34
  import { platformInfo, platformLabel, platformSetupHints } from "./src/platform.js";
@@ -38,8 +46,11 @@ const __dirname = path.dirname(__filename);
38
46
  const packageDir = __dirname;
39
47
  const packageJson = JSON.parse(await fs.readFile(path.join(packageDir, "package.json"), "utf8"));
40
48
  const baseDir = path.resolve(process.env.AGINTIFLOW_RUNTIME_DIR || process.cwd());
41
- const sessionsDir = path.join(baseDir, ".sessions");
49
+ const storagePaths = projectPaths(baseDir);
50
+ const sessionsDir = storagePaths.globalSessionsDir;
51
+ const projectSessionsDir = storagePaths.sessionsDir;
42
52
  loadProjectEnv(baseDir);
53
+ await ensureProjectSessionStorage(baseDir);
43
54
 
44
55
  const app = express();
45
56
  const port = Number(process.env.PORT || 3210);
@@ -48,7 +59,11 @@ const runs = new Map();
48
59
  const db = new WebDatabase(baseDir);
49
60
 
50
61
  function sessionStore(sessionId) {
51
- return new SessionStore(sessionsDir, sessionId);
62
+ return new SessionStore(sessionsDir, sessionId, {
63
+ projectRoot: baseDir,
64
+ projectSessionsDir,
65
+ legacySessionDir: path.join(storagePaths.legacySessionsDir, sessionId),
66
+ });
52
67
  }
53
68
 
54
69
  function isSafeSessionId(sessionId) {
@@ -322,7 +337,8 @@ function deriveSessionRecordFromState(state, existing = null) {
322
337
  provider: state.provider || existing?.provider || "deepseek",
323
338
  model: state.model || existing?.model || getProviderDefaults(state.provider || existing?.provider || "deepseek").model,
324
339
  goal: state.goal || existing?.goal || "",
325
- title: existing?.title || "",
340
+ title: state.title || existing?.title || "",
341
+ commandCwd: state.commandCwd || existing?.commandCwd || baseDir,
326
342
  status,
327
343
  startedAt: state.createdAt || existing?.startedAt || new Date().toISOString(),
328
344
  updatedAt,
@@ -333,17 +349,19 @@ function deriveSessionRecordFromState(state, existing = null) {
333
349
  }
334
350
 
335
351
  async function syncStoredSessions() {
336
- const entries = await fs.readdir(sessionsDir, { withFileTypes: true }).catch(() => []);
337
-
338
- for (const entry of entries) {
339
- if (!entry.isDirectory()) continue;
340
-
341
- const store = sessionStore(entry.name);
352
+ const sessions = await listProjectSessions(baseDir, 500);
353
+ for (const session of sessions) {
354
+ const store = sessionStore(session.sessionId);
342
355
  const state = await store.loadState();
343
356
  if (!state?.sessionId) continue;
344
357
 
345
358
  const existing = db.getSession(state.sessionId);
346
- db.upsertSession(deriveSessionRecordFromState(state, existing));
359
+ db.upsertSession({
360
+ ...deriveSessionRecordFromState(state, existing),
361
+ projectRoot: baseDir,
362
+ projectSessionsDir,
363
+ sessionDir: store.sessionDir,
364
+ });
347
365
  }
348
366
  }
349
367
 
@@ -546,6 +564,10 @@ function createRunRecord(config, goal, existingLogs = []) {
546
564
  provider: config.provider,
547
565
  model: config.model,
548
566
  goal,
567
+ projectRoot: baseDir,
568
+ commandCwd: config.commandCwd,
569
+ projectSessionsDir,
570
+ sessionDir: path.join(sessionsDir, config.sessionId),
549
571
  startedAt: new Date().toISOString(),
550
572
  updatedAt: new Date().toISOString(),
551
573
  endedAt: "",
@@ -615,8 +637,10 @@ app.get("/api/config", async (_req, res) => {
615
637
  root: paths.root,
616
638
  commandCwd: config.commandCwd,
617
639
  sessionsDir,
640
+ projectSessionsDir,
618
641
  sessionDbPath: paths.sessionDbPath,
619
642
  sharedSessionFolder: path.resolve(config.sessionsDir) === path.resolve(sessionsDir),
643
+ globalSessionIndexPath: paths.globalSessionIndexPath,
620
644
  localEnvPresent: keyStatus.localEnv,
621
645
  platform: {
622
646
  ...platform,
@@ -926,6 +950,7 @@ app.patch("/api/sessions/:sessionId", async (req, res) => {
926
950
  return;
927
951
  }
928
952
 
953
+ await renameProjectSession(baseDir, sessionId, title);
929
954
  db.renameSession(sessionId, title);
930
955
  await sessionStore(sessionId).appendEvent("session.renamed", { title }).catch(() => {});
931
956
  res.json({ ok: true, session: db.getSession(sessionId) });
@@ -945,6 +970,7 @@ app.post("/api/sessions/:sessionId/auto-title", async (req, res) => {
945
970
  }
946
971
 
947
972
  const title = autoSessionTitleFromChat(data);
973
+ await renameProjectSession(baseDir, sessionId, title);
948
974
  db.renameSession(sessionId, title);
949
975
  await sessionStore(sessionId).appendEvent("session.auto_renamed", { title }).catch(() => {});
950
976
  res.json({ ok: true, session: db.getSession(sessionId) });