pi-goal-x 0.10.1 → 0.10.2
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 -3
- package/extensions/goal.ts +4 -51
- package/extensions/prompts/goal-prompts.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,10 +10,10 @@ The extension is designed around one rule: **the user owns intent; the agent exe
|
|
|
10
10
|
|
|
11
11
|
All core features of [@capyup/pi-goal](https://github.com/capyup/pi-goal) are preserved. The following changes are specific to pi-goal-x:
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### Goal objective is immutable
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
- **`apply_goal_tweak`**
|
|
15
|
+
- The goal objective is immutable — the agent **must not** modify it autonomously. Objective changes are only possible through `apply_goal_tweak`, which is gated behind the user-initiated `/goal-tweak` drafting flow. This prevents the agent from silently changing the goal contract.
|
|
16
|
+
- **`apply_goal_tweak`** is the sole mechanism for updating the objective, available exclusively during a `/goal-tweak` drafting interview. If the user's requirements change, they must run `/goal-tweak` to initiate the revision flow.
|
|
17
17
|
|
|
18
18
|
### Deferred archival
|
|
19
19
|
|
package/extensions/goal.ts
CHANGED
|
@@ -106,7 +106,6 @@ import {
|
|
|
106
106
|
shouldInjectPostCompactReminder,
|
|
107
107
|
validateGoalAbort,
|
|
108
108
|
validateGoalCompletion,
|
|
109
|
-
validateGoalUpdate,
|
|
110
109
|
validatePauseGoal,
|
|
111
110
|
validateResumeGoal,
|
|
112
111
|
} from "./goal-policy.ts";
|
|
@@ -1707,73 +1706,27 @@ export default function goalExtension(pi: ExtensionAPI): void {
|
|
|
1707
1706
|
"Do not call update_goal merely because work is stopping, substantial progress was made, or tests passed without covering every requirement.",
|
|
1708
1707
|
"Do not use update_goal=complete as an escape hatch when you are blocked. If you are blocked, call pause_goal({reason, suggestedAction?}) instead so the user can intervene.",
|
|
1709
1708
|
"For sisyphus goals, do not mark complete until every numbered step has been executed and individually verified against its done criterion.",
|
|
1710
|
-
"If the user gives requirements, feedback, or corrections that differ from the goal objective, the
|
|
1709
|
+
"The goal objective is immutable. The agent MUST NOT modify the goal objective on its own initiative. If the user gives requirements, feedback, or corrections that differ from the goal objective, ask the user to run /goal-tweak to revise the goal. Use goal_question to confirm when the change is ambiguous.",
|
|
1711
1710
|
"If you have just run the test suite successfully and the tests all pass, include a testResults object with the exit code (0) and relevant output. The auditor will see this evidence and can skip re-running the tests.",
|
|
1712
1711
|
],
|
|
1713
1712
|
parameters: Type.Object({
|
|
1714
1713
|
status: Type.Optional(StringEnum([COMPLETE_STATUS] as const, { description: "Set to complete only when the objective is achieved." })),
|
|
1715
1714
|
completionSummary: Type.Optional(Type.String({ description: "Concise completion claim and evidence summary passed to the independent auditor agent." })),
|
|
1716
1715
|
confirmBypassAuditor: Type.Optional(Type.Boolean({ description: "Set to true to confirm bypassing the independent auditor when it is disabled in settings." })),
|
|
1717
|
-
|
|
1716
|
+
|
|
1718
1717
|
testResults: Type.Optional(Type.Object({
|
|
1719
1718
|
exitCode: Type.Number({ description: "Exit code of the test run (0 = success)" }),
|
|
1720
1719
|
suiteName: Type.Optional(Type.String({ description: "Test suite name, e.g. 'npm test'" })),
|
|
1721
1720
|
output: Type.Optional(Type.String({ description: "Last lines of test output showing results" })),
|
|
1722
1721
|
timestamp: Type.Optional(Type.String({ description: "ISO timestamp of when tests were run" })),
|
|
1723
1722
|
}, { description: "Structured test evidence passed to the auditor so it can skip redundant test re-runs. If you have just run the test suite successfully, include this so the auditor accepts the results without re-running." })),
|
|
1724
|
-
}),
|
|
1723
|
+
}, { additionalProperties: false }),
|
|
1725
1724
|
executionMode: "sequential",
|
|
1726
1725
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
1727
1726
|
reconcileFocusedGoalFromDisk(ctx);
|
|
1728
1727
|
|
|
1729
|
-
// -- Phase 1: Objective update (quick sync) --
|
|
1730
|
-
// Apply updatedObjective before any completion logic so the completion
|
|
1731
|
-
// flow (if status=complete is also set) reads the latest objective.
|
|
1732
|
-
if (params.updatedObjective !== undefined) {
|
|
1733
|
-
const newObjective = params.updatedObjective.trim();
|
|
1734
|
-
if (!newObjective) throw new Error("update_goal requires a non-empty updatedObjective.");
|
|
1735
|
-
const updateGate = validateGoalUpdate({ goal: state.goal });
|
|
1736
|
-
if (!updateGate.ok) {
|
|
1737
|
-
return {
|
|
1738
|
-
content: [{ type: "text", text: updateGate.message }],
|
|
1739
|
-
details: goalDetails(state.goal),
|
|
1740
|
-
};
|
|
1741
|
-
}
|
|
1742
|
-
if (!state.goal) throw new Error("Goal disappeared during objective update.");
|
|
1743
|
-
const next: GoalRecord = {
|
|
1744
|
-
...state.goal,
|
|
1745
|
-
objective: newObjective,
|
|
1746
|
-
updatedAt: nowIso(),
|
|
1747
|
-
};
|
|
1748
|
-
state.goal = writeActiveGoalFile(ctx, next);
|
|
1749
|
-
pi.appendEntry(STATE_ENTRY, goalDetails(state.goal));
|
|
1750
|
-
try {
|
|
1751
|
-
appendGoalEvent(ctx, {
|
|
1752
|
-
type: "goal_tweaked",
|
|
1753
|
-
goalId: state.goal.id,
|
|
1754
|
-
changeSummary: "Objective updated via update_goal",
|
|
1755
|
-
at: state.goal.updatedAt,
|
|
1756
|
-
});
|
|
1757
|
-
} catch {
|
|
1758
|
-
// Ledger append failure should not block update
|
|
1759
|
-
}
|
|
1760
|
-
updateUI(ctx);
|
|
1761
|
-
|
|
1762
|
-
// Quick sync only (no status=complete) — return without terminating
|
|
1763
|
-
if (params.status !== COMPLETE_STATUS) {
|
|
1764
|
-
return {
|
|
1765
|
-
content: [{ type: "text", text: `Goal objective updated.` }],
|
|
1766
|
-
details: goalDetails(state.goal),
|
|
1767
|
-
};
|
|
1768
|
-
}
|
|
1769
|
-
// Fall through: status=complete also set, proceed with completion below
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
1728
|
// -- Phase 2: Status validation --
|
|
1773
1729
|
if (params.status !== COMPLETE_STATUS) {
|
|
1774
|
-
if (params.updatedObjective === undefined) {
|
|
1775
|
-
throw new Error("update_goal requires either status=complete or updatedObjective.");
|
|
1776
|
-
}
|
|
1777
1730
|
throw new Error("update_goal requires status=complete when marking a goal complete.");
|
|
1778
1731
|
}
|
|
1779
1732
|
|
|
@@ -2074,7 +2027,7 @@ export default function goalExtension(pi: ExtensionAPI): void {
|
|
|
2074
2027
|
};
|
|
2075
2028
|
},
|
|
2076
2029
|
renderCall(args, theme) {
|
|
2077
|
-
const label = args?.status ??
|
|
2030
|
+
const label = args?.status ?? "";
|
|
2078
2031
|
return new Text(theme.fg("toolTitle", "update_goal ") + theme.fg("success", label), 0, 0);
|
|
2079
2032
|
},
|
|
2080
2033
|
renderResult(result, _options, theme) {
|
|
@@ -48,7 +48,7 @@ If the user explicitly asks to abandon/cancel this goal, or the objective is obs
|
|
|
48
48
|
|
|
49
49
|
Do NOT silently invent workarounds, fake completion, or quietly redefine the objective. Do NOT call update_goal=complete to escape a blocker.
|
|
50
50
|
|
|
51
|
-
Goal evolution: if the user gives requirements, feedback, or corrections that differ from the goal objective, the goal is stale.
|
|
51
|
+
Goal evolution: if the user gives requirements, feedback, or corrections that differ from the goal objective, the goal is stale. The goal objective is immutable — the agent must NOT modify it autonomously. Propose the updated objective concisely and ask the user to run /goal-tweak to revise it. Do NOT mark the goal complete with a stale objective.${sisyphusDisciplineBlock(goal) ? `\n${sisyphusDisciplineBlock(goal)}` : ""}`;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
export function continuationPrompt(goal: GoalRecord): string {
|
|
@@ -83,7 +83,7 @@ export function continuationPrompt(goal: GoalRecord): string {
|
|
|
83
83
|
"Do not call update_goal unless the goal is complete enough to survive independent semantic auditing. Do not mark a goal complete merely because work is stopping.",
|
|
84
84
|
"Do not ask the user for confirmation unless there is a real blocker.",
|
|
85
85
|
"",
|
|
86
|
-
"Goal evolution: if the user gives requirements, feedback, or corrections that differ from the goal objective, the goal is stale.
|
|
86
|
+
"Goal evolution: if the user gives requirements, feedback, or corrections that differ from the goal objective, the goal is stale. The goal objective is immutable — the agent must NOT modify it autonomously. Propose the updated objective concisely and ask the user to run /goal-tweak to revise it. Do NOT mark the goal complete with a stale objective.",
|
|
87
87
|
"",
|
|
88
88
|
"If you hit a real blocker (missing credentials, contradictory spec, file/permission you cannot access, dangerous operation pending user approval, or an unclear Sisyphus-style ordered plan), call pause_goal({reason, suggestedAction?}) and stop. If the user explicitly asks to abandon/cancel, or the objective is obsolete, impossible, or unsafe to continue, call abort_goal({reason}) and stop. Do not silently invent workarounds. Do not fake completion. pause_goal and abort_goal are structured lifecycle exits; update_goal=complete is not an escape hatch for blockers.",
|
|
89
89
|
...(goal.sisyphus ? ["", sisyphusDisciplineBlock(goal)] : []),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-x",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Goal mode extension for pi: persistent long-running objectives, /goal-set drafting, Sisyphus prompt style, autoContinue, and an above-editor status overlay. Fork of @capyup/pi-goal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "pi-goal-x contributors",
|