@widnyana/design-thinking 0.0.1 → 0.0.5
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
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
# design-thinking — a pi package
|
|
2
3
|
|
|
3
4
|
AI coding agents ship code before asking what breaks. This extension flips the
|
|
@@ -12,12 +13,35 @@ gist](https://gist.github.com/r17x/90eb2f7be93932b5693753aedb09c01a),
|
|
|
12
13
|
originally Effect-TS), generalized into this stack-agnostic pi package.
|
|
13
14
|
Licensed MIT — see [LICENSE](LICENSE).
|
|
14
15
|
|
|
16
|
+
## Why
|
|
17
|
+
|
|
18
|
+
A prose plan doesn't survive contact with review. An agent proposes "add
|
|
19
|
+
rate limiting, handle errors," the plan reads fine, and the diff either
|
|
20
|
+
matches it or it doesn't — prose gives no way to check which. Two failure
|
|
21
|
+
modes follow from that: the agent picks an unstated failure path (swallow
|
|
22
|
+
the error, retry silently, drop the request) nobody agreed to, or the
|
|
23
|
+
reviewer approves a plan that was never specific enough to catch the
|
|
24
|
+
mismatch once the code lands.
|
|
25
|
+
|
|
26
|
+
Design Graph replaces the prose plan with something that can be diffed.
|
|
27
|
+
Nodes are functions, edges are data and error/escape paths, boundaries are
|
|
28
|
+
named — fixed before code exists. `/cg-review` then reconstructs the graph
|
|
29
|
+
the code actually implements and diffs it against the one that was planned,
|
|
30
|
+
finding by finding, ending in a VERDICT. The notation is the same shape in
|
|
31
|
+
Go, Rust, Python, or TypeScript, so the check doesn't depend on the stack.
|
|
32
|
+
|
|
33
|
+
Skip it for a one-line fix — prose is fine there. Reach for `/dt` when the
|
|
34
|
+
change has a failure path worth agreeing on before it's written.
|
|
35
|
+
|
|
15
36
|
## Install
|
|
16
37
|
|
|
17
38
|
```bash
|
|
18
39
|
# from npm
|
|
19
40
|
pi install npm:@widnyana/design-thinking
|
|
20
41
|
|
|
42
|
+
# via OMP
|
|
43
|
+
omp install npm:@widnyana/design-thinking
|
|
44
|
+
|
|
21
45
|
# pinned version
|
|
22
46
|
pi install npm:@widnyana/design-thinking@0.0.1
|
|
23
47
|
|
|
@@ -61,28 +61,50 @@ Pipeline: shapes → graph(A) → cardinality → E(⟳retry ↯escape ☠die)
|
|
|
61
61
|
🔒 parse at boundaries → ⛈ orthogonal behavior → scope → test-R → verdict.
|
|
62
62
|
|
|
63
63
|
Rules:
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
- ANY turn that will end in code or file edits (feature, change, fix,
|
|
65
|
+
refactor — the model does NOT get to reclassify the request): render the
|
|
66
|
+
Design Graph in Graph Protocol form and any clarifying questions FIRST;
|
|
67
|
+
ZERO file edits until the user approves the design. Reading/exploring code
|
|
68
|
+
first is fine; the FIRST edit is not allowed before the graph.
|
|
69
|
+
- Design, plan, and review answers must render a Design Graph — fixed
|
|
70
|
+
sections: PROBLEM, SHAPES, GRAPH, CARDINALITY, BOUNDARIES, BEHAVIOR, SCOPE,
|
|
71
|
+
TEST LAYERS, VERDICT.
|
|
67
72
|
- The happy path (A) stays readable; failure handling lives at defined join points.
|
|
68
73
|
- Each layer scopes its own E; inner errors never leak through.
|
|
69
74
|
- If the code doesn't match the call graph, the implementation is wrong.
|
|
70
|
-
- For build/fix/refactor tasks: present the Design Graph and any clarifying
|
|
71
|
-
questions FIRST; implement only after the user approves the design.
|
|
72
75
|
- Adapt vocabulary to the current language/stack; never the discipline.
|
|
73
76
|
|
|
74
77
|
Full specs — read these when a section needs detail:
|
|
75
78
|
- ${REF_DIR}/protocol.md (Graph Protocol: notation spec + worked example)
|
|
76
79
|
- ${REF_DIR}/method.md (the §1–§10 method, generalized)
|
|
77
80
|
- ${REF_DIR}/design-graph.md (the artifact spec + completeness checklist)
|
|
81
|
+
Skills load BY NAME into the agent (/skill:<name>); the files above are named
|
|
82
|
+
by stem, NOT by skill name. Exact mapping:
|
|
83
|
+
/skill:graph-protocol → protocol.md /skill:design-method → method.md
|
|
84
|
+
/skill:design-graph → design-graph.md
|
|
85
|
+
Zero file edits are possible until the user runs /dt approve for the turn —
|
|
86
|
+
the extension blocks write/edit tools mechanically. Present the graph first.
|
|
87
|
+
NEVER read references/<skill-name>.md — no such files exist.
|
|
78
88
|
`.trim();
|
|
79
89
|
|
|
90
|
+
const MUTATING_TOOLS: Record<string, true> = {
|
|
91
|
+
write: true,
|
|
92
|
+
edit: true,
|
|
93
|
+
apply_patch: true,
|
|
94
|
+
multiedit: true,
|
|
95
|
+
};
|
|
96
|
+
|
|
80
97
|
interface DtState {
|
|
81
98
|
enabled: boolean;
|
|
82
99
|
}
|
|
83
100
|
|
|
101
|
+
const GATE_REASON =
|
|
102
|
+
"Design Thinking mode is ON: present the Design Graph (Graph Protocol) and wait for user approval before file edits. The user can unlock this turn with /dt approve.";
|
|
103
|
+
|
|
84
104
|
export default function designThinkingExtension(pi: ExtensionAPI) {
|
|
85
105
|
let enabled = false;
|
|
106
|
+
// Per-turn approval flag: set by /dt approve, reset on every user turn.
|
|
107
|
+
let approvedForTurn = false;
|
|
86
108
|
|
|
87
109
|
function applyStatus(ctx: ExtensionContext) {
|
|
88
110
|
ctx.ui.setStatus(
|
|
@@ -123,13 +145,27 @@ export default function designThinkingExtension(pi: ExtensionAPI) {
|
|
|
123
145
|
|
|
124
146
|
// /dt — the Design Thinking tool. Toggles mode, or /dt on|off|status.
|
|
125
147
|
pi.registerCommand("dt", {
|
|
126
|
-
description: "Design Thinking mode: /dt toggles, on|off|status set/query, anything else runs as a prompt with mode on",
|
|
148
|
+
description: "Design Thinking mode: /dt toggles, on|off|status set/query, approve|deny unlock/lock file edits for this turn, anything else runs as a prompt with mode on",
|
|
127
149
|
handler: async (args, ctx) => {
|
|
128
150
|
const arg = (args ?? "").trim();
|
|
129
151
|
const lower = arg.toLowerCase();
|
|
130
152
|
|
|
131
153
|
if (lower === "status") {
|
|
132
|
-
ctx.ui.notify(`Design Thinking mode: ${enabled ? "on" : "off"}`, "info");
|
|
154
|
+
ctx.ui.notify(`Design Thinking mode: ${enabled ? "on" : "off"}${approvedForTurn ? " (edits approved for this turn)" : ""}`, "info");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// /dt approve|deny — explicit user unlock/lock for the CURRENT turn.
|
|
159
|
+
if (lower === "approve") {
|
|
160
|
+
approvedForTurn = enabled;
|
|
161
|
+
ctx.ui.notify(
|
|
162
|
+
enabled ? "Design Thinking: file edits approved for this turn" : "Design Thinking is OFF — nothing to approve",
|
|
163
|
+
"info",
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (lower === "deny") {
|
|
167
|
+
approvedForTurn = false;
|
|
168
|
+
ctx.ui.notify("Design Thinking: file edits blocked again", "info");
|
|
133
169
|
return;
|
|
134
170
|
}
|
|
135
171
|
|
|
@@ -137,6 +173,7 @@ export default function designThinkingExtension(pi: ExtensionAPI) {
|
|
|
137
173
|
// mode and always turns the mode ON (never toggles it off); bare /dt toggles.
|
|
138
174
|
const prompt = /^(on|off|status)$/.test(lower) ? "" : arg;
|
|
139
175
|
enabled = lower === "on" || prompt ? true : lower === "off" ? false : !enabled;
|
|
176
|
+
if (!enabled) approvedForTurn = false;
|
|
140
177
|
persist();
|
|
141
178
|
applyStatus(ctx);
|
|
142
179
|
ctx.ui.notify(
|
|
@@ -158,9 +195,21 @@ export default function designThinkingExtension(pi: ExtensionAPI) {
|
|
|
158
195
|
|
|
159
196
|
// While active, append the distilled block to the system prompt every turn.
|
|
160
197
|
pi.on("before_agent_start", async (event) => {
|
|
198
|
+
// A new user turn starts a fresh agent run: the approval from the
|
|
199
|
+
// previous turn does not carry over.
|
|
200
|
+
approvedForTurn = false;
|
|
161
201
|
if (!enabled) return undefined;
|
|
162
202
|
return {
|
|
163
203
|
systemPrompt: event.systemPrompt + "\n\n" + DISTILLED + "\n",
|
|
164
204
|
};
|
|
165
205
|
});
|
|
206
|
+
|
|
207
|
+
// Hard gate: while enabled, mutating tools are blocked until the user
|
|
208
|
+
// approves the design for this turn (/dt approve). Prompt-level rules
|
|
209
|
+
// alone proved insufficient — this is the mechanical backstop.
|
|
210
|
+
pi.on("tool_call", async (event) => {
|
|
211
|
+
if (!enabled || approvedForTurn) return undefined;
|
|
212
|
+
if (!MUTATING_TOOLS[event.toolName]) return undefined;
|
|
213
|
+
return { block: true, reason: GATE_REASON };
|
|
214
|
+
});
|
|
166
215
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@widnyana/design-thinking",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Design Thinking · Design Graph · Graph Protocol — a stack-agnostic design methodology for pi. Turns every plan, review, and refactor into an annotated call graph. Method originally by r17x; generalized to a pi package by widnyana.",
|
|
6
6
|
"author": {
|
|
@@ -35,8 +35,11 @@
|
|
|
35
35
|
"methodology",
|
|
36
36
|
"call-graph"
|
|
37
37
|
],
|
|
38
|
+
"omp": {
|
|
39
|
+
"extensions": ["./extensions/design-thinking.ts"]
|
|
40
|
+
},
|
|
38
41
|
"pi": {
|
|
39
|
-
"extensions": ["./extensions"],
|
|
42
|
+
"extensions": ["./extensions/design-thinking.ts"],
|
|
40
43
|
"prompts": ["./prompts"],
|
|
41
44
|
"skills": ["./skills"]
|
|
42
45
|
},
|
|
@@ -13,6 +13,9 @@ A Design Graph is not documentation written after the fact. It is drawn
|
|
|
13
13
|
**before** implementation (planning), **reconstructed** from implementation
|
|
14
14
|
(review), and **compared** against implementation (verdict). The graph is the
|
|
15
15
|
contract; the code is one instantiation of it.
|
|
16
|
+
**Hard gate:** when a turn will produce code or file edits, the graph comes
|
|
17
|
+
first — render it (and any clarifying questions), get the user's approval,
|
|
18
|
+
and only then write code that matches it.
|
|
16
19
|
|
|
17
20
|
---
|
|
18
21
|
|
package/references/method.md
CHANGED
|
@@ -8,6 +8,13 @@ The method is language-neutral. Where it says "Effect", "gen", or "pipe" in the
|
|
|
8
8
|
Effect-TS appendix (`effect-ts.md`), substitute your stack's equivalent: Result
|
|
9
9
|
types, exceptions at layer joins, middleware, RAII, constructor injection —
|
|
10
10
|
whatever your language provides. The discipline never changes, only the vocabulary.
|
|
11
|
+
**Hard gate — applies in every harness (pi, omp, Claude Code, any agent):**
|
|
12
|
+
When the user asks for a feature, change, fix, or refactor — or when any turn
|
|
13
|
+
will end in proposed code or file edits — you MUST render the Design Graph
|
|
14
|
+
(Graph Protocol) and any clarifying questions BEFORE touching any file, and
|
|
15
|
+
implement only after the user approves the design. Reading and exploring code
|
|
16
|
+
first is fine; the FIRST edit is not allowed before the graph. This rule is
|
|
17
|
+
not optional and not stack-dependent.
|
|
11
18
|
|
|
12
19
|
Render every result in [Graph Protocol](protocol.md) format.
|
|
13
20
|
|
|
@@ -11,8 +11,8 @@ description: >
|
|
|
11
11
|
# Design Graph — The Artifact
|
|
12
12
|
|
|
13
13
|
A **Design Graph** is the annotated call graph of a concrete problem. It is
|
|
14
|
-
what you produce when you apply
|
|
15
|
-
something, and it is written in
|
|
14
|
+
what you produce when you apply Design Thinking (see the `design-method` skill) to
|
|
15
|
+
something, and it is written in Graph Protocol notation (see the `graph-protocol` skill).
|
|
16
16
|
|
|
17
17
|
Nodes are functions. Edges are data flow. The annotations answer, for every
|
|
18
18
|
node: what flows through it (A), how many times it runs (cardinality), where
|
|
@@ -23,6 +23,9 @@ A Design Graph is not documentation written after the fact. It is drawn
|
|
|
23
23
|
**before** implementation (planning), **reconstructed** from implementation
|
|
24
24
|
(review), and **compared** against implementation (verdict). The graph is the
|
|
25
25
|
contract; the code is one instantiation of it.
|
|
26
|
+
**Hard gate:** when a turn will produce code or file edits, the graph comes
|
|
27
|
+
first — render it (and any clarifying questions), get the user's approval,
|
|
28
|
+
and only then write code that matches it.
|
|
26
29
|
|
|
27
30
|
---
|
|
28
31
|
|
|
@@ -94,5 +97,5 @@ VERDICT line.
|
|
|
94
97
|
|
|
95
98
|
## Worked example
|
|
96
99
|
|
|
97
|
-
See the end of
|
|
100
|
+
See the end of the `graph-protocol` skill for a complete, non-TS worked
|
|
98
101
|
example (a resumable URL-sync CLI in Python) with all sections filled.
|
|
@@ -17,8 +17,15 @@ The method is language-neutral. Where it says "Effect", "gen", or "pipe" in the
|
|
|
17
17
|
Effect-TS appendix (`effect-ts.md`), substitute your stack's equivalent: Result
|
|
18
18
|
types, exceptions at layer joins, middleware, RAII, constructor injection —
|
|
19
19
|
whatever your language provides. The discipline never changes, only the vocabulary.
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
**Hard gate — applies in every harness (pi, omp, Claude Code, any agent):**
|
|
21
|
+
When the user asks for a feature, change, fix, or refactor — or when any turn
|
|
22
|
+
will end in proposed code or file edits — you MUST render the Design Graph
|
|
23
|
+
(Graph Protocol) and any clarifying questions BEFORE touching any file, and
|
|
24
|
+
implement only after the user approves the design. Reading and exploring code
|
|
25
|
+
first is fine; the FIRST edit is not allowed before the graph. This rule is
|
|
26
|
+
not optional and not stack-dependent.
|
|
27
|
+
|
|
28
|
+
Render every result in Graph Protocol format (see the `graph-protocol` skill).
|
|
22
29
|
|
|
23
30
|
```
|
|
24
31
|
X → DesignGraph<A, E, R>
|