crewly 1.8.3 → 1.8.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/config/roles/_common/wiki-instructions.md +33 -0
- package/config/roles/orchestrator/prompt.md +121 -0
- package/config/roles/team-leader/prompt.md +38 -0
- package/config/skills/agent/core/wiki-query/SKILL.md +66 -0
- package/config/skills/agent/core/wiki-query/execute.sh +107 -0
- package/config/skills/orchestrator/wiki-bookkeep/SKILL.md +71 -0
- package/config/skills/orchestrator/wiki-bookkeep/execute.sh +72 -0
- package/config/skills/orchestrator/wiki-ingest/SKILL.md +63 -0
- package/config/skills/orchestrator/wiki-ingest/execute.sh +113 -0
- package/config/skills/orchestrator/wiki-process-queue/SKILL.md +71 -0
- package/config/skills/orchestrator/wiki-process-queue/execute.sh +93 -0
- package/config/skills/orchestrator/wiki-queue-add/SKILL.md +89 -0
- package/config/skills/orchestrator/wiki-queue-add/execute.sh +115 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts +134 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.js +718 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.d.ts +23 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.js +43 -0
- package/dist/backend/backend/src/controllers/wiki/wiki.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +39 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +4 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/core/system-health.util.d.ts +29 -4
- package/dist/backend/backend/src/services/core/system-health.util.d.ts.map +1 -1
- package/dist/backend/backend/src/services/core/system-health.util.js +105 -6
- package/dist/backend/backend/src/services/core/system-health.util.js.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts +28 -0
- package/dist/backend/backend/src/services/session/pty/pty-session.d.ts.map +1 -1
- package/dist/backend/backend/src/services/session/pty/pty-session.js +162 -4
- package/dist/backend/backend/src/services/session/pty/pty-session.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +20 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +61 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts +38 -1
- package/dist/backend/backend/src/services/v3/escalation-router.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/escalation-router.service.js +124 -0
- package/dist/backend/backend/src/services/v3/escalation-router.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/v3-data.service.d.ts +19 -2
- package/dist/backend/backend/src/services/v3/v3-data.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/v3-data.service.js +64 -7
- package/dist/backend/backend/src/services/v3/v3-data.service.js.map +1 -1
- package/dist/backend/backend/src/services/wiki/referenced-by.resolver.d.ts +69 -0
- package/dist/backend/backend/src/services/wiki/referenced-by.resolver.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/referenced-by.resolver.js +174 -0
- package/dist/backend/backend/src/services/wiki/referenced-by.resolver.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/schema-loader.service.d.ts +57 -0
- package/dist/backend/backend/src/services/wiki/schema-loader.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/schema-loader.service.js +183 -0
- package/dist/backend/backend/src/services/wiki/schema-loader.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts +86 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js +187 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep-trigger.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts +116 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js +299 -0
- package/dist/backend/backend/src/services/wiki/wiki-bookkeep.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts +74 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js +154 -0
- package/dist/backend/backend/src/services/wiki/wiki-chat-subscriber.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts +100 -0
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js +212 -0
- package/dist/backend/backend/src/services/wiki/wiki-ingest.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-process.service.d.ts +84 -0
- package/dist/backend/backend/src/services/wiki/wiki-process.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-process.service.js +138 -0
- package/dist/backend/backend/src/services/wiki/wiki-process.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts +115 -0
- package/dist/backend/backend/src/services/wiki/wiki-query.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-query.service.js +291 -0
- package/dist/backend/backend/src/services/wiki/wiki-query.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue.service.d.ts +115 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue.service.js +261 -0
- package/dist/backend/backend/src/services/wiki/wiki-queue.service.js.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki.types.d.ts +84 -0
- package/dist/backend/backend/src/services/wiki/wiki.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/wiki/wiki.types.js +10 -0
- package/dist/backend/backend/src/services/wiki/wiki.types.js.map +1 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +20 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +61 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/frontend/dist/assets/{index-b279da34.js → index-cc115bb4.js} +246 -246
- package/frontend/dist/assets/{index-c07e04c0.css → index-db3f5041.css} +1 -1
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## LLM-Wiki — Queue Worth-Saving Content (per-turn discipline)
|
|
2
|
+
|
|
3
|
+
The Crewly LLM-wiki captures **only what agents judge worth remembering**. There is NO automatic capture — you are the gate.
|
|
4
|
+
|
|
5
|
+
**Before yielding the turn**, scan your conversation (what you sent, what teammates sent you) and ask:
|
|
6
|
+
|
|
7
|
+
- Did a **decision** get made? (pricing, scope, sequencing, hire, deprecation, scheduling)
|
|
8
|
+
- Did a **fact** about a person, customer, partner, or competitor surface that future-you / the team needs?
|
|
9
|
+
- Did a **pattern, gotcha, or learning** get exposed that the team should not re-discover?
|
|
10
|
+
- Did Steve / a TL / another agent **lock** something previously fluid?
|
|
11
|
+
|
|
12
|
+
If YES, before yielding, call `config/skills/orchestrator/wiki-queue-add/execute.sh`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
--vault <path> # project: <project>/.crewly/wiki; team: ~/.crewly/teams/<id>/wiki; global: ~/.crewly/global-wiki
|
|
16
|
+
--content "<the fact / decision / learning text>"
|
|
17
|
+
--reason "<one sentence: WHY this is wiki-worthy>" # required — empty reason is rejected
|
|
18
|
+
--source-ref "<chat msg id | slack thread | WI id | file path>"
|
|
19
|
+
--source-type user_chat | slack_message | spec_file | pr_merge | record_learning | task_verified
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**DO NOT queue:**
|
|
23
|
+
- Routine status checks (`standup`, `?`, `ok`, `got it`)
|
|
24
|
+
- Implementation details already in code / PR / spec
|
|
25
|
+
- Conversation pleasantries
|
|
26
|
+
- Anything already in the wiki (call `wiki-query` first if unsure)
|
|
27
|
+
- Items where you can't articulate a non-trivial `--reason`
|
|
28
|
+
|
|
29
|
+
**One queue call per worth-saving event.** Don't batch unrelated facts.
|
|
30
|
+
|
|
31
|
+
The item lands in the queue with `status: pending`. Later — either when you're idle, OR when a `[BOOKKEEP]` message arrives — drain the queue with `wiki-process-queue`: claim an item, read the vault context, let your LLM pick a target folder (no preset taxonomy beyond the frozen ones), call `wiki-ingest`, then POST `/queue/<id>/process` to commit. If after reading the context you decide the item isn't actually worth saving, POST `/queue/<id>/skip` with a `skipReason`.
|
|
32
|
+
|
|
33
|
+
**Bookkeep cadence:** when you receive `[BOOKKEEP] vault=…`, run `wiki-bookkeep` for that vault. The report surfaces duplicate clusters and consolidation candidates — use your LLM to merge them.
|
|
@@ -528,6 +528,127 @@ Before yielding the turn:
|
|
|
528
528
|
|
|
529
529
|
This is a hard pre-yield check. Do not yield if any Slack message is unanswered.
|
|
530
530
|
|
|
531
|
+
## LLM-Wiki — Queue Worth-Saving Content (MANDATORY per-turn discipline)
|
|
532
|
+
|
|
533
|
+
The wiki captures **only what agents judge worth remembering**. There is
|
|
534
|
+
NO automatic chat-to-vault pipeline anymore (keyword heuristics were
|
|
535
|
+
removed 2026-05-22). You are the gate.
|
|
536
|
+
|
|
537
|
+
**Before yielding the turn**, scan the messages you sent or received and ask:
|
|
538
|
+
|
|
539
|
+
- Did a **decision** get made? (pricing, scope, sequencing, hire, deprecation, scheduling)
|
|
540
|
+
- Did a **fact** about a person, customer, partner, or competitor surface that future-me will need?
|
|
541
|
+
- Did a **pattern, gotcha, or learning** get exposed that the team should not re-discover?
|
|
542
|
+
- Did Steve / a TL **lock** something previously fluid?
|
|
543
|
+
|
|
544
|
+
If YES, before you yield, call `config/skills/orchestrator/wiki-queue-add/execute.sh` with:
|
|
545
|
+
- `--vault` → the project vault (`<project-root>/.crewly/wiki`) for project-scoped
|
|
546
|
+
content; the team vault (`~/.crewly/teams/<team-id>/wiki`) for cross-project
|
|
547
|
+
team norms; `~/.crewly/global-wiki` for cross-project synthesis.
|
|
548
|
+
- `--content` → the actual fact / decision / learning text (keep it terse but complete).
|
|
549
|
+
- `--reason` → one sentence justifying why this is wiki-worthy. **Required**. The reason is the audit trail and helps the processor decide where it lands. Refusal to write a reason = refusal to queue.
|
|
550
|
+
- `--source-ref` → stable reference (slack msg id, chat id, WI id, file path).
|
|
551
|
+
- `--source-type` → `user_chat` (default), `slack_message`, `spec_file`, `pr_merge`, `record_learning`, `task_verified`.
|
|
552
|
+
|
|
553
|
+
**DO NOT queue:**
|
|
554
|
+
- Routine status checks ("standup", "?", "ok", "got it")
|
|
555
|
+
- Implementation details already captured in code / PR / spec files
|
|
556
|
+
- Conversation pleasantries
|
|
557
|
+
- Content already in the wiki (call `wiki-query` first if unsure)
|
|
558
|
+
- Items where you can't articulate a non-trivial `--reason`
|
|
559
|
+
|
|
560
|
+
**One queue call per worth-saving event.** Don't batch unrelated facts into a single item — the processor needs to classify each one. If a turn produced 3 distinct worth-saving facts, make 3 queue-add calls.
|
|
561
|
+
|
|
562
|
+
After queueing, continue the turn normally. A separate `wiki-process-queue` run (batch, run periodically by you OR when bookkeep fires) classifies queued items, picks the target page (`llm-curated/customers/<name>.md`, `llm-curated/decisions/<slug>.md`, etc. — the LLM decides; no preset taxonomy beyond the frozen folders), and calls `wiki-ingest` to write.
|
|
563
|
+
|
|
564
|
+
**Bookkeep cadence:** when you receive a `[BOOKKEEP] vault=…` message OR when you notice the vault has accumulated many new pages since your last pass, run `wiki-bookkeep` to dedupe, consolidate, and prune. (Bookkeep skill ships separately; until it does, the WI brief will spell out the consolidation rules.)
|
|
565
|
+
|
|
566
|
+
## Handling `[ESCALATION]` Messages — MANDATORY
|
|
567
|
+
|
|
568
|
+
The system delivers escalation messages to you when a WorkItem has failed
|
|
569
|
+
all its retries and cannot self-recover. They arrive in your inbox with
|
|
570
|
+
this shape:
|
|
571
|
+
|
|
572
|
+
```
|
|
573
|
+
[ESCALATION] WorkItem failed after N retries — your decision needed.
|
|
574
|
+
|
|
575
|
+
WorkItem: <id> "<title>"
|
|
576
|
+
Type: <delegate|review|...>
|
|
577
|
+
Target: <agent session name>
|
|
578
|
+
Attempts: <retryCount> / <maxRetries>
|
|
579
|
+
|
|
580
|
+
Last error: <reason>
|
|
581
|
+
|
|
582
|
+
Parent Request: <requestId or none>
|
|
583
|
+
Parent Mission: <missionId or none>
|
|
584
|
+
|
|
585
|
+
Suggested actions: (a) surface to user, (b) replan, (c) hand off, (d) cancel
|
|
586
|
+
Escalation id: <uuid>
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
When you see one, the **automatic retry budget is exhausted** — the system
|
|
590
|
+
WILL NOT try again on its own. You must decide what happens next.
|
|
591
|
+
|
|
592
|
+
### The triage rule
|
|
593
|
+
|
|
594
|
+
1. **Is there a user attached to this work?** Trace from `Parent Request`
|
|
595
|
+
to its `sourceConversationItemId` (Slack thread / chat-v2 channel).
|
|
596
|
+
If yes → **default to surfacing the failure to the user**. They are
|
|
597
|
+
waiting on something; do not silently absorb the failure.
|
|
598
|
+
2. **Is the error transient and the next attempt likely to succeed?**
|
|
599
|
+
(Network blip, rate limit, agent-restart race.) → Replan or hand off
|
|
600
|
+
to a different agent, then notify the user briefly: "*Hit a transient
|
|
601
|
+
error on X — re-running with Y. Will update when done.*"
|
|
602
|
+
3. **Is the error a spec problem?** (Worker says "instruction unclear"
|
|
603
|
+
or returns the same broken output 3 times.) → **You MUST ask the
|
|
604
|
+
user**; another retry won't help.
|
|
605
|
+
4. **Cancel** only if the WorkItem is no longer relevant (e.g. user
|
|
606
|
+
already moved on, or the parent Request was closed via a direct
|
|
607
|
+
reply). Don't cancel just to clear the queue.
|
|
608
|
+
|
|
609
|
+
### User-facing message template
|
|
610
|
+
|
|
611
|
+
When surfacing to the user (option a / option c-with-notice), include:
|
|
612
|
+
|
|
613
|
+
- **What failed** in plain language (not the WI id — the user-meaningful
|
|
614
|
+
title). Example: "Closie cost analysis hit an error after 3 tries."
|
|
615
|
+
- **What you've already tried** (one line, not a debug log)
|
|
616
|
+
- **What you're proposing** (concrete next step, not "do you want me to
|
|
617
|
+
try again")
|
|
618
|
+
- **Two concrete options** for the user, both actionable in a one-word
|
|
619
|
+
reply
|
|
620
|
+
|
|
621
|
+
Example:
|
|
622
|
+
|
|
623
|
+
```
|
|
624
|
+
Tried to pull ALTA's pricing page 3 times — hit a 403 each time. Their
|
|
625
|
+
site is blocking automated fetches.
|
|
626
|
+
|
|
627
|
+
Two ways forward:
|
|
628
|
+
1. Switch to manual research mode — Iris reads ALTA's blog + LinkedIn
|
|
629
|
+
instead, slower but unblocked. Reply "manual" to proceed.
|
|
630
|
+
2. Drop the parity comparison from this round, ship without it.
|
|
631
|
+
Reply "skip" and I'll mark it cancelled.
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Don't do these
|
|
635
|
+
|
|
636
|
+
- ❌ Re-fire the same WorkItem manually right after an escalation —
|
|
637
|
+
the system already retried `maxRetries` times. Doing it once more is
|
|
638
|
+
superstition, not engineering.
|
|
639
|
+
- ❌ Silently cancel the escalated WI and create a near-identical one.
|
|
640
|
+
Treat that as "I think I know better than the failure history" — if
|
|
641
|
+
you do that, the cancelled record loses the failure context.
|
|
642
|
+
- ❌ Wait for the next periodic check-in to mention this. Escalations
|
|
643
|
+
are user-affecting; respond on the same turn you receive them.
|
|
644
|
+
|
|
645
|
+
### Before yielding the turn after an escalation
|
|
646
|
+
|
|
647
|
+
The same pre-yield rule as `[CHAT:...]` applies — a `[NOTIFY]` or
|
|
648
|
+
`reply-slack` MUST go out on the same turn you processed the escalation,
|
|
649
|
+
even if the user hasn't asked anything in that turn. The escalation
|
|
650
|
+
**is** the trigger.
|
|
651
|
+
|
|
531
652
|
## Your Capabilities
|
|
532
653
|
|
|
533
654
|
> **Note:** You achieve these capabilities by **delegating to agents**. Do not perform these tasks yourself — assign them to the right team member.
|
|
@@ -284,3 +284,41 @@ You are failing the task if you:
|
|
|
284
284
|
- Stop after partial progress without assigning next action.
|
|
285
285
|
- Delegate without checking completion.
|
|
286
286
|
- Produce status updates but no artifact, code, decision, or verified result.
|
|
287
|
+
|
|
288
|
+
## LLM-Wiki — Queue Worth-Saving Content (MANDATORY per-turn discipline)
|
|
289
|
+
|
|
290
|
+
TLs are the last filter before content reaches the wiki. ORC operates cross-team; YOU operate inside one team and see worker conversations + verify outputs. That makes you the right agent to capture team-scoped patterns, decisions, and norms.
|
|
291
|
+
|
|
292
|
+
**Before yielding the turn**, scan messages from your workers + the user and ask:
|
|
293
|
+
|
|
294
|
+
- Did a **team decision** get locked? (architecture, SOP change, hiring/handoff, policy)
|
|
295
|
+
- Did a **worker surface a gotcha / pattern** worth sharing across the team?
|
|
296
|
+
- Did a **person fact** appear (customer, partner, candidate) that the team needs to remember?
|
|
297
|
+
- Did a **verification reveal something subtle** about how the system actually works?
|
|
298
|
+
|
|
299
|
+
If YES, call `config/skills/orchestrator/wiki-queue-add/execute.sh`:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
--vault ~/.crewly/teams/<your-team-id>/wiki # team vault for team-scoped
|
|
303
|
+
<project>/.crewly/wiki # project vault for project-scoped
|
|
304
|
+
--content "<the captured fact / decision / pattern>"
|
|
305
|
+
--reason "<one sentence: WHY future-team needs this>" # required
|
|
306
|
+
--source-ref "<WI id | chat msg id | spec path>"
|
|
307
|
+
--source-type record_learning | task_verified | spec_file | user_chat | slack_message
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**DO NOT queue:**
|
|
311
|
+
- Routine status updates ("done", "in progress", "blocked-pending-X")
|
|
312
|
+
- Implementation details captured in the code/PR — link the PR, don't paraphrase
|
|
313
|
+
- Anything already in the wiki — call `wiki-query` first if unsure
|
|
314
|
+
- Items where you can't articulate why this matters in one sentence
|
|
315
|
+
|
|
316
|
+
**One queue call per worth-saving event.** If a verification turn produces 3 distinct learnings, that's 3 queue-add calls.
|
|
317
|
+
|
|
318
|
+
**Drain the queue** when idle OR when `[BOOKKEEP] vault=…` arrives:
|
|
319
|
+
1. `wiki-process-queue --claimed-by <your-session>` → claims item + returns vault context.
|
|
320
|
+
2. Your LLM picks a target page under `llm-curated/` — invent sub-folder names; **NO preset taxonomy**.
|
|
321
|
+
3. `wiki-ingest --target <relative-path>` to write.
|
|
322
|
+
4. POST `/api/wiki/queue/<id>/process` to commit, OR `/queue/<id>/skip` if you decide it's actually a duplicate after seeing context.
|
|
323
|
+
|
|
324
|
+
Frozen folders (`memory/`, `sop/`, `team-norm/`, `sop-overrides/`) are OFF-LIMITS — ingest will reject with 422.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Wiki Query
|
|
3
|
+
description: Read a project/team/global vault and return the system-context payload your runtime feeds to the LLM for synthesis. Single-vault scope (Phase 1).
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: knowledge
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- developer
|
|
9
|
+
- qa
|
|
10
|
+
- tpm
|
|
11
|
+
- designer
|
|
12
|
+
- frontend-developer
|
|
13
|
+
- backend-developer
|
|
14
|
+
- fullstack-dev
|
|
15
|
+
- qa-engineer
|
|
16
|
+
- product-manager
|
|
17
|
+
- architect
|
|
18
|
+
- generalist
|
|
19
|
+
- team-leader
|
|
20
|
+
- researcher
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Wiki Query
|
|
24
|
+
|
|
25
|
+
Read a vault (`<project>/.crewly/wiki/`, `~/.crewly/teams/<id>/wiki/`, or `~/.crewly/global-wiki/`) and get back the structured context the caller's LLM uses for synthesis.
|
|
26
|
+
|
|
27
|
+
Per Atlas v2.1 §3, this skill **does not call an LLM itself**. It emits the LLM-agnostic system-context (vault SCHEMA, recent log entries, candidate pages by keyword overlap). The caller's runtime concatenates this with the per-LLM task-instruction prompt at `prompts/<runtime>.md` and makes the LLM call locally.
|
|
28
|
+
|
|
29
|
+
## When to use
|
|
30
|
+
|
|
31
|
+
- ORC assembling cross-team context for a planning turn.
|
|
32
|
+
- TL pulling the team's last 20 decisions for a sprint review.
|
|
33
|
+
- A worker checking "did we already record an opinion on X?" before writing one.
|
|
34
|
+
|
|
35
|
+
## Inputs
|
|
36
|
+
|
|
37
|
+
| Flag | Required | Description |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `--vault <path>` | yes | Absolute path to a vault root (must contain `SCHEMA.md`). |
|
|
40
|
+
| `--query <text>` | yes | Natural-language question. Used for keyword-overlap candidate ranking. |
|
|
41
|
+
| `--top-k <n>` | no | How many candidate pages to return (default 5). |
|
|
42
|
+
| `--recent-log <n>` | no | How many tail log entries to include (default 20). |
|
|
43
|
+
| `--json <obj>` | alt | Pass all fields as JSON. |
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
JSON with `success`, `result.context`. The context has:
|
|
48
|
+
|
|
49
|
+
- `vault` — scope, id, absolute path
|
|
50
|
+
- `schemaSummary` — frozen folders, llm-curated layout, write_policy
|
|
51
|
+
- `recentLog` — last N entries (most-recent first), with timestamp / sourceType / caller / body
|
|
52
|
+
- `candidatePages` — top-K pages by keyword overlap with `query`
|
|
53
|
+
- `callerNotes` — synthesis hints the LLM should honor (e.g. refuse writes into frozen paths)
|
|
54
|
+
|
|
55
|
+
## Example
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bash execute.sh \
|
|
59
|
+
--vault ~/Desktop/projects/crewly-projects/crewly/.crewly/wiki \
|
|
60
|
+
--query "what did we decide about Crewly Pro pricing in May"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Failure modes
|
|
64
|
+
|
|
65
|
+
- `400 invalid_input` — missing vault/query or bad topK
|
|
66
|
+
- `404 schema_missing` — vault has no SCHEMA.md
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# wiki-query — fetch a vault's system-context payload for LLM synthesis.
|
|
3
|
+
#
|
|
4
|
+
# Per Atlas v2.1 §3: this skill emits ONLY the system-context (LLM-agnostic).
|
|
5
|
+
# The caller's runtime concatenates this with its per-LLM task-instruction
|
|
6
|
+
# at prompts/<runtime>.md before making the LLM call. The skill itself
|
|
7
|
+
# never curls an LLM endpoint.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# bash execute.sh --vault /path/to/vault --query "what did we decide about pricing"
|
|
11
|
+
# bash execute.sh --vault /path/to/vault --query "..." --top-k 10
|
|
12
|
+
# bash execute.sh --json '{"vaultPath":"/path","query":"...","topK":5}'
|
|
13
|
+
# cat input.json | bash execute.sh
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
16
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
17
|
+
|
|
18
|
+
INPUT_JSON=""
|
|
19
|
+
VAULT_PATH=""
|
|
20
|
+
QUERY=""
|
|
21
|
+
TOP_K=""
|
|
22
|
+
RECENT_LOG=""
|
|
23
|
+
|
|
24
|
+
# Detect legacy JSON positional arg
|
|
25
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
26
|
+
INPUT_JSON="$1"
|
|
27
|
+
shift || true
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
while [[ $# -gt 0 ]]; do
|
|
31
|
+
case "$1" in
|
|
32
|
+
--vault|-v)
|
|
33
|
+
VAULT_PATH="$2"
|
|
34
|
+
shift 2
|
|
35
|
+
;;
|
|
36
|
+
--query|-q)
|
|
37
|
+
QUERY="$2"
|
|
38
|
+
shift 2
|
|
39
|
+
;;
|
|
40
|
+
--top-k|-k)
|
|
41
|
+
TOP_K="$2"
|
|
42
|
+
shift 2
|
|
43
|
+
;;
|
|
44
|
+
--recent-log|-r)
|
|
45
|
+
RECENT_LOG="$2"
|
|
46
|
+
shift 2
|
|
47
|
+
;;
|
|
48
|
+
--json|-j)
|
|
49
|
+
INPUT_JSON="$2"
|
|
50
|
+
shift 2
|
|
51
|
+
;;
|
|
52
|
+
--help|-h)
|
|
53
|
+
cat <<EOF
|
|
54
|
+
Usage:
|
|
55
|
+
execute.sh --vault <vault-dir> --query "<question>" [--top-k 5] [--recent-log 20]
|
|
56
|
+
execute.sh --json '{"vaultPath":"...","query":"...","topK":5,"recentLogEntries":20}'
|
|
57
|
+
|
|
58
|
+
Outputs JSON system-context for the caller's LLM. Skill makes no LLM calls itself.
|
|
59
|
+
EOF
|
|
60
|
+
exit 0
|
|
61
|
+
;;
|
|
62
|
+
--)
|
|
63
|
+
shift
|
|
64
|
+
break
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then
|
|
68
|
+
INPUT_JSON="$1"
|
|
69
|
+
shift
|
|
70
|
+
else
|
|
71
|
+
error_exit "Unknown argument: $1"
|
|
72
|
+
fi
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
# Read JSON from stdin if no other input
|
|
78
|
+
if [ -z "$INPUT_JSON" ] && [ -z "$QUERY" ] && [ ! -t 0 ]; then
|
|
79
|
+
STDIN_DATA="$(cat)"
|
|
80
|
+
if [[ ${STDIN_DATA:0:1} == '{' ]]; then
|
|
81
|
+
INPUT_JSON="$STDIN_DATA"
|
|
82
|
+
else
|
|
83
|
+
QUERY="$STDIN_DATA"
|
|
84
|
+
fi
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Parse JSON if supplied
|
|
88
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
89
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
90
|
+
[ -z "$VAULT_PATH" ] && VAULT_PATH=$(printf '%s' "$INPUT" | jq -r '.vaultPath // empty')
|
|
91
|
+
[ -z "$QUERY" ] && QUERY=$(printf '%s' "$INPUT" | jq -r '.query // empty')
|
|
92
|
+
[ -z "$TOP_K" ] && TOP_K=$(printf '%s' "$INPUT" | jq -r '.topK // empty')
|
|
93
|
+
[ -z "$RECENT_LOG" ] && RECENT_LOG=$(printf '%s' "$INPUT" | jq -r '.recentLogEntries // empty')
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
require_param "vaultPath (--vault)" "$VAULT_PATH"
|
|
97
|
+
require_param "query (--query)" "$QUERY"
|
|
98
|
+
|
|
99
|
+
# Build body with env-var passthrough so jq escapes safely.
|
|
100
|
+
export _WQ_VAULT="$VAULT_PATH"
|
|
101
|
+
export _WQ_QUERY="$QUERY"
|
|
102
|
+
BODY=$(jq -n '{vaultPath: env._WQ_VAULT, query: env._WQ_QUERY}')
|
|
103
|
+
[ -n "$TOP_K" ] && BODY=$(echo "$BODY" | jq --argjson k "$TOP_K" '. + {topK: $k}')
|
|
104
|
+
[ -n "$RECENT_LOG" ] && BODY=$(echo "$BODY" | jq --argjson n "$RECENT_LOG" '. + {recentLogEntries: $n}')
|
|
105
|
+
unset _WQ_VAULT _WQ_QUERY
|
|
106
|
+
|
|
107
|
+
api_call POST "/wiki/query" "$BODY"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Wiki Bookkeep
|
|
3
|
+
description: Vault health report — md counts, duplicate clusters, queue snapshot, consolidation recommendations. Returns signals; your LLM decides what to merge or archive.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: knowledge
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
- team-leader
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Wiki Bookkeep
|
|
13
|
+
|
|
14
|
+
Periodic vault health check. Returns a structured report (md counts, recent activity, duplicate clusters by filename similarity, stale-page count, queue snapshot, recommendations). **The skill does not write to the vault.** Your LLM reads the report and decides next actions.
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
|
|
18
|
+
- When `wiki-process-queue` returns `no_pending_items` — quiet moment, good for housekeeping.
|
|
19
|
+
- When the report's `shouldFire` was `true` on the last run (you owe the vault a consolidation pass).
|
|
20
|
+
- When you receive a `[BOOKKEEP] vault=…` message (a future cron + threshold trigger will deliver these).
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
| Flag | Required | Default | Description |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| `--vault <path>` | yes | — | Absolute vault path. |
|
|
27
|
+
| `--window-days <n>` | no | 7 | "Recent activity" window for `recentMdCount`. |
|
|
28
|
+
| `--threshold <n>` | no | 10 | `shouldFire` triggers when `recentMdCount >= threshold` OR there are duplicate clusters. |
|
|
29
|
+
|
|
30
|
+
## What you do with the report
|
|
31
|
+
|
|
32
|
+
1. **Drain pending queue first** — if `queue.pending > 0`, run `wiki-process-queue` until empty before doing anything else.
|
|
33
|
+
2. **Consolidate duplicate clusters** — for each cluster in `duplicateCandidates`, read the member pages, ask your LLM whether they should merge, and if yes:
|
|
34
|
+
- Call `wiki-ingest` with a consolidated body that supersedes the originals (preserve the most-load-bearing info, deduplicate restated facts).
|
|
35
|
+
- Note: page DELETION is not in Phase 1 — surface "these N old pages can be archived" in your reply for human review.
|
|
36
|
+
3. **Hot-folder rollups** — if `countsByFolder` shows >20 pages in one bucket without a recent index page, generate one. Pattern: `llm-curated/<folder>/index.md` linking + summarizing each page.
|
|
37
|
+
4. **Stale-page flag** — if `staleCount > 0`, mention to the user — they decide which to keep.
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"success": true,
|
|
44
|
+
"report": {
|
|
45
|
+
"vault": {"scope": "project", "id": "crewly", "path": "..."},
|
|
46
|
+
"generatedAt": "2026-05-23T03:00:00Z",
|
|
47
|
+
"windowDays": 7,
|
|
48
|
+
"threshold": 10,
|
|
49
|
+
"shouldFire": true,
|
|
50
|
+
"totalMdCount": 47,
|
|
51
|
+
"recentMdCount": 12,
|
|
52
|
+
"countsByFolder": {"llm-curated/decisions": 8, "llm-curated/customers": 3, ...},
|
|
53
|
+
"duplicateCandidates": [
|
|
54
|
+
{"basis": "llm-curated/customers/anthropic-pricing", "pages": ["...-v1.md", "...-v2.md"]}
|
|
55
|
+
],
|
|
56
|
+
"staleCount": 4,
|
|
57
|
+
"queue": {"pending": 2, "claimed": 0, "processed": 11, "skipped": 1, "total": 14},
|
|
58
|
+
"recommendations": [
|
|
59
|
+
"Window has 12 new md(s) — at or above threshold (10). Consider a consolidation pass.",
|
|
60
|
+
"1 likely-duplicate cluster(s) detected. ...",
|
|
61
|
+
...
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Failure modes
|
|
68
|
+
|
|
69
|
+
- `404 vault_missing` — the vault directory does not exist.
|
|
70
|
+
- `404 schema_missing` — vault has no SCHEMA.md.
|
|
71
|
+
- `400 invalid_input` — vaultPath not absolute / windowDays or threshold non-positive.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# wiki-bookkeep — vault health report + consolidation signals.
|
|
3
|
+
#
|
|
4
|
+
# Use this skill periodically (or when the queue stats / md-count
|
|
5
|
+
# threshold says "fire"). The skill returns a JSON report:
|
|
6
|
+
# - total / recent md counts
|
|
7
|
+
# - per-folder bucket counts
|
|
8
|
+
# - likely-duplicate clusters (filename Jaccard)
|
|
9
|
+
# - stale-page count (90+ days untouched)
|
|
10
|
+
# - queue snapshot (pending/claimed/processed/skipped)
|
|
11
|
+
# - recommendations
|
|
12
|
+
#
|
|
13
|
+
# This skill does NOT write to the vault. After reading the report,
|
|
14
|
+
# YOUR runtime decides which clusters to merge (call wiki-ingest with
|
|
15
|
+
# a consolidated body) and which pages to archive (out of Phase 1
|
|
16
|
+
# scope — flag in chat for now).
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# bash execute.sh --vault /path
|
|
20
|
+
# bash execute.sh --vault /path --window-days 14 --threshold 10
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
|
+
source "${SCRIPT_DIR}/../../_common/lib.sh"
|
|
24
|
+
|
|
25
|
+
INPUT_JSON=""
|
|
26
|
+
VAULT_PATH=""
|
|
27
|
+
WINDOW=""
|
|
28
|
+
THRESHOLD=""
|
|
29
|
+
|
|
30
|
+
if [[ $# -gt 0 && ${1:0:1} == '{' ]]; then
|
|
31
|
+
INPUT_JSON="$1"; shift || true
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
while [[ $# -gt 0 ]]; do
|
|
35
|
+
case "$1" in
|
|
36
|
+
--vault|-v) VAULT_PATH="$2"; shift 2 ;;
|
|
37
|
+
--window-days|-d) WINDOW="$2"; shift 2 ;;
|
|
38
|
+
--threshold|-t) THRESHOLD="$2"; shift 2 ;;
|
|
39
|
+
--json|-j) INPUT_JSON="$2"; shift 2 ;;
|
|
40
|
+
--help|-h)
|
|
41
|
+
cat <<EOF
|
|
42
|
+
Usage:
|
|
43
|
+
execute.sh --vault <path> [--window-days 7] [--threshold 10]
|
|
44
|
+
|
|
45
|
+
Returns a JSON bookkeeping report with should-fire signal, recent activity,
|
|
46
|
+
duplicate clusters, queue snapshot, and recommendations. The skill makes
|
|
47
|
+
no LLM calls; you decide next actions based on the report.
|
|
48
|
+
EOF
|
|
49
|
+
exit 0 ;;
|
|
50
|
+
--) shift; break ;;
|
|
51
|
+
*)
|
|
52
|
+
if [[ -z "$INPUT_JSON" && ${1:0:1} == '{' ]]; then INPUT_JSON="$1"; shift
|
|
53
|
+
else error_exit "Unknown argument: $1"; fi ;;
|
|
54
|
+
esac
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
if [ -n "$INPUT_JSON" ]; then
|
|
58
|
+
INPUT=$(read_json_input "$INPUT_JSON")
|
|
59
|
+
[ -z "$VAULT_PATH" ] && VAULT_PATH=$(printf '%s' "$INPUT" | jq -r '.vaultPath // empty')
|
|
60
|
+
[ -z "$WINDOW" ] && WINDOW=$(printf '%s' "$INPUT" | jq -r '.windowDays // empty')
|
|
61
|
+
[ -z "$THRESHOLD" ] && THRESHOLD=$(printf '%s' "$INPUT" | jq -r '.threshold // empty')
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
require_param "vaultPath (--vault)" "$VAULT_PATH"
|
|
65
|
+
|
|
66
|
+
export _WB_V="$VAULT_PATH"
|
|
67
|
+
BODY=$(jq -n '{vaultPath: env._WB_V}')
|
|
68
|
+
[ -n "$WINDOW" ] && BODY=$(echo "$BODY" | jq --argjson w "$WINDOW" '. + {windowDays: $w}')
|
|
69
|
+
[ -n "$THRESHOLD" ] && BODY=$(echo "$BODY" | jq --argjson t "$THRESHOLD" '. + {threshold: $t}')
|
|
70
|
+
unset _WB_V
|
|
71
|
+
|
|
72
|
+
api_call POST "/wiki/bookkeep" "$BODY"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Wiki Ingest
|
|
3
|
+
description: Append a source (spec / decision / chat / pr / learning) into a vault's llm-curated/ tree. Refuses writes into frozen paths.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: knowledge
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
- team-leader
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Wiki Ingest
|
|
13
|
+
|
|
14
|
+
Append a source to a vault's `llm-curated/log.md` (default) or to a dedicated page under `llm-curated/` (via `--target`). Per Atlas v2.1 §2 + §3.
|
|
15
|
+
|
|
16
|
+
The chat subscriber **already** auto-ingests every user→ORC chat message; this skill is for explicit manual ingest:
|
|
17
|
+
|
|
18
|
+
- TL promoting a decision to `llm-curated/decisions/<date>-<slug>.md`
|
|
19
|
+
- ORC archiving a synthesis memo into `~/.crewly/global-wiki/llm-curated/`
|
|
20
|
+
- A worker filing a `record-learning`-style pattern page
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
| Flag | Required | Description |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `--vault <path>` | yes | Absolute vault root (must contain `SCHEMA.md`). |
|
|
27
|
+
| `--source-type <t>` | yes | One of: `user_chat`, `slack_message`, `spec_file`, `pr_merge`, `record_learning`, `task_verified`. |
|
|
28
|
+
| `--source-ref <ref>` | yes | Stable reference for audit (URL, file path, message id, …). |
|
|
29
|
+
| `--source-body <text>` | yes | Body content to ingest. |
|
|
30
|
+
| `--caller <sess>` | no | Session/user that authored the source (defaults to source-ref). |
|
|
31
|
+
| `--target <relpath>` | no | Override the default `llm-curated/log.md`. Must NOT be inside a frozen folder. |
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"success": true,
|
|
38
|
+
"result": {
|
|
39
|
+
"ok": true,
|
|
40
|
+
"pagesWritten": ["llm-curated/log.md"],
|
|
41
|
+
"logEntry": "## [ISO] sourceType | caller ...",
|
|
42
|
+
"frozenPathsTouched": []
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Failure modes
|
|
48
|
+
|
|
49
|
+
- `422 frozen_path` — target lives under a `hardcoded:` (frozen) folder. The `outcome.frozenFolders` field lists every frozen path in the vault.
|
|
50
|
+
- `404 schema_missing` — vault has no `SCHEMA.md`.
|
|
51
|
+
- `400 invalid_input | empty_body` — missing/invalid args.
|
|
52
|
+
|
|
53
|
+
## Example: ingest a TL-promoted decision
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bash execute.sh \
|
|
57
|
+
--vault ~/.crewly/teams/ad923b66-19dd-4d73-9c92-dc1107d37501/wiki \
|
|
58
|
+
--source-type user_chat \
|
|
59
|
+
--source-ref slack://thread/D0ABC/1779363330.313849 \
|
|
60
|
+
--source-body "Pricing locked at \$999 setup + \$799/month." \
|
|
61
|
+
--caller user/steve \
|
|
62
|
+
--target llm-curated/decisions/2026-05-22-crewly-pro-pricing.md
|
|
63
|
+
```
|