deepclause-pi 0.1.3

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.
@@ -0,0 +1,423 @@
1
+ # `/dc-plan`: pi-native planning with executable DML
2
+
3
+ ## Status
4
+
5
+ Implemented for `deepclause-pi` 0.1.2. This document retains the architecture and security rationale behind the implementation. The output is an executable DML program: **the DML file is the plan**. There is no Markdown plan and no Markdown-to-DML compiler.
6
+
7
+ The shipped implementation includes the normal pi planning turn, transaction-scoped typed `dc_plan_commit`, deterministic DML assembly and validation, non-destructive `plans/` output, bounded `pi_agent_step` delegation, exact active-tool scoping and restoration, user confirmation, cancellation, and rejection through model-callable `dc_run`. Schema hashing and richer preflight drift reports remain possible later enhancements.
8
+
9
+ ## Revised design goal
10
+
11
+ A generated plan should not be limited to the small host-tool boundary used by ordinary DML tasks. Planning and plan execution should be able to benefit from the current pi environment:
12
+
13
+ - the effective pi system prompt, including context files and additions from extensions
14
+ - loaded skill metadata and instructions
15
+ - the current compacted or forked session branch
16
+ - the selected model, credentials, and thinking level
17
+ - built-in pi tools
18
+ - tools registered by other extensions
19
+ - the tools currently active for the user
20
+ - normal tool UI, approval, cancellation, and result rendering
21
+
22
+ This changes the architecture. Merely copying the SDK `plan.dml` and exposing more tool schemas to the DeepClause model loop is insufficient.
23
+
24
+ ## Important API finding
25
+
26
+ Pi exposes enough information to **discover** the environment:
27
+
28
+ - `ctx.getSystemPrompt()` returns the effective system prompt.
29
+ - Command contexts additionally expose `ctx.getSystemPromptOptions()`, whose structured value includes context files, loaded skills, tool snippets, prompt guidelines, and appended prompt text.
30
+ - `ctx.sessionManager.getBranch()` returns the active linear branch, including compacted-history entries.
31
+ - `pi.getActiveTools()` returns the current active tool names.
32
+ - `pi.getAllTools()` returns every configured tool's name, description, parameter schema, prompt guidelines, and source metadata.
33
+ - `pi.getThinkingLevel()` and `ctx.thinkingLevel` expose current reasoning configuration.
34
+
35
+ Pi does **not** expose a public `invokeTool(name, args)` API to extensions. `getAllTools()` deliberately returns metadata without each tool's `execute` closure. Consequently, DeepClause cannot safely mirror arbitrary built-in and third-party extension tools into `exec/2` by itself.
36
+
37
+ Passing all pi tool schemas to `modelRegistry.complete()` would let the model request those tools, but there would be no supported dispatcher to execute the calls. Pretending otherwise would create plans that look capable but fail at runtime.
38
+
39
+ ## Core architectural decision
40
+
41
+ Use pi itself as the contextual worker for plan creation and for plan steps that require pi capabilities.
42
+
43
+ DML remains the orchestration language. It decides step order, alternatives, deterministic checks, constraints, progress, and fallback. A new host operation delegates selected steps to a normal pi agent turn, where pi supplies its complete current prompt, skills, extensions, active tools, UI, approvals, and session semantics.
44
+
45
+ ```mermaid
46
+ flowchart TD
47
+ U[User invokes /dc-plan] --> P[Pi-native planning turn]
48
+ P --> C[dc_plan_commit with typed PlanSpec]
49
+ C --> V[Validate tool requirements and plan structure]
50
+ V --> A[Deterministically assemble DML]
51
+ A --> L[Parse and lint DML]
52
+ L --> F[.pi/deepclause/plans/name.dml]
53
+
54
+ R[User invokes /dc-run plans/name.dml] --> D[DML runtime]
55
+ D --> S1[Prolog sequencing and checks]
56
+ S1 --> X[exec pi_agent_step]
57
+ X --> T[Normal pi agent turn]
58
+ T --> K[Current skills, context, and active tools]
59
+ K --> X
60
+ X --> S2[Structured step result]
61
+ S2 --> D
62
+ ```
63
+
64
+ ## Planning phase
65
+
66
+ ### `/dc-plan` starts a normal pi turn
67
+
68
+ The command should not perform a headless one-shot completion. A one-shot `modelRegistry.complete()` call can inspect supplied text and schemas but cannot use pi's tools. Instead, `/dc-plan <request>` should start a regular pi agent turn with a temporary, narrowly scoped commit capability.
69
+
70
+ Conceptual flow:
71
+
72
+ 1. Verify pi is idle and a model is selected.
73
+ 2. Initialize `.pi/deepclause/` and the `plans/` directory non-destructively.
74
+ 3. Snapshot the effective planning environment:
75
+ - effective system prompt
76
+ - structured prompt options and loaded skills
77
+ - current branch and context usage
78
+ - all tool metadata
79
+ - active tool names
80
+ - existing DML skills and plans
81
+ - model and thinking level
82
+ 4. Register or activate `dc_plan_commit` for this planning transaction only.
83
+ 5. Send a planning request into the current pi session with `pi.sendUserMessage()`.
84
+ 6. Let pi inspect the workspace, consult relevant skills, and call active built-in or extension tools under their normal policies.
85
+ 7. Require the planning turn to finish by calling `dc_plan_commit(PlanSpec)`.
86
+ 8. Validate and assemble the DML deterministically.
87
+ 9. Show a preview and ask before writing.
88
+ 10. Deactivate `dc_plan_commit` and return the generated plan path.
89
+
90
+ Because this is a normal pi turn, `before_agent_start` hooks run and the planning model sees the effective system prompt assembled by pi. It does not need a stale copy embedded by DeepClause.
91
+
92
+ ### Why a commit tool
93
+
94
+ The planning model should produce a typed plan specification, not raw DML source. `dc_plan_commit` is analogous to the SDK task loop's structured result tool, but its output is richer and checked against the live pi environment.
95
+
96
+ Suggested shape:
97
+
98
+ ```ts
99
+ interface PlanSpec {
100
+ slug: string;
101
+ title: string;
102
+ objective: string;
103
+ assumptions: string[];
104
+ steps: Array<{
105
+ id: string;
106
+ title: string;
107
+ instruction: string;
108
+ executor: "pi" | "dml";
109
+ requiredTools: string[];
110
+ relevantSkills: string[];
111
+ expectedResult: string;
112
+ continueWhen?: ResultCondition;
113
+ }>;
114
+ finalSynthesis?: string;
115
+ failureMessage: string;
116
+ }
117
+ ```
118
+
119
+ The planner chooses `executor: "pi"` when a step needs current skills, repository context, built-in tools, or another extension. It chooses `executor: "dml"` when ordinary DML, typed model reasoning, Prolog, CLP, or the restricted DeepClause tools are sufficient.
120
+
121
+ `requiredTools` must contain exact names from the planning-time `getAllTools()` catalog. `relevantSkills` records why a loaded skill informed the step, but it does not copy the complete skill or system prompt into the generated file.
122
+
123
+ ### Planning-time tool decisions
124
+
125
+ The planner receives two distinct inventories:
126
+
127
+ - **Available tools:** all metadata from `getAllTools()`.
128
+ - **Currently active tools:** names from `getActiveTools()`.
129
+
130
+ It may inspect unavailable-but-configured tools for planning, but the commit validator should flag any requirement that is not currently active. The user can either revise the plan or explicitly activate the tool. `/dc-plan` must never silently enable tools.
131
+
132
+ The planner should prefer capabilities in this order:
133
+
134
+ 1. deterministic Prolog or CLP
135
+ 2. current DML helpers
136
+ 3. a narrow active pi tool
137
+ 4. a relevant loaded skill or extension capability
138
+ 5. approval-gated shell only when no safer capability fits
139
+
140
+ ## Generated DML
141
+
142
+ The assembler owns all DML syntax and quoting. The model never writes the source directly.
143
+
144
+ A generated plan can mix local DML reasoning and pi-native steps:
145
+
146
+ ```prolog
147
+ % Generated by /dc-plan. This DML file is the executable plan.
148
+ % Planning tool snapshot: read, edit, bash, test
149
+
150
+ agent_main :-
151
+ output("Step 1/4: analyzing requirements with current pi context..."),
152
+ exec(pi_agent_step(
153
+ instruction: "Inspect the request, relevant project instructions, loaded skills, and repository structure. Produce a concise implementation map.",
154
+ tools: [read, find, grep],
155
+ expected: "Implementation map with concrete files and constraints"
156
+ ), AnalysisResult),
157
+ get_dict(success, AnalysisResult, true),
158
+ get_dict(summary, AnalysisResult, Analysis),
159
+
160
+ output("Step 2/4: applying deterministic acceptance constraints..."),
161
+ acceptable_analysis(Analysis),
162
+
163
+ output("Step 3/4: implementing and validating through pi..."),
164
+ exec(pi_agent_step(
165
+ instruction: "Implement the smallest coherent change based on the prior plan context, run focused validation, and repair failures caused by the change.",
166
+ tools: [read, edit, bash, test],
167
+ expected: "Changed files, validation results, and remaining risks"
168
+ ), ImplementationResult),
169
+ get_dict(success, ImplementationResult, true),
170
+ get_dict(summary, ImplementationResult, Summary),
171
+
172
+ output("Step 4/4: preparing the final report..."),
173
+ task("Summarize this completed plan result for the user: {Summary}. Store it in Report.",
174
+ string(Report)),
175
+ answer(Report).
176
+
177
+ agent_main :-
178
+ answer("The plan could not be completed safely. Review the visible step results and retry or revise the plan.").
179
+ ```
180
+
181
+ The exact tool list is data in each `pi_agent_step`. The DML runtime does not receive or invoke arbitrary tool implementations directly.
182
+
183
+ ## `pi_agent_step` execution bridge
184
+
185
+ ### Semantics
186
+
187
+ `pi_agent_step` asks the current pi agent to execute one bounded instruction as a normal turn and waits for that turn to settle.
188
+
189
+ It should return a dict such as:
190
+
191
+ ```ts
192
+ {
193
+ success: boolean;
194
+ summary: string;
195
+ toolsUsed: string[];
196
+ errors: string[];
197
+ turnEntryIds: string[];
198
+ }
199
+ ```
200
+
201
+ The delegated turn naturally receives:
202
+
203
+ - current effective pi system prompt
204
+ - context files and extension prompt additions
205
+ - loaded skills
206
+ - the current session branch, including earlier delegated steps
207
+ - current model and thinking level
208
+ - normal tool execution and rendering
209
+ - provider and extension hooks
210
+
211
+ This is superior to serializing the complete system prompt into DML. It uses current context at execution time, avoids leaking or freezing irrelevant instructions, and respects changes made after plan creation.
212
+
213
+ ### Tool scoping
214
+
215
+ Before a delegated turn:
216
+
217
+ 1. Read the current active-tool snapshot.
218
+ 2. Verify every requested tool still exists in `getAllTools()`.
219
+ 3. Verify every requested tool is currently active.
220
+ 4. Reject missing or inactive requirements; never activate them silently.
221
+ 5. Temporarily scope active tools to the intersection requested by the plan plus any unavoidable pi core mechanism.
222
+ 6. Always exclude `dc_run`, `dc_plan_commit`, and future planning/execution control tools to prevent recursion.
223
+ 7. Start the delegated turn.
224
+ 8. Capture `turn_end`, `agent_end`, tool lifecycle events, and final assistant text.
225
+ 9. Wait for `agent_settled` before resuming DML.
226
+ 10. Restore the exact prior active-tool snapshot in `finally`.
227
+
228
+ Other extensions retain control of their tools. Their own validation, approval dialogs, hooks, cancellation, and rendering execute normally because pi—not DeepClause—dispatches the tool call.
229
+
230
+ ### Event correlation
231
+
232
+ Only one DeepClause execution is already allowed at a time. Extend that guard with one delegated-step transaction containing a unique plan ID and step ID. Register extension event handlers once and route the next matching agent turn to the pending transaction.
233
+
234
+ The step prompt should contain an internal correlation marker and explicit completion contract. The correlation marker must not be interpreted as authority and should be omitted from the user-facing summary.
235
+
236
+ Cancellation must abort both the DML controller and the active pi turn. Session shutdown, session switching, or branch navigation fails the step and stops the plan.
237
+
238
+ ### Re-entrancy restriction
239
+
240
+ A plan that uses `pi_agent_step` can only be started by a user command while pi is idle. It cannot run inside the model-callable `dc_run` tool because that tool is already executing within a pi agent turn; starting another agent turn would be recursive and unsafe.
241
+
242
+ Therefore:
243
+
244
+ - `/dc-run plans/name.dml` may execute contextual pi steps.
245
+ - `dc_run` must reject plans requiring `pi_agent_step` with `interactive_plan_requires_user_run`.
246
+ - Ordinary skills that do not use the bridge remain callable through `dc_run` when enabled.
247
+
248
+ This boundary must be explicit in the UI and authoring guide.
249
+
250
+ ## Skills and context handling
251
+
252
+ ### Planning
253
+
254
+ `getSystemPromptOptions()` exposes loaded skill objects and context files to the command. The planning turn also receives the fully assembled prompt through normal pi startup. The planner can decide that a skill is relevant, inspect it through ordinary pi mechanisms when needed, and record the skill name in the plan specification.
255
+
256
+ ### Execution
257
+
258
+ Do not paste all skill content or the complete effective system prompt into generated DML. That would:
259
+
260
+ - make plans stale
261
+ - duplicate large context
262
+ - risk persisting sensitive or irrelevant instructions
263
+ - disconnect execution from future extension and skill updates
264
+
265
+ Instead, a `pi_agent_step` reacquires the current effective pi context. A generated step may name relevant skills as a hint, but current pi decides how those skills are represented and used.
266
+
267
+ ### DML-local tasks
268
+
269
+ A normal DML `task/N` still receives the DeepClause memory selected by `turn`, `branch`, or `isolated`. It does not automatically receive the complete pi system prompt or arbitrary pi tools. This distinction is desirable:
270
+
271
+ - use `task/N` for a contained DeepClause subtask
272
+ - use `pi_agent_step` for work that intentionally needs the full pi environment
273
+
274
+ The UI and generated comments should make the executor boundary visible per step.
275
+
276
+ ## Security and consent model
277
+
278
+ ### Plan creation
279
+
280
+ - `/dc-plan` is user-triggered.
281
+ - Planning uses only tools already active in pi.
282
+ - Tool calls remain subject to their normal policies.
283
+ - `dc_plan_commit` accepts data but cannot execute the generated plan.
284
+ - The assembler writes only below `.pi/deepclause/plans/`.
285
+ - Existing plans are never overwritten silently.
286
+ - The user sees the step list, executor choice, required tools, and relevant skills before commit.
287
+
288
+ ### Plan execution
289
+
290
+ - Starting a contextual plan requires a user slash command.
291
+ - Show a preflight summary before the first delegated turn.
292
+ - All required tools must still be active.
293
+ - Other extensions' policies remain authoritative.
294
+ - Approval of the plan does not imply approval of every shell or privileged tool call.
295
+ - The plan cannot activate tools, alter provider credentials, or mutate pi configuration.
296
+ - Recursion into `dc_run`, `/dc-plan`, or plan commit is blocked.
297
+ - Every delegated step is visible in the current pi session, which remains the sole execution record.
298
+
299
+ ## Plan portability and drift
300
+
301
+ A plan should record descriptive metadata as DML comments or harmless facts:
302
+
303
+ - generation timestamp
304
+ - plan format version
305
+ - requested tool names
306
+ - tool source identifiers when available
307
+ - optional stable hashes of parameter schemas
308
+ - relevant skill names
309
+ - planning model label
310
+
311
+ At execution, compare current tools with this snapshot:
312
+
313
+ - Missing required tool: fail preflight.
314
+ - Tool exists but is inactive: ask the user to activate it outside the plan.
315
+ - Schema changed: warn and require confirmation or regeneration.
316
+ - Additional tools exist: ignore unless explicitly requested by a step.
317
+ - Skill missing or changed: warn, but allow the user to continue if it was guidance rather than a hard dependency.
318
+
319
+ Do not persist the full effective system prompt, credentials, tool implementation paths beyond what is needed for diagnostics, or session content in the plan.
320
+
321
+ ## Command surface
322
+
323
+ ```text
324
+ /dc-plan <request>
325
+ /dc-plan <request> --name=<slug>
326
+ /dc-plan <request> --context=turn|branch
327
+ /dc-plan <request> --debug
328
+ /dc-run plans/<slug>.dml
329
+ ```
330
+
331
+ `isolated` planning can be supported for DML-only plans. It conflicts with the goal of using current pi skills and context, so `/dc-plan` should default to `branch` or an explicit `current` planning mode rather than ordinary DML's `turn` default.
332
+
333
+ `/dc-list` should separate reusable skills from generated plans.
334
+
335
+ ## Workspace layout
336
+
337
+ ```text
338
+ .pi/deepclause/
339
+ ├── config.json
340
+ ├── AGENTS.md
341
+ ├── DML_REFERENCE.md
342
+ ├── plans/
343
+ │ └── migrate_to_esm.dml
344
+ └── skills/
345
+ ├── example.dml
346
+ └── deep_research.dml
347
+ ```
348
+
349
+ Plans are request-specific orchestration. Skills are reusable programs. Both are DML and use the same parser and path isolation.
350
+
351
+ ## Implementation phases
352
+
353
+ ### Phase 1: contextual planning and DML generation
354
+
355
+ - Add `/dc-plan`.
356
+ - Run planning as a normal pi turn.
357
+ - Add transaction-scoped `dc_plan_commit`.
358
+ - Collect effective prompt options, loaded skills, tool catalog, active tools, model, thinking level, and branch metadata.
359
+ - Validate a typed `PlanSpec`.
360
+ - Deterministically assemble and statically validate DML.
361
+ - Save non-destructively under `plans/`.
362
+ - Initially generate DML-only and the already supported restricted operations.
363
+
364
+ This phase proves plan quality and the plan format without pretending arbitrary tools are executable.
365
+
366
+ ### Phase 2: pi-native delegated execution
367
+
368
+ - Add `pi_agent_step` only for user-triggered plan runs.
369
+ - Implement correlated agent-turn delegation and result capture.
370
+ - Add exact tool snapshot/scoping/restoration.
371
+ - Preserve extension approvals and lifecycle events.
372
+ - Add preflight, plan-level confirmation, cancellation, and session-change handling.
373
+ - Reject delegated plans from model-callable `dc_run`.
374
+
375
+ ### Phase 3: advanced DML planning
376
+
377
+ - Typed conditions between steps.
378
+ - Prolog and CLP acceptance constraints.
379
+ - Multiple `agent_main` strategy clauses.
380
+ - User-editable plan review and regeneration.
381
+ - Optional independent verification turns.
382
+ - Explicit step outputs that subsequent DML predicates can inspect.
383
+
384
+ ## Tests required
385
+
386
+ ### Planning context
387
+
388
+ - Effective system prompt additions are present in the planning turn.
389
+ - Context files and loaded skill metadata are visible.
390
+ - Compacted and forked branch context behaves correctly.
391
+ - All and active tool inventories differ correctly.
392
+ - A tool registered by a test extension appears in the planner catalog.
393
+
394
+ ### Plan commit
395
+
396
+ - Unknown, inactive, recursive, or malformed tool requirements are rejected.
397
+ - Raw model DML is never accepted.
398
+ - Strings are quoted by the assembler.
399
+ - Existing plans are preserved.
400
+ - Path traversal and symlink escape are rejected.
401
+ - Generated DML passes the SDK parser/linter.
402
+
403
+ ### Delegated execution
404
+
405
+ - A built-in tool and a mock third-party extension tool execute through normal pi dispatch.
406
+ - Third-party approval denial propagates into the DML step result.
407
+ - Tool subsets are enforced and restored after success, failure, and cancellation.
408
+ - `dc_run` and planning tools are unavailable inside delegated turns.
409
+ - The next DML step receives the prior step summary.
410
+ - Compaction and session closure stop or resume according to explicit policy.
411
+ - A model-triggered `dc_run` cannot start a contextual plan.
412
+
413
+ ## Decision summary
414
+
415
+ The desired behavior is possible only if the generated plan delegates contextual work back to pi rather than trying to clone pi's environment inside DeepClause.
416
+
417
+ The key separation is:
418
+
419
+ - **DML is the plan and orchestrator.**
420
+ - **Pi is the contextual worker and tool dispatcher.**
421
+ - **The SDK task loop remains available for contained DML-native reasoning.**
422
+
423
+ This preserves the benefits of DML—executable structure, typed data, Prolog control, backtracking, and constraints—while using pi's live skills, session context, built-in tools, and extension ecosystem without bypassing their policies.
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "deepclause-pi",
3
+ "version": "0.1.3",
4
+ "description": "Pi-hosted runtime for DeepClause DML programs",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "DeepClause",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/deepclause/deepclause-pi.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/deepclause/deepclause-pi/issues"
14
+ },
15
+ "homepage": "https://github.com/deepclause/deepclause-pi#readme",
16
+ "keywords": [
17
+ "pi",
18
+ "deepclause",
19
+ "dml",
20
+ "prolog",
21
+ "agent",
22
+ "llm"
23
+ ],
24
+ "files": [
25
+ "dist",
26
+ "docs",
27
+ "src"
28
+ ],
29
+ "pi": {
30
+ "extensions": [
31
+ "./src/index.ts"
32
+ ]
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.json",
36
+ "test": "vitest run",
37
+ "check": "npm run build && npm test",
38
+ "prepublishOnly": "npm run check"
39
+ },
40
+ "dependencies": {
41
+ "deepclause-sdk": "npm:deepclause-sdk@0.0.87",
42
+ "typebox": "1.3.7"
43
+ },
44
+ "peerDependencies": {
45
+ "@earendil-works/pi-ai": ">=0.84.0",
46
+ "@earendil-works/pi-coding-agent": ">=0.84.0"
47
+ },
48
+ "devDependencies": {
49
+ "@earendil-works/pi-ai": "0.84.2",
50
+ "@earendil-works/pi-coding-agent": "0.84.2",
51
+ "@types/node": "^22.0.0",
52
+ "typescript": "^5.9.0",
53
+ "vitest": "^4.0.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=22"
57
+ }
58
+ }