predicate-skill 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.claude-plugin/plugin.json +6 -5
  2. package/README.md +88 -17
  3. package/cli.bundle.mjs +29269 -234
  4. package/dashboard/index.html +180 -0
  5. package/hooks/codex-cli/README.md +30 -0
  6. package/hooks/codex-cli/config.toml.template +10 -0
  7. package/hooks/codex-cli/pre-compact.sh +4 -0
  8. package/hooks/codex-cli/session-start.sh +7 -0
  9. package/hooks/codex-cli/stop.sh +4 -0
  10. package/hooks/cursor/README.md +46 -0
  11. package/hooks/cursor/mcp.json.template +12 -0
  12. package/hooks/cursor/pre-compact.sh +7 -0
  13. package/hooks/cursor/session-start.sh +7 -0
  14. package/hooks/cursor/stop.sh +5 -0
  15. package/hooks/gemini-cli/README.md +38 -0
  16. package/hooks/gemini-cli/pre-compact.sh +5 -0
  17. package/hooks/gemini-cli/session-start.sh +6 -0
  18. package/hooks/gemini-cli/settings.json.template +17 -0
  19. package/hooks/gemini-cli/stop.sh +20 -0
  20. package/hooks/hooks.json +25 -7
  21. package/hooks/opencode/README.md +40 -0
  22. package/hooks/opencode/opencode.json.template +18 -0
  23. package/hooks/opencode/pre-compact.sh +5 -0
  24. package/hooks/opencode/session-start.sh +6 -0
  25. package/hooks/opencode/stop.sh +20 -0
  26. package/hooks/post-tool-use.sh +10 -0
  27. package/hooks/pre-tool-use.sh +11 -0
  28. package/hooks/session-start.sh +7 -19
  29. package/hooks/stop.sh +20 -0
  30. package/hooks/vscode-copilot/README.md +43 -0
  31. package/hooks/vscode-copilot/pre-compact.sh +4 -0
  32. package/hooks/vscode-copilot/session-start.sh +7 -0
  33. package/hooks/vscode-copilot/settings.json.template +12 -0
  34. package/hooks/vscode-copilot/stop.sh +5 -0
  35. package/package.json +2 -1
  36. package/server.bundle.mjs +28422 -18694
  37. package/skills/predicate/SKILL.md +193 -1
@@ -16,6 +16,11 @@ Use Predicate when the user asks:
16
16
  - **What breaks if** X changes ("blast radius of renaming `validateToken`?")
17
17
  - **What's connected to** X transitively ("everything downstream of `JWT_SECRET`?")
18
18
  - **Where the contradiction is** ("these two docs disagree — which holds?")
19
+ - **What was done previously** ("which files did I modify last session?",
20
+ "did `pnpm test` pass last time?", "what commands have failed most often?") —
21
+ the Stop-hook extractor records every prior session's tool calls into
22
+ `kg:abox` as `pred:Session` + `codebase:modifiedIn` / `succeededIn` /
23
+ `failedIn` triples. See worked example 4.
19
24
 
20
25
  Do NOT use Predicate for:
21
26
  - Fuzzy semantic recall ("find docs about login" — use vector search)
@@ -101,7 +106,99 @@ kg_ask(
101
106
  )
102
107
  ```
103
108
 
104
- ## 4. Schema gap propose
109
+ ## 4. Session history "which files did I touch last session?"
110
+
111
+ When the user references prior work, query the session-history slice that
112
+ the Stop-hook extractor maintains in `kg:abox`. The relevant predicates
113
+ are `pred:Session` (the session entity), `codebase:modifiedIn`,
114
+ `codebase:succeededIn`, `codebase:failedIn`, `codebase:commandText`.
115
+
116
+ ```
117
+ kg_explore_schema("Session") # confirm the predicates
118
+ kg_ask(
119
+ question="Which files did I modify in the most recent session?",
120
+ sparql="""
121
+ PREFIX pred: <https://predicate.dev/meta#>
122
+ PREFIX cb: <https://predicate.dev/codebase#>
123
+ SELECT ?file ?session ?at WHERE {
124
+ GRAPH <kg:abox> {
125
+ ?session a pred:Session ; pred:at ?at .
126
+ ?file cb:modifiedIn ?session .
127
+ }
128
+ } ORDER BY DESC(?at) LIMIT 20
129
+ """
130
+ )
131
+ ```
132
+
133
+ Other useful queries on this slice:
134
+
135
+ ```
136
+ # Commands that have failed most often (debug-cycle hotspots)
137
+ SELECT ?text (COUNT(?session) AS ?failures) WHERE {
138
+ GRAPH <kg:abox> {
139
+ ?cmd a cb:Command ; cb:commandText ?text ; cb:failedIn ?session .
140
+ }
141
+ } GROUP BY ?text ORDER BY DESC(?failures)
142
+
143
+ # Files modified in this session that also failed a command (suspect debug targets)
144
+ SELECT DISTINCT ?file WHERE {
145
+ GRAPH <kg:abox> {
146
+ ?file cb:modifiedIn ?session .
147
+ ?cmd cb:failedIn ?session .
148
+ }
149
+ }
150
+ ```
151
+
152
+ Cite the session URI as provenance when the answer is "you last touched
153
+ auth.ts in session ses-X".
154
+
155
+ The reasoner derives additional classes on top of the raw action data
156
+ (refreshed by every `predicate maintain` run):
157
+
158
+ | Derived class | Means |
159
+ |---|---|
160
+ | `codebase:Hotspot` | File modified in >= 3 sessions — likely active work-in-progress |
161
+ | `codebase:FlakyCommand` | Command that has failed in >= 2 sessions — suspect debug target |
162
+ | `codebase:ActiveFile` | File modified in the single most-recent session |
163
+
164
+ Query them directly via `kg:inferred`:
165
+
166
+ ```sparql
167
+ PREFIX cb: <https://predicate.dev/codebase#>
168
+ SELECT ?file WHERE { GRAPH <kg:inferred> { ?file a cb:Hotspot } }
169
+ ```
170
+
171
+ ## 5. Memory recall — "what did I do with X recently?"
172
+
173
+ For substring-match recall over session history, call `predicate recall`
174
+ (or `kg_ask` with the equivalent SPARQL). Useful when the user asks
175
+ "what did I work on related to X?" or "did I ever run command Y?"
176
+
177
+ ```sparql
178
+ PREFIX cb: <https://predicate.dev/codebase#>
179
+ PREFIX pred: <https://predicate.dev/meta#>
180
+ SELECT ?file (COUNT(DISTINCT ?session) AS ?n) (MAX(?at) AS ?lastAt)
181
+ WHERE {
182
+ GRAPH <kg:abox> {
183
+ ?file cb:modifiedIn ?session .
184
+ ?session pred:at ?at .
185
+ FILTER (CONTAINS(LCASE(STR(?file)), LCASE("auth")))
186
+ }
187
+ } GROUP BY ?file ORDER BY DESC(?lastAt)
188
+ ```
189
+
190
+ Combine with the `cb:Hotspot` / `cb:FlakyCommand` / `cb:ActiveFile` derived
191
+ classes from `kg:inferred` for richer answers ("is auth.ts a hotspot?").
192
+
193
+ Shell shortcut:
194
+
195
+ ```bash
196
+ predicate recall auth # files + commands matching "auth"
197
+ predicate recall "pnpm test" # commands matching exact substring
198
+ predicate recall auth --json # machine-readable output
199
+ ```
200
+
201
+ ## 6. Schema gap → propose
105
202
 
106
203
  ```
107
204
  # User asks: "which services own these endpoints?"
@@ -117,3 +214,98 @@ kg_propose_schema(
117
214
  )
118
215
  # This goes to kg:tbox-staging. The promotion gate requires 3 successful uses in 7 days.
119
216
  ```
217
+
218
+ ## Federation
219
+
220
+ If teammates also use Predicate, they can share session-history:
221
+
222
+ ```bash
223
+ # On Alice's machine:
224
+ predicate export-sessions --user alice > alice.trig
225
+ # Send to Bob (Slack, scp, etc.)
226
+
227
+ # On Bob's machine:
228
+ predicate import-sessions alice.trig
229
+ predicate peer add alice http://alice.local:3030/predicate/query # optional, for live queries
230
+
231
+ # Then kg_ask can union local + remote:
232
+ kg_ask --include-remote ...
233
+ ```
234
+
235
+ This MVP is offline-friendly: no realtime sync, no auth. Each user's data
236
+ lives in a separate named graph so there are no merge conflicts. Same-IRI
237
+ collisions (e.g. `file:///work/auth.ts` from two users) are treated as
238
+ the same resource by RDF — use `owl:sameAs` if you want them merged, or
239
+ namespace your files per-user if you want them separate.
240
+
241
+ ## External Linked Data
242
+
243
+ For canonical public knowledge (Wikidata, DBpedia), call `predicate ld
244
+ ask` instead of trying to recall from training data. Examples:
245
+
246
+ ```bash
247
+ predicate ld init # one-time
248
+
249
+ predicate ld ask 'SELECT ?label WHERE {
250
+ <http://dbpedia.org/resource/JSON> rdfs:label ?label .
251
+ FILTER (LANG(?label) = "en")
252
+ } LIMIT 1'
253
+ ```
254
+
255
+ Use cases:
256
+ - "Is library X deprecated?" → check Wikidata for last-release metadata
257
+ - "Who maintains project Y?" → DBpedia abstract
258
+ - "What's the canonical URI for concept Z?" → both
259
+
260
+ `predicate ld init` registers `dbpedia` and `wikidata` as peers in
261
+ `kg:peers` with `pred:peerKind "external-ld"`. The marker keeps them
262
+ distinct from team peers — `predicate peer list` shows everything
263
+ side-by-side with a `kind` column; `predicate ld list` filters to just
264
+ the LD endpoints. Results from `ld ask` are NOT written back to local
265
+ `kg:abox` — each call re-fetches, so don't run this in tight loops.
266
+
267
+ ## Goal decomposition
268
+
269
+ The default `kg_research_goal` uses a pattern-based decomposer
270
+ (deterministic, fast, predictable). For questions that don't match any
271
+ pattern, you can opt-in to LLM-augmented decomposition by passing
272
+ `useLlmDecomposer: true`. The LLM (Claude Haiku) is constrained to
273
+ emit only the known intent kinds — invented kinds are filtered out.
274
+ If no `ANTHROPIC_API_KEY` is set, it transparently falls back to the
275
+ deterministic decomposer's 'unknown' result. The response includes a
276
+ `decomposerKind` field (`"deterministic"` or `"semantic"`) so you know
277
+ which path produced the sub-questions. Pattern-matched questions like
278
+ "what calls X" skip the LLM entirely.
279
+
280
+ ## Schema-learning toggle (v2.0)
281
+
282
+ The autonomous proposer (Generalizer) runs by default — when the agent
283
+ asserts a triple using a not-yet-declared pattern that appears in >= K
284
+ instances, it auto-stages a `kg_propose_schema` candidate. The sweeper
285
+ promotes after 3 successful uses.
286
+
287
+ To pause that loop (e.g., the user says "stop adding new predicates"):
288
+
289
+ ```
290
+ kg_config_set({ key: "schema-learning", value: false })
291
+ ```
292
+
293
+ When off:
294
+ - The Generalizer skips proposal generation.
295
+ - `kg_propose_schema` (explicit MCP calls) STILL works.
296
+ - The PromotionSweeper STILL promotes existing staged proposals.
297
+
298
+ Re-enable with `kg_config_set({ key: "schema-learning", value: true })`.
299
+ Read current state with `kg_config_get({ key: "schema-learning" })`.
300
+
301
+ ## Init / bootstrap (v2.0)
302
+
303
+ Predicate v2.0 boots empty. On first `predicate up`, the user picks one
304
+ of three modes via `predicate init` (interactive prompt or flags):
305
+
306
+ - **community**: bundled ontology (codebase, foaf, schema-org-lite, fhir-core)
307
+ - **upload**: user-supplied .ttl
308
+ - **empty**: meta + minimal top vocab; agent grows it via propose -> 3-use -> promote
309
+
310
+ The chosen mode is stored at `<urn:predicate:config>` in kg:meta and the
311
+ SessionStart banner reflects it.