@codyswann/lisa 2.140.1 → 2.141.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/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/skills/analyze-claude-remote/SKILL.md +109 -10
- package/plugins/lisa/skills/generate-claude-remote-build-script/SKILL.md +12 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/analyze-claude-remote/SKILL.md +109 -10
- package/plugins/lisa-agy/skills/generate-claude-remote-build-script/SKILL.md +12 -2
- 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/skills/analyze-claude-remote/SKILL.md +109 -10
- package/plugins/lisa-copilot/skills/generate-claude-remote-build-script/SKILL.md +12 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/analyze-claude-remote/SKILL.md +109 -10
- package/plugins/lisa-cursor/skills/generate-claude-remote-build-script/SKILL.md +12 -2
- 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-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/skills/analyze-claude-remote/SKILL.md +109 -10
- package/plugins/src/base/skills/generate-claude-remote-build-script/SKILL.md +12 -2
- package/scripts/claude-remote-setup.sh +114 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: analyze-claude-remote
|
|
3
|
-
description: "Audit whether the current repository can run as a Claude Code remote routine (cloud session). Read-only analysis that inventories what Lisa AND the host project need to configure or build in the cloud environment — external CLIs/binaries to install, environment variables and secrets to set, startup hooks and their headless-safety, MCP server scope/transport/auth, user-scoped config and auto-memory gaps that don't replicate to the cloud, and platform constraints (bun proxy, IP allowlist, network tier, no interactivity). Emits grouped findings plus a machine-readable inventory that /lisa:generate-claude-remote-build-script consumes."
|
|
3
|
+
description: "Audit whether the current repository can run as a Claude Code remote routine (cloud session). Read-only analysis that inventories what Lisa AND the host project need to configure or build in the cloud environment — external CLIs/binaries to install, environment variables and secrets to set, startup hooks and their headless-safety, MCP server scope/transport/auth, user-scoped config and auto-memory gaps that don't replicate to the cloud, and platform constraints (bun proxy, IP allowlist, network tier, no interactivity). Reads `.lisa.config.json` `tracker`/`source` to determine which tracker/PRD-source integrations are active, resolves each to its headless-viable substrate (CLI/curl + token, never browser-OAuth MCP, never OS-keychain), and spells out the exact secret env vars, where to obtain each token, and the precise access scope required — without guessing. Emits grouped findings plus a machine-readable inventory that /lisa:generate-claude-remote-build-script consumes."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -88,12 +88,46 @@ Group the findings as:
|
|
|
88
88
|
in `.claude/settings.json` (e.g. `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`) as `REQUIRED` to match
|
|
89
89
|
local behavior, since the environment `env` block is the reliable place to set them.
|
|
90
90
|
|
|
91
|
+
4a. **Tracker / PRD-source credentials** — this is the load-bearing part of the audit and must be
|
|
92
|
+
driven by config, not by what the scan happens to find. Resolve the active integrations first:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
TRACKER=$(jq -r '.tracker // "jira"' .lisa.config.json 2>/dev/null) # tickets: jira | github | linear
|
|
96
|
+
SOURCE=$(jq -r '.source // empty' .lisa.config.json 2>/dev/null) # PRDs: notion | confluence | github | linear
|
|
97
|
+
```
|
|
98
|
+
(Apply `config-resolution`: `.lisa.config.local.json` overrides `.lisa.config.json`.) For the
|
|
99
|
+
**active** `tracker` and the **active** `source` — and only those — emit a `REQUIRED` credential
|
|
100
|
+
finding using the **Credential reference** table below. For every integration that is *not* the
|
|
101
|
+
active tracker/source, its credentials are `OPTIONAL` (dormant) — never mark them `REQUIRED`.
|
|
102
|
+
|
|
103
|
+
Two non-negotiable headless rules govern which substrate a routine can actually use:
|
|
104
|
+
|
|
105
|
+
- **Browser-OAuth MCP is dead headless.** A routine cannot complete an interactive OAuth/SSO
|
|
106
|
+
browser flow. So for any integration whose local substrate is an OAuth MCP (the committed
|
|
107
|
+
`linear-server` MCP; the Notion MCP; the Atlassian MCP) or an interactively-authed CLI
|
|
108
|
+
(`acli auth login --web`), the MCP/interactive tier is a `GAP` — the audit must route to that
|
|
109
|
+
integration's **token substrate** (CLI/curl + API token) and report the token's env vars.
|
|
110
|
+
- **OS keychain is absent headless.** Lisa's access skills read the token from the OS keychain
|
|
111
|
+
first (`security` / `secret-tool` / `cmdkey`) and fall back to an **env var**. A cloud routine
|
|
112
|
+
has no keyring daemon, so only the env-var fallback works. Always report the **env-var form**,
|
|
113
|
+
including the per-account suffixed names (`ATLASSIAN_API_TOKEN_<slug>`, `NOTION_API_TOKEN_<slug>`,
|
|
114
|
+
`LINEAR_API_KEY_<slug>`) when the integration keys tokens by email/workspace.
|
|
115
|
+
|
|
116
|
+
For each active integration, the finding must carry: the env var name(s), where to get the token
|
|
117
|
+
(`Acquire:` URL), and the **exact** access/scope required (`Access:`) — copied from the table, not
|
|
118
|
+
guessed. If a value the table needs (server URL, project key, workspace id, email, team key) is
|
|
119
|
+
missing from `.lisa.config.json`, flag it as a `GAP`/`Action:` to set it, rather than inventing one.
|
|
120
|
+
|
|
91
121
|
5. **MCP servers** — read every committed `.mcp.json`. For each server report transport and auth.
|
|
92
|
-
Project-scoped HTTP/SSE servers are `OK`. Flag stdio servers as
|
|
93
|
-
process — only viable if the cloud session can spawn them from the
|
|
94
|
-
interactively/OAuth-authed servers
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
Project-scoped HTTP/SSE servers with no interactive auth are `OK`. Flag stdio servers as
|
|
123
|
+
`RISK`/`GAP` (need a local process — only viable if the cloud session can spawn them from the
|
|
124
|
+
repo). Flag interactively/OAuth-authed servers as `GAP` for headless auth — they cannot complete
|
|
125
|
+
a browser flow headless **regardless of transport** (an HTTP MCP like `linear-server` is still a
|
|
126
|
+
`GAP` because its *auth* is OAuth, not because of its transport). When an OAuth MCP backs an
|
|
127
|
+
active tracker/source, do not stop at the `GAP` — cross-reference group 4a and point to the
|
|
128
|
+
integration's token substrate as the headless replacement (e.g. `linear-server` MCP → `LINEAR_API_KEY`
|
|
129
|
+
+ Linear GraphQL). Note any user-scoped MCP (`~/.claude.json`) as `GAP` — it never reaches the
|
|
130
|
+
cloud; it must be moved into project `.mcp.json`.
|
|
97
131
|
|
|
98
132
|
6. **Config scope & memory gaps** — identify reliance on user-scoped config that will not load
|
|
99
133
|
remotely: `~/.claude/CLAUDE.md`, user `enabledPlugins`, user skills/agents, user MCP. Most
|
|
@@ -112,6 +146,46 @@ Group the findings as:
|
|
|
112
146
|
runtime service it depends on (database, queue, external API) that will not exist in a fresh
|
|
113
147
|
cloud environment, so the user can decide whether the routine's task is even feasible there.
|
|
114
148
|
|
|
149
|
+
## Credential reference (tracker / source → headless secret)
|
|
150
|
+
|
|
151
|
+
Authoritative mapping for group 4a, transcribed from Lisa's `setup-*` skills and access layers
|
|
152
|
+
(`setup-github`, `setup-atlassian`, `setup-jira`, `setup-notion`, `setup-linear`,
|
|
153
|
+
`atlassian-access`, `notion-access`). Use the row for the **active** `tracker`/`source` only. Report
|
|
154
|
+
the **env-var form** of each secret — keychain reads do not work in a cloud routine. Slugs:
|
|
155
|
+
`<email-slug>` = email via `tr '[:upper:]@.' '[:lower:]__'`; `<ws-slug>` = workspace via
|
|
156
|
+
`tr '[:upper:]-' '[:lower:]_'`. If a token has both an unsuffixed and a per-account form, the
|
|
157
|
+
unsuffixed `…_TOKEN`/`…_KEY` is the simplest to set in a single-account routine.
|
|
158
|
+
|
|
159
|
+
### GitHub — `tracker: github` and/or `source: github`
|
|
160
|
+
- Headless substrate: `gh` CLI authed by token (every Lisa GitHub script gates on `gh auth status`).
|
|
161
|
+
- Env: `GH_TOKEN` (the routine's built-in repo connection may not authenticate the `gh` CLI — verify; set `GH_TOKEN` if `gh auth status` fails). `PAT` only for cross-repo flows.
|
|
162
|
+
- Acquire: fine-grained — `https://github.com/settings/personal-access-tokens`; classic — `https://github.com/settings/tokens`.
|
|
163
|
+
- Access: fine-grained → Repository access to the target repo(s); Repository permissions: Contents R/W, Issues R/W, Pull requests R/W, Metadata R (mandatory); add Workflows R/W only if editing `.github/workflows`, and Organization → Projects R/W only if using ProjectV2. Classic equivalent: `repo` + `workflow` (+ `project`, `read:org` for boards). The identity must hold WRITE/MAINTAIN/ADMIN on the repo.
|
|
164
|
+
|
|
165
|
+
### JIRA — `tracker: jira`
|
|
166
|
+
- Headless substrate: `jira-cli` + curl (Basic auth). The acli and Atlassian-MCP tiers need prior interactive/OAuth auth → not viable headless.
|
|
167
|
+
- Env: `JIRA_API_TOKEN`, `JIRA_SERVER` (e.g. `https://acme.atlassian.net`), `JIRA_LOGIN` (account email), `JIRA_PROJECT` (default project key); optional `JIRA_INSTALLATION` (default `cloud`), `JIRA_BOARD`. (`setup-jira-cli.sh` writes the jira-cli config from these on SessionStart.)
|
|
168
|
+
- Acquire: `https://id.atlassian.com/manage-profile/security/api-tokens`.
|
|
169
|
+
- Access: the API token inherits the Atlassian user's permissions — the user must have Browse/Create/Edit/Transition on the target project. An unscoped token suffices for jira-cli; a scoped token must cover the JIRA project read/write operations.
|
|
170
|
+
|
|
171
|
+
### Confluence — `source: confluence`
|
|
172
|
+
- Headless substrate: curl + Basic auth + **scoped** API token.
|
|
173
|
+
- Env: `ATLASSIAN_API_TOKEN` (or per-account `ATLASSIAN_API_TOKEN_<email-slug>`). Config (`.lisa.config.json`): `atlassian.cloudId`, `atlassian.site`, `atlassian.email`.
|
|
174
|
+
- Acquire: `https://id.atlassian.com/manage-profile/security/api-tokens` → "Create API token **with scopes**" → App: **Confluence**.
|
|
175
|
+
- Access (select EXACTLY): `read:page:confluence`, `read:hierarchical-content:confluence`, `read:comment:confluence`, `read:space:confluence`, `write:page:confluence`, `write:comment:confluence`, `write:label:confluence`, `search:confluence`.
|
|
176
|
+
|
|
177
|
+
### Notion — `source: notion`
|
|
178
|
+
- Headless substrate: curl + Bearer + internal-integration token. The Notion MCP tier is OAuth → not viable headless.
|
|
179
|
+
- Env: `NOTION_API_TOKEN` (or per-account `NOTION_API_TOKEN_<ws-slug>`). Config: `notion.workspaceId`, `notion.prdDatabaseId`.
|
|
180
|
+
- Acquire: `https://www.notion.so/profile/integrations` → New integration → type **Internal** → copy the `ntn_*` Internal Integration Token.
|
|
181
|
+
- Access: internal-integration token. **Non-optional:** share the target PRD database with the integration (Notion's share-based model) or every call returns 404/`object_not_found`.
|
|
182
|
+
|
|
183
|
+
### Linear — `tracker: linear` and/or `source: linear`
|
|
184
|
+
- Headless substrate: curl GraphQL (`https://api.linear.app/graphql`) + personal API key. The committed `linear-server` MCP is OAuth/browser → cannot authenticate headless; the API key is the only headless path.
|
|
185
|
+
- Env: `LINEAR_API_KEY` (or per-account `LINEAR_API_KEY_<ws-slug>`). Config: `linear.workspace`; `linear.teamKey` required when Linear is the tracker.
|
|
186
|
+
- Acquire: `https://linear.app/<workspace>/settings/account/security` → Personal API keys → New API key.
|
|
187
|
+
- Access: the personal API key inherits the user's workspace permissions — the user must be able to read/create/update Issues in the destination team.
|
|
188
|
+
|
|
115
189
|
## Output
|
|
116
190
|
|
|
117
191
|
Render the report grouped exactly as above. Start with one `Summary:` line, then a `Counts:` line
|
|
@@ -120,8 +194,17 @@ line per check as `- <STATUS> <id>: <summary>`, with optional `Observed:` and `A
|
|
|
120
194
|
beneath that separate fact from advice. Render an empty group as a single `OK`/`SKIP` line with the
|
|
121
195
|
reason rather than omitting it.
|
|
122
196
|
|
|
197
|
+
Immediately after the grouped findings, render a **`Credentials to provision`** subsection — a
|
|
198
|
+
checklist of the secrets the user must set in the routine's environment for the **active**
|
|
199
|
+
`tracker`/`source` (from group 4a). One block per active integration, each with its env-var name(s),
|
|
200
|
+
an `Acquire:` URL, and an `Access:` scope line, plus a one-line note that the environment UI is where
|
|
201
|
+
these are set (the generated build script only emits a names-only template, never values). If both
|
|
202
|
+
`tracker` and `source` resolve to the same vendor (e.g. both `github`), render it once.
|
|
203
|
+
|
|
123
204
|
End with a fenced, machine-readable inventory block (also printed when `--json` is passed) so
|
|
124
|
-
`/lisa:generate-claude-remote-build-script` can consume it without re-deriving everything
|
|
205
|
+
`/lisa:generate-claude-remote-build-script` can consume it without re-deriving everything. Secret
|
|
206
|
+
`env` entries for active integrations MUST carry `acquireUrl`, `accessScope`, and `headlessSubstrate`
|
|
207
|
+
so the generator can render acquisition comments into its template:
|
|
125
208
|
|
|
126
209
|
```json
|
|
127
210
|
{
|
|
@@ -130,12 +213,22 @@ End with a fenced, machine-readable inventory block (also printed when `--json`
|
|
|
130
213
|
{ "name": "gh", "required": true, "reason": "github-* skills and scripts shell out to gh" },
|
|
131
214
|
{ "name": "jq", "required": true, "reason": "hooks and scripts parse JSON" }
|
|
132
215
|
],
|
|
216
|
+
"tracker": "github",
|
|
217
|
+
"source": "github",
|
|
133
218
|
"env": [
|
|
134
219
|
{ "name": "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS", "required": true, "secret": false, "reason": "set in .claude/settings.json" },
|
|
135
|
-
{
|
|
220
|
+
{
|
|
221
|
+
"name": "GH_TOKEN", "required": true, "secret": true, "integration": "github",
|
|
222
|
+
"reason": "active tracker+source; gh scripts gate on gh auth status",
|
|
223
|
+
"headlessSubstrate": "gh CLI (token)",
|
|
224
|
+
"acquireUrl": "https://github.com/settings/personal-access-tokens",
|
|
225
|
+
"accessScope": "fine-grained PAT on target repo: Contents R/W, Issues R/W, Pull requests R/W, Metadata R; +Workflows R/W if editing .github/workflows; +Projects R/W if using ProjectV2"
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
"mcp": [
|
|
229
|
+
{ "name": "linear-server", "transport": "http", "auth": "oauth", "headlessUsable": false, "replacedBy": "LINEAR_API_KEY + Linear GraphQL", "dormant": true }
|
|
136
230
|
],
|
|
137
|
-
"
|
|
138
|
-
"gaps": [ "auto-memory not synced to cloud", "bun package fetch behind proxy" ],
|
|
231
|
+
"gaps": [ "auto-memory not synced to cloud", "bun package fetch behind proxy", "OS keychain absent — env-var token form only" ],
|
|
139
232
|
"allowlistDomains": []
|
|
140
233
|
}
|
|
141
234
|
```
|
|
@@ -159,3 +252,9 @@ End with a fenced, machine-readable inventory block (also printed when `--json`
|
|
|
159
252
|
- Never report a `GAP` as satisfiable by configuration — a gap is a constraint, and the action must
|
|
160
253
|
be a change of approach, not "set an env var".
|
|
161
254
|
- Never invent tools or env vars that no committed file references.
|
|
255
|
+
- Credential scopes and acquisition URLs come from the **Credential reference** table (sourced from
|
|
256
|
+
Lisa's `setup-*` skills) — transcribe them exactly; never guess at the access a token needs.
|
|
257
|
+
- For the active `tracker`/`source`, always report the **env-var** form of the secret, never the OS
|
|
258
|
+
keychain form — keychain reads do not work in a cloud routine.
|
|
259
|
+
- A browser-OAuth MCP (or interactively-authed CLI) backing an active integration is a `GAP`; the
|
|
260
|
+
remediation is its token substrate from the table, not "authenticate the MCP".
|
|
@@ -53,7 +53,12 @@ tracker/source, plus the host project's own package manager and tooling — not
|
|
|
53
53
|
with the reason. **Never write real secret values** — only names and placeholders, because the
|
|
54
54
|
environment config is visible to anyone who can edit it. Include feature flags actually set in
|
|
55
55
|
`.claude/settings.json` (e.g. `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`) so cloud behavior matches
|
|
56
|
-
local.
|
|
56
|
+
local. For every secret entry that carries `acquireUrl`/`accessScope`/`headlessSubstrate` (the
|
|
57
|
+
active tracker/source credentials from the analysis's group 4a), render those as comment lines
|
|
58
|
+
directly above the name — `# Acquire: <url>` and `# Access: <scope>` — so the user knows exactly
|
|
59
|
+
where to get the token and what permissions it needs. Emit only the **env-var form** of the name
|
|
60
|
+
that the analysis reported (including any per-account suffixed form like `LINEAR_API_KEY_<slug>`);
|
|
61
|
+
never emit a keychain instruction — keychain does not exist in a cloud routine.
|
|
57
62
|
|
|
58
63
|
4. **Emit the allowlist + gaps notice.** List any custom domains the setup or runtime reaches
|
|
59
64
|
(from `allowlistDomains`) that the user must add to the environment's network access, and echo
|
|
@@ -80,7 +85,10 @@ shape, not a fixed payload):
|
|
|
80
85
|
# - <gaps from analysis, e.g. auto-memory is machine-local and not synced to cloud routines>
|
|
81
86
|
# ENV VARS to set in the environment config (names only — set real values there, not here):
|
|
82
87
|
# - CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 # REQUIRED, matches .claude/settings.json
|
|
83
|
-
#
|
|
88
|
+
# # --- credentials for the active tracker/source (set in the environment UI) ---
|
|
89
|
+
# # Acquire: https://github.com/settings/personal-access-tokens
|
|
90
|
+
# # Access: fine-grained PAT on target repo: Contents R/W, Issues R/W, Pull requests R/W, Metadata R
|
|
91
|
+
# - GH_TOKEN=<token> # REQUIRED, github is the active tracker+source
|
|
84
92
|
# NETWORK: allowlist these domains in the environment if not on full access:
|
|
85
93
|
# - <allowlistDomains, if any>
|
|
86
94
|
set -uo pipefail
|
|
@@ -116,6 +124,8 @@ to stop are: the analysis could not run, or the `--out` path is not writable.
|
|
|
116
124
|
- Always derive the script from a fresh `/lisa:analyze-claude-remote` run — never from a stale or
|
|
117
125
|
assumed inventory.
|
|
118
126
|
- Never write real secret values into the script or template — names and placeholders only.
|
|
127
|
+
- For active tracker/source credentials, carry the analysis's `Acquire:` URL and `Access:` scope into
|
|
128
|
+
the template as comments, and emit only the env-var form of the name — never a keychain command.
|
|
119
129
|
- Never emit an install for a tool the analysis did not surface, and never install `OPTIONAL` tools
|
|
120
130
|
unless `--include-optional` is set.
|
|
121
131
|
- Keep the script idempotent and detect-before-install so it is safe to re-run and cache.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: analyze-claude-remote
|
|
3
|
-
description: "Audit whether the current repository can run as a Claude Code remote routine (cloud session). Read-only analysis that inventories what Lisa AND the host project need to configure or build in the cloud environment — external CLIs/binaries to install, environment variables and secrets to set, startup hooks and their headless-safety, MCP server scope/transport/auth, user-scoped config and auto-memory gaps that don't replicate to the cloud, and platform constraints (bun proxy, IP allowlist, network tier, no interactivity). Emits grouped findings plus a machine-readable inventory that /lisa:generate-claude-remote-build-script consumes."
|
|
3
|
+
description: "Audit whether the current repository can run as a Claude Code remote routine (cloud session). Read-only analysis that inventories what Lisa AND the host project need to configure or build in the cloud environment — external CLIs/binaries to install, environment variables and secrets to set, startup hooks and their headless-safety, MCP server scope/transport/auth, user-scoped config and auto-memory gaps that don't replicate to the cloud, and platform constraints (bun proxy, IP allowlist, network tier, no interactivity). Reads `.lisa.config.json` `tracker`/`source` to determine which tracker/PRD-source integrations are active, resolves each to its headless-viable substrate (CLI/curl + token, never browser-OAuth MCP, never OS-keychain), and spells out the exact secret env vars, where to obtain each token, and the precise access scope required — without guessing. Emits grouped findings plus a machine-readable inventory that /lisa:generate-claude-remote-build-script consumes."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -88,12 +88,46 @@ Group the findings as:
|
|
|
88
88
|
in `.claude/settings.json` (e.g. `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`) as `REQUIRED` to match
|
|
89
89
|
local behavior, since the environment `env` block is the reliable place to set them.
|
|
90
90
|
|
|
91
|
+
4a. **Tracker / PRD-source credentials** — this is the load-bearing part of the audit and must be
|
|
92
|
+
driven by config, not by what the scan happens to find. Resolve the active integrations first:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
TRACKER=$(jq -r '.tracker // "jira"' .lisa.config.json 2>/dev/null) # tickets: jira | github | linear
|
|
96
|
+
SOURCE=$(jq -r '.source // empty' .lisa.config.json 2>/dev/null) # PRDs: notion | confluence | github | linear
|
|
97
|
+
```
|
|
98
|
+
(Apply `config-resolution`: `.lisa.config.local.json` overrides `.lisa.config.json`.) For the
|
|
99
|
+
**active** `tracker` and the **active** `source` — and only those — emit a `REQUIRED` credential
|
|
100
|
+
finding using the **Credential reference** table below. For every integration that is *not* the
|
|
101
|
+
active tracker/source, its credentials are `OPTIONAL` (dormant) — never mark them `REQUIRED`.
|
|
102
|
+
|
|
103
|
+
Two non-negotiable headless rules govern which substrate a routine can actually use:
|
|
104
|
+
|
|
105
|
+
- **Browser-OAuth MCP is dead headless.** A routine cannot complete an interactive OAuth/SSO
|
|
106
|
+
browser flow. So for any integration whose local substrate is an OAuth MCP (the committed
|
|
107
|
+
`linear-server` MCP; the Notion MCP; the Atlassian MCP) or an interactively-authed CLI
|
|
108
|
+
(`acli auth login --web`), the MCP/interactive tier is a `GAP` — the audit must route to that
|
|
109
|
+
integration's **token substrate** (CLI/curl + API token) and report the token's env vars.
|
|
110
|
+
- **OS keychain is absent headless.** Lisa's access skills read the token from the OS keychain
|
|
111
|
+
first (`security` / `secret-tool` / `cmdkey`) and fall back to an **env var**. A cloud routine
|
|
112
|
+
has no keyring daemon, so only the env-var fallback works. Always report the **env-var form**,
|
|
113
|
+
including the per-account suffixed names (`ATLASSIAN_API_TOKEN_<slug>`, `NOTION_API_TOKEN_<slug>`,
|
|
114
|
+
`LINEAR_API_KEY_<slug>`) when the integration keys tokens by email/workspace.
|
|
115
|
+
|
|
116
|
+
For each active integration, the finding must carry: the env var name(s), where to get the token
|
|
117
|
+
(`Acquire:` URL), and the **exact** access/scope required (`Access:`) — copied from the table, not
|
|
118
|
+
guessed. If a value the table needs (server URL, project key, workspace id, email, team key) is
|
|
119
|
+
missing from `.lisa.config.json`, flag it as a `GAP`/`Action:` to set it, rather than inventing one.
|
|
120
|
+
|
|
91
121
|
5. **MCP servers** — read every committed `.mcp.json`. For each server report transport and auth.
|
|
92
|
-
Project-scoped HTTP/SSE servers are `OK`. Flag stdio servers as
|
|
93
|
-
process — only viable if the cloud session can spawn them from the
|
|
94
|
-
interactively/OAuth-authed servers
|
|
95
|
-
|
|
96
|
-
|
|
122
|
+
Project-scoped HTTP/SSE servers with no interactive auth are `OK`. Flag stdio servers as
|
|
123
|
+
`RISK`/`GAP` (need a local process — only viable if the cloud session can spawn them from the
|
|
124
|
+
repo). Flag interactively/OAuth-authed servers as `GAP` for headless auth — they cannot complete
|
|
125
|
+
a browser flow headless **regardless of transport** (an HTTP MCP like `linear-server` is still a
|
|
126
|
+
`GAP` because its *auth* is OAuth, not because of its transport). When an OAuth MCP backs an
|
|
127
|
+
active tracker/source, do not stop at the `GAP` — cross-reference group 4a and point to the
|
|
128
|
+
integration's token substrate as the headless replacement (e.g. `linear-server` MCP → `LINEAR_API_KEY`
|
|
129
|
+
+ Linear GraphQL). Note any user-scoped MCP (`~/.claude.json`) as `GAP` — it never reaches the
|
|
130
|
+
cloud; it must be moved into project `.mcp.json`.
|
|
97
131
|
|
|
98
132
|
6. **Config scope & memory gaps** — identify reliance on user-scoped config that will not load
|
|
99
133
|
remotely: `~/.claude/CLAUDE.md`, user `enabledPlugins`, user skills/agents, user MCP. Most
|
|
@@ -112,6 +146,46 @@ Group the findings as:
|
|
|
112
146
|
runtime service it depends on (database, queue, external API) that will not exist in a fresh
|
|
113
147
|
cloud environment, so the user can decide whether the routine's task is even feasible there.
|
|
114
148
|
|
|
149
|
+
## Credential reference (tracker / source → headless secret)
|
|
150
|
+
|
|
151
|
+
Authoritative mapping for group 4a, transcribed from Lisa's `setup-*` skills and access layers
|
|
152
|
+
(`setup-github`, `setup-atlassian`, `setup-jira`, `setup-notion`, `setup-linear`,
|
|
153
|
+
`atlassian-access`, `notion-access`). Use the row for the **active** `tracker`/`source` only. Report
|
|
154
|
+
the **env-var form** of each secret — keychain reads do not work in a cloud routine. Slugs:
|
|
155
|
+
`<email-slug>` = email via `tr '[:upper:]@.' '[:lower:]__'`; `<ws-slug>` = workspace via
|
|
156
|
+
`tr '[:upper:]-' '[:lower:]_'`. If a token has both an unsuffixed and a per-account form, the
|
|
157
|
+
unsuffixed `…_TOKEN`/`…_KEY` is the simplest to set in a single-account routine.
|
|
158
|
+
|
|
159
|
+
### GitHub — `tracker: github` and/or `source: github`
|
|
160
|
+
- Headless substrate: `gh` CLI authed by token (every Lisa GitHub script gates on `gh auth status`).
|
|
161
|
+
- Env: `GH_TOKEN` (the routine's built-in repo connection may not authenticate the `gh` CLI — verify; set `GH_TOKEN` if `gh auth status` fails). `PAT` only for cross-repo flows.
|
|
162
|
+
- Acquire: fine-grained — `https://github.com/settings/personal-access-tokens`; classic — `https://github.com/settings/tokens`.
|
|
163
|
+
- Access: fine-grained → Repository access to the target repo(s); Repository permissions: Contents R/W, Issues R/W, Pull requests R/W, Metadata R (mandatory); add Workflows R/W only if editing `.github/workflows`, and Organization → Projects R/W only if using ProjectV2. Classic equivalent: `repo` + `workflow` (+ `project`, `read:org` for boards). The identity must hold WRITE/MAINTAIN/ADMIN on the repo.
|
|
164
|
+
|
|
165
|
+
### JIRA — `tracker: jira`
|
|
166
|
+
- Headless substrate: `jira-cli` + curl (Basic auth). The acli and Atlassian-MCP tiers need prior interactive/OAuth auth → not viable headless.
|
|
167
|
+
- Env: `JIRA_API_TOKEN`, `JIRA_SERVER` (e.g. `https://acme.atlassian.net`), `JIRA_LOGIN` (account email), `JIRA_PROJECT` (default project key); optional `JIRA_INSTALLATION` (default `cloud`), `JIRA_BOARD`. (`setup-jira-cli.sh` writes the jira-cli config from these on SessionStart.)
|
|
168
|
+
- Acquire: `https://id.atlassian.com/manage-profile/security/api-tokens`.
|
|
169
|
+
- Access: the API token inherits the Atlassian user's permissions — the user must have Browse/Create/Edit/Transition on the target project. An unscoped token suffices for jira-cli; a scoped token must cover the JIRA project read/write operations.
|
|
170
|
+
|
|
171
|
+
### Confluence — `source: confluence`
|
|
172
|
+
- Headless substrate: curl + Basic auth + **scoped** API token.
|
|
173
|
+
- Env: `ATLASSIAN_API_TOKEN` (or per-account `ATLASSIAN_API_TOKEN_<email-slug>`). Config (`.lisa.config.json`): `atlassian.cloudId`, `atlassian.site`, `atlassian.email`.
|
|
174
|
+
- Acquire: `https://id.atlassian.com/manage-profile/security/api-tokens` → "Create API token **with scopes**" → App: **Confluence**.
|
|
175
|
+
- Access (select EXACTLY): `read:page:confluence`, `read:hierarchical-content:confluence`, `read:comment:confluence`, `read:space:confluence`, `write:page:confluence`, `write:comment:confluence`, `write:label:confluence`, `search:confluence`.
|
|
176
|
+
|
|
177
|
+
### Notion — `source: notion`
|
|
178
|
+
- Headless substrate: curl + Bearer + internal-integration token. The Notion MCP tier is OAuth → not viable headless.
|
|
179
|
+
- Env: `NOTION_API_TOKEN` (or per-account `NOTION_API_TOKEN_<ws-slug>`). Config: `notion.workspaceId`, `notion.prdDatabaseId`.
|
|
180
|
+
- Acquire: `https://www.notion.so/profile/integrations` → New integration → type **Internal** → copy the `ntn_*` Internal Integration Token.
|
|
181
|
+
- Access: internal-integration token. **Non-optional:** share the target PRD database with the integration (Notion's share-based model) or every call returns 404/`object_not_found`.
|
|
182
|
+
|
|
183
|
+
### Linear — `tracker: linear` and/or `source: linear`
|
|
184
|
+
- Headless substrate: curl GraphQL (`https://api.linear.app/graphql`) + personal API key. The committed `linear-server` MCP is OAuth/browser → cannot authenticate headless; the API key is the only headless path.
|
|
185
|
+
- Env: `LINEAR_API_KEY` (or per-account `LINEAR_API_KEY_<ws-slug>`). Config: `linear.workspace`; `linear.teamKey` required when Linear is the tracker.
|
|
186
|
+
- Acquire: `https://linear.app/<workspace>/settings/account/security` → Personal API keys → New API key.
|
|
187
|
+
- Access: the personal API key inherits the user's workspace permissions — the user must be able to read/create/update Issues in the destination team.
|
|
188
|
+
|
|
115
189
|
## Output
|
|
116
190
|
|
|
117
191
|
Render the report grouped exactly as above. Start with one `Summary:` line, then a `Counts:` line
|
|
@@ -120,8 +194,17 @@ line per check as `- <STATUS> <id>: <summary>`, with optional `Observed:` and `A
|
|
|
120
194
|
beneath that separate fact from advice. Render an empty group as a single `OK`/`SKIP` line with the
|
|
121
195
|
reason rather than omitting it.
|
|
122
196
|
|
|
197
|
+
Immediately after the grouped findings, render a **`Credentials to provision`** subsection — a
|
|
198
|
+
checklist of the secrets the user must set in the routine's environment for the **active**
|
|
199
|
+
`tracker`/`source` (from group 4a). One block per active integration, each with its env-var name(s),
|
|
200
|
+
an `Acquire:` URL, and an `Access:` scope line, plus a one-line note that the environment UI is where
|
|
201
|
+
these are set (the generated build script only emits a names-only template, never values). If both
|
|
202
|
+
`tracker` and `source` resolve to the same vendor (e.g. both `github`), render it once.
|
|
203
|
+
|
|
123
204
|
End with a fenced, machine-readable inventory block (also printed when `--json` is passed) so
|
|
124
|
-
`/lisa:generate-claude-remote-build-script` can consume it without re-deriving everything
|
|
205
|
+
`/lisa:generate-claude-remote-build-script` can consume it without re-deriving everything. Secret
|
|
206
|
+
`env` entries for active integrations MUST carry `acquireUrl`, `accessScope`, and `headlessSubstrate`
|
|
207
|
+
so the generator can render acquisition comments into its template:
|
|
125
208
|
|
|
126
209
|
```json
|
|
127
210
|
{
|
|
@@ -130,12 +213,22 @@ End with a fenced, machine-readable inventory block (also printed when `--json`
|
|
|
130
213
|
{ "name": "gh", "required": true, "reason": "github-* skills and scripts shell out to gh" },
|
|
131
214
|
{ "name": "jq", "required": true, "reason": "hooks and scripts parse JSON" }
|
|
132
215
|
],
|
|
216
|
+
"tracker": "github",
|
|
217
|
+
"source": "github",
|
|
133
218
|
"env": [
|
|
134
219
|
{ "name": "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS", "required": true, "secret": false, "reason": "set in .claude/settings.json" },
|
|
135
|
-
{
|
|
220
|
+
{
|
|
221
|
+
"name": "GH_TOKEN", "required": true, "secret": true, "integration": "github",
|
|
222
|
+
"reason": "active tracker+source; gh scripts gate on gh auth status",
|
|
223
|
+
"headlessSubstrate": "gh CLI (token)",
|
|
224
|
+
"acquireUrl": "https://github.com/settings/personal-access-tokens",
|
|
225
|
+
"accessScope": "fine-grained PAT on target repo: Contents R/W, Issues R/W, Pull requests R/W, Metadata R; +Workflows R/W if editing .github/workflows; +Projects R/W if using ProjectV2"
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
"mcp": [
|
|
229
|
+
{ "name": "linear-server", "transport": "http", "auth": "oauth", "headlessUsable": false, "replacedBy": "LINEAR_API_KEY + Linear GraphQL", "dormant": true }
|
|
136
230
|
],
|
|
137
|
-
"
|
|
138
|
-
"gaps": [ "auto-memory not synced to cloud", "bun package fetch behind proxy" ],
|
|
231
|
+
"gaps": [ "auto-memory not synced to cloud", "bun package fetch behind proxy", "OS keychain absent — env-var token form only" ],
|
|
139
232
|
"allowlistDomains": []
|
|
140
233
|
}
|
|
141
234
|
```
|
|
@@ -159,3 +252,9 @@ End with a fenced, machine-readable inventory block (also printed when `--json`
|
|
|
159
252
|
- Never report a `GAP` as satisfiable by configuration — a gap is a constraint, and the action must
|
|
160
253
|
be a change of approach, not "set an env var".
|
|
161
254
|
- Never invent tools or env vars that no committed file references.
|
|
255
|
+
- Credential scopes and acquisition URLs come from the **Credential reference** table (sourced from
|
|
256
|
+
Lisa's `setup-*` skills) — transcribe them exactly; never guess at the access a token needs.
|
|
257
|
+
- For the active `tracker`/`source`, always report the **env-var** form of the secret, never the OS
|
|
258
|
+
keychain form — keychain reads do not work in a cloud routine.
|
|
259
|
+
- A browser-OAuth MCP (or interactively-authed CLI) backing an active integration is a `GAP`; the
|
|
260
|
+
remediation is its token substrate from the table, not "authenticate the MCP".
|
|
@@ -53,7 +53,12 @@ tracker/source, plus the host project's own package manager and tooling — not
|
|
|
53
53
|
with the reason. **Never write real secret values** — only names and placeholders, because the
|
|
54
54
|
environment config is visible to anyone who can edit it. Include feature flags actually set in
|
|
55
55
|
`.claude/settings.json` (e.g. `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`) so cloud behavior matches
|
|
56
|
-
local.
|
|
56
|
+
local. For every secret entry that carries `acquireUrl`/`accessScope`/`headlessSubstrate` (the
|
|
57
|
+
active tracker/source credentials from the analysis's group 4a), render those as comment lines
|
|
58
|
+
directly above the name — `# Acquire: <url>` and `# Access: <scope>` — so the user knows exactly
|
|
59
|
+
where to get the token and what permissions it needs. Emit only the **env-var form** of the name
|
|
60
|
+
that the analysis reported (including any per-account suffixed form like `LINEAR_API_KEY_<slug>`);
|
|
61
|
+
never emit a keychain instruction — keychain does not exist in a cloud routine.
|
|
57
62
|
|
|
58
63
|
4. **Emit the allowlist + gaps notice.** List any custom domains the setup or runtime reaches
|
|
59
64
|
(from `allowlistDomains`) that the user must add to the environment's network access, and echo
|
|
@@ -80,7 +85,10 @@ shape, not a fixed payload):
|
|
|
80
85
|
# - <gaps from analysis, e.g. auto-memory is machine-local and not synced to cloud routines>
|
|
81
86
|
# ENV VARS to set in the environment config (names only — set real values there, not here):
|
|
82
87
|
# - CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 # REQUIRED, matches .claude/settings.json
|
|
83
|
-
#
|
|
88
|
+
# # --- credentials for the active tracker/source (set in the environment UI) ---
|
|
89
|
+
# # Acquire: https://github.com/settings/personal-access-tokens
|
|
90
|
+
# # Access: fine-grained PAT on target repo: Contents R/W, Issues R/W, Pull requests R/W, Metadata R
|
|
91
|
+
# - GH_TOKEN=<token> # REQUIRED, github is the active tracker+source
|
|
84
92
|
# NETWORK: allowlist these domains in the environment if not on full access:
|
|
85
93
|
# - <allowlistDomains, if any>
|
|
86
94
|
set -uo pipefail
|
|
@@ -116,6 +124,8 @@ to stop are: the analysis could not run, or the `--out` path is not writable.
|
|
|
116
124
|
- Always derive the script from a fresh `/lisa:analyze-claude-remote` run — never from a stale or
|
|
117
125
|
assumed inventory.
|
|
118
126
|
- Never write real secret values into the script or template — names and placeholders only.
|
|
127
|
+
- For active tracker/source credentials, carry the analysis's `Acquire:` URL and `Access:` scope into
|
|
128
|
+
the template as comments, and emit only the env-var form of the name — never a keychain command.
|
|
119
129
|
- Never emit an install for a tool the analysis did not surface, and never install `OPTIONAL` tools
|
|
120
130
|
unless `--include-optional` is set.
|
|
121
131
|
- Keep the script idempotent and detect-before-install so it is safe to re-run and cache.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.141.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.141.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.141.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.141.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.141.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"
|