@mbe24/99problems 0.1.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/.githooks/pre-commit +22 -0
- package/.github/logo.svg +12 -0
- package/.github/scripts/publish.js +93 -0
- package/.github/social-preview.svg +82 -0
- package/.github/workflows/ci.yml +47 -0
- package/.github/workflows/release.yml +115 -0
- package/CONTRIBUTING.md +74 -0
- package/Cargo.lock +1758 -0
- package/Cargo.toml +27 -0
- package/LICENSE +201 -0
- package/README.md +124 -0
- package/artifacts/binary-aarch64-apple-darwin/99problems +0 -0
- package/artifacts/binary-aarch64-unknown-linux-gnu/99problems +0 -0
- package/artifacts/binary-x86_64-apple-darwin/99problems +0 -0
- package/artifacts/binary-x86_64-pc-windows-msvc/99problems.exe +0 -0
- package/artifacts/binary-x86_64-unknown-linux-gnu/99problems +0 -0
- package/npm/bin/99problems.js +42 -0
- package/npm/install.js +26 -0
- package/package.json +23 -0
- package/src/config.rs +101 -0
- package/src/format/json.rs +46 -0
- package/src/format/mod.rs +10 -0
- package/src/format/yaml.rs +44 -0
- package/src/lib.rs +4 -0
- package/src/main.rs +127 -0
- package/src/model.rs +17 -0
- package/src/source/github_issues.rs +232 -0
- package/src/source/mod.rs +110 -0
- package/tests/integration.rs +58 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Pre-commit hook: format check + clippy
|
|
3
|
+
# Install: this file is already at .git/hooks/pre-commit
|
|
4
|
+
# For new clones run: cp .githooks/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
echo "→ cargo fmt --check"
|
|
9
|
+
cargo fmt --check || {
|
|
10
|
+
echo ""
|
|
11
|
+
echo " Formatting issues found. Run 'cargo fmt' to fix them, then re-stage."
|
|
12
|
+
exit 1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
echo "→ cargo clippy"
|
|
16
|
+
cargo clippy --no-deps -- -D warnings || {
|
|
17
|
+
echo ""
|
|
18
|
+
echo " Clippy warnings found. Fix them before committing."
|
|
19
|
+
exit 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
echo "✓ Pre-commit checks passed"
|
package/.github/logo.svg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
|
|
2
|
+
<rect width="120" height="120" rx="24" fill="#6D28D9"/>
|
|
3
|
+
<text
|
|
4
|
+
x="60"
|
|
5
|
+
y="82"
|
|
6
|
+
font-family="'Segoe UI', Arial, sans-serif"
|
|
7
|
+
font-size="68"
|
|
8
|
+
font-weight="800"
|
|
9
|
+
text-anchor="middle"
|
|
10
|
+
fill="#FFFFFF"
|
|
11
|
+
letter-spacing="-3">9P</text>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Builds per-platform npm packages from CI artifacts and publishes them,
|
|
3
|
+
// then updates + publishes the main wrapper package.
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { execSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
const version = process.env.VERSION?.replace(/^v/, "");
|
|
9
|
+
if (!version) throw new Error("VERSION env var is required (e.g. v0.1.0)");
|
|
10
|
+
|
|
11
|
+
const platforms = [
|
|
12
|
+
{
|
|
13
|
+
pkg: "@mbe24/99problems-win32-x64",
|
|
14
|
+
dir: "npm-win32-x64",
|
|
15
|
+
artifact: "artifacts/binary-x86_64-pc-windows-msvc/99problems.exe",
|
|
16
|
+
binary: "99problems.exe",
|
|
17
|
+
os: "win32",
|
|
18
|
+
cpu: "x64",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
pkg: "@mbe24/99problems-linux-x64",
|
|
22
|
+
dir: "npm-linux-x64",
|
|
23
|
+
artifact: "artifacts/binary-x86_64-unknown-linux-gnu/99problems",
|
|
24
|
+
binary: "99problems",
|
|
25
|
+
os: "linux",
|
|
26
|
+
cpu: "x64",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pkg: "@mbe24/99problems-darwin-x64",
|
|
30
|
+
dir: "npm-darwin-x64",
|
|
31
|
+
artifact: "artifacts/binary-x86_64-apple-darwin/99problems",
|
|
32
|
+
binary: "99problems",
|
|
33
|
+
os: "darwin",
|
|
34
|
+
cpu: "x64",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pkg: "@mbe24/99problems-darwin-arm64",
|
|
38
|
+
dir: "npm-darwin-arm64",
|
|
39
|
+
artifact: "artifacts/binary-aarch64-apple-darwin/99problems",
|
|
40
|
+
binary: "99problems",
|
|
41
|
+
os: "darwin",
|
|
42
|
+
cpu: "arm64",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pkg: "@mbe24/99problems-linux-arm64",
|
|
46
|
+
dir: "npm-linux-arm64",
|
|
47
|
+
artifact: "artifacts/binary-aarch64-unknown-linux-gnu/99problems",
|
|
48
|
+
binary: "99problems",
|
|
49
|
+
os: "linux",
|
|
50
|
+
cpu: "arm64",
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
for (const p of platforms) {
|
|
55
|
+
const pkgDir = path.join(p.dir);
|
|
56
|
+
fs.mkdirSync(path.join(pkgDir, "bin"), { recursive: true });
|
|
57
|
+
|
|
58
|
+
// Copy binary
|
|
59
|
+
fs.copyFileSync(p.artifact, path.join(pkgDir, "bin", p.binary));
|
|
60
|
+
if (p.os !== "win32") {
|
|
61
|
+
fs.chmodSync(path.join(pkgDir, "bin", p.binary), 0o755);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Write package.json
|
|
65
|
+
const pkgJson = {
|
|
66
|
+
name: p.pkg,
|
|
67
|
+
version,
|
|
68
|
+
description: `${p.os}-${p.cpu} binary for @mbe24/99problems`,
|
|
69
|
+
os: [p.os],
|
|
70
|
+
cpu: [p.cpu],
|
|
71
|
+
main: `bin/${p.binary}`,
|
|
72
|
+
license: "MIT",
|
|
73
|
+
repository: { type: "git", url: "https://github.com/mbe24/99problems" },
|
|
74
|
+
};
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(pkgDir, "package.json"),
|
|
77
|
+
JSON.stringify(pkgJson, null, 2) + "\n"
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
console.log(`Publishing ${p.pkg}@${version} ...`);
|
|
81
|
+
execSync("npm publish --access public", { cwd: pkgDir, stdio: "inherit" });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Update main package.json version + optionalDependencies versions
|
|
85
|
+
const mainPkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
86
|
+
mainPkg.version = version;
|
|
87
|
+
for (const p of platforms) {
|
|
88
|
+
mainPkg.optionalDependencies[p.pkg] = version;
|
|
89
|
+
}
|
|
90
|
+
fs.writeFileSync("package.json", JSON.stringify(mainPkg, null, 2) + "\n");
|
|
91
|
+
|
|
92
|
+
console.log(`Publishing @mbe24/99problems@${version} ...`);
|
|
93
|
+
execSync("npm publish --access public", { stdio: "inherit" });
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 640" width="1280" height="640">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1280" y2="640" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0%" stop-color="#0F0720"/>
|
|
5
|
+
<stop offset="100%" stop-color="#1C0B38"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<radialGradient id="logoglow" cx="50%" cy="50%" r="50%">
|
|
8
|
+
<stop offset="0%" stop-color="#7C3AED" stop-opacity="0.4"/>
|
|
9
|
+
<stop offset="100%" stop-color="#7C3AED" stop-opacity="0"/>
|
|
10
|
+
</radialGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<!-- Background -->
|
|
14
|
+
<rect width="1280" height="640" fill="url(#bg)"/>
|
|
15
|
+
|
|
16
|
+
<!-- Decorative circles -->
|
|
17
|
+
<circle cx="1220" cy="60" r="320" fill="#6D28D9" opacity="0.07"/>
|
|
18
|
+
<circle cx="60" cy="610" r="220" fill="#5B21B6" opacity="0.07"/>
|
|
19
|
+
|
|
20
|
+
<!-- Soft glow behind logo -->
|
|
21
|
+
<ellipse cx="220" cy="320" rx="240" ry="240" fill="url(#logoglow)"/>
|
|
22
|
+
|
|
23
|
+
<!-- Logo mark -->
|
|
24
|
+
<rect x="70" y="180" width="300" height="300" rx="44" fill="#6D28D9"/>
|
|
25
|
+
<text
|
|
26
|
+
x="220" y="372"
|
|
27
|
+
font-family="'Segoe UI', Arial, sans-serif"
|
|
28
|
+
font-size="160" font-weight="900"
|
|
29
|
+
text-anchor="middle" fill="#FFFFFF"
|
|
30
|
+
letter-spacing="-8">9P</text>
|
|
31
|
+
|
|
32
|
+
<!-- Vertical divider -->
|
|
33
|
+
<line x1="440" y1="100" x2="440" y2="540" stroke="#6D28D9" stroke-width="1" opacity="0.35"/>
|
|
34
|
+
|
|
35
|
+
<!-- Title -->
|
|
36
|
+
<text
|
|
37
|
+
x="472" y="234"
|
|
38
|
+
font-family="'Segoe UI', Arial, sans-serif"
|
|
39
|
+
font-size="86" font-weight="800"
|
|
40
|
+
fill="#FFFFFF" letter-spacing="-3">99problems</text>
|
|
41
|
+
|
|
42
|
+
<!-- Tagline -->
|
|
43
|
+
<text
|
|
44
|
+
x="474" y="282"
|
|
45
|
+
font-family="'Segoe UI', Arial, sans-serif"
|
|
46
|
+
font-size="28" font-weight="400"
|
|
47
|
+
fill="#A78BFA">AI-friendly access to GitHub issues</text>
|
|
48
|
+
|
|
49
|
+
<!-- Feature pills -->
|
|
50
|
+
<rect x="474" y="306" width="116" height="30" rx="6" fill="#2D1260"/>
|
|
51
|
+
<text x="532" y="326" font-family="'Segoe UI', Arial, sans-serif" font-size="14" text-anchor="middle" fill="#C4B5FD">JSON · YAML</text>
|
|
52
|
+
|
|
53
|
+
<rect x="600" y="306" width="116" height="30" rx="6" fill="#2D1260"/>
|
|
54
|
+
<text x="658" y="326" font-family="'Segoe UI', Arial, sans-serif" font-size="14" text-anchor="middle" fill="#C4B5FD">5 platforms</text>
|
|
55
|
+
|
|
56
|
+
<rect x="726" y="306" width="186" height="30" rx="6" fill="#2D1260"/>
|
|
57
|
+
<text x="819" y="326" font-family="'Segoe UI', Arial, sans-serif" font-size="14" text-anchor="middle" fill="#C4B5FD">GitHub search syntax</text>
|
|
58
|
+
|
|
59
|
+
<!-- Terminal window -->
|
|
60
|
+
<rect x="472" y="352" width="762" height="216" rx="12" fill="#0D0520" stroke="#3B1D7A" stroke-width="1.5"/>
|
|
61
|
+
|
|
62
|
+
<!-- Terminal chrome bar -->
|
|
63
|
+
<rect x="472" y="352" width="762" height="36" rx="12" fill="#1A0A38"/>
|
|
64
|
+
<rect x="472" y="370" width="762" height="18" fill="#1A0A38"/>
|
|
65
|
+
<circle cx="502" cy="370" r="7" fill="#FF5F57"/>
|
|
66
|
+
<circle cx="526" cy="370" r="7" fill="#FFBD2E"/>
|
|
67
|
+
<circle cx="550" cy="370" r="7" fill="#28C840"/>
|
|
68
|
+
<text x="760" y="375" font-family="'Segoe UI', Arial, sans-serif" font-size="13" text-anchor="middle" fill="#6B4FA0">zsh</text>
|
|
69
|
+
|
|
70
|
+
<!-- Install line -->
|
|
71
|
+
<text x="496" y="418" font-family="'Courier New', monospace" font-size="17" fill="#6D28D9">$</text>
|
|
72
|
+
<text x="514" y="418" font-family="'Courier New', monospace" font-size="17" fill="#94A3B8"> npm install -g @mbe24/99problems</text>
|
|
73
|
+
|
|
74
|
+
<!-- Command line -->
|
|
75
|
+
<text x="496" y="458" font-family="'Courier New', monospace" font-size="17" fill="#6D28D9">$</text>
|
|
76
|
+
<text x="514" y="458" font-family="'Courier New', monospace" font-size="17" fill="#E2E8F0"> 99problems -q </text>
|
|
77
|
+
<text x="672" y="458" font-family="'Courier New', monospace" font-size="17" fill="#86EFAC">"state:closed repo:owner/repo"</text>
|
|
78
|
+
<text x="514" y="482" font-family="'Courier New', monospace" font-size="17" fill="#E2E8F0"> -o conversations.json</text>
|
|
79
|
+
|
|
80
|
+
<!-- Output line -->
|
|
81
|
+
<text x="496" y="524" font-family="'Courier New', monospace" font-size="17" fill="#34D399">✓ Wrote 262 conversations to conversations.json</text>
|
|
82
|
+
</svg>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["**"]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Test
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install Rust toolchain
|
|
20
|
+
uses: dtolnay/rust-toolchain@stable
|
|
21
|
+
with:
|
|
22
|
+
components: clippy, rustfmt
|
|
23
|
+
|
|
24
|
+
- name: Cache cargo registry
|
|
25
|
+
uses: actions/cache@v4
|
|
26
|
+
with:
|
|
27
|
+
path: |
|
|
28
|
+
~/.cargo/registry
|
|
29
|
+
~/.cargo/git
|
|
30
|
+
target
|
|
31
|
+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
32
|
+
restore-keys: ${{ runner.os }}-cargo-
|
|
33
|
+
|
|
34
|
+
- name: Check formatting
|
|
35
|
+
run: cargo fmt --check
|
|
36
|
+
|
|
37
|
+
- name: Clippy
|
|
38
|
+
run: cargo clippy --no-deps -- -D warnings
|
|
39
|
+
|
|
40
|
+
- name: Unit tests
|
|
41
|
+
run: cargo test
|
|
42
|
+
|
|
43
|
+
- name: Integration tests
|
|
44
|
+
if: env.GITHUB_TOKEN != ''
|
|
45
|
+
env:
|
|
46
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
47
|
+
run: cargo test -- --include-ignored
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: "Version to release (e.g. v0.1.0)"
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
env:
|
|
15
|
+
CARGO_TERM_COLOR: always
|
|
16
|
+
# Resolve version from tag push or manual input
|
|
17
|
+
RELEASE_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
build:
|
|
21
|
+
name: Build ${{ matrix.target }}
|
|
22
|
+
runs-on: ${{ matrix.os }}
|
|
23
|
+
strategy:
|
|
24
|
+
matrix:
|
|
25
|
+
include:
|
|
26
|
+
- target: x86_64-pc-windows-msvc
|
|
27
|
+
os: windows-latest
|
|
28
|
+
npm_pkg: "@mbe24/99problems-win32-x64"
|
|
29
|
+
binary: "99problems.exe"
|
|
30
|
+
- target: x86_64-unknown-linux-gnu
|
|
31
|
+
os: ubuntu-latest
|
|
32
|
+
npm_pkg: "@mbe24/99problems-linux-x64"
|
|
33
|
+
binary: "99problems"
|
|
34
|
+
- target: x86_64-apple-darwin
|
|
35
|
+
os: macos-latest
|
|
36
|
+
npm_pkg: "@mbe24/99problems-darwin-x64"
|
|
37
|
+
binary: "99problems"
|
|
38
|
+
- target: aarch64-apple-darwin
|
|
39
|
+
os: macos-latest
|
|
40
|
+
npm_pkg: "@mbe24/99problems-darwin-arm64"
|
|
41
|
+
binary: "99problems"
|
|
42
|
+
- target: aarch64-unknown-linux-gnu
|
|
43
|
+
os: ubuntu-latest
|
|
44
|
+
npm_pkg: "@mbe24/99problems-linux-arm64"
|
|
45
|
+
binary: "99problems"
|
|
46
|
+
use_cross: true
|
|
47
|
+
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v4
|
|
50
|
+
|
|
51
|
+
- name: Install Rust toolchain
|
|
52
|
+
uses: dtolnay/rust-toolchain@stable
|
|
53
|
+
with:
|
|
54
|
+
targets: ${{ matrix.target }}
|
|
55
|
+
|
|
56
|
+
- name: Cache cargo registry
|
|
57
|
+
uses: actions/cache@v4
|
|
58
|
+
with:
|
|
59
|
+
path: |
|
|
60
|
+
~/.cargo/registry
|
|
61
|
+
~/.cargo/git
|
|
62
|
+
target
|
|
63
|
+
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
64
|
+
restore-keys: ${{ runner.os }}-${{ matrix.target }}-cargo-
|
|
65
|
+
|
|
66
|
+
- name: Install cross (for cross-compilation)
|
|
67
|
+
if: matrix.use_cross
|
|
68
|
+
run: cargo install cross --locked
|
|
69
|
+
|
|
70
|
+
- name: Build binary
|
|
71
|
+
run: ${{ matrix.use_cross && 'cross' || 'cargo' }} build --release --target ${{ matrix.target }}
|
|
72
|
+
|
|
73
|
+
- name: Upload binary artifact
|
|
74
|
+
uses: actions/upload-artifact@v4
|
|
75
|
+
with:
|
|
76
|
+
name: binary-${{ matrix.target }}
|
|
77
|
+
path: target/${{ matrix.target }}/release/${{ matrix.binary }}
|
|
78
|
+
|
|
79
|
+
publish-crates:
|
|
80
|
+
name: Publish to crates.io
|
|
81
|
+
needs: build
|
|
82
|
+
runs-on: ubuntu-latest
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/checkout@v4
|
|
85
|
+
|
|
86
|
+
- name: Install Rust toolchain
|
|
87
|
+
uses: dtolnay/rust-toolchain@stable
|
|
88
|
+
|
|
89
|
+
- name: Publish to crates.io
|
|
90
|
+
env:
|
|
91
|
+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
92
|
+
run: cargo publish --no-verify
|
|
93
|
+
|
|
94
|
+
publish-npm:
|
|
95
|
+
name: Publish npm packages
|
|
96
|
+
needs: build
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@v4
|
|
100
|
+
|
|
101
|
+
- uses: actions/setup-node@v4
|
|
102
|
+
with:
|
|
103
|
+
node-version: "20"
|
|
104
|
+
registry-url: "https://registry.npmjs.org"
|
|
105
|
+
|
|
106
|
+
- name: Download all binaries
|
|
107
|
+
uses: actions/download-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
path: artifacts/
|
|
110
|
+
|
|
111
|
+
- name: Publish platform packages and main package
|
|
112
|
+
env:
|
|
113
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
114
|
+
VERSION: ${{ env.RELEASE_VERSION }}
|
|
115
|
+
run: node .github/scripts/publish.js
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Contributing to 99problems
|
|
2
|
+
|
|
3
|
+
Thank you for taking the time to contribute! 🎉
|
|
4
|
+
|
|
5
|
+
## Ways to contribute
|
|
6
|
+
|
|
7
|
+
- **Bug reports** — open an issue describing what happened and what you expected
|
|
8
|
+
- **Feature requests** — open an issue with the `enhancement` label
|
|
9
|
+
- **Pull requests** — see the workflow below
|
|
10
|
+
|
|
11
|
+
## Development setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Prerequisites: Rust stable (1.85+), cargo
|
|
15
|
+
git clone https://github.com/mbe24/99problems
|
|
16
|
+
cd 99problems
|
|
17
|
+
|
|
18
|
+
# Install the pre-commit hook (runs cargo fmt + clippy before each commit)
|
|
19
|
+
cp .githooks/pre-commit .git/hooks/pre-commit
|
|
20
|
+
chmod +x .git/hooks/pre-commit # not needed on Windows
|
|
21
|
+
|
|
22
|
+
# Build
|
|
23
|
+
cargo build
|
|
24
|
+
|
|
25
|
+
# Run unit tests
|
|
26
|
+
cargo test
|
|
27
|
+
|
|
28
|
+
# Run integration tests (requires a GitHub token)
|
|
29
|
+
export GITHUB_TOKEN=ghp_your_token
|
|
30
|
+
cargo test -- --include-ignored
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Pull request workflow
|
|
34
|
+
|
|
35
|
+
1. Fork the repo and create a branch: `git checkout -b my-feature`
|
|
36
|
+
2. Make your changes and add tests where appropriate
|
|
37
|
+
3. Run `cargo test` — all tests must pass
|
|
38
|
+
4. Run `cargo clippy` and `cargo fmt --check` — no new warnings
|
|
39
|
+
5. Open a pull request with a clear description of what and why
|
|
40
|
+
|
|
41
|
+
## Project structure
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
src/
|
|
45
|
+
main.rs # CLI entry point (clap)
|
|
46
|
+
config.rs # Dotfile config loading
|
|
47
|
+
model.rs # Shared data types (Conversation, Comment)
|
|
48
|
+
source/
|
|
49
|
+
mod.rs # Source trait + Query builder
|
|
50
|
+
github_issues.rs # GitHub Issues API client
|
|
51
|
+
format/
|
|
52
|
+
mod.rs # Formatter trait
|
|
53
|
+
json.rs # JSON output
|
|
54
|
+
yaml.rs # YAML output
|
|
55
|
+
tests/
|
|
56
|
+
integration.rs # Live API tests (#[ignore] by default)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Adding a new source
|
|
60
|
+
|
|
61
|
+
1. Create `src/source/my_source.rs` implementing the `Source` trait
|
|
62
|
+
2. Register it in `src/source/mod.rs`
|
|
63
|
+
3. Add a variant to `SourceKind` in `src/main.rs`
|
|
64
|
+
|
|
65
|
+
## Adding a new output format
|
|
66
|
+
|
|
67
|
+
1. Create `src/format/my_format.rs` implementing the `Formatter` trait
|
|
68
|
+
2. Register it in `src/format/mod.rs`
|
|
69
|
+
3. Add a variant to `OutputFormat` in `src/main.rs`
|
|
70
|
+
|
|
71
|
+
## Code of conduct
|
|
72
|
+
|
|
73
|
+
Be respectful and constructive. We follow the
|
|
74
|
+
[Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|