@codyswann/lisa 4.82.3 → 4.83.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/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +8 -7
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-session-manager/SKILL.md +7 -5
- package/plugins/lisa/rules/reference/config-resolution.md +3 -2
- package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa/skills/lisa-setup-session-manager/SKILL.md +7 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa-agy/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa-agy/skills/lisa-setup-session-manager/SKILL.md +7 -5
- 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-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +3 -2
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa-copilot/skills/lisa-setup-session-manager/SKILL.md +7 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +3 -2
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa-cursor/skills/lisa-setup-session-manager/SKILL.md +7 -5
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/rules/reference/config-resolution.md +3 -2
- package/plugins/lisa-devin/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/lisa-devin/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/lisa-devin/skills/lisa-setup-session-manager/SKILL.md +7 -5
- 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-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-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-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-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-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-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-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-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-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-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-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-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-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-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/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +3 -2
- package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +4 -1
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-setup.mjs +7 -6
- package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +4 -3
- package/plugins/src/base/skills/lisa-session-manager/scripts/config.mjs +8 -4
- package/plugins/src/base/skills/lisa-session-manager/scripts/repo-detect.mjs +40 -2
- package/plugins/src/base/skills/lisa-setup-session-manager/SKILL.md +7 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-setup-session-manager
|
|
3
|
-
description: "Set up the local session manager for this project: writes the non-secret `sessionManager` block to `.lisa.config.json` (detecting a multi-repo `projects
|
|
3
|
+
description: "Set up the local session manager for this project: writes the non-secret `sessionManager` block to `.lisa.config.json` (detecting a multi-repo layout: repos under `projects/`, or directly under the project root), stores the project's own Telegram bot token outside the repo, checks the Telegram plugin is installed but not enabled at user scope, keeps the manager's state out of git, seeds the checked-in runbook, starts the manager in tmux, walks the operator through pairing, and finishes with doctor's session-manager check. Idempotent."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Write", "Skill", "AskUserQuestion"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -41,10 +41,12 @@ writes `$SM`, and pass `--project-root "$ROOT"` (the absolute project root) on e
|
|
|
41
41
|
## Step 2: Write the config block
|
|
42
42
|
|
|
43
43
|
1. Preview: `node "$SM/session-manager.mjs" init-config --project-root "$ROOT"`. It detects
|
|
44
|
-
`projects/*/.lisa.config.json
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
`projects/*/.lisa.config.json`, or, when `projects/` holds none, the root's own children that
|
|
45
|
+
have a `.lisa.config.json` and their own `.git` (written as `repos.root: "."`). It proposes
|
|
46
|
+
`name`, `interval`, `repos`, `capacity`, `stall` and a per-project `notify.stateDir`. Repo
|
|
47
|
+
detection leaves out linked worktrees and keeps one checkout per remote, so ticket worktrees and
|
|
48
|
+
second clones are not proposed. Show the block to the operator and ask whether any repo is
|
|
49
|
+
missing or should not be routed.
|
|
48
50
|
2. Write it: the same command with `--write`. It adds only non-secret fields and never overwrites an
|
|
49
51
|
existing block (`reason: "exists"` means keep it).
|
|
50
52
|
3. Each repo's `hints` are a draft: its name plus one per well-known dependency (`NestJS`, `Expo`,
|
|
@@ -696,7 +696,8 @@ claims Ready leaf items and runs each one as `/lisa:implement` in a fresh backgr
|
|
|
696
696
|
session. It is **opt-in**: an absent block means no manager, and `lisa sync` never populates it
|
|
697
697
|
(it is deliberately not in the sync registry, because the manager starts sessions with permissions
|
|
698
698
|
bypassed). `/lisa:setup:session-manager` writes it, detecting a multi-repo layout from
|
|
699
|
-
`projects/*/.lisa.config.json
|
|
699
|
+
`projects/*/.lisa.config.json`, or, when `projects/` holds none, from the root's own children that
|
|
700
|
+
have a `.lisa.config.json` and their own `.git` (written as `"root": "."`).
|
|
700
701
|
|
|
701
702
|
```json
|
|
702
703
|
"sessionManager": {
|
|
@@ -720,7 +721,7 @@ bypassed). `/lisa:setup:session-manager` writes it, detecting a multi-repo layou
|
|
|
720
721
|
| `sessionManager.name` | **yes** | — | Manager session name: lowercase letters, digits, `-` or `_`, at most 64 characters. It names the tmux session and the session workers `SendMessage` to. Setup writes `<project>-manager`. |
|
|
721
722
|
| `sessionManager.interval` | no | `5m` | `/loop` cadence: a positive integer plus `s`, `m`, `h` or `d`. |
|
|
722
723
|
| `sessionManager.repos` | no | — | Omit for a single-repo project: every item routes to the project root. When present, `entries` must name at least one repo. |
|
|
723
|
-
| `sessionManager.repos.root` | no | `projects` | Relative directory holding the child repos. It must stay inside the project. |
|
|
724
|
+
| `sessionManager.repos.root` | no | `projects` | Relative directory holding the child repos. It must stay inside the project. `.` means the repos are direct children of the project root. |
|
|
724
725
|
| `sessionManager.repos.entries.<key>.hints` | **yes** (per entry) | — | Non-empty list of words the manager matches a work item against to choose the repo. `<key>` is the child directory name (one safe path segment). |
|
|
725
726
|
| `sessionManager.capacity.maxWorkers` | no | `6` | Hard cap on concurrent workers (a positive integer). Telegram `cap N` overrides it at runtime through the manager's ledger, not config. |
|
|
726
727
|
| `sessionManager.capacity.gbPerWorker` | no | `3` | Memory budgeted per worker, in GB (positive). |
|
|
@@ -552,13 +552,16 @@ function isPlainObject(value) {
|
|
|
552
552
|
*/
|
|
553
553
|
function validateReposRoot(root) {
|
|
554
554
|
if (root === undefined) return [];
|
|
555
|
+
// `.` means the repos are direct children of the project root.
|
|
556
|
+
if (root === ".") return [];
|
|
555
557
|
const segments = typeof root === "string" ? root.split("/") : [];
|
|
556
558
|
if (segments.length && segments.every(part => SAFE_SEGMENT.test(part))) {
|
|
557
559
|
return [];
|
|
558
560
|
}
|
|
559
561
|
return [
|
|
560
562
|
`sessionManager.repos.root ${JSON.stringify(root)} must be a relative ` +
|
|
561
|
-
`path inside the project, such as "projects".
|
|
563
|
+
`path inside the project, such as "projects" (or "." for repos at the ` +
|
|
564
|
+
`project root). Workers start there with ` +
|
|
562
565
|
`permissions bypassed.`,
|
|
563
566
|
];
|
|
564
567
|
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./cli-runtime.mjs";
|
|
20
20
|
import {
|
|
21
21
|
buildDefaultBlock,
|
|
22
|
-
|
|
22
|
+
detectRepoLayout,
|
|
23
23
|
draftHints,
|
|
24
24
|
resolveRepoDir,
|
|
25
25
|
} from "./config.mjs";
|
|
@@ -37,8 +37,9 @@ import {
|
|
|
37
37
|
* `init-config [--slug <slug>] [--write]`: the default block for this
|
|
38
38
|
* project, written to `.lisa.config.json` only with `--write` and only when
|
|
39
39
|
* no block exists. Non-secret fields only; the token never goes here. Repos
|
|
40
|
-
* are the routable children `
|
|
41
|
-
*
|
|
40
|
+
* are the routable children `detectRepoLayout` finds under `projects/`, else
|
|
41
|
+
* directly under the root (linked worktrees and second clones of one remote
|
|
42
|
+
* left out), each with drafted hints.
|
|
42
43
|
* @param {object} ctx - CLI context
|
|
43
44
|
* @returns {{ json: object }} `{written,block,...}`
|
|
44
45
|
*/
|
|
@@ -51,15 +52,15 @@ export function initConfig(ctx) {
|
|
|
51
52
|
}
|
|
52
53
|
const slug =
|
|
53
54
|
ctx.values.slug ?? defaultProjectSlug(ctx.root, global?.github?.repo);
|
|
54
|
-
const detectedRepos =
|
|
55
|
+
const { reposRoot, repos: detectedRepos } = detectRepoLayout(ctx.root);
|
|
55
56
|
const hints = Object.fromEntries(
|
|
56
57
|
detectedRepos.map(name => [
|
|
57
58
|
name,
|
|
58
|
-
draftHints(path.join(ctx.root,
|
|
59
|
+
draftHints(path.join(ctx.root, reposRoot, name), name),
|
|
59
60
|
])
|
|
60
61
|
);
|
|
61
62
|
const block = asSetupError(() =>
|
|
62
|
-
buildDefaultBlock({ projectSlug: slug, detectedRepos, hints })
|
|
63
|
+
buildDefaultBlock({ projectSlug: slug, detectedRepos, hints, reposRoot })
|
|
63
64
|
);
|
|
64
65
|
if (!ctx.values.write) return { json: { written: false, block } };
|
|
65
66
|
|
|
@@ -82,9 +82,10 @@ Config and routing
|
|
|
82
82
|
validate stdout {valid,errors}; exit 2 when invalid or absent.
|
|
83
83
|
init-config [--slug <slug>] [--write]
|
|
84
84
|
stdout {written,block[,reason:"exists"][,path]}. Detects
|
|
85
|
-
projects/*/.lisa.config.json,
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
projects/*/.lisa.config.json, else root children with their own
|
|
86
|
+
.lisa.config.json and .git (repos.root "."), skipping linked
|
|
87
|
+
worktrees (.git is a file) and keeping one child per origin
|
|
88
|
+
remote (the one named after the repo, else the first by name). Each repo's hints are a
|
|
88
89
|
draft: its name, then one per well-known package.json dependency
|
|
89
90
|
(e.g. @nestjs/* -> NestJS, expo -> Expo, aws-cdk-lib -> AWS CDK).
|
|
90
91
|
Default slug: <github.repo or folder name>-<first 6 hex of
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "../../lisa-secrets-access/scripts/validate-config.mjs";
|
|
26
26
|
|
|
27
27
|
export { parseLoopInterval, validateSessionManager };
|
|
28
|
-
export { detectRepos, draftHints } from "./repo-detect.mjs";
|
|
28
|
+
export { detectRepoLayout, detectRepos, draftHints } from "./repo-detect.mjs";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Documented defaults for every optional key.
|
|
@@ -157,15 +157,19 @@ function normalizeSlug(projectSlug) {
|
|
|
157
157
|
* no `repos` key, which is what makes a project single-repo. Each detected
|
|
158
158
|
* repo's hints are its drafted hints when given (`draftHints`), else its own
|
|
159
159
|
* name: valid either way, and setup asks the operator to review them.
|
|
160
|
+
* `reposRoot` is where the repos were found (`detectRepoLayout`): `projects`
|
|
161
|
+
* by default, or `.` when they sit directly under the project root.
|
|
160
162
|
* @param {{ projectSlug: string, detectedRepos?: string[],
|
|
161
|
-
* hints?: Record<string, string[]
|
|
162
|
-
* `detectRepos`,
|
|
163
|
+
* hints?: Record<string, string[]>, reposRoot?: string }} input Project
|
|
164
|
+
* slug, the output of `detectRepos`, drafted hints per repo, and the repos
|
|
165
|
+
* root they were found under.
|
|
163
166
|
* @returns {SessionManagerBlock} A block `validateSessionManager` accepts.
|
|
164
167
|
*/
|
|
165
168
|
export function buildDefaultBlock({
|
|
166
169
|
projectSlug,
|
|
167
170
|
detectedRepos = [],
|
|
168
171
|
hints = {},
|
|
172
|
+
reposRoot = DEFAULT_REPOS_ROOT,
|
|
169
173
|
}) {
|
|
170
174
|
const slug = normalizeSlug(projectSlug);
|
|
171
175
|
const repos = [...detectedRepos].sort();
|
|
@@ -175,7 +179,7 @@ export function buildDefaultBlock({
|
|
|
175
179
|
...(repos.length > 0
|
|
176
180
|
? {
|
|
177
181
|
repos: {
|
|
178
|
-
root:
|
|
182
|
+
root: reposRoot,
|
|
179
183
|
entries: Object.fromEntries(
|
|
180
184
|
repos.map(name => [
|
|
181
185
|
name,
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* ticket worktree builds on the wrong branch, so the detector keeps one
|
|
12
12
|
* checkout per remote: the one named after the repo when there is one.
|
|
13
13
|
*
|
|
14
|
+
* Not every multi-repo host has a `projects/` dir: some keep each repo as a
|
|
15
|
+
* direct child of the project root (`api/`, `web/`, `infra/`). Setup checks
|
|
16
|
+
* `projects/` first and falls back to the root's own children. At the root a
|
|
17
|
+
* child must also be its own checkout (it has a `.git`): a folder of a
|
|
18
|
+
* single-repo project that happens to hold a `.lisa.config.json` is part of
|
|
19
|
+
* that repo, not a repo to route workers into.
|
|
20
|
+
*
|
|
14
21
|
* Every filesystem call goes through an injectable seam.
|
|
15
22
|
* @module session-manager/repo-detect
|
|
16
23
|
*/
|
|
@@ -152,8 +159,9 @@ function onePerRemote(children) {
|
|
|
152
159
|
* run `/lisa:implement` inside it, which needs that file), is not a linked
|
|
153
160
|
* worktree, and is the chosen checkout of its remote.
|
|
154
161
|
* @param {string} root - Project root
|
|
155
|
-
* @param {{ reposRoot?: string,
|
|
156
|
-
* Repos root (default
|
|
162
|
+
* @param {{ reposRoot?: string, requireGit?: boolean,
|
|
163
|
+
* fs?: Partial<typeof NODE_FS> }} [options] - Repos root (default
|
|
164
|
+
* `projects`), whether a child needs its own `.git`, and filesystem seam
|
|
157
165
|
* @returns {string[]} Child directory names, sorted
|
|
158
166
|
*/
|
|
159
167
|
export function detectRepos(root, options = {}) {
|
|
@@ -165,6 +173,9 @@ export function detectRepos(root, options = {}) {
|
|
|
165
173
|
.filter(entry => entry.isDirectory() && SAFE_SEGMENT.test(entry.name))
|
|
166
174
|
.map(entry => ({ name: entry.name, dir: join(base, entry.name) }))
|
|
167
175
|
.filter(child => fs.existsSync(join(child.dir, ".lisa.config.json")))
|
|
176
|
+
.filter(
|
|
177
|
+
child => !options.requireGit || fs.existsSync(join(child.dir, ".git"))
|
|
178
|
+
)
|
|
168
179
|
.filter(child => !isLinkedWorktree(child.dir, fs))
|
|
169
180
|
.map(child => ({
|
|
170
181
|
name: child.name,
|
|
@@ -174,6 +185,33 @@ export function detectRepos(root, options = {}) {
|
|
|
174
185
|
return onePerRemote(children);
|
|
175
186
|
}
|
|
176
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Where setup looks for child repos, in order. `.` is the root itself, where
|
|
190
|
+
* only children with their own `.git` count.
|
|
191
|
+
*/
|
|
192
|
+
const LAYOUT_CANDIDATES = Object.freeze([
|
|
193
|
+
{ reposRoot: "projects", requireGit: false },
|
|
194
|
+
{ reposRoot: ".", requireGit: true },
|
|
195
|
+
]);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Find where a multi-repo project keeps its repos and which ones are routable.
|
|
199
|
+
* The first candidate that yields any repo wins: `projects/`, then the
|
|
200
|
+
* project root's direct children that are their own checkouts. A project
|
|
201
|
+
* where neither yields one is single-repo, reported with the default
|
|
202
|
+
* `projects` root and no repos.
|
|
203
|
+
* @param {string} root - Project root
|
|
204
|
+
* @param {{ fs?: Partial<typeof NODE_FS> }} [options] - Filesystem seam
|
|
205
|
+
* @returns {{ reposRoot: string, repos: string[] }} Repos root and names
|
|
206
|
+
*/
|
|
207
|
+
export function detectRepoLayout(root, options = {}) {
|
|
208
|
+
for (const { reposRoot, requireGit } of LAYOUT_CANDIDATES) {
|
|
209
|
+
const repos = detectRepos(root, { ...options, reposRoot, requireGit });
|
|
210
|
+
if (repos.length > 0) return { reposRoot, repos };
|
|
211
|
+
}
|
|
212
|
+
return { reposRoot: LAYOUT_CANDIDATES[0].reposRoot, repos: [] };
|
|
213
|
+
}
|
|
214
|
+
|
|
177
215
|
/**
|
|
178
216
|
* Draft routing hints for one child: its name, then a hint per well-known
|
|
179
217
|
* dependency in its `package.json`. Only a draft; setup asks the operator to
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-setup-session-manager
|
|
3
|
-
description: "Set up the local session manager for this project: writes the non-secret `sessionManager` block to `.lisa.config.json` (detecting a multi-repo `projects
|
|
3
|
+
description: "Set up the local session manager for this project: writes the non-secret `sessionManager` block to `.lisa.config.json` (detecting a multi-repo layout: repos under `projects/`, or directly under the project root), stores the project's own Telegram bot token outside the repo, checks the Telegram plugin is installed but not enabled at user scope, keeps the manager's state out of git, seeds the checked-in runbook, starts the manager in tmux, walks the operator through pairing, and finishes with doctor's session-manager check. Idempotent."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Write", "Skill", "AskUserQuestion"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -41,10 +41,12 @@ writes `$SM`, and pass `--project-root "$ROOT"` (the absolute project root) on e
|
|
|
41
41
|
## Step 2: Write the config block
|
|
42
42
|
|
|
43
43
|
1. Preview: `node "$SM/session-manager.mjs" init-config --project-root "$ROOT"`. It detects
|
|
44
|
-
`projects/*/.lisa.config.json
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
`projects/*/.lisa.config.json`, or, when `projects/` holds none, the root's own children that
|
|
45
|
+
have a `.lisa.config.json` and their own `.git` (written as `repos.root: "."`). It proposes
|
|
46
|
+
`name`, `interval`, `repos`, `capacity`, `stall` and a per-project `notify.stateDir`. Repo
|
|
47
|
+
detection leaves out linked worktrees and keeps one checkout per remote, so ticket worktrees and
|
|
48
|
+
second clones are not proposed. Show the block to the operator and ask whether any repo is
|
|
49
|
+
missing or should not be routed.
|
|
48
50
|
2. Write it: the same command with `--write`. It adds only non-secret fields and never overwrites an
|
|
49
51
|
existing block (`reason: "exists"` means keep it).
|
|
50
52
|
3. Each repo's `hints` are a draft: its name plus one per well-known dependency (`NestJS`, `Expo`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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": "4.
|
|
3
|
+
"version": "4.83.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"
|