@lazyingart/agintiflow 0.20.80 → 0.20.82

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
@@ -270,7 +270,7 @@ Inside chat:
270
270
  /aaps dry-run workflows/main.aaps
271
271
  ```
272
272
 
273
- Use AAPS when the task is bigger than a single chat: app development with stages, paper/book workflows, validation gates, recovery steps, artifact production, or top-down agentic scripts. See [docs/aaps.md](docs/aaps.md) and the package [https://www.npmjs.com/package/@lazyingart/aaps](https://www.npmjs.com/package/@lazyingart/aaps).
273
+ Use AAPS when the task is bigger than a single chat: app development with stages, paper/book workflows, validation gates, recovery steps, artifact production, or top-down agentic scripts. The current adapter is intentionally lightweight: prompt-only AAPS tasks are reported as handoffs and do not automatically execute an LLM/backend agent yet, so AgInTiFlow warns when a run has no executable steps or misses a declared output. See [docs/aaps.md](docs/aaps.md) and the package [https://www.npmjs.com/package/@lazyingart/aaps](https://www.npmjs.com/package/@lazyingart/aaps).
274
274
 
275
275
  ## Local API Quick Reference
276
276
 
package/docs/aaps.md CHANGED
@@ -42,6 +42,8 @@ The adapter keeps paths project-relative and uses `execFile`, not shell interpol
42
42
 
43
43
  `compile check` and `validate` are the recommended first checks. `run` can execute commands declared by the `.aaps` workflow, so treat it like any other project execution step and run only workflows you intend to execute.
44
44
 
45
+ Current lightweight adapter boundary: prompt-only AAPS tasks are recorded as handoffs. They do not automatically call an LLM/backend agent yet. When a workflow has prompt-only steps, `aginti aaps run` and `aginti aaps dry-run` print `promptOnly=<n>` plus warnings if no executable steps ran or a declared output was not produced.
46
+
45
47
  `aginti aaps install` installs `@lazyingart/aaps` as a project dev dependency only when the current project has `package.json`. Use `aginti aaps install global` only when you intentionally want a global npm install.
46
48
 
47
49
  ## Project Shape
@@ -56,7 +58,7 @@ runs/
56
58
  artifacts/
57
59
  ```
58
60
 
59
- The starter workflow is deliberately simple: it defines a planner agent and a `draft_plan` task that writes `reports/aaps-plan.md`. Use it as a safe scaffold, then expand the workflow with blocks, validations, recovery steps, and review gates.
61
+ The starter workflow is deliberately simple: it defines a planner agent and a `draft_plan` task whose declared output is `reports/aaps-plan.md`. With the current lightweight adapter this task is prompt-only, so `run` produces durable run metadata and a handoff warning rather than writing the plan itself. Use AgInTiFlow to act on that handoff, or expand the workflow with executable actions, validations, recovery steps, and review gates.
60
62
 
61
63
  ## When To Use AAPS
62
64
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyingart/agintiflow",
3
- "version": "0.20.80",
3
+ "version": "0.20.82",
4
4
  "type": "module",
5
5
  "description": "Low-cost, project-aware Web and CLI agents with DeepSeek/Venice/OpenAI routing, visible tool calls, durable sessions, scouts, AAPS, SCS, and guarded local execution.",
6
6
  "license": "Apache-2.0",
@@ -45,6 +45,21 @@ if (discovery.found) {
45
45
  const compile = await runAapsAction("compile", ["check"], { cwd: tempRoot, packageDir: repoRoot });
46
46
  assert(compile.json?.phase?.parse === "ok", `AAPS compile check did not return a structured parse-ok report\n${formatAapsResult(compile)}`);
47
47
  assert(compile.ok && compile.json?.ok === true, `AAPS starter should compile cleanly after init\n${formatAapsResult(compile)}`);
48
+
49
+ const dryRun = await runAapsAction("dry-run", [], { cwd: tempRoot, packageDir: repoRoot });
50
+ const dryRunText = formatAapsResult(dryRun);
51
+ assert(dryRun.ok && dryRun.json?.dryRun === true, `AAPS dry-run failed\n${dryRunText}`);
52
+ assert(dryRunText.includes("promptOnly=1"), `AAPS dry-run summary should expose prompt-only steps\n${dryRunText}`);
53
+ assert(dryRunText.includes("did not execute an LLM/backend agent"), `AAPS dry-run should warn about prompt-only handoff\n${dryRunText}`);
54
+
55
+ const run = await runAapsAction("run", [], { cwd: tempRoot, packageDir: repoRoot });
56
+ const runText = formatAapsResult(run);
57
+ assert(run.ok && run.json?.dryRun === false, `AAPS run failed\n${runText}`);
58
+ assert(runText.includes("promptOnly=1"), `AAPS run summary should expose prompt-only steps\n${runText}`);
59
+ assert(
60
+ run.missingDeclaredOutputs?.includes("reports/aaps-plan.md") && runText.includes("declared output(s) not present after run"),
61
+ `AAPS run should report missing declared outputs for prompt-only starter workflows\n${runText}`
62
+ );
48
63
  } else {
49
64
  const validate = await runAapsAction("validate", [], { cwd: tempRoot, packageDir: repoRoot });
50
65
  assert(validate.ok === false && validate.error, "AAPS missing path should return a structured error");
@@ -57,7 +72,7 @@ console.log(
57
72
  tempRoot,
58
73
  realAaps: discovery.found,
59
74
  source: discovery.source || "",
60
- checks: ["init", "files", "status", discovery.found ? "validate/parse/compile" : "missing-error"],
75
+ checks: ["init", "files", "status", discovery.found ? "validate/parse/compile/dry-run/run-warnings" : "missing-error"],
61
76
  },
62
77
  null,
63
78
  2
@@ -474,6 +474,65 @@ async function runDiscoveredAaps(discovery, cliArgs, { timeoutMs = DEFAULT_TIMEO
474
474
  }
475
475
  }
476
476
 
477
+ function relativeIfInside(root, value = "") {
478
+ const text = String(value || "").trim();
479
+ if (!text) return "";
480
+ const resolved = path.isAbsolute(text) ? path.resolve(text) : path.resolve(root, text);
481
+ const relative = path.relative(root, resolved);
482
+ if (relative === "" || relative.startsWith("..") || path.isAbsolute(relative)) return "";
483
+ return toProjectPath(relative);
484
+ }
485
+
486
+ async function annotateAapsRunResult(result, { action = "", projectDir = "" } = {}) {
487
+ if (!["run", "dry-run"].includes(action) || !result?.json || typeof result.json !== "object") return result;
488
+ const json = result.json;
489
+ const warnings = [];
490
+ const plan = json.plan || {};
491
+ const promptOnlySteps = Number(plan.promptOnlySteps || 0);
492
+ const executableSteps = Number(plan.executableSteps || 0);
493
+ if (promptOnlySteps > 0) {
494
+ warnings.push(
495
+ `workflow has ${promptOnlySteps} prompt-only step(s); AAPS recorded a handoff but did not execute an LLM/backend agent for those steps`
496
+ );
497
+ }
498
+ if (promptOnlySteps > 0 && executableSteps === 0) {
499
+ warnings.push("workflow has no executable steps; use AgInTiFlow to act on the prompt-only handoff or add executable AAPS actions");
500
+ }
501
+
502
+ const missingDeclaredOutputs = [];
503
+ if (action === "run" && !json.dryRun) {
504
+ const outputEntries = Array.isArray(json.outputs)
505
+ ? json.outputs
506
+ : Array.isArray(json.executionPlan?.outputs)
507
+ ? json.executionPlan.outputs
508
+ : [];
509
+ const runDir = String(json.runDir || "").trim();
510
+ const executionPlanPath = runDir ? path.join(runDir, "execution_plan.json") : "";
511
+ let executionPlan = null;
512
+ if (executionPlanPath && relativeIfInside(projectDir, executionPlanPath)) {
513
+ executionPlan = await readJsonIfExists(executionPlanPath);
514
+ }
515
+ const outputs = outputEntries.length ? outputEntries : Array.isArray(executionPlan?.outputs) ? executionPlan.outputs : [];
516
+ for (const output of outputs) {
517
+ const rawPath = typeof output === "string" ? output : output?.value || output?.path || "";
518
+ const rel = relativeIfInside(projectDir, rawPath);
519
+ if (!rel) continue;
520
+ if (!fsSync.existsSync(path.join(projectDir, rel))) missingDeclaredOutputs.push(rel);
521
+ }
522
+ if (missingDeclaredOutputs.length > 0) {
523
+ warnings.push(`declared output(s) not present after run: ${missingDeclaredOutputs.join(", ")}`);
524
+ }
525
+ }
526
+
527
+ return {
528
+ ...result,
529
+ warnings,
530
+ promptOnlySteps,
531
+ executableSteps,
532
+ missingDeclaredOutputs,
533
+ };
534
+ }
535
+
477
536
  async function createAapsStarterProject({ cwd = process.cwd(), name = "" } = {}) {
478
537
  const projectDir = path.resolve(cwd || process.cwd());
479
538
  const projectName = String(name || path.basename(projectDir) || "AgInTiFlow AAPS Project").trim();
@@ -672,8 +731,9 @@ export async function runAapsAction(action = "status", rawArgs = [], { cwd = pro
672
731
 
673
732
  const built = buildAapsArgs(normalized, commandArgs, { cwd: projectDir });
674
733
  const result = await runDiscoveredAaps(discovery, built.cliArgs, { timeoutMs: built.timeoutMs });
734
+ const annotated = await annotateAapsRunResult(result, { action: built.action, projectDir });
675
735
  return {
676
- ...result,
736
+ ...annotated,
677
737
  action: built.action,
678
738
  projectDir,
679
739
  source: discovery.source,
@@ -696,9 +756,19 @@ function summarizeJson(action, json) {
696
756
  }
697
757
  if (action === "check" || action === "plan" || action === "run" || action === "dry-run") {
698
758
  const ok = json.ok ?? json.ready ?? "";
699
- const steps = json.plan?.steps?.length ?? json.steps?.length ?? "";
759
+ const steps = typeof json.plan?.steps === "number" ? json.plan.steps : (json.plan?.steps?.length ?? json.steps?.length ?? "");
760
+ const executable = json.plan?.executableSteps ?? "";
761
+ const promptOnly = json.plan?.promptOnlySteps ?? "";
700
762
  const runDir = json.runDir || json.runRoot || "";
701
- return `ok=${ok} steps=${steps} runDir=${runDir}`;
763
+ return [
764
+ `ok=${ok}`,
765
+ steps !== "" ? `steps=${steps}` : "",
766
+ executable !== "" ? `executable=${executable}` : "",
767
+ promptOnly !== "" ? `promptOnly=${promptOnly}` : "",
768
+ runDir ? `runDir=${runDir}` : "",
769
+ ]
770
+ .filter(Boolean)
771
+ .join(" ");
702
772
  }
703
773
  return "";
704
774
  }
@@ -750,6 +820,7 @@ export function formatAapsResult(result = {}) {
750
820
  `AAPS ${result.action || "command"} ${result.ok ? "ok" : "failed"}`,
751
821
  result.command ? `command=${result.command}` : "",
752
822
  summary ? `summary=${summary}` : "",
823
+ result.warnings?.length ? `warnings\n${result.warnings.map((warning) => `- ${warning}`).join("\n")}` : "",
753
824
  result.stdout ? `stdout\n${result.stdout.trim()}` : "",
754
825
  result.stderr ? `stderr\n${result.stderr.trim()}` : "",
755
826
  result.error ? `error=${result.error}` : "",