opencode-planpilot 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/docs/planpilot.md CHANGED
@@ -42,6 +42,7 @@ A CLI binary named `planpilot` is available for manual use. If you use the CLI d
42
42
 
43
43
  ## AI Workflow Guidelines
44
44
  - Use Planpilot for all planning, status, and progress tracking; do not use built-in plan/todo tools or other methods to track plan/step/goal status.
45
+ - Do not read plan files from disk or follow plan file placeholders; use the planpilot tool for plan/step/goal info.
45
46
  - Treat tool output as authoritative. Do not invent IDs; only use IDs shown by `list`/`show`.
46
47
  - If the tool is missing or unavailable, ask the user to enable/install the plugin.
47
48
  - Record implementation details using Planpilot comments (plan/step/goal `--comment` or `comment` commands). Before starting a step or goal, think through the next actions and capture that context in comments so the plan stays actionable.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-planpilot",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Planpilot plugin for OpenCode (TypeScript rewrite)",
5
5
  "type": "module",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -9,6 +9,14 @@ import { loadPlanpilotInstructions } from "./lib/instructions"
9
9
 
10
10
  export const PlanpilotPlugin: Plugin = async (ctx) => {
11
11
  const inFlight = new Set<string>()
12
+ const skipNextAuto = new Set<string>()
13
+ const lastIdleAt = new Map<string, number>()
14
+
15
+ const PLANPILOT_GUIDANCE = [
16
+ "Planpilot guidance:",
17
+ "- Do not read plan files from disk or follow plan file placeholders.",
18
+ "- Use the planpilot tool for plan/step/goal info (plan show-active, step show-next, goal list <step_id>).",
19
+ ].join("\n")
12
20
 
13
21
  const log = async (level: "debug" | "info" | "warn" | "error", message: string, extra?: Record<string, any>) => {
14
22
  try {
@@ -27,6 +35,14 @@ export const PlanpilotPlugin: Plugin = async (ctx) => {
27
35
 
28
36
  const handleSessionIdle = async (sessionID: string) => {
29
37
  if (inFlight.has(sessionID)) return
38
+ if (skipNextAuto.has(sessionID)) {
39
+ skipNextAuto.delete(sessionID)
40
+ return
41
+ }
42
+ const lastIdle = lastIdleAt.get(sessionID)
43
+ const now = Date.now()
44
+ if (lastIdle && now - lastIdle < 1000) return
45
+ lastIdleAt.set(sessionID, now)
30
46
  inFlight.add(sessionID)
31
47
  try {
32
48
  const app = new PlanpilotApp(openDatabase(), sessionID)
@@ -42,6 +58,8 @@ export const PlanpilotPlugin: Plugin = async (ctx) => {
42
58
  const message =
43
59
  "Planpilot (auto):\n" +
44
60
  "Before acting, think through the next step and its goals. Record implementation details using Planpilot comments (plan/step/goal --comment or comment commands). Continue with the next step (executor: ai). Do not ask for confirmation; proceed and report results.\n\n" +
61
+ PLANPILOT_GUIDANCE +
62
+ "\n\n" +
45
63
  detail.trimEnd()
46
64
 
47
65
  await ctx.client.session.promptAsync({
@@ -116,6 +134,18 @@ export const PlanpilotPlugin: Plugin = async (ctx) => {
116
134
  if (instructions && !alreadyInjected) {
117
135
  output.system.push(instructions)
118
136
  }
137
+ const guidanceInjected = output.system.some((entry) => entry.includes("Planpilot guidance:"))
138
+ if (!guidanceInjected) {
139
+ output.system.push(PLANPILOT_GUIDANCE)
140
+ }
141
+ },
142
+ "experimental.session.compacting": async ({ sessionID }, output) => {
143
+ const hasGuidance = output.context.some((entry) => entry.includes("Planpilot guidance:"))
144
+ if (!hasGuidance) {
145
+ output.context.push(PLANPILOT_GUIDANCE)
146
+ }
147
+ skipNextAuto.add(sessionID)
148
+ lastIdleAt.set(sessionID, Date.now())
119
149
  },
120
150
  event: async ({ event }) => {
121
151
  if (event.type === "session.idle") {