@trevonistrevon/pi-loop 0.4.1 → 0.4.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/AGENTS.md CHANGED
@@ -32,9 +32,15 @@ src/
32
32
  - Tool descriptions follow Claude Code format: `## When to Use`, `## When NOT to Use`
33
33
  - Cross-extension communication via `pi.events` with `requestId` + reply channels
34
34
  - File-backed stores use atomic write (write tmp → rename) + pid-based file locking
35
- - Widget uses `UICtx.setWidget()` with `render()` callback pattern
35
+ - Runtime tracker UI uses `UICtx.setStatus()` for compact single-line state
36
36
  - Tests co-located in `test/`, named `<module>.test.ts`
37
37
 
38
+ ## Tool Schema Discipline
39
+ - Tool calls must use the exact schema field names from the tool definition. Do not invent aliases.
40
+ - Example: `TaskUpdate` uses `id`, not `taskId`.
41
+ - When a tool validation error clearly indicates an immediately recoverable schema mismatch, correct it silently and retry. Do not emit user-facing chatter like "retrying with the correct shape" unless the recovery itself changes the user's understanding.
42
+ - When adding or revising tool prompt guidance, include concrete parameter-name reminders for commonly miscalled tools.
43
+
38
44
  ## File Locking Pattern
39
45
  Copy TaskStore from pi-tasks: `O_EXCL` lockfile, stale PID detection, `LOCK_RETRY_MS`/`LOCK_MAX_RETRIES`
40
46
 
@@ -44,14 +50,8 @@ Three trigger types, all stored as `LoopEntry.trigger`:
44
50
  - `{ type: "event", source: "tool_execution_start", filter?: "regex:..." | '{"key":"value"}' }` — eventbus-based
45
51
  - `{ type: "hybrid", cron: "...", event: { source, filter? }, debounceMs: 30000 }` — both with debounce
46
52
 
47
- ## Re-wake via System Reminder
48
- When a loop fires, the scheduler calls `onLoopFire()` which emits `pi.events("loop:fire", ...)`. The extension's listener queues a reminder. On the next `tool_result` event, the reminder is injected as `<system-reminder>` text (mirroring pi-tasks' pattern):
49
- ```
50
- <system-reminder>
51
- Scheduled loop "deploy check" fired. Trigger: schedule: */5 * * * *.
52
- [loop:abc12345]
53
- </system-reminder>
54
- ```
53
+ ## Re-wake via In-Memory Pending Notifications
54
+ When a loop fires, the scheduler calls `onLoopFire()` which emits `pi.events("loop:fire", ...)`. The extension buffers a pending notification in memory, re-checks whether the wake is still relevant, and only then injects a `pi.sendMessage()` custom message to wake the agent. Do not rely on early queued follow-up user messages for loop delivery; those are not extension-cancelable once handed to pi's queue.
55
55
 
56
56
  ## Monitor Streaming via PI Events
57
57
  Monitor stdout/stderr lines are emitted as `pi.events("monitor:output", { monitorId, line, timestamp })`. Tool consumers subscribe to these events. Completion emits `"monitor:done"` / `"monitor:error"`.
package/dist/index.js CHANGED
@@ -972,6 +972,10 @@ Fields:
972
972
  - subject: brief actionable title
973
973
  - description: detailed requirements
974
974
  - metadata: optional tags/metadata`,
975
+ promptGuidelines: [
976
+ "Use TaskCreate to track complex multi-step work across turns.",
977
+ "TaskCreate accepts `subject` and `description` parameters only — do not invent extra fields unless the schema explicitly adds them.",
978
+ ],
975
979
  parameters: Type.Object({
976
980
  subject: Type.String({ description: "Brief actionable title for the task" }),
977
981
  description: Type.String({ description: "Detailed description of what needs to be done" }),
@@ -1012,6 +1016,11 @@ Fields:
1012
1016
  description: `Update task status or details. Set status to "in_progress" before starting work, "completed" when done.
1013
1017
 
1014
1018
  Statuses: pending → in_progress → completed`,
1019
+ promptGuidelines: [
1020
+ "Use TaskUpdate with parameter `id`, not `taskId`.",
1021
+ "TaskUpdate accepts only `id`, `status`, `subject`, and `description`.",
1022
+ "When a tool validation error clearly indicates a recoverable schema mismatch, correct the arguments and retry without narrating the recovery unless the user needs to know.",
1023
+ ],
1015
1024
  parameters: Type.Object({
1016
1025
  id: Type.String({ description: "Task ID to update" }),
1017
1026
  status: Type.Optional(Type.String({ description: "New status", enum: ["pending", "in_progress", "completed"] })),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trevonistrevon/pi-loop",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "A pi extension for cron/event-based agent re-wake loops and background process monitoring.",
5
5
  "author": "trevonistrevon",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -1057,6 +1057,10 @@ Fields:
1057
1057
  - subject: brief actionable title
1058
1058
  - description: detailed requirements
1059
1059
  - metadata: optional tags/metadata`,
1060
+ promptGuidelines: [
1061
+ "Use TaskCreate to track complex multi-step work across turns.",
1062
+ "TaskCreate accepts `subject` and `description` parameters only — do not invent extra fields unless the schema explicitly adds them.",
1063
+ ],
1060
1064
  parameters: Type.Object({
1061
1065
  subject: Type.String({ description: "Brief actionable title for the task" }),
1062
1066
  description: Type.String({ description: "Detailed description of what needs to be done" }),
@@ -1099,6 +1103,11 @@ Fields:
1099
1103
  description: `Update task status or details. Set status to "in_progress" before starting work, "completed" when done.
1100
1104
 
1101
1105
  Statuses: pending → in_progress → completed`,
1106
+ promptGuidelines: [
1107
+ "Use TaskUpdate with parameter `id`, not `taskId`.",
1108
+ "TaskUpdate accepts only `id`, `status`, `subject`, and `description`.",
1109
+ "When a tool validation error clearly indicates a recoverable schema mismatch, correct the arguments and retry without narrating the recovery unless the user needs to know.",
1110
+ ],
1102
1111
  parameters: Type.Object({
1103
1112
  id: Type.String({ description: "Task ID to update" }),
1104
1113
  status: Type.Optional(Type.String({ description: "New status", enum: ["pending", "in_progress", "completed"] })),