@codyswann/lisa 2.23.2 → 2.25.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/.claude-plugin/marketplace.json +6 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/commands/setup/github.md +7 -0
- package/plugins/lisa/commands/setup/linear.md +7 -0
- package/plugins/lisa/skills/setup-github/SKILL.md +199 -0
- package/plugins/lisa/skills/setup-linear/SKILL.md +217 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +8 -0
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +32 -0
- package/plugins/lisa-wiki/ci/lisa-wiki-validate.yml +32 -0
- package/plugins/lisa-wiki/commands/add-ingest.md +6 -0
- package/plugins/lisa-wiki/commands/add-role.md +6 -0
- package/plugins/lisa-wiki/commands/doctor.md +6 -0
- package/plugins/lisa-wiki/commands/ingest.md +6 -0
- package/plugins/lisa-wiki/commands/lint.md +6 -0
- package/plugins/lisa-wiki/commands/migrate.md +6 -0
- package/plugins/lisa-wiki/commands/onboard-me.md +6 -0
- package/plugins/lisa-wiki/commands/query.md +6 -0
- package/plugins/lisa-wiki/commands/setup.md +6 -0
- package/plugins/lisa-wiki/schema/lisa-wiki-config.schema.json +118 -0
- package/plugins/lisa-wiki/schema/wiki-structure.schema.json +51 -0
- package/plugins/lisa-wiki/scripts/_wiki-lib.mjs +185 -0
- package/plugins/lisa-wiki/scripts/diff-guard.mjs +116 -0
- package/plugins/lisa-wiki/scripts/ingest-git.mjs +189 -0
- package/plugins/lisa-wiki/scripts/ingest-memory.mjs +130 -0
- package/plugins/lisa-wiki/scripts/ingest-roles.mjs +85 -0
- package/plugins/lisa-wiki/scripts/ingest_slack_channel.py +329 -0
- package/plugins/lisa-wiki/scripts/lint-wiki.mjs +320 -0
- package/plugins/lisa-wiki/scripts/mcp-doctor.mjs +72 -0
- package/plugins/lisa-wiki/scripts/render-contract.mjs +107 -0
- package/plugins/lisa-wiki/scripts/rewrite-refs.mjs +144 -0
- package/plugins/lisa-wiki/scripts/slack_oauth_user.py +179 -0
- package/plugins/lisa-wiki/scripts/validate-config.mjs +232 -0
- package/plugins/lisa-wiki/scripts/verify-migration.mjs +199 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-add-role/SKILL.md +30 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-git/SKILL.md +25 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-connector-web/SKILL.md +23 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-doctor/SKILL.md +47 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-ingest/SKILL.md +43 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-lint/SKILL.md +32 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-migrate/SKILL.md +43 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-query/SKILL.md +30 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-setup/SKILL.md +45 -0
- package/plugins/lisa-wiki/skills/lisa-wiki-usage/SKILL.md +50 -0
- package/plugins/lisa-wiki/templates/agents/role-agent.claude.md +16 -0
- package/plugins/lisa-wiki/templates/agents/role-agent.codex.toml +15 -0
- package/plugins/lisa-wiki/templates/index.md +17 -0
- package/plugins/lisa-wiki/templates/llm-wiki-contract.md +60 -0
- package/plugins/lisa-wiki/templates/log.md +8 -0
- package/plugins/lisa-wiki/templates/page-types/architecture.md +18 -0
- package/plugins/lisa-wiki/templates/page-types/concept.md +18 -0
- package/plugins/lisa-wiki/templates/page-types/decision.md +18 -0
- package/plugins/lisa-wiki/templates/page-types/entity.md +19 -0
- package/plugins/lisa-wiki/templates/page-types/open-question.md +18 -0
- package/plugins/lisa-wiki/templates/page-types/playbook.md +18 -0
- package/plugins/lisa-wiki/templates/page-types/project.md +19 -0
- package/plugins/lisa-wiki/templates/page-types/requirement.md +19 -0
- package/plugins/lisa-wiki/templates/page-types/staff.md +26 -0
- package/plugins/lisa-wiki/templates/start-here.md +24 -0
- package/plugins/lisa-wiki/templates/state-readme.md +20 -0
- package/plugins/src/base/commands/setup/github.md +7 -0
- package/plugins/src/base/commands/setup/linear.md +7 -0
- package/plugins/src/base/skills/setup-github/SKILL.md +199 -0
- package/plugins/src/base/skills/setup-linear/SKILL.md +217 -0
- package/plugins/src/wiki/.claude-plugin/plugin.json +6 -0
- package/plugins/src/wiki/ci/lisa-wiki-validate.yml +32 -0
- package/plugins/src/wiki/commands/add-ingest.md +6 -0
- package/plugins/src/wiki/commands/add-role.md +6 -0
- package/plugins/src/wiki/commands/doctor.md +6 -0
- package/plugins/src/wiki/commands/ingest.md +6 -0
- package/plugins/src/wiki/commands/lint.md +6 -0
- package/plugins/src/wiki/commands/migrate.md +6 -0
- package/plugins/src/wiki/commands/onboard-me.md +6 -0
- package/plugins/src/wiki/commands/query.md +6 -0
- package/plugins/src/wiki/commands/setup.md +6 -0
- package/plugins/src/wiki/schema/lisa-wiki-config.schema.json +118 -0
- package/plugins/src/wiki/schema/wiki-structure.schema.json +51 -0
- package/plugins/src/wiki/scripts/_wiki-lib.mjs +185 -0
- package/plugins/src/wiki/scripts/diff-guard.mjs +116 -0
- package/plugins/src/wiki/scripts/ingest-git.mjs +189 -0
- package/plugins/src/wiki/scripts/ingest-memory.mjs +130 -0
- package/plugins/src/wiki/scripts/ingest-roles.mjs +85 -0
- package/plugins/src/wiki/scripts/ingest_slack_channel.py +329 -0
- package/plugins/src/wiki/scripts/lint-wiki.mjs +320 -0
- package/plugins/src/wiki/scripts/mcp-doctor.mjs +72 -0
- package/plugins/src/wiki/scripts/render-contract.mjs +107 -0
- package/plugins/src/wiki/scripts/rewrite-refs.mjs +144 -0
- package/plugins/src/wiki/scripts/slack_oauth_user.py +179 -0
- package/plugins/src/wiki/scripts/validate-config.mjs +232 -0
- package/plugins/src/wiki/scripts/verify-migration.mjs +199 -0
- package/plugins/src/wiki/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
- package/plugins/src/wiki/skills/lisa-wiki-add-role/SKILL.md +30 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-git/SKILL.md +25 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
- package/plugins/src/wiki/skills/lisa-wiki-connector-web/SKILL.md +23 -0
- package/plugins/src/wiki/skills/lisa-wiki-doctor/SKILL.md +47 -0
- package/plugins/src/wiki/skills/lisa-wiki-ingest/SKILL.md +43 -0
- package/plugins/src/wiki/skills/lisa-wiki-lint/SKILL.md +32 -0
- package/plugins/src/wiki/skills/lisa-wiki-migrate/SKILL.md +43 -0
- package/plugins/src/wiki/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
- package/plugins/src/wiki/skills/lisa-wiki-query/SKILL.md +30 -0
- package/plugins/src/wiki/skills/lisa-wiki-setup/SKILL.md +45 -0
- package/plugins/src/wiki/skills/lisa-wiki-usage/SKILL.md +50 -0
- package/plugins/src/wiki/templates/agents/role-agent.claude.md +16 -0
- package/plugins/src/wiki/templates/agents/role-agent.codex.toml +15 -0
- package/plugins/src/wiki/templates/index.md +17 -0
- package/plugins/src/wiki/templates/llm-wiki-contract.md +60 -0
- package/plugins/src/wiki/templates/log.md +8 -0
- package/plugins/src/wiki/templates/page-types/architecture.md +18 -0
- package/plugins/src/wiki/templates/page-types/concept.md +18 -0
- package/plugins/src/wiki/templates/page-types/decision.md +18 -0
- package/plugins/src/wiki/templates/page-types/entity.md +19 -0
- package/plugins/src/wiki/templates/page-types/open-question.md +18 -0
- package/plugins/src/wiki/templates/page-types/playbook.md +18 -0
- package/plugins/src/wiki/templates/page-types/project.md +19 -0
- package/plugins/src/wiki/templates/page-types/requirement.md +19 -0
- package/plugins/src/wiki/templates/page-types/staff.md +26 -0
- package/plugins/src/wiki/templates/start-here.md +24 -0
- package/plugins/src/wiki/templates/state-readme.md +20 -0
- package/scripts/build-plugins.sh +29 -21
- package/scripts/check-plugins-sync.sh +1 -1
- package/scripts/generate-codex-plugin-artifacts.mjs +22 -0
|
@@ -43,6 +43,12 @@
|
|
|
43
43
|
"source": "./plugins/lisa-rails",
|
|
44
44
|
"description": "Ruby on Rails skills, rules, and conventions",
|
|
45
45
|
"category": "productivity"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "lisa-wiki",
|
|
49
|
+
"source": "./plugins/lisa-wiki",
|
|
50
|
+
"description": "LLM Wiki — git-native markdown knowledge base: ingest, query, lint, onboard (Claude + Codex)",
|
|
51
|
+
"category": "productivity"
|
|
46
52
|
}
|
|
47
53
|
]
|
|
48
54
|
}
|
package/package.json
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"lodash": ">=4.18.1"
|
|
83
83
|
},
|
|
84
84
|
"name": "@codyswann/lisa",
|
|
85
|
-
"version": "2.
|
|
85
|
+
"version": "2.25.0",
|
|
86
86
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
87
87
|
"main": "dist/index.js",
|
|
88
88
|
"exports": {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up GitHub Issues as the tracker and/or PRD source for this project. Verifies the gh CLI, resolves org/repo, scaffolds the `status:*` (build) and/or `prd-*` (PRD) label namespaces, writes the `github` section of `.lisa.config.json`, and offers to set top-level `tracker: \"github\"` / `source: \"github\"`. No /lisa:setup:atlassian prerequisite."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--repo=<org/repo>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-github skill to configure GitHub as the tracker and/or PRD source. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up Linear as the tracker and/or PRD source for this project. Verifies Linear access (MCP OAuth or a personal API key in keychain), resolves the workspace slug and team key, scaffolds the `status:*` issue-label (build) and/or `prd-*` project-label (PRD) namespaces, writes the `linear` section of `.lisa.config.json`, and offers to set top-level `tracker: \"linear\"` / `source: \"linear\"`. No /lisa:setup:atlassian prerequisite."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--workspace=<slug>] [--team=<KEY>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-linear skill to configure Linear as the tracker and/or PRD source. $ARGUMENTS
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-github
|
|
3
|
+
description: "Configure GitHub Issues as the destination tracker and/or the PRD source for this project. Verifies the gh CLI is installed and authenticated, resolves `org/repo`, scaffolds the build-queue label namespace (`status:*`) when GitHub is the tracker and/or the PRD-lifecycle label namespace (`prd-*` + sentinel) when GitHub is the PRD source, writes the `github` section into `.lisa.config.json`, and offers to set top-level `tracker: \"github\"` and/or `source: \"github\"`. Idempotent — re-running updates the existing section and reuses existing labels rather than duplicating. No /lisa:setup:atlassian prerequisite (GitHub auth is standalone)."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Write", "Edit", "Skill", "AskUserQuestion"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Setup GitHub: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Make GitHub Issues a tracker, a PRD source, or both for this project. After this skill, `.lisa.config.json` contains `github.org` + `github.repo`, the configured repo carries the lifecycle label namespaces lisa needs, and (optionally) `tracker` / `source` point at GitHub.
|
|
10
|
+
|
|
11
|
+
Unlike `setup-jira` / `setup-confluence`, this skill has **no `setup-atlassian` dependency** — GitHub auth runs through the `gh` CLI directly.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
### Step 0 — Decide what GitHub is for
|
|
16
|
+
|
|
17
|
+
Ask via `AskUserQuestion` (multiSelect):
|
|
18
|
+
|
|
19
|
+
> What should lisa use this GitHub repo for?
|
|
20
|
+
>
|
|
21
|
+
> 1. **Destination tracker** — lisa writes Epics / Stories / Sub-tasks here as Issues, and the build queue (`/lisa:intake`, `/lisa:implement`) runs off the `status:*` label namespace. Sets `tracker: "github"`.
|
|
22
|
+
> 2. **PRD source** — humans drop PRDs here as Issues labeled `prd-ready`; `/lisa:intake` scans and ticketes them off the `prd-*` label namespace. Sets `source: "github"`.
|
|
23
|
+
|
|
24
|
+
The answer drives which label namespaces get scaffolded in Step 3: **tracker → `status:*`**, **source → `prd-*` + sentinel**. Self-host (both) is supported — the two namespaces never overlap (see the `config-resolution` rule's "Self-host edge case").
|
|
25
|
+
|
|
26
|
+
If the user selects neither, stop — there's nothing to configure.
|
|
27
|
+
|
|
28
|
+
### Step 1 — Ensure the gh CLI is installed and authenticated
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
if ! command -v gh >/dev/null 2>&1; then
|
|
32
|
+
if command -v brew >/dev/null 2>&1; then
|
|
33
|
+
brew install gh
|
|
34
|
+
else
|
|
35
|
+
cat >&2 <<'EOF'
|
|
36
|
+
Error: gh (GitHub CLI) not found and Homebrew unavailable. Install it:
|
|
37
|
+
https://github.com/cli/cli#installation
|
|
38
|
+
Then re-run /lisa:setup:github.
|
|
39
|
+
EOF
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Auth: prefer an interactive login; CI/headless uses GH_TOKEN.
|
|
45
|
+
if ! gh auth status >/dev/null 2>&1; then
|
|
46
|
+
if [ -n "$GH_TOKEN" ] || [ -n "$GITHUB_TOKEN" ]; then
|
|
47
|
+
echo "gh not logged in interactively, but GH_TOKEN/GITHUB_TOKEN is set — gh will use it."
|
|
48
|
+
else
|
|
49
|
+
cat >&2 <<'EOF'
|
|
50
|
+
Error: gh is not authenticated. Run:
|
|
51
|
+
gh auth login # interactive (developer machines)
|
|
52
|
+
or set GH_TOKEN as a secret (CI / headless), then re-run /lisa:setup:github.
|
|
53
|
+
EOF
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Confirm the authenticated identity can write Issues and labels — `gh auth status` shows the token scopes; `repo` scope (or fine-grained Issues: read-write + metadata: read) is required to create labels and issues. If the scopes look read-only, surface it and instruct `gh auth refresh -s repo`.
|
|
60
|
+
|
|
61
|
+
### Step 2 — Resolve `org/repo`
|
|
62
|
+
|
|
63
|
+
Honor any `--repo=org/repo` argument. Otherwise default-detect from the current repo's `origin` remote, then confirm — the tracker/PRD repo is frequently a *different* repo than the code repo (e.g. a dedicated `product-prds` repo):
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
DEFAULT_REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Present the detected value via `AskUserQuestion`:
|
|
70
|
+
|
|
71
|
+
> Use `<DEFAULT_REPO>` as the GitHub repo for lisa's issues/PRDs, or specify a different `org/repo`?
|
|
72
|
+
|
|
73
|
+
Once resolved, split into `ORG` and `REPO` and confirm reachability + write access:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
gh repo view "$ORG/$REPO" --json name,viewerPermission \
|
|
77
|
+
--jq 'if (.viewerPermission | IN("ADMIN","MAINTAIN","WRITE")) then "ok" else error("insufficient permission: \(.viewerPermission)") end'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If permission is `READ` / `TRIAGE`, stop — lisa cannot create labels or issues. Surface and exit.
|
|
81
|
+
|
|
82
|
+
### Step 3 — Scaffold the lifecycle label namespaces
|
|
83
|
+
|
|
84
|
+
Read role → label mappings with the same default-fallback ladder the intake skills use, so the labels created here exactly match what they look for. Only the namespaces selected in Step 0 are scaffolded.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
read_role() { # $1=namespace (build|prd) $2=role $3=default
|
|
88
|
+
local ns="$1" role="$2" default="$3" local_v global_v
|
|
89
|
+
local_v=$(jq -r ".github.labels.${ns}.${role} // empty" .lisa.config.local.json 2>/dev/null)
|
|
90
|
+
global_v=$(jq -r ".github.labels.${ns}.${role} // empty" .lisa.config.json 2>/dev/null)
|
|
91
|
+
echo "${local_v:-${global_v:-$default}}"
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Idempotent label creator: create if missing, leave untouched if present.
|
|
95
|
+
ensure_label() { # $1=name $2=hex-color $3=description
|
|
96
|
+
local name="$1" color="$2" desc="$3"
|
|
97
|
+
if gh label list --repo "$ORG/$REPO" --limit 200 --json name --jq '.[].name' | grep -qxF "$name"; then
|
|
98
|
+
echo " = $name (exists)"
|
|
99
|
+
else
|
|
100
|
+
gh label create "$name" --repo "$ORG/$REPO" --color "$color" --description "$desc" \
|
|
101
|
+
&& echo " + $name (created)"
|
|
102
|
+
fi
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### 3a. Build-queue labels (only if GitHub is the tracker)
|
|
107
|
+
|
|
108
|
+
Defaults from `config-resolution`. The `done` role is **env-keyed** — create all three by default; a project whose terminal state is env-independent can later collapse `github.labels.build.done` to a single string.
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
ensure_label "$(read_role build ready status:ready)" FBCA04 "Ready for build (human signal)"
|
|
112
|
+
ensure_label "$(read_role build claimed status:in-progress)" 0E8A16 "Build in progress (agent owns)"
|
|
113
|
+
ensure_label "$(read_role build review status:code-review)" 5319E7 "PR open, awaiting review"
|
|
114
|
+
ensure_label "$(read_role build blocked status:blocked)" D93F0B "Blocked — human attention required"
|
|
115
|
+
ensure_label "$(read_role build done.dev status:on-dev)" 1D76DB "Deployed to dev"
|
|
116
|
+
ensure_label "$(read_role build done.staging status:on-stg)" 1D76DB "Deployed to staging"
|
|
117
|
+
ensure_label "$(read_role build done.production status:done)" 0E8A16 "Shipped to production"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
#### 3b. PRD-lifecycle labels (only if GitHub is the PRD source)
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
ensure_label "$(read_role prd draft prd-draft)" C5DEF5 "PRD in progress (product owns)"
|
|
124
|
+
ensure_label "$(read_role prd ready prd-ready)" FBCA04 "PRD ready for ticketing"
|
|
125
|
+
ensure_label "$(read_role prd in_review prd-in-review)" 5319E7 "Claude is reviewing this PRD"
|
|
126
|
+
ensure_label "$(read_role prd blocked prd-blocked)" D93F0B "PRD blocked — see comments"
|
|
127
|
+
ensure_label "$(read_role prd ticketed prd-ticketed)" 0E8A16 "Tickets created — see comments"
|
|
128
|
+
ensure_label "$(read_role prd shipped prd-shipped)" 1D76DB "Work delivered (product owns)"
|
|
129
|
+
ensure_label "$(read_role prd sentinel prd-intake-feedback)" EDEDED "Marker for PRD-intake feedback issues"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### 3c. Handle name collisions / renames
|
|
133
|
+
|
|
134
|
+
If a project already uses a differently-named label for a role (e.g. `ready-for-dev` instead of `status:ready`), do NOT create a duplicate. Present the repo's existing labels via `AskUserQuestion` and let the user map the role to the existing label — that mapping becomes an override written in Step 4. Renaming-in-place (keeping lisa's defaults) is also fine if the user prefers; just surface the choice.
|
|
135
|
+
|
|
136
|
+
### Step 4 — Write `.lisa.config.json`
|
|
137
|
+
|
|
138
|
+
`github.org` / `github.repo` are project-wide → committed. Write **only label keys that differ from the documented defaults** — never echo the full default map into config (keeps it lean; missing keys inherit defaults at runtime).
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
touch .lisa.config.json
|
|
142
|
+
[ -s .lisa.config.json ] || echo '{}' > .lisa.config.json
|
|
143
|
+
|
|
144
|
+
jq --arg org "$ORG" --arg repo "$REPO" \
|
|
145
|
+
'.github = ((.github // {}) | .org = $org | .repo = $repo)' \
|
|
146
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
147
|
+
|
|
148
|
+
# Conditionally write label overrides (only roles the user mapped to non-default names).
|
|
149
|
+
# $LABEL_OVERRIDES_JSON is e.g. {"build":{"ready":"ready-for-dev"}} — {} if all defaults.
|
|
150
|
+
if [ -n "$LABEL_OVERRIDES_JSON" ] && [ "$LABEL_OVERRIDES_JSON" != "{}" ]; then
|
|
151
|
+
jq --argjson o "$LABEL_OVERRIDES_JSON" \
|
|
152
|
+
'.github.labels = ((.github.labels // {}) * $o)' \
|
|
153
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
154
|
+
fi
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
No secrets go in config — the GitHub token lives in `gh`'s own store (`~/.config/gh/`) or the `GH_TOKEN` env var, never in `.lisa.config.json`.
|
|
158
|
+
|
|
159
|
+
### Step 5 — Offer to set top-level `tracker` / `source`
|
|
160
|
+
|
|
161
|
+
For each role selected in Step 0, offer the matching top-level flag (skip if already set to GitHub).
|
|
162
|
+
|
|
163
|
+
If **tracker** was selected and `.tracker` is unset or not `"github"`, ask via `AskUserQuestion`:
|
|
164
|
+
|
|
165
|
+
> Repo `<org>/<repo>` configured. Set top-level `tracker: "github"` so all vendor-neutral skills write Issues here?
|
|
166
|
+
|
|
167
|
+
If yes: `jq '.tracker = "github"' ...`
|
|
168
|
+
|
|
169
|
+
If **source** was selected and `.source` is unset or not `"github"`, ask:
|
|
170
|
+
|
|
171
|
+
> Set top-level `source: "github"` so `/lisa:intake` (with no args) scans this repo for `prd-ready` PRDs?
|
|
172
|
+
|
|
173
|
+
If yes: `jq '.source = "github"' ...`
|
|
174
|
+
|
|
175
|
+
Both are project-wide switches that change every downstream skill's default — never set either without explicit confirmation.
|
|
176
|
+
|
|
177
|
+
### Step 6 — Verify
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
jq -e '.github.org and .github.repo' .lisa.config.json >/dev/null
|
|
181
|
+
gh label list --repo "$ORG/$REPO" --limit 200 --json name --jq '.[].name' \
|
|
182
|
+
| grep -E 'status:|prd-' || true # show the scaffolded namespaces
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Report success with the resolved `org/repo`, which label namespaces were scaffolded (and which labels already existed vs. were created), any non-default label overrides written, and whether `tracker` / `source` were set. Direct the user to `/lisa:intake` to test.
|
|
186
|
+
|
|
187
|
+
## Idempotency
|
|
188
|
+
|
|
189
|
+
- Re-running merges the `github` section's fields rather than appending — `jq` merge semantics throughout.
|
|
190
|
+
- `ensure_label` is find-or-create: existing labels are left exactly as they are (color/description not overwritten), so a re-run never churns labels a human customized.
|
|
191
|
+
- Re-running does not re-prompt for `tracker` / `source` if they already point at GitHub.
|
|
192
|
+
|
|
193
|
+
## Rules
|
|
194
|
+
|
|
195
|
+
- Never write the GitHub token to `.lisa.config.json`. It stays in `gh`'s store or `GH_TOKEN`.
|
|
196
|
+
- Never create a duplicate label for a role that already has a (differently-named) label — map the role to the existing label and record it as a config override instead.
|
|
197
|
+
- Never overload one label across both the PRD and build namespaces — a single issue is either a PRD or a build ticket, never both (see `config-resolution`).
|
|
198
|
+
- Never set `tracker` / `source` without explicit user confirmation — they're project-wide and switch every downstream skill's behavior.
|
|
199
|
+
- Never invent an `org/repo`. Default-detect from the remote and confirm; if detection fails, ask the user to supply it.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup-linear
|
|
3
|
+
description: "Configure Linear as the destination tracker and/or the PRD source for this project. Verifies Linear access (MCP OAuth or a personal API key in OS keychain), resolves the workspace slug and team key, scaffolds the build-queue issue-label namespace (`status:*`) when Linear is the tracker and/or the PRD-lifecycle project-label namespace (`prd-*` + issue-level sentinel) when Linear is the PRD source, writes the `linear` section into `.lisa.config.json`, and offers to set top-level `tracker: \"linear\"` and/or `source: \"linear\"`. Idempotent — re-running updates the existing section and reuses existing labels. No /lisa:setup:atlassian prerequisite."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Write", "Edit", "Skill", "AskUserQuestion", "mcp__linear-server__authenticate", "mcp__linear-server__complete_authentication", "mcp__linear-server__list_teams", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label", "mcp__linear-server__list_project_labels", "mcp__linear-server__create_project_label"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Setup Linear: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Make Linear a tracker, a PRD source, or both for this project. After this skill, `.lisa.config.json` contains `linear.workspace` (+ `linear.teamKey` when Linear is the tracker), the team carries the lifecycle label namespaces lisa needs, and (optionally) `tracker` / `source` point at Linear.
|
|
10
|
+
|
|
11
|
+
Linear's data model splits labels into two **kinds** that matter here: **issue labels** (drive the build queue, `status:*`) and **project labels** (drive the PRD lifecycle, `prd-*`). They are distinct namespaces in Linear and are NOT interchangeable — the build lifecycle lives on Issues, the PRD lifecycle lives on Projects. The sentinel feedback marker is an **issue** label even though it belongs to the PRD flow (Linear's MCP has no project-level comments — see `linear-prd-intake`).
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
|
|
15
|
+
### Step 0 — Pick a setup path AND what Linear is for
|
|
16
|
+
|
|
17
|
+
Ask two things via `AskUserQuestion`.
|
|
18
|
+
|
|
19
|
+
**Access path:**
|
|
20
|
+
|
|
21
|
+
> How should lisa talk to Linear for this project?
|
|
22
|
+
>
|
|
23
|
+
> 1. **MCP-only (simplest)** — authenticate the Linear MCP once via browser OAuth; lisa uses it for every operation. Best for single-workspace developers on a personal laptop.
|
|
24
|
+
> 2. **MCP + API key (recommended for teams)** — MCP for interactive dev, a personal API key in keychain for headless / CI. Continue through key-store steps.
|
|
25
|
+
> 3. **API-key-only (headless / CI)** — store a personal API key in the OS keychain; lisa uses curl against the Linear GraphQL API. Best for pipelines / containers.
|
|
26
|
+
|
|
27
|
+
**Role** (multiSelect):
|
|
28
|
+
|
|
29
|
+
> What should lisa use Linear for?
|
|
30
|
+
>
|
|
31
|
+
> 1. **Destination tracker** — lisa writes Epics→Projects, Stories→Issues, Sub-tasks→Sub-issues; the build queue runs off the `status:*` issue-label namespace. Sets `tracker: "linear"`. (Requires a team key.)
|
|
32
|
+
> 2. **PRD source** — humans flag Linear **projects** with `prd-ready`; `/lisa:intake` scans and ticketes them off the `prd-*` project-label namespace. Sets `source: "linear"`.
|
|
33
|
+
|
|
34
|
+
The role answer drives Step 3 (which label namespaces to scaffold) and whether `teamKey` is required (tracker → yes).
|
|
35
|
+
|
|
36
|
+
### Step 1 — Establish Linear access
|
|
37
|
+
|
|
38
|
+
#### MCP path (1 or 2)
|
|
39
|
+
|
|
40
|
+
Verify the Linear MCP is authenticated to the right workspace by listing teams:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
mcp__linear-server__list_teams({})
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If it errors / returns nothing, run `mcp__linear-server__authenticate` and have the user complete OAuth in the browser, then `mcp__linear-server__complete_authentication`, then re-list. A non-empty team list confirms the MCP is authed to a readable workspace.
|
|
47
|
+
|
|
48
|
+
#### API-key path (2 or 3)
|
|
49
|
+
|
|
50
|
+
Linear personal API keys are created at **Linear → Settings → Security & access → Personal API keys** (or `https://linear.app/<workspace>/settings/account/security`). Store the key in the OS keychain keyed by the workspace slug, using the clipboard-pipe pattern (key never enters chat), mirroring `setup-notion`:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
case "$(uname -s)" in
|
|
54
|
+
Darwin)
|
|
55
|
+
cat <<EOF
|
|
56
|
+
1. Copy the Linear API key (starts with 'lin_api_').
|
|
57
|
+
2. Run this single line (leading space keeps it out of zsh history):
|
|
58
|
+
|
|
59
|
+
security delete-generic-password -s lisa-linear -a "$WORKSPACE" 2>/dev/null; TOK="\$(pbpaste)"; security add-generic-password -U -s lisa-linear -a "$WORKSPACE" -w "\$TOK"; unset TOK
|
|
60
|
+
EOF
|
|
61
|
+
;;
|
|
62
|
+
Linux)
|
|
63
|
+
cat <<EOF
|
|
64
|
+
secret-tool clear service lisa-linear account "$WORKSPACE" 2>/dev/null; printf '%s' "\$(wl-paste 2>/dev/null || xclip -selection clipboard -o 2>/dev/null || xsel --clipboard --output 2>/dev/null)" | secret-tool store --label="Lisa Linear ($WORKSPACE)" service lisa-linear account "$WORKSPACE"
|
|
65
|
+
(no clipboard tool? the command reads stdin — paste, then Ctrl-D. Or env-var fallback: export LINEAR_API_KEY_$(echo "$WORKSPACE" | tr '[:upper:]-' '[:lower:]_')="<key>")
|
|
66
|
+
EOF
|
|
67
|
+
;;
|
|
68
|
+
MINGW*|MSYS*|CYGWIN*)
|
|
69
|
+
cat <<EOF
|
|
70
|
+
PowerShell: \$tok = Get-Clipboard; cmdkey /generic:"lisa-linear-$WORKSPACE" /user:"$WORKSPACE" /pass:"\$tok"; Remove-Variable tok
|
|
71
|
+
EOF
|
|
72
|
+
;;
|
|
73
|
+
esac
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Never accept the key via this skill's chat or stdin.** After the user confirms storage, retrieve via the lookup ladder (env → workspace-suffixed env → keychain) and validate against the GraphQL API:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
read_linear_key() { # $1=workspace slug
|
|
80
|
+
local ws="$1"
|
|
81
|
+
[ -n "$LINEAR_API_KEY" ] && { echo "$LINEAR_API_KEY"; return; }
|
|
82
|
+
local slug; slug=$(echo "$ws" | tr '[:upper:]-' '[:lower:]_')
|
|
83
|
+
local varname="LINEAR_API_KEY_${slug}"
|
|
84
|
+
[ -n "${!varname}" ] && { echo "${!varname}"; return; }
|
|
85
|
+
case "$(uname -s)" in
|
|
86
|
+
Darwin) security find-generic-password -s lisa-linear -a "$ws" -w 2>/dev/null ;;
|
|
87
|
+
Linux) command -v secret-tool >/dev/null && secret-tool lookup service lisa-linear account "$ws" 2>/dev/null ;;
|
|
88
|
+
MINGW*|MSYS*|CYGWIN*) cmdkey /list:"lisa-linear-${ws}" 2>/dev/null | grep Password | awk '{print $NF}' ;;
|
|
89
|
+
esac
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
KEY=$(read_linear_key "$WORKSPACE")
|
|
93
|
+
[ -z "$KEY" ] && { echo "Error: key not retrievable from any source. Re-run the store step." >&2; exit 1; }
|
|
94
|
+
|
|
95
|
+
# Validate: viewer query. Personal API keys go in the Authorization header verbatim (no 'Bearer').
|
|
96
|
+
VIEWER=$(curl -s -X POST https://api.linear.app/graphql \
|
|
97
|
+
-H "Authorization: $KEY" -H "Content-Type: application/json" \
|
|
98
|
+
-d '{"query":"{ viewer { id name } organization { urlKey name } }"}')
|
|
99
|
+
if ! echo "$VIEWER" | jq -e '.data.viewer.id' >/dev/null 2>&1; then
|
|
100
|
+
echo "Error: API key failed the Linear viewer probe. Response: $VIEWER" >&2
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
echo "Linear key validated. Org: $(echo "$VIEWER" | jq -r '.data.organization.urlKey')"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Step 2 — Resolve workspace slug + team key
|
|
107
|
+
|
|
108
|
+
- **Workspace slug**: honor `--workspace=<slug>`. Otherwise derive from the validated identity — the GraphQL `organization.urlKey` (API path) or the team list's workspace (MCP path). Confirm with the user; this slug is the keychain `account` key and the multi-workspace disambiguator.
|
|
109
|
+
- **Team key** (required when Linear is the **tracker**): honor `--team=<KEY>`. Otherwise enumerate teams via `mcp__linear-server__list_teams({})` (or the GraphQL `teams` query) and present them via `AskUserQuestion` (label = team key, description = team name) for the user to pick the team that owns lisa's destination Issues. If Linear is source-only, `teamKey` is optional — skip unless the user wants to pin a team scope.
|
|
110
|
+
|
|
111
|
+
### Step 3 — Scaffold the lifecycle label namespaces
|
|
112
|
+
|
|
113
|
+
Read role → label with the default-fallback ladder the intake skills use, so scaffolded labels match exactly what they query.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
read_role() { # $1=namespace (build|prd) $2=role $3=default
|
|
117
|
+
local ns="$1" role="$2" default="$3" local_v global_v
|
|
118
|
+
local_v=$(jq -r ".linear.labels.${ns}.${role} // empty" .lisa.config.local.json 2>/dev/null)
|
|
119
|
+
global_v=$(jq -r ".linear.labels.${ns}.${role} // empty" .lisa.config.json 2>/dev/null)
|
|
120
|
+
echo "${local_v:-${global_v:-$default}}"
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### 3a. Build-queue labels — ISSUE labels (only if Linear is the tracker)
|
|
125
|
+
|
|
126
|
+
Probe with `mcp__linear-server__list_issue_labels` (scoped to the team). For each role's resolved name, create it via `mcp__linear-server__create_issue_label` only if absent. The `done` role is env-keyed — create all three defaults; collapse to a single string in config later if the project's terminal state is env-independent.
|
|
127
|
+
|
|
128
|
+
| Role | Default |
|
|
129
|
+
|------|---------|
|
|
130
|
+
| `ready` | `status:ready` |
|
|
131
|
+
| `claimed` | `status:in-progress` |
|
|
132
|
+
| `review` | `status:code-review` |
|
|
133
|
+
| `blocked` | `status:blocked` |
|
|
134
|
+
| `done.dev` | `status:on-dev` |
|
|
135
|
+
| `done.staging` | `status:on-stg` |
|
|
136
|
+
| `done.production` | `status:done` |
|
|
137
|
+
|
|
138
|
+
#### 3b. PRD-lifecycle labels — PROJECT labels (only if Linear is the PRD source)
|
|
139
|
+
|
|
140
|
+
Probe with `mcp__linear-server__list_project_labels`. Create missing ones via `mcp__linear-server__create_project_label`. These are a **separate label kind** from issue labels — creating an issue label of the same name will NOT work for the PRD flow.
|
|
141
|
+
|
|
142
|
+
| Role | Default | Kind |
|
|
143
|
+
|------|---------|------|
|
|
144
|
+
| `draft` | `prd-draft` | project label |
|
|
145
|
+
| `ready` | `prd-ready` | project label |
|
|
146
|
+
| `in_review` | `prd-in-review` | project label |
|
|
147
|
+
| `blocked` | `prd-blocked` | project label |
|
|
148
|
+
| `ticketed` | `prd-ticketed` | project label |
|
|
149
|
+
| `shipped` | `prd-shipped` | project label |
|
|
150
|
+
| `sentinel` | `prd-intake-feedback` | **issue** label (marks the sentinel feedback issue — create via `create_issue_label`) |
|
|
151
|
+
|
|
152
|
+
#### 3c. Handle name collisions / renames
|
|
153
|
+
|
|
154
|
+
If the team already uses a differently-named label for a role, do not create a duplicate — present the existing labels via `AskUserQuestion`, map the role to the existing label, and record the mapping as a config override (Step 4).
|
|
155
|
+
|
|
156
|
+
### Step 4 — Write `.lisa.config.json`
|
|
157
|
+
|
|
158
|
+
`linear.workspace` (and `linear.teamKey` when tracker) are project-wide → committed. Write **only label keys that differ from defaults**.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
touch .lisa.config.json
|
|
162
|
+
[ -s .lisa.config.json ] || echo '{}' > .lisa.config.json
|
|
163
|
+
|
|
164
|
+
jq --arg ws "$WORKSPACE" \
|
|
165
|
+
'.linear = ((.linear // {}) | .workspace = $ws)' \
|
|
166
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
167
|
+
|
|
168
|
+
# teamKey only when Linear is the tracker (or the user pinned a team scope).
|
|
169
|
+
if [ -n "$TEAM_KEY" ]; then
|
|
170
|
+
jq --arg tk "$TEAM_KEY" '.linear.teamKey = $tk' \
|
|
171
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Conditionally write label overrides (only non-default role names).
|
|
175
|
+
if [ -n "$LABEL_OVERRIDES_JSON" ] && [ "$LABEL_OVERRIDES_JSON" != "{}" ]; then
|
|
176
|
+
jq --argjson o "$LABEL_OVERRIDES_JSON" \
|
|
177
|
+
'.linear.labels = ((.linear.labels // {}) * $o)' \
|
|
178
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
179
|
+
fi
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
No secrets in config — the API key stays in keychain / `LINEAR_API_KEY`, the MCP session in its own store.
|
|
183
|
+
|
|
184
|
+
### Step 5 — Offer to set top-level `tracker` / `source`
|
|
185
|
+
|
|
186
|
+
For each role selected in Step 0, offer the matching top-level flag (skip if already pointing at Linear).
|
|
187
|
+
|
|
188
|
+
If **tracker** selected and `.tracker` ≠ `"linear"`: ask "Set top-level `tracker: \"linear\"` so vendor-neutral skills write Issues here?" → `jq '.tracker = "linear"'`.
|
|
189
|
+
|
|
190
|
+
If **source** selected and `.source` ≠ `"linear"`: ask "Set top-level `source: \"linear\"` so `/lisa:intake` (no args) scans this workspace for `prd-ready` projects?" → `jq '.source = "linear"'`.
|
|
191
|
+
|
|
192
|
+
Both are project-wide — never set without explicit confirmation.
|
|
193
|
+
|
|
194
|
+
### Step 6 — Verify
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
jq -e '.linear.workspace' .lisa.config.json >/dev/null
|
|
198
|
+
# If tracker: also require teamKey.
|
|
199
|
+
[ "$(jq -r '.tracker // empty' .lisa.config.json)" = "linear" ] && jq -e '.linear.teamKey' .lisa.config.json >/dev/null
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Confirm the scaffolded labels are present (`list_issue_labels` for `status:*` + the sentinel; `list_project_labels` for `prd-*`). Report success with the resolved workspace, team key (if any), which namespaces were scaffolded (created vs. already existed), any non-default overrides, and whether `tracker` / `source` were set. Direct the user to `/lisa:intake` to test.
|
|
203
|
+
|
|
204
|
+
## Idempotency
|
|
205
|
+
|
|
206
|
+
- Re-running merges the `linear` section's fields rather than appending — `jq` merge throughout.
|
|
207
|
+
- Label creation is find-or-create per kind; existing labels are left untouched, so re-runs never churn human-customized labels.
|
|
208
|
+
- Re-running does not re-prompt for `tracker` / `source` if they already point at Linear. The keychain store in Step 1 is the user's manual action — they re-run the same `security` / `secret-tool` / `cmdkey` command.
|
|
209
|
+
|
|
210
|
+
## Rules
|
|
211
|
+
|
|
212
|
+
- Never write the API key to `.lisa.config.json`. It stays in keychain or `LINEAR_API_KEY`.
|
|
213
|
+
- Never accept the API key via this skill's stdin/chat — always the platform clipboard-pipe pattern, so the value never enters the LLM context.
|
|
214
|
+
- Never conflate the two label kinds: build labels are **issue** labels, PRD labels are **project** labels. The sentinel is an issue label. Creating the wrong kind silently breaks the corresponding intake flow.
|
|
215
|
+
- Never create a duplicate label for a role that already has a (differently-named) label — map and record an override instead.
|
|
216
|
+
- Never set `tracker` / `source` without explicit confirmation — they're project-wide switches.
|
|
217
|
+
- Never invent a workspace slug or team key. Derive from the validated identity / team list and confirm; if resolution fails, ask the user.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lisa-wiki",
|
|
3
|
+
"version": "2.25.0",
|
|
4
|
+
"description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Cody Swann"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"wiki",
|
|
10
|
+
"knowledge-base",
|
|
11
|
+
"ingest",
|
|
12
|
+
"documentation",
|
|
13
|
+
"llm-wiki"
|
|
14
|
+
],
|
|
15
|
+
"skills": "./skills/",
|
|
16
|
+
"interface": {
|
|
17
|
+
"displayName": "LLM Wiki",
|
|
18
|
+
"shortDescription": "LLM Wiki knowledge base",
|
|
19
|
+
"longDescription": "A config-driven, git-native LLM Wiki: ingest sources (git, PRs, project-scoped memory, Jira, Slack, docs, …) into durable markdown, query with citations, lint integrity, onboard users, absorb existing documentation, and scaffold domain-expert role subagents. Distributed for both Claude Code and Codex.",
|
|
20
|
+
"developerName": "Cody Swann",
|
|
21
|
+
"category": "Productivity",
|
|
22
|
+
"capabilities": [
|
|
23
|
+
"Interactive",
|
|
24
|
+
"Write"
|
|
25
|
+
],
|
|
26
|
+
"defaultPrompt": [
|
|
27
|
+
"Onboard me to this project",
|
|
28
|
+
"Ingest the latest sources into the wiki",
|
|
29
|
+
"Query the wiki"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|