practicode 0.1.0 → 0.1.1

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/Cargo.lock CHANGED
@@ -357,7 +357,7 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
357
357
 
358
358
  [[package]]
359
359
  name = "practicode"
360
- version = "0.1.0"
360
+ version = "0.1.1"
361
361
  dependencies = [
362
362
  "anyhow",
363
363
  "crossterm 0.29.0",
package/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "practicode"
3
- version = "0.1.0"
3
+ version = "0.1.1"
4
4
  edition = "2024"
5
5
  description = "Local-first coding-test practice in a Rust terminal UI with optional AI help."
6
6
  readme = "README.md"
package/README.md CHANGED
@@ -11,70 +11,55 @@
11
11
  Personal coding practice, right in your terminal.
12
12
 
13
13
  `practicode` is a small Rust TUI for stdin/stdout practice: problem on the left, code on the right, judge loop in the same terminal.
14
- No browser tab shuffle, no paste dance, just solve and run.
15
14
 
16
- ## Why It Exists
15
+ ## Start
17
16
 
18
- - Fast local judging for Python, TypeScript, Java, and Rust
19
- - Gradual problem flow with local history
20
- - AI-powered `/next <request>` when you want a custom problem
21
- - Personal problem-generation notes
22
- - Small stack: Rust, Ratatui, Crossterm, and plain process execution
17
+ ### Prerequisites
23
18
 
24
- ## Quick Start
19
+ - Node.js 18+ for npm installation.
20
+ - Rust and Cargo. The npm package builds the Rust binary during install, and also on first run if needed.
21
+ - A runtime for the language you practice in: Python, Node.js for TypeScript, JDK for Java, or Rust.
25
22
 
26
- ```bash
27
- git clone https://github.com/baba9811/practicode.git
28
- cd practicode
29
- cargo run --
30
- ```
31
-
32
- Want a local binary?
23
+ ### npm
33
24
 
34
25
  ```bash
35
- cargo install practicode
26
+ npm install -g practicode
36
27
  practicode
37
28
  ```
38
29
 
39
- Prefer npm from GitHub?
30
+ ### Cargo
40
31
 
41
32
  ```bash
42
- npm install -g github:baba9811/practicode
43
- practicode
44
- ```
45
-
46
- Working from a local checkout?
47
-
48
- ```bash
49
- cargo install --path .
33
+ cargo install practicode
50
34
  practicode
51
35
  ```
52
36
 
53
- Or with npm:
37
+ ### Local checkout
54
38
 
55
39
  ```bash
56
- npm install -g .
57
- practicode
40
+ git clone https://github.com/baba9811/practicode.git
41
+ cd practicode
42
+ npm install
43
+ npm start
58
44
  ```
59
45
 
60
- The npm wrapper builds the Rust binary with Cargo, so Rust/Cargo is still required.
61
-
62
46
  ## Daily Loop
63
47
 
64
48
  The code editor starts focused.
65
49
 
66
50
  ```text
67
51
  write code
68
- Esc, then /run
69
- Esc, then /next easy string problem
52
+ Esc, then /
53
+ choose /run
54
+ choose /next when it passes
70
55
  ```
71
56
 
57
+ Typing `/` outside the editor opens the command palette. Use `up/down` to move, `Enter` to run or complete the selected command, and `Esc` to cancel.
58
+
72
59
  Submissions are saved as you type under `submissions/<problem-id>/solution.<ext>`.
73
60
 
74
61
  ## Commands
75
62
 
76
- Press `Esc`, then `/`, to focus the command bar.
77
-
78
63
  | Command | Action |
79
64
  | --- | --- |
80
65
  | `/run` | Judge the current submission |
@@ -86,21 +71,20 @@ Press `Esc`, then `/`, to focus the command bar.
86
71
  | `/giveup` | Show the reference answer |
87
72
  | `/ai hint` | Ask the selected AI about the current problem and submission |
88
73
  | `/provider codex` | Set AI provider: `codex` or `claude` |
89
- | `/model sonnet` | Set the model for `/ai` and AI-backed `/next`; use `auto` for the CLI default |
74
+ | `/model auto` | Set the model for `/ai` and AI-backed `/next` |
90
75
  | `/note prefer hashmap practice` | Append a standing note for future problem generation |
91
76
  | `/notes` | Show your local next-problem notes |
92
- | `/lang python` | Set language: `python`, `ts`, `java`, `rust` |
93
- | `/ui ko` | Set UI language: `ko`, `en` |
94
- | `/theme` | Toggle dark/light theme |
77
+ | `/lang python` | Set code language: `python`, `ts`, `java`, `rust` |
78
+ | `/ui en` | Set UI language: `en`, `ko`, `ja`, `zh`, `es` |
79
+ | `/theme dark` | Set theme: `dark` or `light` |
95
80
  | `/source ai` | Prefer AI for next-problem generation |
96
81
  | `/exit` | Quit |
97
82
 
98
- The editor owns normal typing keys.
99
- Press `Esc`, then `/`, when you want the command bar.
83
+ The default UI language is English. Switch it any time with `/ui ko`, `/ui ja`, `/ui zh`, or `/ui es`.
100
84
 
101
- ## Custom Problem Generation
85
+ ## AI Problems
102
86
 
103
- `/next <request>` passes your request into the selected AI problem generator. Examples:
87
+ `/next <request>` passes your request into the selected AI problem generator.
104
88
 
105
89
  ```text
106
90
  /next a slightly harder string problem
@@ -108,19 +92,7 @@ Press `Esc`, then `/`, when you want the command bar.
108
92
  /next sorting problem, no graph yet
109
93
  ```
110
94
 
111
- AI generation reads [docs/problem-authoring-notes.md](docs/problem-authoring-notes.md) every time it creates a problem. Add personal preferences from inside the TUI:
112
-
113
- ```text
114
- /note Prefer concise statements.
115
- /note I want more string and hashmap practice.
116
- /note Avoid DP until I ask for it.
117
- ```
118
-
119
- Those notes are stored in `.practicode/problem_notes.md`, so they stay local.
120
-
121
- ## AI Providers
122
-
123
- Codex is the default:
95
+ Codex is the default provider:
124
96
 
125
97
  ```text
126
98
  /provider codex
@@ -135,10 +107,7 @@ Claude Code is also supported:
135
107
  /source ai
136
108
  ```
137
109
 
138
- `/ai <prompt>` uses the current provider for coaching. AI-backed `/next` uses the same provider and model.
139
- If you want a custom daemon or wrapper script, set `/ai-next-command <shell command>`; practicode passes `PRACTICODE_NEXT_REQUEST`, `PRACTICODE_AI_PROVIDER`, and `PRACTICODE_AI_MODEL`.
140
-
141
- Generated problem banks stay local:
110
+ Generated problem banks and submissions stay local:
142
111
 
143
112
  | Path | Purpose |
144
113
  | --- | --- |
@@ -150,51 +119,21 @@ Generated problem banks stay local:
150
119
 
151
120
  Those paths are ignored by git, so your practice history stays yours.
152
121
 
153
- ## Safety
154
-
155
- `/run` executes your local submission as a normal process. practicode runs it from `.practicode/build/<problem-id>/run`, but this is not an OS sandbox. Only run code you trust.
156
-
157
- ## Debug Prints
122
+ ## Update
158
123
 
159
- `/run` shows raw stdout when a case fails. If you want debug output without changing the judged answer, print to stderr:
124
+ ```bash
125
+ npm update -g practicode
126
+ cargo install --force practicode
127
+ ```
160
128
 
161
- ```python
162
- import sys
129
+ ## Safety
163
130
 
164
- print("debug", value, file=sys.stderr)
165
- ```
131
+ `/run` executes your local submission as a normal process. practicode runs it from `.practicode/build/<problem-id>/run`, but this is not an OS sandbox. Only run code you trust.
166
132
 
167
- ## Development
133
+ ## Contributors
168
134
 
169
- ```bash
170
- cargo test
171
- cargo run -- --smoke
172
- cargo run --
173
- ```
135
+ Development, release, problem-authoring, and design references live in [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).
174
136
 
175
- The source is split by boring responsibility:
137
+ ## License
176
138
 
177
- | Path | Role |
178
- | --- | --- |
179
- | `src/core.rs` | Problem bank, state, rendering, judging |
180
- | `src/tui.rs` | Ratatui app, editor, command parser |
181
- | `src/ai.rs` | Codex/Claude command integration and notes |
182
- | `src/text.rs` | UTF-8 cursor math and Hangul composition |
183
- | `src/process.rs` | Process execution helpers |
184
- | `tests/` | Integration tests split by module |
185
-
186
- ## Discovery Notes
187
-
188
- Recommended GitHub topics for this repo:
189
- `coding-practice`, `competitive-programming`, `algorithms`, `ratatui`, `tui`, `rust`, `codex`, `claude-code`, `local-first`.
190
-
191
- ## References
192
-
193
- - Ratatui terminal UI library: https://ratatui.rs/
194
- - Crossterm terminal backend/events: https://github.com/crossterm-rs/crossterm
195
- - Codex CLI open-source repo: https://github.com/openai/codex
196
- - Claude Code CLI reference: https://docs.anthropic.com/en/docs/claude-code/cli-reference
197
- - Kattis problem package format: https://www.kattis.com/problem-package-format/
198
- - ICPC judging guidelines: https://icpc.global/regionals/regional-contest-cookbook-judging-guidelines
199
- - GitHub README image guidance: https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
200
- - GitHub repository topics: https://docs.github.com/articles/classifying-your-repository-with-topics
139
+ practicode is MIT licensed. Third-party dependency license notes are in [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).
@@ -0,0 +1,58 @@
1
+ # Third-Party Licenses
2
+
3
+ This file summarizes third-party dependency license metadata for practicode
4
+ 0.1.0, checked from Cargo.lock and Cargo metadata.
5
+
6
+ This is not legal advice.
7
+
8
+ ## Project License
9
+
10
+ practicode is licensed under MIT. The current dependency set is compatible with
11
+ that choice: all Rust dependencies use permissive licenses, and the npm package
12
+ has no npm dependencies.
13
+
14
+ ## npm Dependencies
15
+
16
+ None.
17
+
18
+ ## Direct Rust Dependencies
19
+
20
+ | Crate | Version | License |
21
+ | --- | --- | --- |
22
+ | anyhow | 1.0.103 | MIT OR Apache-2.0 |
23
+ | crossterm | 0.29.0 | MIT |
24
+ | ratatui | 0.29.0 | MIT |
25
+ | serde | 1.0.228 | MIT OR Apache-2.0 |
26
+ | serde_json | 1.0.150 | MIT OR Apache-2.0 |
27
+ | unicode-width | 0.2.0 | MIT OR Apache-2.0 |
28
+ | wait-timeout | 0.2.1 | MIT/Apache-2.0 |
29
+
30
+ ## Transitive Rust Dependency License Groups
31
+
32
+ The locked Rust dependency graph contains 87 third-party packages.
33
+
34
+ | License expression | Packages |
35
+ | --- | ---: |
36
+ | MIT OR Apache-2.0 | 50 |
37
+ | MIT | 20 |
38
+ | MIT/Apache-2.0 | 5 |
39
+ | Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT | 5 |
40
+ | Apache-2.0 OR MIT | 1 |
41
+ | Apache-2.0/MIT | 1 |
42
+ | MIT / Apache-2.0 | 1 |
43
+ | Unlicense OR MIT | 1 |
44
+ | Zlib | 1 |
45
+ | Apache-2.0 OR BSL-1.0 | 1 |
46
+ | (MIT OR Apache-2.0) AND Unicode-3.0 | 1 |
47
+
48
+ No GPL, LGPL, AGPL, or MPL dependencies were detected in the locked Rust
49
+ dependency graph.
50
+
51
+ ## Release Notes
52
+
53
+ The crates.io and npm packages distribute practicode source, not vendored
54
+ third-party source or prebuilt third-party binaries. The npm installer builds
55
+ the Rust binary locally with Cargo.
56
+
57
+ If practicode later ships prebuilt binaries, include full third-party notices
58
+ and license texts with those binary artifacts.
@@ -0,0 +1,76 @@
1
+ # Contributing
2
+
3
+ This repo is a Rust coding-practice workspace with a Ratatui terminal UI.
4
+
5
+ ## Prerequisites
6
+
7
+ - Rust stable with Cargo, rustfmt, and clippy.
8
+ - Node.js 18+ for the npm wrapper and package checks.
9
+ - Optional local runtimes for judging: Python, Node.js, JDK, and Rust.
10
+
11
+ ## Development
12
+
13
+ ```bash
14
+ cargo run --
15
+ cargo run -- --smoke
16
+ cargo test
17
+ npm run smoke
18
+ ```
19
+
20
+ Full local check:
21
+
22
+ ```bash
23
+ make test
24
+ ```
25
+
26
+ The source is split by boring responsibility:
27
+
28
+ | Path | Role |
29
+ | --- | --- |
30
+ | `src/core.rs` | Problem bank, state, rendering, judging |
31
+ | `src/tui.rs` | Ratatui app, editor, command parser |
32
+ | `src/ai.rs` | Codex/Claude command integration and notes |
33
+ | `src/text.rs` | UTF-8 cursor math and Hangul composition |
34
+ | `src/process.rs` | Process execution helpers |
35
+ | `tests/` | Integration tests split by module |
36
+
37
+ ## Problem Authoring
38
+
39
+ AI generation reads [problem-authoring-notes.md](problem-authoring-notes.md) every time it creates a problem.
40
+
41
+ Local generated data stays ignored by git:
42
+
43
+ | Path | Purpose |
44
+ | --- | --- |
45
+ | `.practicode/problem_bank.json` | Local/custom/generated problem bank |
46
+ | `.practicode/problem_notes.md` | Personal problem-generation notes |
47
+ | `.practicode/problem-state.json` | Current problem, history, settings |
48
+ | `problems/` | Generated problem markdown/index files |
49
+ | `submissions/` | Local answer files |
50
+
51
+ ## Release
52
+
53
+ `main` runs CI only. Releases are tag-based and publish to crates.io and npm through GitHub Actions.
54
+
55
+ ```bash
56
+ make release VERSION=0.1.1
57
+ ```
58
+
59
+ The release script checks versions, runs tests, creates the version commit and tag, and pushes `main` plus the tag. Do not print or commit tokens; GitHub Actions uses repository secrets.
60
+
61
+ ## Documentation
62
+
63
+ Keep the root [README](../README.md) focused on users. Put contributor workflow, implementation notes, release notes, and design references here or in nearby `docs/` files.
64
+
65
+ Use relative links for repo-local docs and assets. The terminal screenshot is stored at [assets/practicode-terminal.svg](../assets/practicode-terminal.svg).
66
+
67
+ ## UX And Documentation References
68
+
69
+ - WAI-ARIA combobox keyboard interaction: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
70
+ - Command Line Interface Guidelines: https://clig.dev/
71
+ - GitHub README guidance: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
72
+ - GitHub relative links and images: https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#relative-links
73
+ - Ratatui terminal UI library: https://ratatui.rs/
74
+ - Crossterm terminal backend/events: https://github.com/crossterm-rs/crossterm
75
+ - Kattis problem package format: https://www.kattis.com/problem-package-format/
76
+ - ICPC judging guidelines: https://icpc.global/regionals/regional-contest-cookbook-judging-guidelines
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "practicode",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Local-first coding-test practice in a Rust terminal UI with optional AI help.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -12,6 +12,7 @@
12
12
  "practicode": "bin/practicode.js"
13
13
  },
14
14
  "scripts": {
15
+ "start": "node bin/practicode.js",
15
16
  "build": "cargo build --release --locked",
16
17
  "postinstall": "node scripts/npm-postinstall.js",
17
18
  "smoke": "node bin/practicode.js --smoke"
@@ -25,7 +26,8 @@
25
26
  "Cargo.lock",
26
27
  "Cargo.toml",
27
28
  "LICENSE",
28
- "README.md"
29
+ "README.md",
30
+ "THIRD_PARTY_LICENSES.md"
29
31
  ],
30
32
  "keywords": [
31
33
  "algorithms",
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ current=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
5
+ npm_current=$(node -p "require('./package.json').version")
6
+
7
+ if [[ "$current" != "$npm_current" ]]; then
8
+ echo "Cargo.toml version ($current) does not match package.json ($npm_current)" >&2
9
+ exit 1
10
+ fi
11
+
12
+ if [[ -n "$(git status --porcelain)" ]]; then
13
+ echo "working tree is dirty; commit or stash changes first" >&2
14
+ exit 1
15
+ fi
16
+
17
+ branch=$(git branch --show-current)
18
+ if [[ "$branch" != "main" ]]; then
19
+ echo "release from main, not $branch" >&2
20
+ exit 1
21
+ fi
22
+
23
+ git fetch origin main --tags
24
+ if [[ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]]; then
25
+ echo "local main is not synced with origin/main" >&2
26
+ exit 1
27
+ fi
28
+
29
+ echo "Current version: $current"
30
+ version="${1:-}"
31
+ if [[ -z "$version" ]]; then
32
+ read -r -p "Next version: " version
33
+ fi
34
+
35
+ if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
36
+ echo "version must look like 0.1.1" >&2
37
+ exit 2
38
+ fi
39
+
40
+ node -e '
41
+ const [current, next] = process.argv.slice(1).map(v => v.split(".").map(Number));
42
+ const ok = next[0] > current[0] ||
43
+ (next[0] === current[0] && (next[1] > current[1] ||
44
+ (next[1] === current[1] && next[2] > current[2])));
45
+ process.exit(ok ? 0 : 1);
46
+ ' "$current" "$version" || {
47
+ echo "next version must be greater than $current" >&2
48
+ exit 2
49
+ }
50
+
51
+ if git rev-parse -q --verify "refs/tags/v$version" >/dev/null; then
52
+ echo "tag v$version already exists locally" >&2
53
+ exit 1
54
+ fi
55
+ if git ls-remote --exit-code --tags origin "v$version" >/dev/null 2>&1; then
56
+ echo "tag v$version already exists on origin" >&2
57
+ exit 1
58
+ fi
59
+
60
+ echo "Releasing v$version"
61
+ VERSION="$version" perl -0pi -e 's/^version = ".*"/version = "$ENV{VERSION}"/m' Cargo.toml
62
+ node -e "const fs=require('fs'); const p=require('./package.json'); p.version=process.env.VERSION; fs.writeFileSync('package.json', JSON.stringify(p, null, 2) + '\n')"
63
+ cargo test
64
+ npm pack --dry-run >/dev/null
65
+
66
+ git add Cargo.toml Cargo.lock package.json
67
+ git commit -m "Release v$version"
68
+ git tag "v$version"
69
+ git push origin main "v$version"