opencode-discipline 0.1.0 → 0.1.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.
- package/dist/index.js +83 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12703,8 +12703,62 @@ function buildCompactionContext(state) {
|
|
|
12703
12703
|
].join(`
|
|
12704
12704
|
`);
|
|
12705
12705
|
}
|
|
12706
|
+
function buildTodoSeedContent(planName) {
|
|
12707
|
+
return `Plan kickoff: ${planName}`;
|
|
12708
|
+
}
|
|
12709
|
+
function buildTodoSeedInstruction(planName, retry) {
|
|
12710
|
+
const content = buildTodoSeedContent(planName);
|
|
12711
|
+
const title = retry ? "## Discipline Plugin \u2014 Todo Seed Retry" : "## Discipline Plugin \u2014 Todo Seed";
|
|
12712
|
+
const intro = retry ? "The plan kickoff todo is still missing in the right panel." : "Before continuing, create the kickoff todo so progress is visible in the right panel.";
|
|
12713
|
+
return [
|
|
12714
|
+
title,
|
|
12715
|
+
intro,
|
|
12716
|
+
"Call `todowrite` now with this item:",
|
|
12717
|
+
`- content: \`${content}\``,
|
|
12718
|
+
"- status: `in_progress`",
|
|
12719
|
+
"- priority: `high`"
|
|
12720
|
+
].join(`
|
|
12721
|
+
`);
|
|
12722
|
+
}
|
|
12723
|
+
function extractTodos(response) {
|
|
12724
|
+
if (Array.isArray(response)) {
|
|
12725
|
+
return response.filter((item) => {
|
|
12726
|
+
return typeof item === "object" && item !== null && typeof item.content === "string" && typeof item.status === "string" && typeof item.priority === "string";
|
|
12727
|
+
});
|
|
12728
|
+
}
|
|
12729
|
+
if (response && typeof response === "object") {
|
|
12730
|
+
const data = response.data;
|
|
12731
|
+
if (Array.isArray(data)) {
|
|
12732
|
+
return extractTodos(data);
|
|
12733
|
+
}
|
|
12734
|
+
}
|
|
12735
|
+
return [];
|
|
12736
|
+
}
|
|
12737
|
+
function hasPlanKickoffTodo(todos, planName) {
|
|
12738
|
+
const planNameLower = planName.toLowerCase();
|
|
12739
|
+
return todos.some((todo) => {
|
|
12740
|
+
const content = todo.content.toLowerCase();
|
|
12741
|
+
return content.includes(planNameLower) && content.includes("plan");
|
|
12742
|
+
});
|
|
12743
|
+
}
|
|
12744
|
+
async function readSessionTodos(client, directory, sessionID) {
|
|
12745
|
+
const sessionApi = client.session;
|
|
12746
|
+
if (!sessionApi || typeof sessionApi.todo !== "function") {
|
|
12747
|
+
return;
|
|
12748
|
+
}
|
|
12749
|
+
try {
|
|
12750
|
+
const response = await sessionApi.todo({
|
|
12751
|
+
query: { directory },
|
|
12752
|
+
path: { id: sessionID }
|
|
12753
|
+
});
|
|
12754
|
+
return extractTodos(response);
|
|
12755
|
+
} catch {
|
|
12756
|
+
return;
|
|
12757
|
+
}
|
|
12758
|
+
}
|
|
12706
12759
|
var DisciplinePlugin = async ({ worktree, directory, client }) => {
|
|
12707
12760
|
const manager = new WaveStateManager(worktree);
|
|
12761
|
+
const todoNudges = new Map;
|
|
12708
12762
|
return {
|
|
12709
12763
|
"experimental.session.compacting": async (input, output) => {
|
|
12710
12764
|
const state = manager.getState(input.sessionID);
|
|
@@ -12725,6 +12779,28 @@ var DisciplinePlugin = async ({ worktree, directory, client }) => {
|
|
|
12725
12779
|
if (currentAgent === "plan" && state.wave < 3) {
|
|
12726
12780
|
output.system.push(buildPlanReadOnlyReminder());
|
|
12727
12781
|
}
|
|
12782
|
+
if (sessionID && currentAgent === "plan" && !state.accepted) {
|
|
12783
|
+
const nudgeState = todoNudges.get(sessionID) ?? {
|
|
12784
|
+
prompted: false,
|
|
12785
|
+
retried: false,
|
|
12786
|
+
seeded: false
|
|
12787
|
+
};
|
|
12788
|
+
const todos = await readSessionTodos(client, directory, sessionID);
|
|
12789
|
+
const hasSeededTodo = todos !== undefined && hasPlanKickoffTodo(todos, state.planName);
|
|
12790
|
+
if (hasSeededTodo) {
|
|
12791
|
+
nudgeState.seeded = true;
|
|
12792
|
+
}
|
|
12793
|
+
if (!nudgeState.seeded) {
|
|
12794
|
+
if (!nudgeState.prompted) {
|
|
12795
|
+
output.system.push(buildTodoSeedInstruction(state.planName, false));
|
|
12796
|
+
nudgeState.prompted = true;
|
|
12797
|
+
} else if (todos !== undefined && !hasSeededTodo && !nudgeState.retried) {
|
|
12798
|
+
output.system.push(buildTodoSeedInstruction(state.planName, true));
|
|
12799
|
+
nudgeState.retried = true;
|
|
12800
|
+
}
|
|
12801
|
+
}
|
|
12802
|
+
todoNudges.set(sessionID, nudgeState);
|
|
12803
|
+
}
|
|
12728
12804
|
},
|
|
12729
12805
|
"tool.execute.before": async (input, output) => {
|
|
12730
12806
|
const filePath = output.args?.filePath;
|
|
@@ -12756,6 +12832,13 @@ var DisciplinePlugin = async ({ worktree, directory, client }) => {
|
|
|
12756
12832
|
try {
|
|
12757
12833
|
const current = manager.getState(args.sessionID);
|
|
12758
12834
|
const state = current ? manager.advanceWave(args.sessionID) : manager.startPlan(args.sessionID);
|
|
12835
|
+
if (!current) {
|
|
12836
|
+
todoNudges.set(args.sessionID, {
|
|
12837
|
+
prompted: false,
|
|
12838
|
+
retried: false,
|
|
12839
|
+
seeded: false
|
|
12840
|
+
});
|
|
12841
|
+
}
|
|
12759
12842
|
const waveName = WAVE_NAMES[state.wave];
|
|
12760
12843
|
const nextStep = WAVE_NEXT_STEPS[state.wave];
|
|
12761
12844
|
return `Wave ${state.wave} (${waveName}) started for plan '${state.planName}'. You may now proceed with ${nextStep}.`;
|