prune: drop file cmd (files are the API); wiki editing is a skill convention
Message
prune: drop file cmd (files are the API); wiki editing is a skill convention
Diff
OUTLINE.md+3 −2
--- a/OUTLINE.md+++ b/OUTLINE.md@@ -79,8 +79,9 @@ Port as gh (models are trained on gh; keep the muscle memory):7979 schemas (`number,title,state,labels,assignees,milestone,body`,8080 `databaseId,status,conclusion`, …). Never parse human text.8181 82-The one deliberate difference: `gh api` → direct file access83-(`f0rge file get .forge/…`), because the files *are* the API.82+The one deliberate difference: there is no `gh api` — the files83+*are* the API; any agent already in the repo reads and edits `.forge/`84+directly.8485 8586 Better than gh (nothing to inherit):8687
PLAN.md+4 −3
--- a/PLAN.md+++ b/PLAN.md@@ -160,7 +160,6 @@ f0rge160160 ├── release create list view161161 ├── merge <folder|zip|branch>162162 ├── init [dir]163-├── file get put # the gh-api replacement: raw file access164163 └── --skill # the contract, short165164 ```166165 @@ -258,8 +257,10 @@ per SEC-07.258257 Input: M1, M2.259258 260259 - `wiki get <path>`, `put <path> -` (stdin), `list` (index derived from261- tree + first H1; never stored). `wiki edit` opens `$EDITOR` or wr1te if262- configured. Paths are flat-ish (`docs/`, `research/`, `experiments/`).260+ tree + first H1; never stored). Wiki editing is a skill convention, not261+ a command: pages are `.forge/wiki/` files — edit them in place with262+ editor tools (or wr1te), or via `wiki put <path> -`. Paths are flat-ish263+ (`docs/`, `research/`, `experiments/`).263264 - `release create <ver> --notes <file|->`: write `releases/<ver>.md`,264265 then run `releases/build/` scripts at the tag: checkout, build per265266 platform into `out/` (gitignored). `release list|view`.
crates/cli/src/cmd/file.rs+0 −9
--- a/crates/cli/src/cmd/file.rs+++ /dev/null@@ -1,9 +0,0 @@1-#![forbid(unsafe_code)]2-//! f0rge file: raw files. PLAN M2 stub; owner module implements.3-use crate::CliError;4-pub fn help() -> &'static str {5- "f0rge file: raw access\nusage: f0rge file <get|put> <path>\npaths stay under .forge/\n"6-}7-pub fn run(_args: &[String], _fg: &f0rge_core::Forge) -> Result<(), CliError> {8- Err(CliError::Usage("not implemented: file".to_string()))9-}
crates/cli/src/cmd/mod.rs+2 −6
--- a/crates/cli/src/cmd/mod.rs+++ b/crates/cli/src/cmd/mod.rs@@ -4,7 +4,6 @@44 //! except the single registration line (already present).55 66 pub mod ci;7-pub mod file;87 pub mod init;98 pub mod issue;109 pub mod label;@@ -23,7 +22,7 @@ use crate::CliError;2322 pub const ROOT_HELP: &str = "f0rge: local forge\n\2423 usage: f0rge [--json|--jq E|--skill] <cmd> [args]\n\2524 issue pr task label milestone ci wiki\n\26-release merge init file skill\n\25+release merge init skill\n\2726 'cmd -h' for help\n";2827 2928 /// Dispatch over subcommand names (mirror of folder tree).@@ -49,7 +48,6 @@ pub fn dispatch(4948 "release" => release::run(args, fg),5049 "merge" => merge::run(args, fg),5150 "init" => init::run(args, fg),52- "file" => file::run(args, fg),5351 "skill" => skill::run(args, fg),5452 _ => Err(CliError::Usage(format!("unknown command: {sub}"))),5553 }@@ -67,13 +65,12 @@ fn help_for(sub: &str) -> Option<&'static str> {6765 "release" => release::help(),6866 "merge" => merge::help(),6967 "init" => init::help(),70- "file" => file::help(),7168 "skill" => skill::help(),7269 _ => return None,7370 })7471 }7572 76-/// All sub helps for budget tests (exactly 12).73+/// All sub helps for budget tests (exactly 11).7774 #[allow(dead_code)]7875 pub fn all_helps() -> Vec<(&'static str, &'static str)> {7976 vec![@@ -87,7 +84,6 @@ pub fn all_helps() -> Vec<(&'static str, &'static str)> {8784 ("release", release::help()),8885 ("merge", merge::help()),8986 ("init", init::help()),90- ("file", file::help()),9187 ("skill", skill::help()),9288 ]9389 }
crates/cli/src/cmd/skill.rs+1 −0
--- a/crates/cli/src/cmd/skill.rs+++ b/crates/cli/src/cmd/skill.rs@@ -14,6 +14,7 @@ files: one file per entity; command tree mirrors folder tree\n\1414 frontmatter: strict --- fences; unknown field warning; missing required error\n\1515 ci verdict: step exit code; pass|fail|running|cancelled\n\1616 never delete: close/archive only; archive moves folder\n\17+wiki: pages are files under wiki/; edit in place or via stdin\n\1718 usage: f0rge [--json] <cmd> [args]; --jq uses system jq\n\1819 json: compact fixed order; empty is [] or {}\n";1920
crates/cli/src/main.rs+1 −1
--- a/crates/cli/src/main.rs+++ b/crates/cli/src/main.rs@@ -102,7 +102,7 @@ mod budget_tests {102102 #[test]103103 fn all_sub_helps_within_budget() {104104 let helps = crate::cmd::all_helps();105- assert_eq!(helps.len(), 12, "expected 12 sub helps");105+ assert_eq!(helps.len(), 11, "expected 11 sub helps");106106 for (name, h) in helps {107107 let (lines, bytes) = lines_and_bytes(h);108108 assert!(lines <= 8, "{name} -h {lines} lines > 8");
crates/cli/tests/cli.rs+1 −1
--- a/crates/cli/tests/cli.rs+++ b/crates/cli/tests/cli.rs@@ -22,7 +22,7 @@ fn lines_and_bytes(s: &str) -> (usize, usize) {2222 }2323 2424 const SUBS: &[&str] =25- &["issue", "pr", "task", "label", "milestone", "ci", "wiki", "release", "merge", "init", "file", "skill"];25+ &["issue", "pr", "task", "label", "milestone", "ci", "wiki", "release", "merge", "init", "skill"];2626 2727 #[test]2828 fn root_help_within_budget() {
skill/skill.md+2 −0
--- a/skill/skill.md+++ b/skill/skill.md@@ -10,6 +10,8 @@ tree mirrors folders:1010 issue <-> issues/ pr <-> prs/1111 task <-> tasks/ ci <-> ci/1212 wiki <-> wiki/ release <-> releases/13+wiki pages are .forge/wiki/ files:14+edit in place (or wr1te) or `wiki put <path> -`.1315 discover: run `f0rge`; `cmd -h` for verbs.1416 never parse prose; always use --json.1517 `f0rge --skill` prints the contract.