@codyswann/lisa 2.176.11 → 2.177.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/dist/codex/scripts/setup-jira-cli.sh +34 -0
- package/dist/opencode/plugin-templates/lisa-session-bootstrap.ts +34 -4
- 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/hooks/setup-jira-cli.sh +36 -2
- package/plugins/lisa/rules/eager/integration-access-layer.md +10 -0
- package/plugins/lisa/rules/reference/integration-access-layer.md +56 -0
- package/plugins/lisa/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa/skills/jam-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa/skills/linear-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa/skills/posthog-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa/skills/sentry-access/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa/skills/sonarcloud-access/agents/openai.yaml +4 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-agy/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-agy/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-agy/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/setup-jira-cli.sh +36 -2
- package/plugins/lisa-copilot/rules/eager/integration-access-layer.md +10 -0
- package/plugins/lisa-copilot/rules/reference/integration-access-layer.md +56 -0
- package/plugins/lisa-copilot/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-copilot/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-copilot/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-copilot/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/setup-jira-cli.sh +36 -2
- package/plugins/lisa-cursor/rules/integration-access-layer-reference.mdc +61 -0
- package/plugins/lisa-cursor/rules/integration-access-layer.mdc +15 -0
- package/plugins/lisa-cursor/skills/jam-access/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/linear-access/SKILL.md +90 -0
- package/plugins/lisa-cursor/skills/posthog-access/SKILL.md +60 -0
- package/plugins/lisa-cursor/skills/sentry-access/SKILL.md +56 -0
- package/plugins/lisa-cursor/skills/sonarcloud-access/SKILL.md +71 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-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-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-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-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-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-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-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-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/setup-jira-cli.sh +36 -2
- package/plugins/src/base/rules/eager/integration-access-layer.md +10 -0
- package/plugins/src/base/rules/reference/integration-access-layer.md +56 -0
- package/plugins/src/base/skills/jam-access/SKILL.md +51 -0
- package/plugins/src/base/skills/linear-access/SKILL.md +90 -0
- package/plugins/src/base/skills/posthog-access/SKILL.md +60 -0
- package/plugins/src/base/skills/sentry-access/SKILL.md +56 -0
- package/plugins/src/base/skills/sonarcloud-access/SKILL.md +71 -0
- package/scripts/generate-codex-plugin-artifacts.mjs +28 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.177.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.177.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.177.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.177.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.177.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
#
|
|
6
6
|
# Required env vars (must be created in your Claude Code Web environment):
|
|
7
7
|
# JIRA_INSTALLATION - cloud or local
|
|
8
|
-
# JIRA_SERVER - Atlassian instance URL
|
|
8
|
+
# JIRA_SERVER - Atlassian instance URL (falls back to .lisa.config*.json atlassian.site)
|
|
9
9
|
# JIRA_LOGIN - login email
|
|
10
|
-
# JIRA_PROJECT - default project key
|
|
10
|
+
# JIRA_PROJECT - default project key (falls back to .lisa.config*.json jira.project)
|
|
11
11
|
# JIRA_API_TOKEN - already expected by jira-cli natively
|
|
12
12
|
#
|
|
13
13
|
# Optional env vars:
|
|
@@ -31,6 +31,40 @@ fi
|
|
|
31
31
|
CONFIG_DIR="${HOME}/.config/.jira"
|
|
32
32
|
CONFIG_FILE="${CONFIG_DIR}/.config.yml"
|
|
33
33
|
|
|
34
|
+
read_lisa_config() {
|
|
35
|
+
local query="$1"
|
|
36
|
+
local value=""
|
|
37
|
+
|
|
38
|
+
if ! command -v jq &>/dev/null; then
|
|
39
|
+
return 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [[ -f ".lisa.config.local.json" ]]; then
|
|
43
|
+
value=$(jq -r "${query} // empty" .lisa.config.local.json 2>/dev/null || true)
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [[ -z "${value}" && -f ".lisa.config.json" ]]; then
|
|
47
|
+
value=$(jq -r "${query} // empty" .lisa.config.json 2>/dev/null || true)
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
printf '%s' "${value}"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if [[ -z "${JIRA_SERVER:-}" ]]; then
|
|
54
|
+
ATLASSIAN_SITE="$(read_lisa_config '.atlassian.site')"
|
|
55
|
+
if [[ -n "${ATLASSIAN_SITE}" ]]; then
|
|
56
|
+
if [[ "${ATLASSIAN_SITE}" == http://* || "${ATLASSIAN_SITE}" == https://* ]]; then
|
|
57
|
+
JIRA_SERVER="${ATLASSIAN_SITE}"
|
|
58
|
+
else
|
|
59
|
+
JIRA_SERVER="https://${ATLASSIAN_SITE}"
|
|
60
|
+
fi
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
if [[ -z "${JIRA_PROJECT:-}" ]]; then
|
|
65
|
+
JIRA_PROJECT="$(read_lisa_config '.jira.project')"
|
|
66
|
+
fi
|
|
67
|
+
|
|
34
68
|
# Skip config write if required vars are missing
|
|
35
69
|
if [[ -z "${JIRA_SERVER:-}" || -z "${JIRA_LOGIN:-}" ]]; then
|
|
36
70
|
exit 0
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Integration Access Layer
|
|
2
|
+
|
|
3
|
+
Skills and rules that use external integrations route through the matching
|
|
4
|
+
`*-access` skill. Do not call vendor MCP tools or REST APIs directly from a
|
|
5
|
+
consumer skill.
|
|
6
|
+
|
|
7
|
+
Resolution order is MCP when available and authenticated, then documented
|
|
8
|
+
token/REST substrate when the env var is set, then a loud error naming the env
|
|
9
|
+
var. Full matrix and migration rules:
|
|
10
|
+
[reference/integration-access-layer.md](../reference/integration-access-layer.md).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Integration Access Layer
|
|
2
|
+
|
|
3
|
+
Every Lisa skill or rule that consumes an external integration MUST route through
|
|
4
|
+
the integration's `*-access` skill instead of calling that vendor's MCP tools or
|
|
5
|
+
REST API directly.
|
|
6
|
+
|
|
7
|
+
The access skill owns substrate resolution:
|
|
8
|
+
|
|
9
|
+
1. MCP, when the tool is available and already authenticated to the configured
|
|
10
|
+
workspace/account.
|
|
11
|
+
2. Token/REST substrate, only when the documented env var is present.
|
|
12
|
+
3. Loud failure naming the exact env var to set.
|
|
13
|
+
|
|
14
|
+
Do not blind-retry a failed or absent MCP. Fall back only after checking the
|
|
15
|
+
documented env var for that vendor, and never silently no-op when neither tier is
|
|
16
|
+
available.
|
|
17
|
+
|
|
18
|
+
## Access Skills
|
|
19
|
+
|
|
20
|
+
| Vendor | Access skill | Headless env var | REST/token substrate |
|
|
21
|
+
|---|---|---|---|
|
|
22
|
+
| Atlassian | `lisa:atlassian-access` | `ATLASSIAN_API_TOKEN` | Atlassian Cloud REST |
|
|
23
|
+
| Notion | `lisa:notion-access` | `NOTION_API_TOKEN` | Notion REST |
|
|
24
|
+
| Linear | `lisa:linear-access` | `LINEAR_API_KEY` | Linear GraphQL |
|
|
25
|
+
| Jam | `lisa:jam-access` | `JAM_PAT` | Jam MCP HTTP endpoint with bearer PAT |
|
|
26
|
+
| SonarCloud | `lisa:sonarcloud-access` | `SONAR_TOKEN` | SonarCloud Web API |
|
|
27
|
+
| Sentry | `lisa:sentry-access` | `SENTRY_AUTH_TOKEN` | Sentry REST API |
|
|
28
|
+
| PostHog | `lisa:posthog-access` | `POSTHOG_PERSONAL_API_KEY` | PostHog REST API |
|
|
29
|
+
|
|
30
|
+
## Current Coupling Matrix
|
|
31
|
+
|
|
32
|
+
Source audit date: 2026-06-23. Scope: `plugins/src/**/skills/**` and
|
|
33
|
+
`plugins/src/**/rules/**`.
|
|
34
|
+
|
|
35
|
+
| Vendor | Direct source MCP references | Current route | Retrofit status |
|
|
36
|
+
|---|---:|---|---|
|
|
37
|
+
| Atlassian | setup-only references plus legacy stack-generated sources | `atlassian-access` for base runtime paths | Done for base hot paths; stack overlays still need sync from base patterns when touched. |
|
|
38
|
+
| Notion | setup-only references | `notion-access` | Done. |
|
|
39
|
+
| Linear | Multiple base queue/read/write/verify skills | Raw Linear MCP | Access layer added; consumers still need migration to `linear-access`. |
|
|
40
|
+
| Jam | None in `plugins/src` at audit time | No access layer | Access layer added for host rules that include Jam triage. |
|
|
41
|
+
| SonarCloud | None in `plugins/src` at audit time | No access layer | Access layer added for host rules that include SonarCloud gate triage. |
|
|
42
|
+
| Sentry | No Sentry MCP references in `plugins/src`; CLI/REST mentions only | CLI/REST scattered in observability docs | Access layer added for future MCP-backed consumers. |
|
|
43
|
+
| PostHog | No PostHog MCP references in `plugins/src`; observability docs mention PostHog detection | No access layer | Access layer added for future MCP-backed consumers. |
|
|
44
|
+
|
|
45
|
+
## Migration Rule For Consumers
|
|
46
|
+
|
|
47
|
+
When editing any skill listed in the matrix:
|
|
48
|
+
|
|
49
|
+
- Replace direct `mcp__<vendor>__*` calls in `allowed-tools` with `Skill` and
|
|
50
|
+
delegate to the matching access skill.
|
|
51
|
+
- Keep operation names coarse and vendor-native. Add new operation rows to the
|
|
52
|
+
access skill instead of embedding REST details in the consumer.
|
|
53
|
+
- Preserve existing MCP behavior as the first tier where Claude/Codex can expose
|
|
54
|
+
the MCP, but make headless token fallback explicit and gated by the env var.
|
|
55
|
+
- If a vendor has no documented token substrate, keep the MCP-only behavior and
|
|
56
|
+
fail with a clear "no documented headless substrate" message.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jam-access
|
|
3
|
+
description: "Vendor-neutral access layer for Jam. Jam triage rules and skills MUST delegate through this skill rather than calling Jam MCP tools directly. Resolves Jam MCP first when available, then falls back to JAM_PAT bearer auth for headless routines."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Jam Access: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Single chokepoint for Jam operations. Caller skills and rules MUST NOT call
|
|
10
|
+
`mcp__Jam__*` tools directly.
|
|
11
|
+
|
|
12
|
+
## Invocation Contract
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
operation: get-trace url:<jam-url-or-id>
|
|
16
|
+
operation: get-recording url:<jam-url-or-id>
|
|
17
|
+
operation: get-bug-report url:<jam-url-or-id>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Return parsed JSON or a concise structured summary in a `<result>` block.
|
|
21
|
+
|
|
22
|
+
## Substrate Selection
|
|
23
|
+
|
|
24
|
+
Probe in order:
|
|
25
|
+
|
|
26
|
+
1. Jam MCP, if the tool is available and authenticated.
|
|
27
|
+
2. `JAM_PAT` bearer token against Jam's MCP/trace HTTP substrate.
|
|
28
|
+
|
|
29
|
+
Jam documents personal access tokens for MCP clients so a browser OAuth flow is
|
|
30
|
+
not required. The headless tier uses:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
curl -sS "https://mcp.jam.dev/mcp" \
|
|
34
|
+
-H "Authorization: Bearer $JAM_PAT" \
|
|
35
|
+
-H "Content-Type: application/json" \
|
|
36
|
+
--data-binary "$PAYLOAD"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If neither tier works, fail with:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
Error: no Jam access substrate available. Authenticate the Jam MCP or set JAM_PAT.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Invariants
|
|
46
|
+
|
|
47
|
+
- Fallback is gated on `JAM_PAT`; do not retry Jam MCP failures blindly.
|
|
48
|
+
- Never commit a Jam PAT into `.mcp.json`. Use env interpolation in host MCP
|
|
49
|
+
config, for example `Authorization: Bearer ${JAM_PAT}`.
|
|
50
|
+
- If a requested operation is not yet mapped to the Jam HTTP substrate, surface
|
|
51
|
+
that exact missing adapter instead of pretending the trace is unavailable.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: linear-access
|
|
3
|
+
description: "Vendor-neutral access layer for Linear. Linear skills MUST delegate through this skill rather than calling Linear MCP tools or Linear GraphQL directly. Resolves Linear MCP first when authenticated, then falls back to LINEAR_API_KEY + Linear GraphQL in headless environments."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Linear Access: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Single chokepoint for Linear operations. Caller skills (`linear-*`) MUST go
|
|
10
|
+
through this skill. They MUST NOT call `mcp__linear-server__*` tools directly or
|
|
11
|
+
curl `https://api.linear.app/graphql` themselves.
|
|
12
|
+
|
|
13
|
+
## Invocation Contract
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
operation: list-teams [query:<KEY>]
|
|
17
|
+
operation: get-team id:<ID>
|
|
18
|
+
operation: list-projects [team:<KEY>] [label:<NAME>] [state:<arr>]
|
|
19
|
+
operation: get-project id:<ID>
|
|
20
|
+
operation: save-project payload:{...}
|
|
21
|
+
operation: list-issues [team:<ID>] [project:<ID>] [label:<NAME>] [state_type:<arr>]
|
|
22
|
+
operation: get-issue id:<ID>
|
|
23
|
+
operation: save-issue payload:{...}
|
|
24
|
+
operation: list-comments issue_id:<ID>
|
|
25
|
+
operation: save-comment issue_id:<ID> body:"..."
|
|
26
|
+
operation: list-issue-labels [team:<ID>]
|
|
27
|
+
operation: create-issue-label payload:{...}
|
|
28
|
+
operation: list-project-labels
|
|
29
|
+
operation: create-project-label payload:{...}
|
|
30
|
+
operation: list-documents project_id:<ID>
|
|
31
|
+
operation: get-document id:<ID>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Return parsed JSON in a `<result>` block. On failure, prefix the message with
|
|
35
|
+
`Error:` and include the failing operation name.
|
|
36
|
+
|
|
37
|
+
## Substrate Selection
|
|
38
|
+
|
|
39
|
+
Read config:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
WORKSPACE=$(jq -r '.linear.workspace // empty' .lisa.config.json 2>/dev/null)
|
|
43
|
+
TEAM_KEY=$(jq -r '.linear.teamKey // empty' .lisa.config.json 2>/dev/null)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Probe in order:
|
|
47
|
+
|
|
48
|
+
1. Linear MCP, if `mcp__linear-server__list_teams` is available and can list the
|
|
49
|
+
configured workspace/team.
|
|
50
|
+
2. `LINEAR_API_KEY` with Linear GraphQL (`https://api.linear.app/graphql`).
|
|
51
|
+
|
|
52
|
+
The Linear GraphQL docs support personal API keys for scripts and authenticate
|
|
53
|
+
with an `Authorization: <API_KEY>` header. Treat `LINEAR_API_KEY` as the
|
|
54
|
+
headless substrate. If neither tier works, fail with:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Error: no Linear access substrate available. Authenticate the Linear MCP or set LINEAR_API_KEY.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## GraphQL Adapter
|
|
61
|
+
|
|
62
|
+
All GraphQL calls use:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
linear_graphql() {
|
|
66
|
+
local query="$1"
|
|
67
|
+
local variables="${2:-{}}"
|
|
68
|
+
[ -n "$LINEAR_API_KEY" ] || {
|
|
69
|
+
echo "Error: LINEAR_API_KEY is not set." >&2
|
|
70
|
+
return 1
|
|
71
|
+
}
|
|
72
|
+
jq -n --arg query "$query" --argjson variables "$variables" \
|
|
73
|
+
'{query:$query, variables:$variables}' |
|
|
74
|
+
curl -sS -X POST "https://api.linear.app/graphql" \
|
|
75
|
+
-H "Content-Type: application/json" \
|
|
76
|
+
-H "Authorization: '"$LINEAR_API_KEY"'" \
|
|
77
|
+
--data-binary @-
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Map operation names to Linear GraphQL queries/mutations in this access skill.
|
|
82
|
+
Consumers pass business-shaped arguments only; they do not embed GraphQL.
|
|
83
|
+
|
|
84
|
+
## Invariants
|
|
85
|
+
|
|
86
|
+
- MCP is preferred when it is present and already authenticated.
|
|
87
|
+
- GraphQL fallback runs only when `LINEAR_API_KEY` is present.
|
|
88
|
+
- Missing MCP plus missing token is a hard failure naming `LINEAR_API_KEY`.
|
|
89
|
+
- Mutations send only the fields being changed, matching existing Linear skill
|
|
90
|
+
guidance that `save_*` style updates should not clobber unrelated fields.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: posthog-access
|
|
3
|
+
description: "Vendor-neutral access layer for PostHog. PostHog skills and observability rules MUST delegate through this skill rather than calling PostHog MCP tools or REST directly. Resolves PostHog MCP first when available, then falls back to POSTHOG_PERSONAL_API_KEY bearer auth."
|
|
4
|
+
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PostHog Access: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Single chokepoint for PostHog operations. Caller skills and rules MUST NOT call
|
|
10
|
+
`mcp__posthog__*` tools or PostHog REST directly.
|
|
11
|
+
|
|
12
|
+
## Invocation Contract
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
operation: query project_id:<ID> payload:{...}
|
|
16
|
+
operation: insights project_id:<ID>
|
|
17
|
+
operation: persons project_id:<ID> [query:<QUERY>]
|
|
18
|
+
operation: events project_id:<ID> [after:<ISO>] [before:<ISO>]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Return parsed JSON in a `<result>` block.
|
|
22
|
+
|
|
23
|
+
## Substrate Selection
|
|
24
|
+
|
|
25
|
+
Probe in order:
|
|
26
|
+
|
|
27
|
+
1. PostHog MCP, if available and authenticated.
|
|
28
|
+
2. `POSTHOG_PERSONAL_API_KEY` bearer token against the configured PostHog host.
|
|
29
|
+
|
|
30
|
+
PostHog documents personal API keys and bearer authentication. The headless REST
|
|
31
|
+
tier uses:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
POSTHOG_HOST=${POSTHOG_HOST:-https://app.posthog.com}
|
|
35
|
+
posthog_api() {
|
|
36
|
+
local path="$1"
|
|
37
|
+
local method="${2:-GET}"
|
|
38
|
+
local body="${3:-}"
|
|
39
|
+
[ -n "$POSTHOG_PERSONAL_API_KEY" ] || {
|
|
40
|
+
echo "Error: POSTHOG_PERSONAL_API_KEY is not set." >&2
|
|
41
|
+
return 1
|
|
42
|
+
}
|
|
43
|
+
local args=(-sS -X "$method" -H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY")
|
|
44
|
+
[ -n "$body" ] && args+=(-H "Content-Type: application/json" --data-binary "$body")
|
|
45
|
+
curl "${args[@]}" "${POSTHOG_HOST%/}/api${path}"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If neither tier works, fail with:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
Error: no PostHog access substrate available. Authenticate the PostHog MCP or set POSTHOG_PERSONAL_API_KEY.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Invariants
|
|
56
|
+
|
|
57
|
+
- Fallback is gated on `POSTHOG_PERSONAL_API_KEY`.
|
|
58
|
+
- `POSTHOG_HOST` defaults to PostHog Cloud but can point at a self-hosted
|
|
59
|
+
deployment.
|
|
60
|
+
- Consumer skills do not embed PostHog REST paths.
|