@codyswann/lisa 2.24.0 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/.claude-plugin/marketplace.json +6 -0
  2. package/package.json +1 -1
  3. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  5. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  8. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  9. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  15. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  17. package/plugins/lisa-wiki/.claude-plugin/plugin.json +8 -0
  18. package/plugins/lisa-wiki/.codex-plugin/plugin.json +32 -0
  19. package/plugins/lisa-wiki/ci/lisa-wiki-validate.yml +32 -0
  20. package/plugins/lisa-wiki/commands/add-ingest.md +6 -0
  21. package/plugins/lisa-wiki/commands/add-role.md +6 -0
  22. package/plugins/lisa-wiki/commands/doctor.md +6 -0
  23. package/plugins/lisa-wiki/commands/ingest.md +6 -0
  24. package/plugins/lisa-wiki/commands/lint.md +6 -0
  25. package/plugins/lisa-wiki/commands/migrate.md +6 -0
  26. package/plugins/lisa-wiki/commands/onboard-me.md +6 -0
  27. package/plugins/lisa-wiki/commands/query.md +6 -0
  28. package/plugins/lisa-wiki/commands/setup.md +6 -0
  29. package/plugins/lisa-wiki/schema/lisa-wiki-config.schema.json +118 -0
  30. package/plugins/lisa-wiki/schema/wiki-structure.schema.json +51 -0
  31. package/plugins/lisa-wiki/scripts/_wiki-lib.mjs +185 -0
  32. package/plugins/lisa-wiki/scripts/diff-guard.mjs +116 -0
  33. package/plugins/lisa-wiki/scripts/ingest-git.mjs +189 -0
  34. package/plugins/lisa-wiki/scripts/ingest-memory.mjs +130 -0
  35. package/plugins/lisa-wiki/scripts/ingest-roles.mjs +85 -0
  36. package/plugins/lisa-wiki/scripts/ingest_slack_channel.py +329 -0
  37. package/plugins/lisa-wiki/scripts/lint-wiki.mjs +320 -0
  38. package/plugins/lisa-wiki/scripts/mcp-doctor.mjs +72 -0
  39. package/plugins/lisa-wiki/scripts/render-contract.mjs +107 -0
  40. package/plugins/lisa-wiki/scripts/rewrite-refs.mjs +144 -0
  41. package/plugins/lisa-wiki/scripts/slack_oauth_user.py +179 -0
  42. package/plugins/lisa-wiki/scripts/validate-config.mjs +232 -0
  43. package/plugins/lisa-wiki/scripts/verify-migration.mjs +199 -0
  44. package/plugins/lisa-wiki/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
  45. package/plugins/lisa-wiki/skills/lisa-wiki-add-role/SKILL.md +30 -0
  46. package/plugins/lisa-wiki/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
  47. package/plugins/lisa-wiki/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
  48. package/plugins/lisa-wiki/skills/lisa-wiki-connector-git/SKILL.md +25 -0
  49. package/plugins/lisa-wiki/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
  50. package/plugins/lisa-wiki/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
  51. package/plugins/lisa-wiki/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
  52. package/plugins/lisa-wiki/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
  53. package/plugins/lisa-wiki/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
  54. package/plugins/lisa-wiki/skills/lisa-wiki-connector-web/SKILL.md +23 -0
  55. package/plugins/lisa-wiki/skills/lisa-wiki-doctor/SKILL.md +47 -0
  56. package/plugins/lisa-wiki/skills/lisa-wiki-ingest/SKILL.md +43 -0
  57. package/plugins/lisa-wiki/skills/lisa-wiki-lint/SKILL.md +32 -0
  58. package/plugins/lisa-wiki/skills/lisa-wiki-migrate/SKILL.md +43 -0
  59. package/plugins/lisa-wiki/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
  60. package/plugins/lisa-wiki/skills/lisa-wiki-query/SKILL.md +30 -0
  61. package/plugins/lisa-wiki/skills/lisa-wiki-setup/SKILL.md +45 -0
  62. package/plugins/lisa-wiki/skills/lisa-wiki-usage/SKILL.md +50 -0
  63. package/plugins/lisa-wiki/templates/agents/role-agent.claude.md +16 -0
  64. package/plugins/lisa-wiki/templates/agents/role-agent.codex.toml +15 -0
  65. package/plugins/lisa-wiki/templates/index.md +17 -0
  66. package/plugins/lisa-wiki/templates/llm-wiki-contract.md +60 -0
  67. package/plugins/lisa-wiki/templates/log.md +8 -0
  68. package/plugins/lisa-wiki/templates/page-types/architecture.md +18 -0
  69. package/plugins/lisa-wiki/templates/page-types/concept.md +18 -0
  70. package/plugins/lisa-wiki/templates/page-types/decision.md +18 -0
  71. package/plugins/lisa-wiki/templates/page-types/entity.md +19 -0
  72. package/plugins/lisa-wiki/templates/page-types/open-question.md +18 -0
  73. package/plugins/lisa-wiki/templates/page-types/playbook.md +18 -0
  74. package/plugins/lisa-wiki/templates/page-types/project.md +19 -0
  75. package/plugins/lisa-wiki/templates/page-types/requirement.md +19 -0
  76. package/plugins/lisa-wiki/templates/page-types/staff.md +26 -0
  77. package/plugins/lisa-wiki/templates/start-here.md +24 -0
  78. package/plugins/lisa-wiki/templates/state-readme.md +20 -0
  79. package/plugins/src/wiki/.claude-plugin/plugin.json +6 -0
  80. package/plugins/src/wiki/ci/lisa-wiki-validate.yml +32 -0
  81. package/plugins/src/wiki/commands/add-ingest.md +6 -0
  82. package/plugins/src/wiki/commands/add-role.md +6 -0
  83. package/plugins/src/wiki/commands/doctor.md +6 -0
  84. package/plugins/src/wiki/commands/ingest.md +6 -0
  85. package/plugins/src/wiki/commands/lint.md +6 -0
  86. package/plugins/src/wiki/commands/migrate.md +6 -0
  87. package/plugins/src/wiki/commands/onboard-me.md +6 -0
  88. package/plugins/src/wiki/commands/query.md +6 -0
  89. package/plugins/src/wiki/commands/setup.md +6 -0
  90. package/plugins/src/wiki/schema/lisa-wiki-config.schema.json +118 -0
  91. package/plugins/src/wiki/schema/wiki-structure.schema.json +51 -0
  92. package/plugins/src/wiki/scripts/_wiki-lib.mjs +185 -0
  93. package/plugins/src/wiki/scripts/diff-guard.mjs +116 -0
  94. package/plugins/src/wiki/scripts/ingest-git.mjs +189 -0
  95. package/plugins/src/wiki/scripts/ingest-memory.mjs +130 -0
  96. package/plugins/src/wiki/scripts/ingest-roles.mjs +85 -0
  97. package/plugins/src/wiki/scripts/ingest_slack_channel.py +329 -0
  98. package/plugins/src/wiki/scripts/lint-wiki.mjs +320 -0
  99. package/plugins/src/wiki/scripts/mcp-doctor.mjs +72 -0
  100. package/plugins/src/wiki/scripts/render-contract.mjs +107 -0
  101. package/plugins/src/wiki/scripts/rewrite-refs.mjs +144 -0
  102. package/plugins/src/wiki/scripts/slack_oauth_user.py +179 -0
  103. package/plugins/src/wiki/scripts/validate-config.mjs +232 -0
  104. package/plugins/src/wiki/scripts/verify-migration.mjs +199 -0
  105. package/plugins/src/wiki/skills/lisa-wiki-add-ingest/SKILL.md +34 -0
  106. package/plugins/src/wiki/skills/lisa-wiki-add-role/SKILL.md +30 -0
  107. package/plugins/src/wiki/skills/lisa-wiki-connector-confluence/SKILL.md +25 -0
  108. package/plugins/src/wiki/skills/lisa-wiki-connector-docs/SKILL.md +30 -0
  109. package/plugins/src/wiki/skills/lisa-wiki-connector-git/SKILL.md +25 -0
  110. package/plugins/src/wiki/skills/lisa-wiki-connector-jira/SKILL.md +28 -0
  111. package/plugins/src/wiki/skills/lisa-wiki-connector-memory/SKILL.md +28 -0
  112. package/plugins/src/wiki/skills/lisa-wiki-connector-notion/SKILL.md +25 -0
  113. package/plugins/src/wiki/skills/lisa-wiki-connector-roles/SKILL.md +22 -0
  114. package/plugins/src/wiki/skills/lisa-wiki-connector-slack/SKILL.md +30 -0
  115. package/plugins/src/wiki/skills/lisa-wiki-connector-web/SKILL.md +23 -0
  116. package/plugins/src/wiki/skills/lisa-wiki-doctor/SKILL.md +47 -0
  117. package/plugins/src/wiki/skills/lisa-wiki-ingest/SKILL.md +43 -0
  118. package/plugins/src/wiki/skills/lisa-wiki-lint/SKILL.md +32 -0
  119. package/plugins/src/wiki/skills/lisa-wiki-migrate/SKILL.md +43 -0
  120. package/plugins/src/wiki/skills/lisa-wiki-onboard-me/SKILL.md +33 -0
  121. package/plugins/src/wiki/skills/lisa-wiki-query/SKILL.md +30 -0
  122. package/plugins/src/wiki/skills/lisa-wiki-setup/SKILL.md +45 -0
  123. package/plugins/src/wiki/skills/lisa-wiki-usage/SKILL.md +50 -0
  124. package/plugins/src/wiki/templates/agents/role-agent.claude.md +16 -0
  125. package/plugins/src/wiki/templates/agents/role-agent.codex.toml +15 -0
  126. package/plugins/src/wiki/templates/index.md +17 -0
  127. package/plugins/src/wiki/templates/llm-wiki-contract.md +60 -0
  128. package/plugins/src/wiki/templates/log.md +8 -0
  129. package/plugins/src/wiki/templates/page-types/architecture.md +18 -0
  130. package/plugins/src/wiki/templates/page-types/concept.md +18 -0
  131. package/plugins/src/wiki/templates/page-types/decision.md +18 -0
  132. package/plugins/src/wiki/templates/page-types/entity.md +19 -0
  133. package/plugins/src/wiki/templates/page-types/open-question.md +18 -0
  134. package/plugins/src/wiki/templates/page-types/playbook.md +18 -0
  135. package/plugins/src/wiki/templates/page-types/project.md +19 -0
  136. package/plugins/src/wiki/templates/page-types/requirement.md +19 -0
  137. package/plugins/src/wiki/templates/page-types/staff.md +26 -0
  138. package/plugins/src/wiki/templates/start-here.md +24 -0
  139. package/plugins/src/wiki/templates/state-readme.md +20 -0
  140. package/scripts/build-plugins.sh +29 -21
  141. package/scripts/check-plugins-sync.sh +1 -1
  142. package/scripts/generate-codex-plugin-artifacts.mjs +22 -0
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: playbook
3
+ created: {{date}}
4
+ updated: {{date}}
5
+ related: []
6
+ sources: []
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## When to use
12
+
13
+ ## Steps
14
+
15
+ ## Verification
16
+ <!-- How to confirm it worked -->
17
+
18
+ ## Pitfalls
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: project
3
+ created: {{date}}
4
+ updated: {{date}}
5
+ related: []
6
+ sources: []
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Repository
12
+ <!-- | Field | Value | : local path, remote, default branch, HEAD, status -->
13
+
14
+ ## Technology signals
15
+
16
+ ## Structure signals
17
+
18
+ ## Notes & evidence
19
+ <!-- Cite source notes, e.g. PR #/commit -->
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: requirement
3
+ created: {{date}}
4
+ updated: {{date}}
5
+ related: []
6
+ sources: []
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Summary
12
+
13
+ ## Acceptance criteria
14
+ <!-- Gherkin: Given / When / Then -->
15
+
16
+ ## Out of scope
17
+
18
+ ## Notes & evidence
19
+ <!-- Cite source notes -->
@@ -0,0 +1,26 @@
1
+ ---
2
+ type: staff
3
+ created: {{date}}
4
+ updated: {{date}}
5
+ related: []
6
+ sources: []
7
+ sensitivity: {{sensitivity}}
8
+ ---
9
+
10
+ # {{role}} ({{id}})
11
+
12
+ ## Role
13
+ <!-- Human or Agent; what this role is responsible for -->
14
+
15
+ ## Domain
16
+ Owned categories: {{ownedCategories}}
17
+ Owned connectors: {{ownedConnectors}}
18
+
19
+ ## Expertise
20
+ {{expertise}}
21
+
22
+ ## Reports to
23
+
24
+ ## Notes
25
+ <!-- The runnable subagent for this role lives at .claude/agents/{{id}}.md and .codex/agents/{{id}}.toml.
26
+ Whether it is ever invoked/scheduled is out of scope for the wiki. -->
@@ -0,0 +1,24 @@
1
+ # Start here — {{displayName}}
2
+
3
+ ## Purpose
4
+ {{purpose}}
5
+
6
+ ## What this is
7
+ A git-native LLM Wiki owned by **{{org}}** and maintained by the `lisa-wiki` kernel. It is the
8
+ durable home for this project's knowledge (and documentation). Raw sources are preserved under
9
+ `{{wikiRoot}}/sources/`; distilled knowledge lives in the category pages; the rules are in
10
+ `{{wikiRoot}}/schema/llm-wiki-contract.md`.
11
+
12
+ ## How to use it
13
+ - **New here?** Run `/onboard-me` (Codex: `$lisa-wiki-onboard-me`) for a guided tour + sample questions.
14
+ - **Find/answer something:** `/query "<question>"` — cited answers from the wiki.
15
+ - **Add knowledge:** `/ingest <url|file|prompt>` (Codex: `$lisa-wiki-ingest`), or `/ingest` with no
16
+ argument for a full ingest across all enabled non-external-write sources (external-write sources
17
+ require explicit intent).
18
+ - **Browse:** [index.md](index.md).
19
+ - **Check health:** `/lint`.
20
+
21
+ ## Map
22
+ Synthesis categories: {{categories}}.
23
+ Sources: `{{wikiRoot}}/sources/` · State: `{{wikiRoot}}/state/` · Contract:
24
+ `{{wikiRoot}}/schema/llm-wiki-contract.md` · Log: `{{wikiRoot}}/log.md`.
@@ -0,0 +1,20 @@
1
+ # state/ — ingestion cursors
2
+
3
+ JSON cursors that let ingestion resume incrementally — one file per source/connector at
4
+ `state/<system>/*.json`. A cursor is advanced **only after** its source notes + synthesis + index +
5
+ log + verification all pass (never before). Common envelope:
6
+
7
+ ```json
8
+ {
9
+ "connector": "git",
10
+ "profile": "default",
11
+ "lastSuccessfulRunAt": "1970-01-01T00:00:00Z",
12
+ "cursor": {},
13
+ "sourceNotes": [],
14
+ "synthesisPages": [],
15
+ "schemaVersion": "1.0.0"
16
+ }
17
+ ```
18
+
19
+ The post-migration / post-setup verification report is written to
20
+ `state/migration/doctor-report.json` by `/doctor`.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "lisa-wiki",
3
+ "version": "1.0.0",
4
+ "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
+ "author": { "name": "Cody Swann" }
6
+ }
@@ -0,0 +1,32 @@
1
+ # lisa-wiki validation — OPTIONAL. Installed into a project by `/setup --with-ci`.
2
+ #
3
+ # Runs the deterministic wiki validators on pull requests that touch the wiki.
4
+ # Node-only, no extra dependencies (the validators are dependency-free).
5
+ #
6
+ # LISA_WIKI_SCRIPTS must point at the installed plugin's scripts/ directory.
7
+ # `/setup --with-ci` wires this — either by resolving the installed plugin path or
8
+ # by vendoring the plugin's scripts/ into the repo (default below: .lisa-wiki/scripts).
9
+ name: 🧠 LLM Wiki Validate
10
+
11
+ on:
12
+ pull_request:
13
+ paths:
14
+ - 'wiki/**'
15
+ - '.lisa-wiki/**'
16
+
17
+ jobs:
18
+ validate:
19
+ runs-on: ubuntu-latest
20
+ env:
21
+ LISA_WIKI_SCRIPTS: ${{ vars.LISA_WIKI_SCRIPTS || '.lisa-wiki/scripts' }}
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: actions/setup-node@v4
25
+ with:
26
+ node-version: '22'
27
+
28
+ - name: Validate config
29
+ run: node "$LISA_WIKI_SCRIPTS/validate-config.mjs" wiki/lisa-wiki.config.json
30
+
31
+ - name: Lint wiki (strict — warnings block once the repo is at hard-enforcement)
32
+ run: node "$LISA_WIKI_SCRIPTS/lint-wiki.mjs" --wiki wiki --config wiki/lisa-wiki.config.json --strict
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Scaffold a project-specific front-door ingest skill that does something unique (classify a source, fetch from a special system, stamp domain frontmatter) and then chains into /ingest. Extends ingestion without forking the kernel."
3
+ argument-hint: "<short name for the new ingest path>"
4
+ ---
5
+
6
+ Use the lisa-wiki-add-ingest skill to generate a thin, registered front-door ingest skill: interview the project for the source type, bucket, frontmatter, and side-effect class; emit a lisa-wiki-local-<name> skill that enriches then chains into /ingest; and register it under customConnectors. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Scaffold a domain-expert digital-staff role over the wiki — a dual-runtime subagent (Claude + Codex) plus a staff doc page — from a config.staff[] entry. The plugin only sets the subagent up; running/scheduling it is out of scope."
3
+ argument-hint: "<role name, e.g. Legal | Finance | Sales>"
4
+ ---
5
+
6
+ Use the lisa-wiki-add-role skill to turn a role into a wiki/staff/<id>.md doc page and brain-pointed subagents on both runtimes (Claude .claude/agents/<id>.md + Codex .codex/agents/<id>.toml), pointed at the role's owned wiki domain. Setup-only — invocation/scheduling/routing is out of scope. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Verify that the wiki is correctly set up and (after migration) fully functional. Runs deterministic checks plus functional smoke tests, writes a doctor report, and returns an overall verdict (READY / READY_WITH_WARNINGS / NOT_READY). The final gate of /migrate; re-runnable anytime."
3
+ argument-hint: "[--migration]"
4
+ ---
5
+
6
+ Use the lisa-wiki-doctor skill to run the post-migration/post-setup verification checklist: structure & config, integrity & safety, no-loss/parity, runtime surfaces on both runtimes, functional smoke tests (no extra PR), mode-specific, and git/CI/distribution. Write wiki/state/migration/doctor-report.json and report the verdict + blocking items. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Ingest source material into the LLM Wiki. With an argument (URL, file path, or prompt) ingest that one source; with no argument run a full ingest across every enabled non-external-write source. Routes to the right connector and runs the ordered pipeline (source note → synthesis → index → log → verify → state → commit/PR)."
3
+ argument-hint: "[url | file path | prompt] (omit for a full ingest)"
4
+ ---
5
+
6
+ Use the lisa-wiki-ingest skill to ingest into the wiki: route the input to the right connector (or, with no argument, run a full ingest across all enabled non-external-write sources), then run the ordered pipeline — sanitized source note, synthesis with citations, index, log, verification, and state advancement, then commit/PR per policy. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Health-check the LLM Wiki: orphan pages, contradictions, stale claims, broken internal links, missing index/log coverage, structure violations, and secret/tenant leaks. Read-only — reports findings, does not fix them."
3
+ argument-hint: ""
4
+ ---
5
+
6
+ Use the lisa-wiki-lint skill to run the wiki's integrity checks and report findings by severity (PASS/WARN/FAIL). It diagnoses only — fixes go through /ingest, /setup, or /migrate. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Migrate an existing hand-rolled wiki onto the lisa-wiki kernel — phased and compatibility-first, with a strict no-loss guarantee (renaming is fine; losing functionality or data is not). Ends by running /doctor."
3
+ argument-hint: "[--phase <0|1|1b|2|3|4|5>]"
4
+ ---
5
+
6
+ Use the lisa-wiki-migrate skill to move this repo's bespoke wiki onto the kernel in reviewable phases: inventory, adopt kernel, absorb documentation, consolidate runtime + connectors, normalize by touch, then hard-enforce — parity-checking each migrated artifact before deleting the old one, and finishing with /doctor. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Onboard a user to the project via its LLM Wiki: interview them about themselves in relation to the project, then give a guided tour and sample questions. Read-mostly by default (session-local); --save-memory persists the capture to project-scoped memory only. No PRs, no PII written into the wiki, never global memory."
3
+ argument-hint: "[--save-memory] [--write-audience-note]"
4
+ ---
5
+
6
+ Use the lisa-wiki-onboard-me skill to onboard the user: briefly interview their role and goals (read-mostly, session-local by default; with --save-memory persist to project-scoped memory only — never global memory, never PII into the wiki), then summarize what the project is, show the folder map, and offer sample /query prompts tuned to their role. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Answer a question from the LLM Wiki with citations. Reads the index, drills into relevant pages, and synthesizes a cited answer. Read-only by default; files new synthesis back only when explicitly asked."
3
+ argument-hint: "<question>"
4
+ ---
5
+
6
+ Use the lisa-wiki-query skill to answer from the wiki with citations: locate relevant pages via the index, synthesize a cited answer, and say plainly when the wiki cannot support an answer. Read-only unless the user explicitly asks to persist new synthesis. $ARGUMENTS
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Scaffold, repair, verify, or upgrade the project's LLM Wiki from its config. Asks the wiki's purpose and README mode, renders the contract snapshot, scaffolds the canonical folders, and seeds the staff roster. Idempotent and non-destructive."
3
+ argument-hint: "[--upgrade] [--with-ci]"
4
+ ---
5
+
6
+ Use the lisa-wiki-setup skill to bring the wiki into conformance from wiki/lisa-wiki.config.json: validate config, ask purpose + README mode, scaffold the canonical structure, render the contract snapshot (stamping kernelVersion), seed the staff roster, then verify with /doctor. $ARGUMENTS
@@ -0,0 +1,118 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://codyswann.github.io/lisa/schema/lisa-wiki-config.schema.json",
4
+ "title": "lisa-wiki project config",
5
+ "description": "Per-project behavioral config for the lisa-wiki plugin. Lives at wiki/lisa-wiki.config.json. The plugin's validate-config script enforces these constraints dependency-free; this schema is the authoritative spec and powers editor tooling.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": ["schemaVersion", "org", "mode", "wikiRoot", "categories"],
9
+ "properties": {
10
+ "schemaVersion": { "type": "string", "description": "Config schema version (semver)." },
11
+ "org": { "type": "string", "description": "Owning organization / project name." },
12
+ "displayName": { "type": "string", "description": "Human-facing wiki name." },
13
+ "purpose": { "type": "string", "description": "One paragraph: what this wiki is for. Asked by /setup; rendered into the contract + start-here; feeds /onboard-me." },
14
+ "mode": { "enum": ["embedded", "wrapper", "standalone", "subdir"], "description": "Repository model." },
15
+ "wikiRoot": { "type": "string", "default": "wiki", "description": "Path to the wiki root, relative to repo root." },
16
+ "frontmatter": { "type": "boolean", "default": true, "description": "Whether new/touched pages require YAML frontmatter." },
17
+ "categories": { "type": "array", "items": { "type": "string" }, "minItems": 1, "description": "Synthesis category directories." },
18
+ "sources": {
19
+ "type": "object",
20
+ "additionalProperties": true,
21
+ "properties": {
22
+ "layout": { "enum": ["by-system", "by-category"], "default": "by-system" },
23
+ "buckets": { "type": "array", "items": { "type": "string" } }
24
+ }
25
+ },
26
+ "git": {
27
+ "type": "object",
28
+ "additionalProperties": true,
29
+ "properties": {
30
+ "prPerIngestion": { "type": "boolean" },
31
+ "autoMerge": { "type": "boolean" },
32
+ "targetBranch": { "type": "string" },
33
+ "branchPrefix": { "type": "string" }
34
+ }
35
+ },
36
+ "sensitivity": {
37
+ "type": "object",
38
+ "additionalProperties": true,
39
+ "properties": {
40
+ "enabled": { "type": "boolean" },
41
+ "default": { "enum": ["public", "internal", "confidential", "restricted"] }
42
+ }
43
+ },
44
+ "sourceRetention": { "enum": ["raw-ok", "sanitized-note-only", "metadata-only", "external-pointer-only"] },
45
+ "readme": {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "properties": { "mode": { "enum": ["rich", "stub", "preserve"], "default": "rich" } }
49
+ },
50
+ "documentation": {
51
+ "type": "object",
52
+ "additionalProperties": true,
53
+ "properties": {
54
+ "absorb": { "type": "boolean", "default": true },
55
+ "keepInPlace": { "type": "array", "items": { "type": "string" } }
56
+ }
57
+ },
58
+ "onboarding": {
59
+ "type": "object",
60
+ "additionalProperties": true,
61
+ "properties": { "allowAudienceNote": { "type": "boolean", "default": false } }
62
+ },
63
+ "connectors": {
64
+ "type": "object",
65
+ "description": "Map of connector name -> connector config.",
66
+ "additionalProperties": {
67
+ "type": "object",
68
+ "additionalProperties": true,
69
+ "required": ["sideEffects"],
70
+ "properties": {
71
+ "enabled": { "type": "boolean" },
72
+ "sideEffects": { "enum": ["read-only-ingest", "repo-write", "external-write"] }
73
+ }
74
+ }
75
+ },
76
+ "customConnectors": {
77
+ "type": "array",
78
+ "description": "Explicit allowlist of project-authored front-door ingest skills (generated by /add-ingest). No auto-discovery.",
79
+ "items": {
80
+ "type": "object",
81
+ "additionalProperties": true,
82
+ "required": ["name", "skill", "sourceSystem", "sideEffects"],
83
+ "properties": {
84
+ "name": { "type": "string" },
85
+ "skill": { "type": "string" },
86
+ "sourceSystem": { "type": "string" },
87
+ "stateFile": { "type": "string" },
88
+ "sideEffects": { "enum": ["read-only-ingest", "repo-write", "external-write"] }
89
+ }
90
+ }
91
+ },
92
+ "staff": {
93
+ "type": "array",
94
+ "description": "Digital-staff roles. Each generates a wiki/staff/<id>.md doc page + dual-runtime subagents.",
95
+ "items": {
96
+ "type": "object",
97
+ "additionalProperties": true,
98
+ "required": ["id", "role"],
99
+ "properties": {
100
+ "id": { "type": "string" },
101
+ "role": { "type": "string" },
102
+ "expertise": { "type": "string" },
103
+ "owns": {
104
+ "type": "object",
105
+ "additionalProperties": true,
106
+ "properties": {
107
+ "categories": { "type": "array", "items": { "type": "string" } },
108
+ "connectors": { "type": "array", "items": { "type": "string" } },
109
+ "skills": { "type": "array", "items": { "type": "string" } }
110
+ }
111
+ },
112
+ "sensitivity": { "enum": ["public", "internal", "confidential", "restricted"] }
113
+ }
114
+ }
115
+ },
116
+ "contaminationTerms": { "type": "array", "items": { "type": "string" }, "description": "Cross-tenant terms scanned for before every commit." }
117
+ }
118
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://codyswann.github.io/lisa/schema/wiki-structure.schema.json",
4
+ "title": "lisa-wiki canonical structure manifest",
5
+ "description": "The canonical folder structure of a lisa-wiki. This manifest is the intended single source of truth for structure conformance, consumed by lint-wiki and validate-config as of M1 (structure enforcement) and by render-contract; in M0 it is the published spec. All paths are relative to config.wikiRoot unless noted. It is a descriptive manifest (not a JSON-Schema validation of a document); validators interpret these fields.",
6
+ "manifestVersion": "1.0.0",
7
+ "requiredFiles": [
8
+ "lisa-wiki.config.json",
9
+ "index.md",
10
+ "log.md",
11
+ "start-here.md",
12
+ "schema/llm-wiki-contract.md"
13
+ ],
14
+ "requiredDirs": ["schema", "sources", "state"],
15
+ "optionalDirs": ["staff", "documentation"],
16
+ "categoryDirs": {
17
+ "default": [
18
+ "concepts",
19
+ "entities",
20
+ "decisions",
21
+ "architecture",
22
+ "requirements",
23
+ "playbooks",
24
+ "open-questions",
25
+ "projects"
26
+ ],
27
+ "note": "A project may declare additional categories in config.categories (e.g. claims, comparisons, finance, sales)."
28
+ },
29
+ "sourcesLayout": {
30
+ "by-system": "sources/<system>/ (e.g. sources/jira/, sources/git/, sources/slack/)",
31
+ "by-category": "sources/<bucket>/ (e.g. sources/primary/, sources/secondary/)"
32
+ },
33
+ "stateLayout": "state/<system>/*.json",
34
+ "reportPath": "state/migration/doctor-report.json",
35
+ "generatedArtifacts": {
36
+ "claudeRoleAgents": ".claude/agents/<id>.md (repo root, not under wikiRoot)",
37
+ "codexRoleAgents": ".codex/agents/<id>.toml (repo root, not under wikiRoot)",
38
+ "frontDoorSkills": ".claude|.agents/skills/lisa-wiki-local-*"
39
+ },
40
+ "keepInPlaceDefault": [
41
+ "LICENSE*",
42
+ "SECURITY.md",
43
+ "CODE_OF_CONDUCT.md",
44
+ "CONTRIBUTING.md",
45
+ "CHANGELOG.md",
46
+ "NOTICE*",
47
+ "SUPPORT.md",
48
+ "GOVERNANCE.md",
49
+ ".github/**"
50
+ ]
51
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * _wiki-lib.mjs — shared, dependency-free helpers for the lisa-wiki validators
3
+ * (lint-wiki, diff-guard, rewrite-refs, verify-migration). Node built-ins only,
4
+ * so the scripts stay portable to any downstream repo that installs the plugin.
5
+ */
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+
9
+ /** Read and parse a JSON file, or return undefined if missing/invalid. */
10
+ export function readJsonSafe(file) {
11
+ try {
12
+ return JSON.parse(fs.readFileSync(file, "utf8"));
13
+ } catch {
14
+ return undefined;
15
+ }
16
+ }
17
+
18
+ /** Resolve the plugin root from a script in scripts/ (parent of scripts/). */
19
+ export function pluginRootFrom(scriptDir) {
20
+ return path.dirname(scriptDir);
21
+ }
22
+
23
+ /** Load the project config (wiki/lisa-wiki.config.json by default). */
24
+ export function loadConfig(configPath) {
25
+ const resolved = path.resolve(configPath ?? "wiki/lisa-wiki.config.json");
26
+ const config = readJsonSafe(resolved);
27
+ return { config, configPath: resolved };
28
+ }
29
+
30
+ /** Load the canonical structure manifest shipped with the plugin. */
31
+ export function loadStructure(pluginRoot) {
32
+ return readJsonSafe(
33
+ path.join(pluginRoot, "schema", "wiki-structure.schema.json")
34
+ );
35
+ }
36
+
37
+ /** Recursively list files under dir matching an optional extension filter. */
38
+ export function walkFiles(dir, { ext } = {}) {
39
+ const out = [];
40
+ const stack = [dir];
41
+ while (stack.length > 0) {
42
+ const current = stack.pop();
43
+ let entries = [];
44
+ try {
45
+ entries = fs.readdirSync(current, { withFileTypes: true });
46
+ } catch {
47
+ continue;
48
+ }
49
+ for (const entry of entries) {
50
+ const full = path.join(current, entry.name);
51
+ if (entry.isDirectory()) {
52
+ if (entry.name === ".git" || entry.name === "node_modules") continue;
53
+ stack.push(full);
54
+ } else if (entry.isFile()) {
55
+ if (!ext || full.endsWith(ext)) out.push(full);
56
+ }
57
+ }
58
+ }
59
+ return out.sort();
60
+ }
61
+
62
+ /**
63
+ * Minimal frontmatter detector. Returns whether a leading `--- ... ---` block
64
+ * exists and the top-level keys it declares (enough to check required fields;
65
+ * NOT a full YAML parser).
66
+ */
67
+ export function parseFrontmatter(text) {
68
+ const lines = text.split("\n");
69
+ if (lines[0].trim() !== "---") return { has: false, keys: [], body: text };
70
+ let closeIdx = -1;
71
+ for (let i = 1; i < lines.length; i += 1) {
72
+ if (lines[i].trim() === "---") {
73
+ closeIdx = i;
74
+ break;
75
+ }
76
+ }
77
+ if (closeIdx === -1) return { has: false, keys: [], body: text };
78
+ const keys = [];
79
+ for (let i = 1; i < closeIdx; i += 1) {
80
+ const m = lines[i].match(/^([A-Za-z][\w-]*):/);
81
+ if (m) keys.push(m[1]);
82
+ }
83
+ const body = lines.slice(closeIdx + 1).join("\n");
84
+ return { has: true, keys, body };
85
+ }
86
+
87
+ /**
88
+ * Extract internal markdown link targets ([txt](target)) — excludes external
89
+ * (http/https/mailto), anchors, and template tokens. Anchors are stripped.
90
+ */
91
+ export function extractMarkdownLinks(text) {
92
+ const targets = [];
93
+ const re = /\[[^\]]*\]\(([^)]+)\)/g;
94
+ let m;
95
+ while ((m = re.exec(text)) !== null) {
96
+ let target = m[1].trim();
97
+ if (!target || target.startsWith("#")) continue;
98
+ if (target.includes("{{") || target.includes("<") || target.includes(">"))
99
+ continue; // template token / placeholder / angle-bracket autolink
100
+ target = target.split(/\s+/)[0]; // drop optional link title: (url "title")
101
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(target) || target.startsWith("mailto:"))
102
+ continue;
103
+ target = target.split("#")[0].trim();
104
+ if (target) targets.push(target);
105
+ }
106
+ return targets;
107
+ }
108
+
109
+ /** Extract plain-text `Source: <path>.md` citations that look like wiki paths. */
110
+ export function extractCitations(text) {
111
+ const cites = [];
112
+ const re = /Source:\s*([^\s)]+\.md)/g;
113
+ let m;
114
+ while ((m = re.exec(text)) !== null) {
115
+ const c = m[1];
116
+ if (c.includes("{{") || c.includes("<") || c.includes(">")) continue; // template token / placeholder example
117
+ cites.push(c);
118
+ }
119
+ return cites;
120
+ }
121
+
122
+ /** Convert a tiny glob (supporting ** and *) to a RegExp anchored full-match. */
123
+ export function globToRegExp(glob) {
124
+ let re = "^";
125
+ for (let i = 0; i < glob.length; i += 1) {
126
+ const c = glob[i];
127
+ if (c === "*") {
128
+ if (glob[i + 1] === "*") {
129
+ re += ".*";
130
+ i += 1;
131
+ if (glob[i + 1] === "/") i += 1; // consume trailing slash of **/
132
+ } else {
133
+ re += "[^/]*";
134
+ }
135
+ } else if ("\\^$+?.()|[]{}".includes(c)) {
136
+ re += `\\${c}`;
137
+ } else {
138
+ re += c;
139
+ }
140
+ }
141
+ re += "$";
142
+ return new RegExp(re);
143
+ }
144
+
145
+ /** Secret-detection patterns (kept minimal + high-signal). */
146
+ export const SECRET_PATTERNS = [
147
+ { name: "Slack token", re: /xox[pbar]-[A-Za-z0-9-]{10,}/ },
148
+ { name: "AWS access key", re: /AKIA[0-9A-Z]{16}/ },
149
+ {
150
+ name: "private key header",
151
+ re: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/,
152
+ },
153
+ { name: "bearer token", re: /bearer\s+[A-Za-z0-9._-]{20,}/i },
154
+ {
155
+ name: "client secret assignment",
156
+ re: /client_secret["'\s:=]+[A-Za-z0-9._-]{16,}/i,
157
+ },
158
+ ];
159
+
160
+ /** Text-ish file extensions allowed inside a wiki (others flagged as binaries). */
161
+ export const TEXT_EXTS = new Set([
162
+ ".md",
163
+ ".mdx",
164
+ ".json",
165
+ ".jsonl",
166
+ ".txt",
167
+ ".yml",
168
+ ".yaml",
169
+ ".toml",
170
+ ".csv",
171
+ ".tsv",
172
+ ".svg",
173
+ ".gitkeep",
174
+ ]);
175
+
176
+ /** Severity-tagged result accumulator. */
177
+ export function makeReport() {
178
+ const items = [];
179
+ return {
180
+ add(group, id, status, message, file) {
181
+ items.push({ group, id, status, message, ...(file ? { file } : {}) });
182
+ },
183
+ items,
184
+ };
185
+ }