first-tree 0.0.2 → 0.0.4
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/README.md +116 -40
- package/dist/cli.js +46 -17
- package/dist/help-Dtdj91HJ.js +25 -0
- package/dist/init--VepFe6N.js +403 -0
- package/dist/installer-cH7N4RNj.js +47 -0
- package/dist/onboarding-C9cYSE6F.js +2 -0
- package/dist/onboarding-CPP8fF4D.js +10 -0
- package/dist/repo-DY57bMqr.js +318 -0
- package/dist/upgrade-Cgx_K2HM.js +135 -0
- package/dist/{verify-CSRIkuoM.js → verify-mC9ZTd1f.js} +118 -29
- package/package.json +33 -10
- package/skills/first-tree/SKILL.md +113 -0
- package/skills/first-tree/agents/openai.yaml +4 -0
- package/skills/first-tree/assets/framework/VERSION +1 -0
- package/skills/first-tree/assets/framework/examples/claude-code/README.md +14 -0
- package/skills/first-tree/assets/framework/examples/claude-code/settings.json +14 -0
- package/skills/first-tree/assets/framework/helpers/generate-codeowners.ts +224 -0
- package/skills/first-tree/assets/framework/helpers/inject-tree-context.sh +15 -0
- package/skills/first-tree/assets/framework/helpers/run-review.ts +193 -0
- package/skills/first-tree/assets/framework/manifest.json +11 -0
- package/skills/first-tree/assets/framework/prompts/pr-review.md +38 -0
- package/skills/first-tree/assets/framework/templates/agents.md.template +49 -0
- package/skills/first-tree/assets/framework/templates/member-node.md.template +18 -0
- package/skills/first-tree/assets/framework/templates/members-domain.md.template +45 -0
- package/skills/first-tree/assets/framework/templates/root-node.md.template +41 -0
- package/skills/first-tree/assets/framework/workflows/codeowners.yml +31 -0
- package/skills/first-tree/assets/framework/workflows/pr-review.yml +146 -0
- package/skills/first-tree/assets/framework/workflows/validate.yml +19 -0
- package/skills/first-tree/engine/commands/help.ts +32 -0
- package/skills/first-tree/engine/commands/init.ts +1 -0
- package/skills/first-tree/engine/commands/upgrade.ts +1 -0
- package/skills/first-tree/engine/commands/verify.ts +1 -0
- package/skills/first-tree/engine/init.ts +414 -0
- package/skills/first-tree/engine/onboarding.ts +10 -0
- package/skills/first-tree/engine/repo.ts +360 -0
- package/skills/first-tree/engine/rules/agent-instructions.ts +59 -0
- package/skills/first-tree/engine/rules/agent-integration.ts +19 -0
- package/skills/first-tree/engine/rules/ci-validation.ts +72 -0
- package/skills/first-tree/engine/rules/framework.ts +13 -0
- package/skills/first-tree/engine/rules/index.ts +41 -0
- package/skills/first-tree/engine/rules/members.ts +21 -0
- package/skills/first-tree/engine/rules/populate-tree.ts +36 -0
- package/skills/first-tree/engine/rules/root-node.ts +41 -0
- package/skills/first-tree/engine/runtime/adapters.ts +22 -0
- package/skills/first-tree/engine/runtime/asset-loader.ts +141 -0
- package/skills/first-tree/engine/runtime/installer.ts +82 -0
- package/skills/first-tree/engine/runtime/upgrader.ts +23 -0
- package/skills/first-tree/engine/upgrade.ts +233 -0
- package/skills/first-tree/engine/validators/members.ts +215 -0
- package/skills/first-tree/engine/validators/nodes.ts +559 -0
- package/skills/first-tree/engine/verify.ts +155 -0
- package/skills/first-tree/references/about.md +36 -0
- package/skills/first-tree/references/maintainer-architecture.md +59 -0
- package/skills/first-tree/references/maintainer-build-and-distribution.md +59 -0
- package/skills/first-tree/references/maintainer-testing.md +58 -0
- package/skills/first-tree/references/maintainer-thin-cli.md +38 -0
- package/skills/first-tree/references/onboarding.md +185 -0
- package/skills/first-tree/references/ownership-and-naming.md +94 -0
- package/skills/first-tree/references/principles.md +113 -0
- package/skills/first-tree/references/source-map.md +94 -0
- package/skills/first-tree/references/upgrade-contract.md +94 -0
- package/skills/first-tree/scripts/check-skill-sync.sh +133 -0
- package/skills/first-tree/scripts/quick_validate.py +95 -0
- package/skills/first-tree/scripts/run-local-cli.sh +35 -0
- package/skills/first-tree/tests/asset-loader.test.ts +75 -0
- package/skills/first-tree/tests/generate-codeowners.test.ts +94 -0
- package/skills/first-tree/tests/helpers.ts +169 -0
- package/skills/first-tree/tests/init.test.ts +250 -0
- package/skills/first-tree/tests/repo.test.ts +440 -0
- package/skills/first-tree/tests/rules.test.ts +413 -0
- package/skills/first-tree/tests/run-review.test.ts +155 -0
- package/skills/first-tree/tests/skill-artifacts.test.ts +311 -0
- package/skills/first-tree/tests/thin-cli.test.ts +104 -0
- package/skills/first-tree/tests/upgrade.test.ts +103 -0
- package/skills/first-tree/tests/validate-members.test.ts +224 -0
- package/skills/first-tree/tests/validate-nodes.test.ts +198 -0
- package/skills/first-tree/tests/verify.test.ts +241 -0
- package/dist/init-CE_944sb.js +0 -283
- package/dist/repo-BByc3VvM.js +0 -111
- package/dist/upgrade-Chr7z0CY.js +0 -82
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
You are a code reviewer for the context tree.
|
|
2
|
+
|
|
3
|
+
Read the NODE.md of every domain touched by the PR.
|
|
4
|
+
Read the leaf nodes in affected domains to check for conflicts or redundancy.
|
|
5
|
+
Follow soft_links to check for conflicts with related domains.
|
|
6
|
+
|
|
7
|
+
Check for:
|
|
8
|
+
1. Tree structure conventions (NODE.md in folders, frontmatter with title/owners)
|
|
9
|
+
2. Ownership — are the right owners declared?
|
|
10
|
+
3. Principles compliance — design in tree, execution in code
|
|
11
|
+
4. Soft links for cross-domain dependencies
|
|
12
|
+
5. Consistency with existing nodes
|
|
13
|
+
6. Clarity for agent consumption
|
|
14
|
+
|
|
15
|
+
After reading the relevant tree files, output your review as a single JSON object in EXACTLY this schema:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"verdict": "APPROVE" | "REQUEST_CHANGES" | "COMMENT",
|
|
20
|
+
"summary": "<1-3 sentence overall assessment>",
|
|
21
|
+
"inline_comments": [
|
|
22
|
+
{
|
|
23
|
+
"file": "<path>",
|
|
24
|
+
"line": <number>,
|
|
25
|
+
"comment": "<comment text>"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `verdict` (required): one of `APPROVE`, `REQUEST_CHANGES`, or `COMMENT`.
|
|
32
|
+
- `summary` (optional): concise overall assessment.
|
|
33
|
+
- `inline_comments` (optional): omit the field entirely if there are none.
|
|
34
|
+
|
|
35
|
+
Rules:
|
|
36
|
+
- Output ONLY the JSON object, no other text.
|
|
37
|
+
- CRITICAL: The `line` number MUST be a line that appears in the diff (a changed or added line). GitHub only allows inline comments on lines that are part of the diff. Do NOT comment on unchanged lines — if you need to reference an unchanged line, include it in the `summary` instead.
|
|
38
|
+
- Only flag real problems in inline comments. Do NOT post positive feedback, praise, or "looks good" comments on individual lines. Do NOT suggest tiny wording improvements or stylistic nitpicks. If a change is correct, say nothing about it — silence means approval.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!-- BEGIN CONTEXT-TREE FRAMEWORK — do not edit this section -->
|
|
2
|
+
# Agent Instructions for Context Tree
|
|
3
|
+
|
|
4
|
+
You are working in a **Context Tree** — the living source of truth for decisions across the organization. Read and follow this before doing anything.
|
|
5
|
+
|
|
6
|
+
## Principles
|
|
7
|
+
|
|
8
|
+
1. **Source of truth for decisions, not execution.** The tree captures the *what* and *why* — strategic choices, cross-domain relationships, constraints. Execution details stay in source systems. If an agent needs this information to *decide* on an approach, it belongs in the tree. If the agent only needs it to *execute*, it stays in the source system.
|
|
9
|
+
|
|
10
|
+
2. **Agents are first-class participants.** The tree is designed to be navigated and updated by agents, not just humans. Domains are organized by concern — what an agent needs to know to act — not by repo, team, or org chart.
|
|
11
|
+
|
|
12
|
+
3. **Transparency by default.** All information is readable by everyone. Writing requires owner approval; reading is open.
|
|
13
|
+
|
|
14
|
+
4. **Git-native tree structure.** Each node is a file; each domain is a directory. Soft links allow cross-references without the complexity of a full graph. History, ownership, and review follow Git conventions.
|
|
15
|
+
|
|
16
|
+
See `skills/first-tree/references/principles.md` for detailed explanations and examples.
|
|
17
|
+
|
|
18
|
+
## Before Every Task
|
|
19
|
+
|
|
20
|
+
1. **Read the root NODE.md** to understand the domain map.
|
|
21
|
+
2. **Read the NODE.md of every domain relevant to your task.** If unsure which domains are relevant, start from root and follow the structure — it's organized by concern, not by repo.
|
|
22
|
+
3. **Follow soft_links.** If a node declares `soft_links` in its frontmatter, read those linked nodes too. They exist because the domains are related.
|
|
23
|
+
4. **Read leaf nodes that match your task.** NODE.md tells you what exists in each domain — scan it and read the leaves that are relevant.
|
|
24
|
+
|
|
25
|
+
Do not skip this. The tree is already a compression of expensive knowledge — cross-domain relationships, strategic decisions, constraints. An agent that skips the tree will produce decisions that conflict with existing ones.
|
|
26
|
+
|
|
27
|
+
## During the Task
|
|
28
|
+
|
|
29
|
+
- **Decide in the tree, execute in source systems.** If the task involves a decision (not just a bug fix), draft or update the relevant tree node before executing.
|
|
30
|
+
- **The tree is not for execution details.** Function signatures, DB schemas, API endpoints, ad copy — those live in source systems. The tree captures the *why* and *how things connect*.
|
|
31
|
+
- **Bring source repos in as additional working directories.** When you need to inspect or edit code, open the relevant source repositories alongside this tree instead of copying execution detail into the tree.
|
|
32
|
+
- **Respect ownership.** Each node declares owners in its frontmatter. If your changes touch a domain you don't own, flag it — the owner needs to review.
|
|
33
|
+
|
|
34
|
+
## After Every Task
|
|
35
|
+
|
|
36
|
+
Ask yourself: **Does the tree need updating?**
|
|
37
|
+
|
|
38
|
+
- Did you discover something the tree didn't capture? (A cross-domain dependency, a new constraint, a decision that future agents would need.)
|
|
39
|
+
- Did you find the tree was wrong or outdated? That's a tree bug — fix it.
|
|
40
|
+
- Not every task changes the tree, but the question must always be asked.
|
|
41
|
+
|
|
42
|
+
## Reference
|
|
43
|
+
|
|
44
|
+
For ownership rules, tree structure, and key files, see [NODE.md](NODE.md) and `skills/first-tree/references/ownership-and-naming.md`.
|
|
45
|
+
<!-- END CONTEXT-TREE FRAMEWORK -->
|
|
46
|
+
|
|
47
|
+
# Project-Specific Instructions
|
|
48
|
+
|
|
49
|
+
<!-- Add your project-specific agent instructions below this line. -->
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "<Display Name>"
|
|
3
|
+
owners: [<github-username>]
|
|
4
|
+
type: "<human | personal_assistant | autonomous_agent>"
|
|
5
|
+
role: "<role title>"
|
|
6
|
+
domains:
|
|
7
|
+
- "<domain>"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# <Display Name>
|
|
11
|
+
|
|
12
|
+
## About
|
|
13
|
+
|
|
14
|
+
<!-- Who you are and what you bring to the team. -->
|
|
15
|
+
|
|
16
|
+
## Current Focus
|
|
17
|
+
|
|
18
|
+
<!-- What you're actively working on. -->
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Members
|
|
3
|
+
owners: []
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Members
|
|
7
|
+
|
|
8
|
+
Member definitions, work scope, and personal node specifications.
|
|
9
|
+
|
|
10
|
+
Members are **humans and AI agents**. Both are first-class participants in the organization — they own nodes, make decisions, and collaborate through the tree.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Joining
|
|
15
|
+
|
|
16
|
+
1. Create a personal directory under `members/` with a `NODE.md` (e.g., `members/alice/NODE.md`)
|
|
17
|
+
2. Follow the required personal node format — CI will reject PRs with missing fields
|
|
18
|
+
3. Be assigned as owner of relevant domain nodes
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Personal Node Format
|
|
23
|
+
|
|
24
|
+
Each member is a **directory** under `members/` containing a `NODE.md`. Required frontmatter fields:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
---
|
|
28
|
+
title: "<display name>"
|
|
29
|
+
owners: [<github-username>]
|
|
30
|
+
type: "<human | personal_assistant | autonomous_agent>"
|
|
31
|
+
role: "<role in the organization>"
|
|
32
|
+
domains:
|
|
33
|
+
- "<high-level domain or direction>"
|
|
34
|
+
---
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
See `skills/first-tree/assets/framework/templates/member-node.md.template` for a full scaffold.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Principles
|
|
42
|
+
|
|
43
|
+
**Keep your node fresh.** Your personal node is how other members understand you. Stale information leads to poor decisions.
|
|
44
|
+
|
|
45
|
+
**Trust the tree.** Communicate through the tree, not around it.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "<Your Organization>"
|
|
3
|
+
owners: [<your-github-username>]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# <Your Organization>
|
|
7
|
+
|
|
8
|
+
<!-- PLACEHOLDER: Replace this with a description of your organization and what this tree captures across your source repos and systems. -->
|
|
9
|
+
|
|
10
|
+
The living source of truth for your organization. A structured knowledge base that agents and humans build and maintain together across one or more source repositories and systems.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Domains
|
|
15
|
+
|
|
16
|
+
<!-- Add your domains here. Each domain is a top-level directory with a NODE.md.
|
|
17
|
+
Organize by concern — what an agent needs to know to act — not by repo or team.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
- **[engineering/](engineering/NODE.md)** — Backend, frontend, infrastructure decisions.
|
|
21
|
+
- **[product/](product/NODE.md)** — Product strategy, roadmap, user research.
|
|
22
|
+
- **[marketing/](marketing/NODE.md)** — Brand, positioning, campaigns.
|
|
23
|
+
- **[members/](members/NODE.md)** — Team member definitions and responsibilities.
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
- **[members/](members/NODE.md)** — Team member definitions and responsibilities.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Working with the Tree
|
|
31
|
+
|
|
32
|
+
Keep decision context here. Keep implementation detail in the source repos this
|
|
33
|
+
tree describes.
|
|
34
|
+
|
|
35
|
+
See [AGENTS.md](AGENTS.md) for agent instructions — the before/during/after workflow, ownership model, and tree maintenance.
|
|
36
|
+
|
|
37
|
+
See [about.md](skills/first-tree/references/about.md) for background — the problem, the idea, and who it's for.
|
|
38
|
+
|
|
39
|
+
See the installed framework documentation:
|
|
40
|
+
- [principles.md](skills/first-tree/references/principles.md) — core principles with examples
|
|
41
|
+
- [ownership-and-naming.md](skills/first-tree/references/ownership-and-naming.md) — node naming and ownership model
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Update CODEOWNERS
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
update:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
ref: ${{ github.head_ref }}
|
|
16
|
+
token: ${{ github.token }}
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: "22"
|
|
21
|
+
|
|
22
|
+
- run: npx tsx skills/first-tree/assets/framework/helpers/generate-codeowners.ts
|
|
23
|
+
|
|
24
|
+
- name: Commit if changed
|
|
25
|
+
run: |
|
|
26
|
+
git add .github/CODEOWNERS
|
|
27
|
+
git diff --cached --quiet .github/CODEOWNERS && exit 0
|
|
28
|
+
git config user.name "github-actions[bot]"
|
|
29
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
30
|
+
git commit -m "chore: update CODEOWNERS from tree ownership"
|
|
31
|
+
git push
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
name: PR Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, reopened, synchronize]
|
|
6
|
+
issue_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
review:
|
|
11
|
+
if: >
|
|
12
|
+
github.event_name == 'pull_request' ||
|
|
13
|
+
(github.event_name == 'issue_comment' &&
|
|
14
|
+
github.event.issue.pull_request &&
|
|
15
|
+
contains(github.event.comment.body, '@claude'))
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
pull-requests: write
|
|
20
|
+
issues: write
|
|
21
|
+
env:
|
|
22
|
+
ANTHROPIC_BASE_URL: "https://openrouter.ai/api"
|
|
23
|
+
ANTHROPIC_AUTH_TOKEN: ${{ secrets.OPENROUTER_API_KEY }}
|
|
24
|
+
ANTHROPIC_API_KEY: ""
|
|
25
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: "anthropic/claude-sonnet-4.6"
|
|
26
|
+
GH_TOKEN: ${{ github.token }}
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version: "22"
|
|
35
|
+
|
|
36
|
+
- name: Install Claude Code
|
|
37
|
+
run: curl -fsSL https://claude.ai/install.sh | bash
|
|
38
|
+
|
|
39
|
+
- name: Get PR info
|
|
40
|
+
id: pr
|
|
41
|
+
run: |
|
|
42
|
+
PR_NUMBER=${{ github.event.pull_request.number || github.event.issue.number }}
|
|
43
|
+
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
|
|
44
|
+
gh pr diff "$PR_NUMBER" > /tmp/pr-diff.txt
|
|
45
|
+
gh pr view "$PR_NUMBER" --json headRefOid -q .headRefOid > /tmp/pr-head-sha.txt
|
|
46
|
+
|
|
47
|
+
- name: Run Claude review
|
|
48
|
+
run: npx tsx skills/first-tree/assets/framework/helpers/run-review.ts
|
|
49
|
+
|
|
50
|
+
- name: Parse and post review
|
|
51
|
+
run: |
|
|
52
|
+
PR_NUMBER=${{ steps.pr.outputs.number }}
|
|
53
|
+
HEAD_SHA=$(cat /tmp/pr-head-sha.txt)
|
|
54
|
+
|
|
55
|
+
# Extract fields
|
|
56
|
+
VERDICT=$(jq -r '.verdict // "COMMENT"' /tmp/review.json)
|
|
57
|
+
SUMMARY=$(jq -r '.summary // "Review completed."' /tmp/review.json)
|
|
58
|
+
|
|
59
|
+
case "$VERDICT" in
|
|
60
|
+
APPROVE) EVENT="APPROVE" ;;
|
|
61
|
+
REQUEST_CHANGES) EVENT="REQUEST_CHANGES" ;;
|
|
62
|
+
*) EVENT="COMMENT" ;;
|
|
63
|
+
esac
|
|
64
|
+
|
|
65
|
+
BODY="${SUMMARY}
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
*Automated review by Claude Code via OpenRouter*"
|
|
69
|
+
|
|
70
|
+
# Check for inline comments
|
|
71
|
+
HAS_COMMENTS=$(jq 'has("inline_comments") and (.inline_comments | length > 0)' /tmp/review.json)
|
|
72
|
+
|
|
73
|
+
if [ "$HAS_COMMENTS" != "true" ]; then
|
|
74
|
+
gh api \
|
|
75
|
+
"repos/${{ github.repository }}/pulls/${PR_NUMBER}/reviews" \
|
|
76
|
+
-f body="$BODY" \
|
|
77
|
+
-f event="$EVENT" \
|
|
78
|
+
-f commit_id="$HEAD_SHA"
|
|
79
|
+
else
|
|
80
|
+
# Transform inline_comments to GitHub API format (file->path, comment->body)
|
|
81
|
+
jq '[.inline_comments[] | {path: .file, line: .line, body: .comment}]' \
|
|
82
|
+
/tmp/review.json > /tmp/comments.json
|
|
83
|
+
|
|
84
|
+
jq -n \
|
|
85
|
+
--arg body "$BODY" \
|
|
86
|
+
--arg event "$EVENT" \
|
|
87
|
+
--arg sha "$HEAD_SHA" \
|
|
88
|
+
--slurpfile comments /tmp/comments.json \
|
|
89
|
+
'{
|
|
90
|
+
body: $body,
|
|
91
|
+
event: $event,
|
|
92
|
+
commit_id: $sha,
|
|
93
|
+
comments: $comments[0]
|
|
94
|
+
}' > /tmp/review-payload.json
|
|
95
|
+
|
|
96
|
+
# Try inline review; fall back to summary-only if lines can't be resolved
|
|
97
|
+
if ! gh api \
|
|
98
|
+
"repos/${{ github.repository }}/pulls/${PR_NUMBER}/reviews" \
|
|
99
|
+
--input /tmp/review-payload.json 2>/tmp/review-api-error.txt; then
|
|
100
|
+
echo "Inline review failed, falling back to summary-only review"
|
|
101
|
+
cat /tmp/review-api-error.txt
|
|
102
|
+
INLINE_TEXT=$(jq -r '.[] | "**\(.path):\(.line)** — \(.body)"' /tmp/comments.json)
|
|
103
|
+
FALLBACK_BODY="${SUMMARY}
|
|
104
|
+
|
|
105
|
+
### Inline Comments
|
|
106
|
+
|
|
107
|
+
${INLINE_TEXT}
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
*Automated review by Claude Code via OpenRouter*"
|
|
111
|
+
gh api \
|
|
112
|
+
"repos/${{ github.repository }}/pulls/${PR_NUMBER}/reviews" \
|
|
113
|
+
-f body="$FALLBACK_BODY" \
|
|
114
|
+
-f event="$EVENT" \
|
|
115
|
+
-f commit_id="$HEAD_SHA"
|
|
116
|
+
fi
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
- name: Post full review output as comment
|
|
120
|
+
if: always()
|
|
121
|
+
run: |
|
|
122
|
+
PR_NUMBER=${{ steps.pr.outputs.number }}
|
|
123
|
+
{
|
|
124
|
+
echo "## Claude Code Review Output"
|
|
125
|
+
echo ""
|
|
126
|
+
if [ -f /tmp/review.json ] && jq empty /tmp/review.json 2>/dev/null; then
|
|
127
|
+
VERDICT=$(jq -r '.verdict // "N/A"' /tmp/review.json)
|
|
128
|
+
SUMMARY=$(jq -r '.summary // "N/A"' /tmp/review.json)
|
|
129
|
+
echo "**Verdict:** ${VERDICT}"
|
|
130
|
+
echo ""
|
|
131
|
+
echo "**Summary:** ${SUMMARY}"
|
|
132
|
+
HAS_COMMENTS=$(jq 'has("inline_comments") and (.inline_comments | length > 0)' /tmp/review.json)
|
|
133
|
+
if [ "$HAS_COMMENTS" = "true" ]; then
|
|
134
|
+
echo ""
|
|
135
|
+
echo "### Inline Comments"
|
|
136
|
+
echo ""
|
|
137
|
+
jq -r '.inline_comments[] | "#### \(.file):\(.line)\n\(.comment)\n"' /tmp/review.json
|
|
138
|
+
fi
|
|
139
|
+
else
|
|
140
|
+
echo "*No review output produced or failed to parse.*"
|
|
141
|
+
fi
|
|
142
|
+
echo ""
|
|
143
|
+
echo "---"
|
|
144
|
+
echo "*Automated review by Claude Code via OpenRouter*"
|
|
145
|
+
} > /tmp/comment-body.md
|
|
146
|
+
gh pr comment "$PR_NUMBER" --body-file /tmp/comment-body.md
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: Validate Tree
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
paths:
|
|
6
|
+
- "**/*.md"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
validate:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- uses: actions/setup-node@v4
|
|
15
|
+
with:
|
|
16
|
+
node-version: "22"
|
|
17
|
+
|
|
18
|
+
- name: Validate tree
|
|
19
|
+
run: npx -p first-tree context-tree verify
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const HELP_USAGE = `usage: context-tree help <topic>
|
|
2
|
+
|
|
3
|
+
Topics:
|
|
4
|
+
onboarding How to set up a context tree from scratch
|
|
5
|
+
`;
|
|
6
|
+
|
|
7
|
+
export { HELP_USAGE };
|
|
8
|
+
|
|
9
|
+
type Output = (text: string) => void;
|
|
10
|
+
|
|
11
|
+
export async function runHelp(
|
|
12
|
+
args: string[],
|
|
13
|
+
output: Output = console.log,
|
|
14
|
+
): Promise<number> {
|
|
15
|
+
const topic = args[0];
|
|
16
|
+
|
|
17
|
+
if (!topic || topic === "--help" || topic === "-h") {
|
|
18
|
+
output(HELP_USAGE);
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
switch (topic) {
|
|
23
|
+
case "onboarding": {
|
|
24
|
+
const { runOnboarding } = await import("#skill/engine/onboarding.js");
|
|
25
|
+
return runOnboarding(output);
|
|
26
|
+
}
|
|
27
|
+
default:
|
|
28
|
+
output(`Unknown help topic: ${topic}`);
|
|
29
|
+
output(HELP_USAGE);
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { INIT_USAGE, parseInitArgs, runInitCli as runInit } from "#skill/engine/init.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UPGRADE_USAGE, runUpgradeCli as runUpgrade } from "#skill/engine/upgrade.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { VERIFY_USAGE, runVerifyCli as runVerify } from "#skill/engine/verify.js";
|