pi-aia-asf 0.14.0 → 0.14.1

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 (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/index.ts +36 -2
  3. package/package.json +6 -5
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.1] - 2026-11-04
11
+
12
+ ### Added
13
+
14
+ - (describe changes for 0.14.1)
15
+
10
16
  ## [0.14.0] - 2026-11-02
11
17
 
12
18
  ### Added
package/index.ts CHANGED
@@ -827,8 +827,18 @@ export default function register(pi: ExtensionAPI): void {
827
827
  // as final and notification-only, while `agent_before_settle` is the final
828
828
  // actionable boundary. And nothing here awaits a resumed run: the loop guard
829
829
  // documents a production hang caused by exactly that.
830
- pi.on("agent_before_settle", () => {
830
+ pi.on("agent_before_settle", async () => {
831
831
  try {
832
+ // The completion gate belongs to an ASF run. Without this check it judged
833
+ // every session that happened to load ASF — a plain question in a scratch
834
+ // directory was held to the same evidence bar as a delivered feature.
835
+ // While pi refused a contentless continuation the gate was inert and
836
+ // nobody noticed; once the continuation actually resumed the run, the
837
+ // gate began interrupting work that never asked for ASF. An ASF run is
838
+ // active when /asf has set a phase for this project and it has not ended.
839
+ const state = await loadState(projectName());
840
+ if (!state.current || state.current.phase === "none") return undefined;
841
+
832
842
  const decision = decideSettlement(ledger, {
833
843
  scale: currentScale(),
834
844
  webTouched,
@@ -845,7 +855,31 @@ export default function register(pi: ExtensionAPI): void {
845
855
  continuationsRequested++;
846
856
  // One bounded continuation naming exactly what is missing. No UI prompt:
847
857
  // this sends the agent back to work, it does not ask anyone anything.
848
- return { continue: true };
858
+ //
859
+ // The continuation MUST carry content. pi commits `entries` and only
860
+ // then re-checks whether the context can run another provider request;
861
+ // at settle time the context ends with the assistant's own message, so
862
+ // a bare `{ continue: true }` is refused with
863
+ // "agent_before_settle requested continuation without runnable model
864
+ // context" and the agent is never told what was missing. A
865
+ // `custom_message` entry projects to a user-role message, which is what
866
+ // makes the next request runnable — and it is the only thing that can
867
+ // deliver the missing list to the model.
868
+ const list = decision.missing.map((item: string) => `- ${item}`).join("\n");
869
+ return {
870
+ entries: [
871
+ {
872
+ type: "custom_message",
873
+ customType: "asf-completion-gate",
874
+ content:
875
+ `ASF completion gate: this run cannot settle yet. Missing:\n${list}\n\n` +
876
+ `Close these now, then let the run settle. Bounded: continuation ${continuationsRequested} of ${MAX_CONTINUATIONS}.`,
877
+ display: true,
878
+ details: { missing: decision.missing, continuation: continuationsRequested },
879
+ },
880
+ ],
881
+ continue: true,
882
+ };
849
883
  }
850
884
  return undefined;
851
885
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-aia-asf",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Ai Applied Agentic Software Factory — codifies the full software development flow: intake, research, spec capture, adversarial analysis, planning with approval gates, test-first implementation, and release. Requires pi-vigilant, pi-smart-web-search, pi-smart-fetch, and pi-aia-browser.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -46,8 +46,8 @@
46
46
  ]
47
47
  },
48
48
  "peerDependencies": {
49
- "@earendil-works/pi-ai": "*",
50
49
  "@earendil-works/pi-agent-core": "*",
50
+ "@earendil-works/pi-ai": "*",
51
51
  "@earendil-works/pi-coding-agent": "*",
52
52
  "typebox": "*"
53
53
  },
@@ -66,9 +66,10 @@
66
66
  }
67
67
  },
68
68
  "devDependencies": {
69
- "@earendil-works/pi-agent-core": "1.2.0",
70
- "@earendil-works/pi-ai": "1.2.0",
71
- "@earendil-works/pi-coding-agent": "1.2.0",
69
+ "@earendil-works/pi-agent-core": "1.5.0",
70
+ "@earendil-works/pi-ai": "1.5.0",
71
+ "@earendil-works/pi-coding-agent": "1.5.0",
72
+ "jiti": "^2.7.0",
72
73
  "typebox": "1.3.27",
73
74
  "typescript": "5.9.3"
74
75
  }