@pathmode/mcp-server 1.10.0 → 1.12.0
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 +8 -2
- package/dist/api-client.d.ts +22 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/index.js +353 -12
- package/dist/intent-compiler.d.ts +4 -0
- package/dist/intent-compiler.d.ts.map +1 -1
- package/dist/readiness.d.ts +53 -0
- package/dist/readiness.d.ts.map +1 -0
- package/package.json +1 -1
- package/skills/README.md +1 -0
- package/skills/preflight/SKILL.md +41 -0
package/README.md
CHANGED
|
@@ -61,6 +61,7 @@ That's it. No API key needed.
|
|
|
61
61
|
id: "intent_17291..."
|
|
62
62
|
version: 1
|
|
63
63
|
status: "draft"
|
|
64
|
+
readiness: "passed 6/6"
|
|
64
65
|
---
|
|
65
66
|
# Fix Checkout Payment Timeout
|
|
66
67
|
|
|
@@ -78,6 +79,8 @@ timeouts exceeding 3 seconds.
|
|
|
78
79
|
- **Unknown provider status**: Hold order, notify user within 30s
|
|
79
80
|
```
|
|
80
81
|
|
|
82
|
+
The `readiness` line is the deterministic preflight verdict, stamped on every save — "passed 6/6", or "failed N/6" naming the blocking gates — so any agent reading the file knows whether the spec cleared the gate without re-running it. Specs exported from a Pathmode workspace also carry `source:` (the canonical intent URL — the file is a working copy of that record) and `evidence:` (how many linked evidence items back it).
|
|
83
|
+
|
|
81
84
|
**.cursorrules** — Agent-directive format for Cursor:
|
|
82
85
|
```
|
|
83
86
|
# CURRENT OBJECTIVE
|
|
@@ -94,7 +97,7 @@ Your implementation MUST satisfy ALL of these:
|
|
|
94
97
|
|
|
95
98
|
## Skill Pack for Claude Code
|
|
96
99
|
|
|
97
|
-
The package also ships
|
|
100
|
+
The package also ships 8 Claude Code skills that auto-trigger based on what you ask — no slash commands required.
|
|
98
101
|
|
|
99
102
|
| Skill | Use when |
|
|
100
103
|
|-------|----------|
|
|
@@ -163,7 +166,10 @@ Get your API key from **Settings > API Keys** in the [Pathmode app](https://path
|
|
|
163
166
|
### Local Mode (Offline)
|
|
164
167
|
|
|
165
168
|
Local mode is the **default when no API key is configured**. It reads and writes `intent.md` in your
|
|
166
|
-
project directory, and nothing leaves your machine.
|
|
169
|
+
project directory, and nothing leaves your machine. Local mode includes `check_intent_readiness` —
|
|
170
|
+
the deterministic preflight that scores a spec against six calibrated gates and names the exact
|
|
171
|
+
blockers, with no model call (the same gate that runs at [preflight.pathmode.io](https://preflight.pathmode.io)).
|
|
172
|
+
The plain block is a complete keyless setup:
|
|
167
173
|
|
|
168
174
|
```json
|
|
169
175
|
{
|
package/dist/api-client.d.ts
CHANGED
|
@@ -185,8 +185,25 @@ export interface ApiVerificationResult {
|
|
|
185
185
|
category: string;
|
|
186
186
|
status: string;
|
|
187
187
|
reasoning: string;
|
|
188
|
+
basis?: 'artifact' | 'self_report' | 'none';
|
|
189
|
+
evidence?: {
|
|
190
|
+
path: string;
|
|
191
|
+
hunk?: string;
|
|
192
|
+
}[];
|
|
188
193
|
}[];
|
|
189
194
|
summary: string;
|
|
195
|
+
/** Whether the verdict was reached by reading a pull request or only the caller's own account. */
|
|
196
|
+
basis?: 'artifact' | 'self_report';
|
|
197
|
+
artifact?: {
|
|
198
|
+
kind: 'pr_diff' | 'self_report';
|
|
199
|
+
repo?: string;
|
|
200
|
+
prNumber?: number;
|
|
201
|
+
headSha?: string;
|
|
202
|
+
filesRead?: number;
|
|
203
|
+
filesOmitted?: number;
|
|
204
|
+
truncated?: boolean;
|
|
205
|
+
reason?: string;
|
|
206
|
+
};
|
|
190
207
|
}
|
|
191
208
|
export interface ApiEvidence {
|
|
192
209
|
id: string;
|
|
@@ -316,5 +333,9 @@ export declare class PathmodeClient {
|
|
|
316
333
|
linked: number;
|
|
317
334
|
unlinked: number;
|
|
318
335
|
}>;
|
|
319
|
-
verifyImplementation(intentId: string,
|
|
336
|
+
verifyImplementation(intentId: string, body: {
|
|
337
|
+
summary?: string;
|
|
338
|
+
prUrl?: string;
|
|
339
|
+
codeChanges?: string;
|
|
340
|
+
}): Promise<ApiVerificationResult>;
|
|
320
341
|
}
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAE;QACpB,aAAa,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAClD,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QACxC,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,uBAAuB,EAAE,MAAM,EAAE,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/E,mBAAmB,EAAE,MAAM,CAAC;KAC/B,GAAG,IAAI,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE;YAAE,EAAE,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1L,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,iBAAiB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE;YAAE,EAAE,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1L,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;QAC5C,QAAQ,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAChD,EAAE,CAAC;IACJ,OAAO,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,KAAK,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC;IACnC,QAAQ,CAAC,EAAE;QACP,IAAI,EAAE,SAAS,GAAG,aAAa,CAAC;QAChC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;KACrC,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,iBAAiB,EAAE;QACf,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;QACnD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;CACP;AAED,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAKD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAgB,UAAU,IAAI,cAAc,GAAG,IAAI,CAsBlD;AAED,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,cAAc;YAMpB,KAAK;IAqBnB;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,UAAU,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9G,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAOlD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAKzC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,SAAgB,EAAE,IAAI,SAAY,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAKnH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1D,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,qBAAqB,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7D,0BAA0B,CAAC,EAAE,MAAM,CAAC;KACvC,CAAC;IAQI,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAQrE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC;IAQxE,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAKrC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAK/B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAKjC,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUtI,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC;IAQ1D,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC;IAQxE,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAU/F,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;IAQhE,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ/I,oBAAoB,CACtB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACjE,OAAO,CAAC,qBAAqB,CAAC;CAQpC"}
|
package/dist/index.js
CHANGED
|
@@ -33742,10 +33742,10 @@ class PathmodeClient {
|
|
|
33742
33742
|
});
|
|
33743
33743
|
return res.json();
|
|
33744
33744
|
}
|
|
33745
|
-
async verifyImplementation(intentId,
|
|
33745
|
+
async verifyImplementation(intentId, body) {
|
|
33746
33746
|
const res = await this.fetch(`/intents/${intentId}/verify`, {
|
|
33747
33747
|
method: 'POST',
|
|
33748
|
-
body: JSON.stringify(
|
|
33748
|
+
body: JSON.stringify(body),
|
|
33749
33749
|
});
|
|
33750
33750
|
return res.json();
|
|
33751
33751
|
}
|
|
@@ -34165,6 +34165,8 @@ function formatIntentMd(spec, opts = {}) {
|
|
|
34165
34165
|
id: spec.id || `intent_${Date.now()}`,
|
|
34166
34166
|
version: opts.version && opts.version >= 1 ? opts.version : 1,
|
|
34167
34167
|
status: opts.status || 'draft',
|
|
34168
|
+
...(opts.readiness ? { readiness: opts.readiness } : {}),
|
|
34169
|
+
...(opts.source ? { source: opts.source } : {}),
|
|
34168
34170
|
created: opts.created || now,
|
|
34169
34171
|
updated: now,
|
|
34170
34172
|
};
|
|
@@ -35003,6 +35005,254 @@ function mergePathmodeSection(existing, section) {
|
|
|
35003
35005
|
}
|
|
35004
35006
|
|
|
35005
35007
|
|
|
35008
|
+
/***/ }),
|
|
35009
|
+
|
|
35010
|
+
/***/ 3079:
|
|
35011
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
35012
|
+
|
|
35013
|
+
"use strict";
|
|
35014
|
+
|
|
35015
|
+
/**
|
|
35016
|
+
* Deterministic intent readiness gate — the preflight.
|
|
35017
|
+
*
|
|
35018
|
+
* This is a PORT of the canonical gate in lib/intentReadiness.ts (the MCP package
|
|
35019
|
+
* cannot import app/lib code). Every regex and threshold below must stay
|
|
35020
|
+
* byte-identical to the source; lib/preflightReadinessParity.test.ts in the app
|
|
35021
|
+
* repo runs both implementations over the 98-item calibration corpus and the
|
|
35022
|
+
* Preflight demo specs, and fails CI on any divergence. Edit the app lib first,
|
|
35023
|
+
* then mirror the change here.
|
|
35024
|
+
*
|
|
35025
|
+
* Pure functions only: no I/O, no network, no model calls. The same spec gets
|
|
35026
|
+
* the same verdict every run — that determinism is the product claim on
|
|
35027
|
+
* https://preflight.pathmode.io, so keep it true.
|
|
35028
|
+
*/
|
|
35029
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
35030
|
+
exports.READINESS_GATE_ORDER = exports.READINESS_BLOCKER_DESCRIPTIONS = void 0;
|
|
35031
|
+
exports.coerceText = coerceText;
|
|
35032
|
+
exports.asArray = asArray;
|
|
35033
|
+
exports.isTitleMeaningful = isTitleMeaningful;
|
|
35034
|
+
exports.isConstraintConcrete = isConstraintConcrete;
|
|
35035
|
+
exports.isVerificationCheckSubstantive = isVerificationCheckSubstantive;
|
|
35036
|
+
exports.isObjectiveSpecific = isObjectiveSpecific;
|
|
35037
|
+
exports.isOutcomeMeasurable = isOutcomeMeasurable;
|
|
35038
|
+
exports.computeReadinessVerdict = computeReadinessVerdict;
|
|
35039
|
+
exports.formatReadinessFrontmatter = formatReadinessFrontmatter;
|
|
35040
|
+
exports.formatReadinessVerdict = formatReadinessVerdict;
|
|
35041
|
+
// ── Text/shape coercion (mirrors lib/intentReadiness coerceText/asArray) ───
|
|
35042
|
+
function coerceText(value) {
|
|
35043
|
+
if (typeof value === 'string')
|
|
35044
|
+
return value;
|
|
35045
|
+
if (value && typeof value === 'object') {
|
|
35046
|
+
const o = value;
|
|
35047
|
+
const cand = o.description ?? o.rule ?? o.text ?? o.name ?? o.scenario ?? o.title ?? o.value ?? o.label ?? o.content;
|
|
35048
|
+
if (typeof cand === 'string')
|
|
35049
|
+
return cand;
|
|
35050
|
+
}
|
|
35051
|
+
return '';
|
|
35052
|
+
}
|
|
35053
|
+
function asArray(value) {
|
|
35054
|
+
if (Array.isArray(value))
|
|
35055
|
+
return value;
|
|
35056
|
+
if (value === null || value === undefined)
|
|
35057
|
+
return [];
|
|
35058
|
+
return [value];
|
|
35059
|
+
}
|
|
35060
|
+
/** Mirrors lib/intentSpecHelpers.outcomeText: outcomes arrive as strings or { text }. */
|
|
35061
|
+
function outcomeText(o) {
|
|
35062
|
+
if (typeof o === 'string')
|
|
35063
|
+
return o;
|
|
35064
|
+
const t = o?.text;
|
|
35065
|
+
return typeof t === 'string' ? t : '';
|
|
35066
|
+
}
|
|
35067
|
+
const PLACEHOLDER_INTENT_TITLES = new Set(['new intent', 'untitled intent']);
|
|
35068
|
+
const TEMPLATE_PATTERNS = [
|
|
35069
|
+
/\[your category\]/i,
|
|
35070
|
+
/^template$/i,
|
|
35071
|
+
/^placeholder$/i,
|
|
35072
|
+
/^todo$/i,
|
|
35073
|
+
/^tbd$/i,
|
|
35074
|
+
];
|
|
35075
|
+
function isLikelyPlaceholderText(value) {
|
|
35076
|
+
const text = coerceText(value).trim();
|
|
35077
|
+
if (!text)
|
|
35078
|
+
return false;
|
|
35079
|
+
if (text.length <= 2)
|
|
35080
|
+
return true;
|
|
35081
|
+
return TEMPLATE_PATTERNS.some((pattern) => pattern.test(text));
|
|
35082
|
+
}
|
|
35083
|
+
// ── The six calibrated gates ────────────────────────────────────────────────
|
|
35084
|
+
const GENERIC_TITLE_WORDS = new Set([
|
|
35085
|
+
'new', 'my', 'our', 'the', 'a', 'an', 'this', 'that', 'some', 'more', 'better',
|
|
35086
|
+
'intent', 'intents', 'feature', 'features', 'idea', 'ideas', 'spec', 'specs',
|
|
35087
|
+
'draft', 'drafts', 'test', 'tests', 'todo', 'tbd', 'wip', 'stuff', 'thing', 'things',
|
|
35088
|
+
'untitled', 'placeholder', 'misc', 'general', 'various', 'update', 'updates',
|
|
35089
|
+
'improvement', 'improvements', 'improve', 'fix', 'fixes', 'change', 'changes',
|
|
35090
|
+
'work', 'item', 'items', 'task', 'tasks',
|
|
35091
|
+
]);
|
|
35092
|
+
function isTitleMeaningful(title) {
|
|
35093
|
+
const t = coerceText(title).trim();
|
|
35094
|
+
if (!t)
|
|
35095
|
+
return false;
|
|
35096
|
+
if (PLACEHOLDER_INTENT_TITLES.has(t.toLowerCase()))
|
|
35097
|
+
return false;
|
|
35098
|
+
if (TEMPLATE_PATTERNS.some((pattern) => pattern.test(t)))
|
|
35099
|
+
return false;
|
|
35100
|
+
const words = t.split(/\s+/).filter(Boolean);
|
|
35101
|
+
if (words.length < 2)
|
|
35102
|
+
return false;
|
|
35103
|
+
return words.some((w) => !GENERIC_TITLE_WORDS.has(w.toLowerCase().replace(/[^a-z0-9-]/gi, '')));
|
|
35104
|
+
}
|
|
35105
|
+
const CONSTRAINT_MARKER_RE = /\b(never|must|not|no|don'?t|cannot|can'?t|forbidden|prohibit\w*|avoid|without|only|at most|at least|within|under|below|above|max\w*|limit\w*|cap(?:ped|s)?|quota|budget|respect\w*|comply|complian\w*|conform\w*|keep|stays?|remains?|preserve\w*|maintain\w*|require[sd]?|always|read[- ]only|backward[- ]?compatib\w*|p\d{2})\b/i;
|
|
35106
|
+
function isConstraintConcrete(value) {
|
|
35107
|
+
const t = coerceText(value).trim();
|
|
35108
|
+
if (t.length < 8)
|
|
35109
|
+
return false;
|
|
35110
|
+
return CONSTRAINT_MARKER_RE.test(t) || t.length >= 40;
|
|
35111
|
+
}
|
|
35112
|
+
function isVerificationCheckSubstantive(description) {
|
|
35113
|
+
const t = coerceText(description).trim();
|
|
35114
|
+
if (isLikelyPlaceholderText(t))
|
|
35115
|
+
return false;
|
|
35116
|
+
return t.split(/\s+/).filter(Boolean).length >= 3;
|
|
35117
|
+
}
|
|
35118
|
+
const ACTOR_RE = /\b(users?|customers?|clients?|teams?|developers?|admins?|administrators?|visitors?|subscribers?|buyers?|sellers?|operators?|managers?|patients?|agents?|founders?|owners?|leads?|members?|employees?|hires?|applicants?|candidates?|players?|creators?|curators?|seekers?|parents?|students?|teachers?|shoppers?|merchants?|reviewers?|engineers?|designers?|marketers?|recruiters?|stakeholders?|people|staff)\b/i;
|
|
35119
|
+
const ACTOR_STRUCT_RE = /\b(enable|allow|let|help|give|empower|support)\s+[A-Za-z]|\bfor\s+[a-z]+\s+(to|who|so)\b|\b[A-Za-z]+['’]s\b|\b[A-Z][a-z]{2,}\s+(can'?t|cannot|can|could|should|needs?|wants?|struggles?|fails?|miss\w*|lose|loses)\b/;
|
|
35120
|
+
const PROBLEM_RE = /\b(can'?t|cannot|unable|struggl\w*|fail\w*|drop\w*|abandon\w*|miss\w*|los\w*|break\w*|broken|block\w*|confus\w*|delay\w*|bottleneck|stale|stuck|friction|painful|manual\w*|error\w*|slow|waste\w*|risk\w*)\b/i;
|
|
35121
|
+
const CAPABILITY_RE = /\b(enable|allow|let|help|give|empower|provide|support|lift|raise|reduce|cut|eliminat\w*|increase|decrease|improve|streamlin\w*|automat\w*|speed up|accelerat\w*|guarantee|ensure|deliver|complete|clear|maintain|achieve|unlock|simplif\w*|consolidat\w*|surface|track|measure|see|view|access|find|understand|know|preview|schedule|resume|inspect|reorder|publish|reconcile|bulk|able to|act on)\b/i;
|
|
35122
|
+
const VAGUE_MARKER_RE = /\b(best[- ]in[- ]class|world[- ]class|seamless\w*|cutting[- ]edge|delight\w*|intuitive|robust|holistic|synerg\w*|revolutioniz\w*|next[- ]gen\w*|frictionless|game[- ]chang\w*|state[- ]of[- ]the[- ]art|leverage|do more|happ(y|ier|iness)|smoother|polished|magical|amazing|wow)\b/i;
|
|
35123
|
+
function isObjectiveSpecific(objective) {
|
|
35124
|
+
const t = coerceText(objective).trim();
|
|
35125
|
+
if (t.length <= 35)
|
|
35126
|
+
return false;
|
|
35127
|
+
if (VAGUE_MARKER_RE.test(t) && !OUTCOME_NUMERIC_RE.test(t))
|
|
35128
|
+
return false;
|
|
35129
|
+
const hasActor = ACTOR_RE.test(t) || ACTOR_STRUCT_RE.test(t);
|
|
35130
|
+
const hasIntent = PROBLEM_RE.test(t) || CAPABILITY_RE.test(t);
|
|
35131
|
+
return hasActor && hasIntent;
|
|
35132
|
+
}
|
|
35133
|
+
const OUTCOME_NUMERIC_RE = /\d|%|≥|≤|>=|<=/;
|
|
35134
|
+
const OUTCOME_METRIC_RE = /\b(under|within|at least|no more than|fewer than|less than|more than|reach\w*|drop\w*|ris\w*|grow\w*|increas\w*|decreas\w*|reduc\w*|eliminat\w*|stays?\s+(under|below|above|within)|from\s+.+\s+to\s+|success rate|completion rate|conversion|retention|adoption|rate\b|score|benchmark|baseline|per\s+\w+|time[- ]to)\b/i;
|
|
35135
|
+
const OUTCOME_CAPABILITY_RE = /\b([a-z]+s?|they|anyone|everyone)\s+(can|could|sees?|views?|receives?|gets?|is able|are able|able to)\b/i;
|
|
35136
|
+
const OUTCOME_STATE_RE = /\b(no longer|without\s+\w+|is fully|are fully|displays?|shows?|appears?|visible|notified|confirmed|enabled|disabled|redirected|prevented|blocked|templated|automated|documented|exists?|persists?|never|always|produces?\s+no\b|results?\s+in\s+no\b|with\s+no\b|free of)\b/i;
|
|
35137
|
+
const OUTCOME_SUBJECTIVE_RE = /\b(amazing|delight\w*|happ(y|ier|iness)|satisf\w*|quality|love[ds]?|world[- ]class|best[- ]in[- ]class|seamless\w*|intuitive|polished|magical|wow|delightful|engaging|meaningful\w*)\b/i;
|
|
35138
|
+
function isOutcomeMeasurable(text) {
|
|
35139
|
+
const t = coerceText(text).trim();
|
|
35140
|
+
if (!t)
|
|
35141
|
+
return false;
|
|
35142
|
+
if (OUTCOME_SUBJECTIVE_RE.test(t))
|
|
35143
|
+
return false;
|
|
35144
|
+
return OUTCOME_NUMERIC_RE.test(t) || OUTCOME_METRIC_RE.test(t) || OUTCOME_CAPABILITY_RE.test(t) || OUTCOME_STATE_RE.test(t);
|
|
35145
|
+
}
|
|
35146
|
+
// ── Verdict ─────────────────────────────────────────────────────────────────
|
|
35147
|
+
exports.READINESS_BLOCKER_DESCRIPTIONS = {
|
|
35148
|
+
objective: 'Objective is too vague — name the actor and the concrete failure they hit today.',
|
|
35149
|
+
goal: 'Title is missing or generic — name the intent in a short, specific noun phrase.',
|
|
35150
|
+
outcomes: 'Outcomes are not all measurable — at least two-thirds need a testable or observable threshold.',
|
|
35151
|
+
constraints: 'No hard constraint — name at least one thing that must never happen.',
|
|
35152
|
+
edgeCases: 'No edge case with a defined expected behavior.',
|
|
35153
|
+
verification: 'No concrete verification — describe at least one check specific enough to run.',
|
|
35154
|
+
};
|
|
35155
|
+
/** Display order for the gate strip (title first, matching the Preflight page). */
|
|
35156
|
+
exports.READINESS_GATE_ORDER = ['goal', 'objective', 'outcomes', 'constraints', 'edgeCases', 'verification'];
|
|
35157
|
+
/** Blocker emission order — byte-identical to lib/intentReadiness computeReviewSignals. */
|
|
35158
|
+
const BLOCKER_ORDER = ['objective', 'goal', 'outcomes', 'constraints', 'edgeCases', 'verification'];
|
|
35159
|
+
/** Flatten a verification field (checks[] plus legacy buckets) into check descriptions. */
|
|
35160
|
+
function verificationDescriptions(verification) {
|
|
35161
|
+
if (!verification || typeof verification !== 'object')
|
|
35162
|
+
return [];
|
|
35163
|
+
const v = verification;
|
|
35164
|
+
const out = [];
|
|
35165
|
+
for (const c of asArray(v.checks)) {
|
|
35166
|
+
const d = coerceText(c).trim();
|
|
35167
|
+
if (d)
|
|
35168
|
+
out.push(d);
|
|
35169
|
+
}
|
|
35170
|
+
for (const bucket of ['manualChecks', 'unitTests', 'e2eTests']) {
|
|
35171
|
+
for (const c of asArray(v[bucket])) {
|
|
35172
|
+
const d = coerceText(c).trim();
|
|
35173
|
+
if (d)
|
|
35174
|
+
out.push(d);
|
|
35175
|
+
}
|
|
35176
|
+
}
|
|
35177
|
+
return out;
|
|
35178
|
+
}
|
|
35179
|
+
/**
|
|
35180
|
+
* The preflight: six deterministic gates over an intent spec. Mirrors
|
|
35181
|
+
* lib/intentReadiness.computeReviewSignals with conversationFirst semantics
|
|
35182
|
+
* (the legacy phase-engagement signal never gates the verdict here).
|
|
35183
|
+
*/
|
|
35184
|
+
function computeReadinessVerdict(spec) {
|
|
35185
|
+
const nonEmptyOutcomes = asArray(spec.outcomes).map(o => outcomeText(o).trim()).filter(Boolean);
|
|
35186
|
+
const testableOutcomeCount = nonEmptyOutcomes.filter(isOutcomeMeasurable).length;
|
|
35187
|
+
const signals = {
|
|
35188
|
+
goal: isTitleMeaningful(typeof spec.title === 'string' ? spec.title : coerceText(spec.title)),
|
|
35189
|
+
objective: isObjectiveSpecific(typeof spec.objective === 'string' ? spec.objective : coerceText(spec.objective)),
|
|
35190
|
+
outcomes: nonEmptyOutcomes.length >= 2 && testableOutcomeCount / Math.max(nonEmptyOutcomes.length, 1) >= 0.66,
|
|
35191
|
+
constraints: asArray(spec.constraints).some(isConstraintConcrete),
|
|
35192
|
+
edgeCases: asArray(spec.edgeCases).some((ec) => {
|
|
35193
|
+
const e = ec;
|
|
35194
|
+
return coerceText(e?.scenario).trim().length > 0 && coerceText(e?.expectedBehavior).trim().length > 0;
|
|
35195
|
+
}),
|
|
35196
|
+
verification: verificationDescriptions(spec.verification).some(isVerificationCheckSubstantive),
|
|
35197
|
+
};
|
|
35198
|
+
const failingBlockers = BLOCKER_ORDER
|
|
35199
|
+
.filter(k => !signals[k])
|
|
35200
|
+
.map(k => exports.READINESS_BLOCKER_DESCRIPTIONS[k]);
|
|
35201
|
+
return { ready: failingBlockers.length === 0, signals, failingBlockers };
|
|
35202
|
+
}
|
|
35203
|
+
const GATE_LABELS = {
|
|
35204
|
+
goal: 'Title',
|
|
35205
|
+
objective: 'Objective',
|
|
35206
|
+
outcomes: 'Outcomes',
|
|
35207
|
+
constraints: 'Constraints',
|
|
35208
|
+
edgeCases: 'Edge cases',
|
|
35209
|
+
verification: 'Verification',
|
|
35210
|
+
};
|
|
35211
|
+
/** Gate keys → short labels for the frontmatter blocking list. */
|
|
35212
|
+
const FRONTMATTER_GATE_LABELS = {
|
|
35213
|
+
goal: 'title',
|
|
35214
|
+
objective: 'objective',
|
|
35215
|
+
outcomes: 'outcomes',
|
|
35216
|
+
constraints: 'constraints',
|
|
35217
|
+
edgeCases: 'edge-cases',
|
|
35218
|
+
verification: 'verification',
|
|
35219
|
+
};
|
|
35220
|
+
/**
|
|
35221
|
+
* Single-line readiness value stamped into intent.md frontmatter, so the verdict travels
|
|
35222
|
+
* with the file: "passed 6/6" or "failed 4/6 — blocking: constraints, verification".
|
|
35223
|
+
* Deterministic and greppable. Mirrored in lib/intentReadiness.formatReadinessFrontmatter;
|
|
35224
|
+
* lib/preflightReadinessParity.test.ts fails CI if the two drift.
|
|
35225
|
+
*/
|
|
35226
|
+
function formatReadinessFrontmatter(verdict) {
|
|
35227
|
+
const total = exports.READINESS_GATE_ORDER.length;
|
|
35228
|
+
const passed = exports.READINESS_GATE_ORDER.filter((k) => verdict.signals[k]).length;
|
|
35229
|
+
if (verdict.ready)
|
|
35230
|
+
return `passed ${passed}/${total}`;
|
|
35231
|
+
const blocking = exports.READINESS_GATE_ORDER.filter((k) => !verdict.signals[k]).map((k) => FRONTMATTER_GATE_LABELS[k]);
|
|
35232
|
+
return `failed ${passed}/${total} — blocking: ${blocking.join(', ')}`;
|
|
35233
|
+
}
|
|
35234
|
+
/** Human/agent-readable verdict block, stable enough to parse by line prefix. */
|
|
35235
|
+
function formatReadinessVerdict(verdict, specTitle) {
|
|
35236
|
+
const lines = [];
|
|
35237
|
+
const name = (specTitle || '').trim();
|
|
35238
|
+
if (verdict.ready) {
|
|
35239
|
+
lines.push(`✓ Preflight passed${name ? ` for "${name}"` : ''}. 6/6 checks. Ready to hand to an agent.`);
|
|
35240
|
+
}
|
|
35241
|
+
else {
|
|
35242
|
+
lines.push(`✗ Preflight failed${name ? ` for "${name}"` : ''}. ${verdict.failingBlockers.length}/6 checks blocking.`);
|
|
35243
|
+
for (const b of verdict.failingBlockers)
|
|
35244
|
+
lines.push(` ✗ ${b}`);
|
|
35245
|
+
}
|
|
35246
|
+
lines.push('');
|
|
35247
|
+
lines.push(exports.READINESS_GATE_ORDER.map(k => `${verdict.signals[k] ? '✓' : '·'} ${GATE_LABELS[k]}`).join(' '));
|
|
35248
|
+
if (!verdict.ready) {
|
|
35249
|
+
lines.push('');
|
|
35250
|
+
lines.push('Repair the failing fields (ask the user one targeted question per blocker), save with intent_save, and re-run check_intent_readiness. The verdict is deterministic: the same spec always gets the same result.');
|
|
35251
|
+
}
|
|
35252
|
+
return lines.join('\n');
|
|
35253
|
+
}
|
|
35254
|
+
|
|
35255
|
+
|
|
35006
35256
|
/***/ }),
|
|
35007
35257
|
|
|
35008
35258
|
/***/ 6137:
|
|
@@ -64931,7 +65181,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"$schema":"http://json-schema.org/dra
|
|
|
64931
65181
|
/***/ ((module) => {
|
|
64932
65182
|
|
|
64933
65183
|
"use strict";
|
|
64934
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.
|
|
65184
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@pathmode/mcp-server","version":"1.12.0","publishConfig":{"access":"public"},"mcpName":"io.github.pathmodeio/mcp-server","description":"Pathmode MCP Server — Build structured intent specs through Socratic AI conversation (zero-config), or connect to your Intent Layer for strategic context, dependency graphs, and implementation prompts.","main":"dist/index.js","bin":{"pathmode-mcp":"dist/index.js"},"files":["dist/","manifest.json","icon.svg","README.md","skills/"],"scripts":{"build":"rm -rf dist && ncc build src/index.ts -o dist","dev":"ts-node src/index.ts","prepublishOnly":"npm run build"},"keywords":["pathmode","mcp","model-context-protocol","claude-code","claude-code-skills","agent-skills","cursor","windsurf","intent-engineering","intent-compiler","ai-agents","product-development","dependency-graph","strategic-planning"],"author":"Pathmode","license":"MIT","type":"commonjs","engines":{"node":">=18.0.0"},"repository":{"type":"git","url":"git+https://github.com/pathmodeio/mcp-server.git","directory":"packages/mcp-server"},"homepage":"https://pathmode.io","dependencies":{"@modelcontextprotocol/sdk":"^1.12.1","gray-matter":"^4.0.3","zod":"^3.24.0"},"devDependencies":{"@types/node":"^25.1.0","@vercel/ncc":"^0.38.4","ts-node":"^10.9.2","typescript":"^5.9.3"}}');
|
|
64935
65185
|
|
|
64936
65186
|
/***/ })
|
|
64937
65187
|
|
|
@@ -65027,6 +65277,7 @@ const path_1 = __nccwpck_require__(6928);
|
|
|
65027
65277
|
const fs_1 = __nccwpck_require__(9896);
|
|
65028
65278
|
const api_client_1 = __nccwpck_require__(7475);
|
|
65029
65279
|
const local_reader_1 = __nccwpck_require__(3518);
|
|
65280
|
+
const readiness_1 = __nccwpck_require__(3079);
|
|
65030
65281
|
const save_policy_1 = __nccwpck_require__(6137);
|
|
65031
65282
|
const intent_compiler_1 = __nccwpck_require__(6488);
|
|
65032
65283
|
const pathmode_section_1 = __nccwpck_require__(4681);
|
|
@@ -65895,24 +66146,56 @@ function startMcpServer() {
|
|
|
65895
66146
|
});
|
|
65896
66147
|
cloudOnly.registerTool('verify_implementation', {
|
|
65897
66148
|
title: 'Verify Implementation',
|
|
65898
|
-
description: '
|
|
66149
|
+
description: 'Grade an implementation against the intent spec by reading the pull request. Pass prUrl and Pathmode fetches the diff itself and grades each outcome, constraint, constitution rule, edge case and verification check against what the code actually shows. Describing your own work instead is weaker evidence and the result says so. Returns pass/fail per item with reasoning, a score, and the basis the verdict rests on. Also logs the result as an implementation note.',
|
|
65899
66150
|
inputSchema: {
|
|
65900
66151
|
intentId: zod_1.z.string().describe('The intent ID to verify against'),
|
|
65901
|
-
|
|
65902
|
-
|
|
66152
|
+
prUrl: zod_1.z.string().optional().describe('Pull request URL (or owner/repo#123) containing the implementation. Strongly preferred: the diff is read from GitHub instead of taken on trust.'),
|
|
66153
|
+
summary: zod_1.z.string().optional().describe('What you implemented and how. Context for the grader, not evidence. Required only when there is no pull request to point at.'),
|
|
66154
|
+
codeChanges: zod_1.z.string().optional().describe('Deprecated, superseded by prUrl. A diff you paste about your own work is not independent evidence.'),
|
|
65903
66155
|
},
|
|
65904
66156
|
annotations: WRITE_OP,
|
|
65905
|
-
}, async ({ intentId, summary, codeChanges }) => {
|
|
66157
|
+
}, async ({ intentId, prUrl, summary, codeChanges }) => {
|
|
65906
66158
|
if (isLocalMode) {
|
|
65907
66159
|
return { content: [{ type: 'text', text: 'Verification requires cloud mode.' }] };
|
|
65908
66160
|
}
|
|
66161
|
+
if (!prUrl && !summary) {
|
|
66162
|
+
return { content: [{ type: 'text', text: 'Provide prUrl (preferred) or summary.' }] };
|
|
66163
|
+
}
|
|
65909
66164
|
try {
|
|
65910
|
-
const result = await requireCloudClient().verifyImplementation(intentId, summary, codeChanges);
|
|
65911
|
-
let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n
|
|
66165
|
+
const result = await requireCloudClient().verifyImplementation(intentId, { summary, prUrl, codeChanges });
|
|
66166
|
+
let text = `Verification ${result.pass ? 'PASSED' : 'FAILED'} (score: ${result.score}/100)\n`;
|
|
66167
|
+
// Say what the verdict was actually based on. A run that could not read the code must not
|
|
66168
|
+
// read like one that did, or the score becomes a rubber stamp for a well-written summary.
|
|
66169
|
+
const a = result.artifact;
|
|
66170
|
+
if (a?.kind === 'pr_diff') {
|
|
66171
|
+
text += `Graded against ${a.repo}#${a.prNumber} at ${a.headSha?.slice(0, 8)}`
|
|
66172
|
+
+ ` (${a.filesRead} file(s)${a.truncated ? `, ${a.filesOmitted} omitted for size` : ''})\n\n`;
|
|
66173
|
+
}
|
|
66174
|
+
else if (a) {
|
|
66175
|
+
text += `Graded on your own description, no code was read (${a.reason}).`
|
|
66176
|
+
+ ` Pass a prUrl for a verdict grounded in the diff.\n\n`;
|
|
66177
|
+
}
|
|
66178
|
+
else {
|
|
66179
|
+
text += '\n';
|
|
66180
|
+
}
|
|
65912
66181
|
text += `${result.summary}\n\n`;
|
|
65913
66182
|
for (const r of result.results) {
|
|
65914
|
-
const icon = r.status === 'pass' ? '[PASS]'
|
|
66183
|
+
const icon = r.status === 'pass' ? '[PASS]'
|
|
66184
|
+
: r.status === 'fail' ? '[FAIL]'
|
|
66185
|
+
: r.status === 'not_applicable' ? '[ -- ]'
|
|
66186
|
+
: '[????]';
|
|
65915
66187
|
text += `${icon} [${r.category}] ${r.item}\n ${r.reasoning}\n`;
|
|
66188
|
+
// Citations are validated server-side against the diff; an item with none, on a run
|
|
66189
|
+
// that had a diff, says so rather than reading like an inspected verdict.
|
|
66190
|
+
if (r.status === 'not_applicable') {
|
|
66191
|
+
// An absence claim has nothing to cite, so a missing citation is not a gap here.
|
|
66192
|
+
}
|
|
66193
|
+
else if (r.evidence?.length) {
|
|
66194
|
+
text += ` cites: ${r.evidence.map(c => c.path).join(', ')}\n`;
|
|
66195
|
+
}
|
|
66196
|
+
else if (r.basis === 'none') {
|
|
66197
|
+
text += ` cites: nothing in the diff\n`;
|
|
66198
|
+
}
|
|
65916
66199
|
}
|
|
65917
66200
|
return { content: [{ type: 'text', text }] };
|
|
65918
66201
|
}
|
|
@@ -66018,6 +66301,57 @@ function startMcpServer() {
|
|
|
66018
66301
|
}],
|
|
66019
66302
|
};
|
|
66020
66303
|
});
|
|
66304
|
+
server.registerTool('check_intent_readiness', {
|
|
66305
|
+
title: 'Check Intent Readiness (Preflight)',
|
|
66306
|
+
description: 'Run the deterministic preflight on an intent spec before handing it to an implementation agent. Six calibrated checks — title, objective, outcomes, constraints, edge cases, verification — computed by pure functions: no model call, no network, the same spec always gets the same verdict. Pass a spec inline to check before saving, pass intentId to check a specific saved intent, or pass nothing to check the current intent. A failing verdict names the exact blockers; repair the fields and re-run. This is the gate that runs at preflight.pathmode.io.',
|
|
66307
|
+
inputSchema: {
|
|
66308
|
+
spec: zod_1.z.object(intentSpecSchema).optional().describe('Check this spec directly (before saving). When omitted, the current intent is checked instead.'),
|
|
66309
|
+
intentId: zod_1.z.string().optional().describe('Check a specific saved intent by id. Ignored when spec is passed.'),
|
|
66310
|
+
},
|
|
66311
|
+
annotations: READ_ONLY,
|
|
66312
|
+
}, async ({ spec, intentId }) => {
|
|
66313
|
+
let subject = spec;
|
|
66314
|
+
let sourceNote = 'inline spec';
|
|
66315
|
+
if (!subject) {
|
|
66316
|
+
if (isLocalMode) {
|
|
66317
|
+
const intents = (0, local_reader_1.readLocalIntents)();
|
|
66318
|
+
subject = intentId ? intents.find(i => i.id === intentId) : pickCurrentIntent(intents);
|
|
66319
|
+
sourceNote = intentId ? `local intent ${intentId}` : 'current local intent (intent.md)';
|
|
66320
|
+
if (!subject) {
|
|
66321
|
+
return {
|
|
66322
|
+
content: [{
|
|
66323
|
+
type: 'text',
|
|
66324
|
+
text: intentId
|
|
66325
|
+
? `No local intent with id "${intentId}". Check intent.md or .pathmode/intents/.`
|
|
66326
|
+
: 'No intent found. Write one first (intent_save), or pass the spec inline to preflight it before saving.',
|
|
66327
|
+
}],
|
|
66328
|
+
};
|
|
66329
|
+
}
|
|
66330
|
+
}
|
|
66331
|
+
else {
|
|
66332
|
+
const cloud = requireCloudClient();
|
|
66333
|
+
const intents = await cloud.listIntents();
|
|
66334
|
+
subject = intentId ? intents.find((i) => i.id === intentId) : pickCurrentIntent(intents);
|
|
66335
|
+
sourceNote = intentId ? `intent ${intentId}` : 'current intent';
|
|
66336
|
+
if (!subject) {
|
|
66337
|
+
return {
|
|
66338
|
+
content: [{
|
|
66339
|
+
type: 'text',
|
|
66340
|
+
text: intentId ? `No intent with id "${intentId}" in this workspace.` : 'No intents found in workspace.',
|
|
66341
|
+
}],
|
|
66342
|
+
};
|
|
66343
|
+
}
|
|
66344
|
+
}
|
|
66345
|
+
}
|
|
66346
|
+
const verdict = (0, readiness_1.computeReadinessVerdict)(subject);
|
|
66347
|
+
const title = (0, readiness_1.coerceText)(subject.title);
|
|
66348
|
+
return {
|
|
66349
|
+
content: [{
|
|
66350
|
+
type: 'text',
|
|
66351
|
+
text: `${(0, readiness_1.formatReadinessVerdict)(verdict, title)}\n\nChecked: ${sourceNote}.`,
|
|
66352
|
+
}],
|
|
66353
|
+
};
|
|
66354
|
+
});
|
|
66021
66355
|
server.tool('intent_save', 'Save an intent spec to intent.md in the project root. Called after building a spec through conversation. Re-saving the same intent bumps its version and preserves its status; it never silently replaces a different intent.', {
|
|
66022
66356
|
spec: zod_1.z.object(intentSpecSchema),
|
|
66023
66357
|
path: zod_1.z.string().optional().describe('File path relative to the project root. Must stay inside the project (absolute paths and ".." are rejected). Defaults to intent.md'),
|
|
@@ -66046,13 +66380,20 @@ function startMcpServer() {
|
|
|
66046
66380
|
};
|
|
66047
66381
|
}
|
|
66048
66382
|
const { id, version, status, created } = decision;
|
|
66049
|
-
|
|
66383
|
+
// The preflight verdict travels with the file: stamped into frontmatter on every save,
|
|
66384
|
+
// recomputed from the spec alone (deterministic). A failing verdict never blocks the
|
|
66385
|
+
// save — the gate reports, the user decides.
|
|
66386
|
+
const verdict = (0, readiness_1.computeReadinessVerdict)(spec);
|
|
66387
|
+
const content = (0, intent_compiler_1.formatIntentMd)({ ...spec, id }, { version, status, created, readiness: (0, readiness_1.formatReadinessFrontmatter)(verdict) });
|
|
66050
66388
|
(0, fs_1.writeFileSync)(filePath, content, 'utf-8');
|
|
66051
66389
|
const action = decision.action === 'update' ? `Updated intent spec (v${version})` : 'Saved intent spec';
|
|
66390
|
+
const readinessNote = verdict.ready
|
|
66391
|
+
? ''
|
|
66392
|
+
: `\n\n${(0, readiness_1.formatReadinessVerdict)(verdict, spec.title)}`;
|
|
66052
66393
|
return {
|
|
66053
66394
|
content: [{
|
|
66054
66395
|
type: 'text',
|
|
66055
|
-
text: `✓ ${action} at ${filePath}\n id: ${id} · status: ${status}\n\nTo connect this to Pathmode for dependency tracking and team collaboration, visit pathmode.io`,
|
|
66396
|
+
text: `✓ ${action} at ${filePath}\n id: ${id} · status: ${status} · readiness: ${(0, readiness_1.formatReadinessFrontmatter)(verdict)}${readinessNote}\n\nTo connect this to Pathmode for dependency tracking and team collaboration, visit pathmode.io`,
|
|
66056
66397
|
}],
|
|
66057
66398
|
};
|
|
66058
66399
|
});
|
|
@@ -83,6 +83,10 @@ export interface IntentMdOptions {
|
|
|
83
83
|
status?: string;
|
|
84
84
|
/** Original `created` timestamp. Preserved across updates; defaults to now. */
|
|
85
85
|
created?: string;
|
|
86
|
+
/** Preflight verdict line ("passed 6/6" / "failed 4/6 — blocking: …"), recomputed at save time. */
|
|
87
|
+
readiness?: string;
|
|
88
|
+
/** Canonical record URL (cloud intents). Omitted when this file is the only copy. */
|
|
89
|
+
source?: string;
|
|
86
90
|
}
|
|
87
91
|
/**
|
|
88
92
|
* Generate intent.md content with YAML frontmatter.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/intent-compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,WAAW,cAAc;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAC1G,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AACxE,MAAM,WAAW,iBAAiB;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,qBAAqB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAsDD,MAAM,WAAW,YAAY;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB;;iCAE6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,CAAC,MAAM,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;KAAE,CAAC,EAAE,CAAC;IAC7F,6GAA6G;IAC7G,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACtD,YAAY,CAAC,EAAE;QACX,8GAA8G;QAC9G,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;QAC7B,kDAAkD;QAClD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IACF;sFACkF;IAClF,qBAAqB,CAAC,EAAE;QACpB,aAAa,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACnD,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;KACtC,GAAG,IAAI,CAAC;CACZ;AAwDD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA4D/C;AAoBD,kGAAkG;AAClG,MAAM,WAAW,eAAe;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/intent-compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic intent readiness gate — the preflight.
|
|
3
|
+
*
|
|
4
|
+
* This is a PORT of the canonical gate in lib/intentReadiness.ts (the MCP package
|
|
5
|
+
* cannot import app/lib code). Every regex and threshold below must stay
|
|
6
|
+
* byte-identical to the source; lib/preflightReadinessParity.test.ts in the app
|
|
7
|
+
* repo runs both implementations over the 98-item calibration corpus and the
|
|
8
|
+
* Preflight demo specs, and fails CI on any divergence. Edit the app lib first,
|
|
9
|
+
* then mirror the change here.
|
|
10
|
+
*
|
|
11
|
+
* Pure functions only: no I/O, no network, no model calls. The same spec gets
|
|
12
|
+
* the same verdict every run — that determinism is the product claim on
|
|
13
|
+
* https://preflight.pathmode.io, so keep it true.
|
|
14
|
+
*/
|
|
15
|
+
export declare function coerceText(value: unknown): string;
|
|
16
|
+
export declare function asArray<T>(value: T | T[] | null | undefined): T[];
|
|
17
|
+
export declare function isTitleMeaningful(title: string | null | undefined): boolean;
|
|
18
|
+
export declare function isConstraintConcrete(value: unknown): boolean;
|
|
19
|
+
export declare function isVerificationCheckSubstantive(description: string | null | undefined): boolean;
|
|
20
|
+
export declare function isObjectiveSpecific(objective: string | null | undefined): boolean;
|
|
21
|
+
export declare function isOutcomeMeasurable(text: string): boolean;
|
|
22
|
+
export declare const READINESS_BLOCKER_DESCRIPTIONS: Record<string, string>;
|
|
23
|
+
/** Display order for the gate strip (title first, matching the Preflight page). */
|
|
24
|
+
export declare const READINESS_GATE_ORDER: readonly ["goal", "objective", "outcomes", "constraints", "edgeCases", "verification"];
|
|
25
|
+
/** Loose spec shape: covers LocalIntent, cloud intent JSON, and hand-built specs. */
|
|
26
|
+
export interface ReadinessSpecInput {
|
|
27
|
+
title?: unknown;
|
|
28
|
+
objective?: unknown;
|
|
29
|
+
outcomes?: unknown;
|
|
30
|
+
constraints?: unknown;
|
|
31
|
+
edgeCases?: unknown;
|
|
32
|
+
verification?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface ReadinessVerdict {
|
|
35
|
+
ready: boolean;
|
|
36
|
+
signals: Record<string, boolean>;
|
|
37
|
+
failingBlockers: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The preflight: six deterministic gates over an intent spec. Mirrors
|
|
41
|
+
* lib/intentReadiness.computeReviewSignals with conversationFirst semantics
|
|
42
|
+
* (the legacy phase-engagement signal never gates the verdict here).
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeReadinessVerdict(spec: ReadinessSpecInput): ReadinessVerdict;
|
|
45
|
+
/**
|
|
46
|
+
* Single-line readiness value stamped into intent.md frontmatter, so the verdict travels
|
|
47
|
+
* with the file: "passed 6/6" or "failed 4/6 — blocking: constraints, verification".
|
|
48
|
+
* Deterministic and greppable. Mirrored in lib/intentReadiness.formatReadinessFrontmatter;
|
|
49
|
+
* lib/preflightReadinessParity.test.ts fails CI if the two drift.
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatReadinessFrontmatter(verdict: ReadinessVerdict): string;
|
|
52
|
+
/** Human/agent-readable verdict block, stable enough to parse by line prefix. */
|
|
53
|
+
export declare function formatReadinessVerdict(verdict: ReadinessVerdict, specTitle?: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"","sourceRoot":"","sources":["file:///Users/jannelammi/code/Pathmode/packages/mcp-server/src/readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQjD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,EAAE,CAIjE;AAoCD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAQ3E;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAI5D;AAED,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAI9F;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAOjF;AAQD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKzD;AAID,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOjE,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,wFAAyF,CAAC;AAK3H,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC7B;AAoBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,gBAAgB,CAkBlF;AAqBD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAM5E;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB5F"}
|
package/package.json
CHANGED
package/skills/README.md
CHANGED
|
@@ -12,6 +12,7 @@ Listed in lifecycle order — most projects use them in roughly this sequence.
|
|
|
12
12
|
|-------|----------|
|
|
13
13
|
| `setup-pathmode-workflow` | First-time setup — capturing test commands, issue tracker, status conventions |
|
|
14
14
|
| `compile-intent` | Building a structured spec for what to ship |
|
|
15
|
+
| `preflight` | Deterministic readiness verdict before an agent builds — six gates, exact blockers, no model call |
|
|
15
16
|
| `verify-intent` | Designing the executable feedback loop for a spec (fastest check, manual fallback, shipped signal) |
|
|
16
17
|
| `grill-intent` | Stress-testing an existing spec for weaknesses before code is written |
|
|
17
18
|
| `split-intent-to-issues` | Breaking a spec into paste-ready Linear / Jira / GitHub Issues tickets |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: preflight
|
|
3
|
+
description: Run the deterministic readiness check on an intent spec before an agent builds against it. Six calibrated gates, computed by pure functions — no model judgment, same spec always gets the same verdict. Use before implementing an intent, before handing a spec to another agent, or whenever the user asks "is this spec ready?".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<what-to-do>
|
|
7
|
+
|
|
8
|
+
Call the `check_intent_readiness` MCP tool (Pathmode). With no arguments it checks the current intent (`intent.md` in local mode, the active workspace intent in cloud mode). Pass `spec` inline to preflight a draft before saving it, or `intentId` for a specific saved intent.
|
|
9
|
+
|
|
10
|
+
Show the user the verdict block exactly as returned — the blocker strings are the calibrated gate output, do not paraphrase them.
|
|
11
|
+
|
|
12
|
+
If the verdict fails: repair, one blocker at a time. For each failing gate, ask the user ONE targeted question, and propose your best-guess answer from the spec and the codebase so they can correct rather than compose. Apply the agreed fix to the spec (`intent_save` in local mode), then re-run `check_intent_readiness`. Stop when the verdict passes or the user explicitly accepts a named gap.
|
|
13
|
+
|
|
14
|
+
If the verdict passes: say so and stop. Do not invent extra requirements beyond the six gates.
|
|
15
|
+
|
|
16
|
+
</what-to-do>
|
|
17
|
+
|
|
18
|
+
<supporting-info>
|
|
19
|
+
|
|
20
|
+
## What the six gates check
|
|
21
|
+
|
|
22
|
+
1. **Title** — a short, specific noun phrase, not a placeholder or generic label ("Bulk edit" passes; "New feature" fails).
|
|
23
|
+
2. **Objective** — names an actor and a concrete problem or capability; rejects buzzword-dressed vagueness with no number.
|
|
24
|
+
3. **Outcomes** — at least two, and at least two-thirds measurable: a threshold, an observable capability, or a concrete state change. "Users are happier" fails.
|
|
25
|
+
4. **Constraints** — at least one violable statement, something an implementation could actually break ("Never double-charge on retry"). Bare adjectives fail.
|
|
26
|
+
5. **Edge cases** — at least one scenario with a defined expected behavior.
|
|
27
|
+
6. **Verification** — at least one check concrete enough to run without asking the author.
|
|
28
|
+
|
|
29
|
+
## Why deterministic matters
|
|
30
|
+
|
|
31
|
+
The gate is pure functions over the spec text: no model call, no network. Re-running never changes the verdict unless the spec changed. That makes it a floor you can put in front of any implementation work — and it means a passing verdict is reproducible evidence, not an opinion. The same gate runs live at preflight.pathmode.io.
|
|
32
|
+
|
|
33
|
+
Every `intent_save` also stamps the verdict into the file's frontmatter as `readiness:` ("passed 6/6", or "failed N/6" with the blocking gates named), so anyone reading intent.md — human or agent — sees the gate state without re-running anything. A failing verdict never blocks the save; the gate reports, the user decides.
|
|
34
|
+
|
|
35
|
+
## Division of labor with the other skills
|
|
36
|
+
|
|
37
|
+
- `preflight` — deterministic verdict: IS the spec ready? Cheap, run it first and often.
|
|
38
|
+
- `grill-intent` — adversarial model-driven review: is the spec WISE? Run it when preflight passes but the stakes are high.
|
|
39
|
+
- `compile-intent` — builds a spec from a vague problem. Preflight what it produces.
|
|
40
|
+
|
|
41
|
+
</supporting-info>
|