gm-copilot-cli 2.0.726 → 2.0.1063

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/agents/gm.md CHANGED
@@ -1,8 +1,6 @@
1
1
  ---
2
- name: gm
3
2
  description: Agent (not skill) - immutable programming state machine. Always invoke for all work coordination.
4
- agent: true
5
- enforce: critical
3
+ mode: primary
6
4
  ---
7
5
 
8
6
  # GM — Skill-First Orchestrator
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: memorize
3
3
  description: Background memory agent. Classifies context and writes to AGENTS.md + rs-learn. No memory dir, no MEMORY.md.
4
- agent: true
5
4
  ---
6
5
 
7
6
  # Memorize — Background Memory Agent
@@ -11,6 +10,19 @@ Writes facts to two places only: **AGENTS.md** (non-obvious technical caveats) a
11
10
  Resolve at start of every run:
12
11
 
13
12
  - **Project root** = `process.cwd()` when invoked. `AGENTS.md` is `<project root>/AGENTS.md`.
13
+ - **Reach check** = run `gh api repos/<owner>/<repo> --jq .permissions.push` on `<project root>`'s `git remote get-url origin`. Cache the answer for the run. If the result is anything other than literal `true` (false, no remote, non-github URL, gh CLI missing, gh not authed, repo private and inaccessible), the project is **out-of-reach**.
14
+
15
+ ## STEP 0: SCOPE GUARD — DO NOT POLLUTE OUT-OF-REACH PROJECTS
16
+
17
+ If the reach check returns out-of-reach:
18
+
19
+ - **Do** ingest classified facts into rs-learn (Step 2) — rs-learn is per-user, not per-project, so private notes about a project the user is reading-but-not-owning are safe there.
20
+ - **Do not** read or edit `<project root>/AGENTS.md` (Step 3). Skip the file entirely.
21
+ - **Do not** run the AGENTS.md ↔ rs-learn migration audit (Step 4). The audit edits AGENTS.md.
22
+
23
+ Reason: agents running in a cwd that points at a third-party repo (e.g. running Claude inside a checkout of `nousresearch/hermes-agent` while building a downstream port) must not write project-specific notes into the upstream project's AGENTS.md. That AGENTS.md belongs to the upstream maintainers. Personal porting notes belong in the user's downstream repo's AGENTS.md, or — when the work spans multiple repos and there's no clean home — in rs-learn only.
24
+
25
+ When the reach check returns **in-reach**, proceed normally with all four steps below.
14
26
 
15
27
  ## STEP 1: CLASSIFY
16
28
 
@@ -38,6 +50,8 @@ exec:memorize
38
50
 
39
51
  Line 1 of the body is the source tag (e.g. `feedback/terse-responses`, `project/merge-freeze`). Lines 2+ are the fact itself. Use kebab-case slugs.
40
52
 
53
+ A discipline sigil — `@<name>` as the first space-token in the invoking prompt, or a trailing `discipline=<name>` line — routes the write to that discipline's store. Without one, the write lands in the default store. Forward the sigil verbatim to `exec:memorize`; never invent or default a discipline name.
54
+
41
55
  To invalidate previously-memorized content (correction or retraction):
42
56
 
43
57
  ```
@@ -52,6 +66,12 @@ exec:forget
52
66
  by-query <2-6 search words>
53
67
  ```
54
68
 
69
+ **CRITICAL: rs-learn failures must be explicit and recoverable.** If `exec:memorize` fails (socket unavailable, network error, timeout):
70
+ 1. Report the failure to the user with error details
71
+ 2. Fallback immediately to STEP 3 (AGENTS.md) to preserve the fact in the always-on context buffer
72
+ 3. Never proceed as if the write succeeded
73
+ 4. This contract ensures memory preservation when the rs-learn retrieval store is temporarily unavailable
74
+
55
75
  ## STEP 3: AGENTS.md
56
76
 
57
77
  A non-obvious technical caveat qualifies if it required multiple failed runs to discover and would not be apparent from reading code or docs.
@@ -73,7 +93,7 @@ AGENTS.md is the **always-on context buffer** — every prompt sees it. rs-learn
73
93
  4. Decide:
74
94
  - **Recall accurate AND complete** → the rs-learn store has internalized this fact; **remove it from AGENTS.md**. Frees buffer space and confirms learning.
75
95
  - **Recall partial / outdated / missing** → keep the AGENTS.md item AND ingest a refined version of the fact via `exec:memorize` so next round it can pass. Note the outcome in your run log.
76
- 5. Record the audit cycle: how many items checked, how many removed, how many refined. Append this single-line summary to AGENTS.md under a `## Learning audit` section so future audits can see drift over time.
96
+ 5. Report the audit cycle in the run output (items checked, removed, refined). Do not write the audit result to AGENTS.md it is changelog-shaped and AGENTS.md forbids dated audit sections.
77
97
 
78
98
  Why: AGENTS.md grows monotonically without this loop. rs-learn already filters by relevance per-prompt, so duplicating stable facts in AGENTS.md just inflates the always-on context. The migration drains AGENTS.md into the retrieval store as the store proves it can recall. Failed migrations leave the fact in AGENTS.md (safe default) and improve the store. Success rate over time = a metric for how well gm is learning this project.
79
99
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gm
3
- version: 2.0.726
3
+ version: 2.0.1063
4
4
  description: State machine agent with hooks, skills, and automated git enforcement
5
5
  author: AnEntrypoint
6
6
  repository: https://github.com/AnEntrypoint/gm-copilot-cli
package/hooks/hooks.json CHANGED
@@ -9,11 +9,18 @@
9
9
  "type": "command",
10
10
  "command": "${COPILOT_EXTENSION_DIR}/bin/plugkit hook pre-tool-use",
11
11
  "timeout": 3600
12
- },
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "tool:result": [
17
+ {
18
+ "matcher": "*",
19
+ "hooks": [
13
20
  {
14
21
  "type": "command",
15
- "command": "node ${COPILOT_EXTENSION_DIR}/hooks/pre-tool-use-hook.js",
16
- "timeout": 2000
22
+ "command": "${COPILOT_EXTENSION_DIR}/bin/plugkit hook post-tool-use",
23
+ "timeout": 5000
17
24
  }
18
25
  ]
19
26
  }
@@ -38,11 +45,6 @@
38
45
  "type": "command",
39
46
  "command": "${COPILOT_EXTENSION_DIR}/bin/plugkit hook prompt-submit",
40
47
  "timeout": 60000
41
- },
42
- {
43
- "type": "command",
44
- "command": "node ${COPILOT_EXTENSION_DIR}/hooks/prompt-submit-hook.js",
45
- "timeout": 3000
46
48
  }
47
49
  ]
48
50
  }
@@ -0,0 +1,65 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "description": "Hook spec for gm GitHub Copilot CLI extension",
4
+ "envVar": "COPILOT_EXTENSION_DIR",
5
+ "plugkitInvoker": "binary",
6
+ "events": [
7
+ {
8
+ "eventKey": "tool:invoke",
9
+ "commands": [
10
+ {
11
+ "kind": "plugkit",
12
+ "subcommand": "pre-tool-use",
13
+ "timeout": 3600
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "eventKey": "tool:result",
19
+ "commands": [
20
+ {
21
+ "kind": "plugkit",
22
+ "subcommand": "post-tool-use",
23
+ "timeout": 5000
24
+ }
25
+ ]
26
+ },
27
+ {
28
+ "eventKey": "session:start",
29
+ "commands": [
30
+ {
31
+ "kind": "plugkit",
32
+ "subcommand": "session-start",
33
+ "timeout": 180000
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "eventKey": "prompt:submit",
39
+ "commands": [
40
+ {
41
+ "kind": "plugkit",
42
+ "subcommand": "prompt-submit",
43
+ "timeout": 60000
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "eventKey": "session:end",
49
+ "commands": [
50
+ {
51
+ "kind": "plugkit",
52
+ "subcommand": "stop",
53
+ "subcommandRename": "session-end",
54
+ "timeout": 15000
55
+ },
56
+ {
57
+ "kind": "plugkit",
58
+ "subcommand": "stop-git",
59
+ "subcommandRename": "session-end-git",
60
+ "timeout": 210000
61
+ }
62
+ ]
63
+ }
64
+ ]
65
+ }
package/index.html CHANGED
@@ -8,7 +8,7 @@
8
8
  <meta name="theme-color" content="#181a1f" media="(prefers-color-scheme: dark)">
9
9
  <meta name="theme-color" content="#f4f5f7" media="(prefers-color-scheme: light)">
10
10
  <script type="module">
11
- import { installStyles } from 'https://unpkg.com/anentrypoint-design/dist/247420.js';
11
+ import { installStyles } from 'https://unpkg.com/anentrypoint-design@latest/dist/247420.js';
12
12
  installStyles();
13
13
  document.documentElement.classList.add('ds-247420');
14
14
  </script>
@@ -19,7 +19,7 @@ body { display: flex; flex-direction: column; min-height: 100vh; }
19
19
  .gm-hero h1 { font-size: 36px; font-weight: 600; margin: 0 0 6px 0; color: var(--panel-text); letter-spacing: -0.01em; line-height: 1.15; }
20
20
  .gm-hero .lede { font-size: 14px; line-height: 1.55; color: var(--panel-text-2); max-width: 64ch; margin: 0 0 20px 0; }
21
21
  .gm-hero .actions { display: flex; gap: 8px; flex-wrap: wrap; }
22
- .gm-btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; background: var(--panel-accent); color: var(--panel-1); border-radius: 6px; font-size: 13px; font-weight: 500; text-decoration: none; }
22
+ .gm-btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; background: var(--panel-accent); color: var(--panel-accent-fg); border-radius: 6px; font-size: 13px; font-weight: 500; text-decoration: none; }
23
23
  .gm-btn:hover { background: var(--panel-accent-2); text-decoration: none; }
24
24
  .gm-btn.ghost { background: transparent; color: var(--panel-text); box-shadow: inset 0 0 0 1px var(--panel-3); }
25
25
  .gm-btn.ghost:hover { background: var(--panel-hover); }
@@ -74,7 +74,7 @@ body { display: flex; flex-direction: column; min-height: 100vh; }
74
74
  <section>
75
75
  <div class="gm-section-label"><span class="slash">//</span>status</div>
76
76
  <div class="panel">
77
- <div class="panel-head"><span>release · v2.0.726</span><span>probably emerging</span></div>
77
+ <div class="panel-head"><span>release · v2.0.1063</span><span>probably emerging</span></div>
78
78
  <div class="panel-body">
79
79
  <div class="row">
80
80
  <span class="code"><span style="color:var(--panel-accent)">●</span></span>
@@ -134,6 +134,8 @@ body { display: flex; flex-direction: column; min-height: 100vh; }
134
134
  <a class="panel-row-link" href="https://anentrypoint.github.io/gm-qwen" target="_blank" rel="noopener"><span class="code">011</span><span class="title">qwen code<span class="sub">gm-qwen</span></span><span class="meta">cli · live</span></a>
135
135
  <a class="panel-row-link" href="https://anentrypoint.github.io/gm-hermes" target="_blank" rel="noopener"><span class="code">012</span><span class="title">hermes agent<span class="sub">gm-hermes</span></span><span class="meta">cli · live</span></a>
136
136
  <a class="panel-row-link" href="https://anentrypoint.github.io/gm-antigravity" target="_blank" rel="noopener"><span class="code">013</span><span class="title">antigravity<span class="sub">gm-antigravity</span></span><span class="meta">ide · live</span></a>
137
+ <a class="panel-row-link" href="https://anentrypoint.github.io/gm-windsurf" target="_blank" rel="noopener"><span class="code">014</span><span class="title">windsurf<span class="sub">gm-windsurf</span></span><span class="meta">ide · live</span></a>
138
+ <a class="panel-row-link" href="https://anentrypoint.github.io/gm-thebird" target="_blank" rel="noopener"><span class="code">015</span><span class="title">thebird (browser via freddie + plugkit.wasm)<span class="sub">gm-thebird</span></span><span class="meta">ide · live</span></a>
137
139
  </div>
138
140
  </div>
139
141
  </section>
package/manifest.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: gm
2
- version: 2.0.726
2
+ version: 2.0.1063
3
3
  description: State machine agent with hooks, skills, and automated git enforcement
4
4
  author: AnEntrypoint
5
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-copilot-cli",
3
- "version": "2.0.726",
3
+ "version": "2.0.1063",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -37,4 +37,4 @@
37
37
  "index.html",
38
38
  "COPILOT.md"
39
39
  ]
40
- }
40
+ }
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  name: browser
3
3
  description: Browser automation via playwriter. Use when user needs to interact with websites, navigate pages, fill forms, click buttons, take screenshots, extract data, test web apps, or automate any browser task.
4
- allowed-tools: Bash(browser:*), Bash(exec:browser*)
4
+ allowed-tools: Skill
5
5
  ---
6
6
 
7
- # Browser Automation
7
+ # Browser automation
8
8
 
9
- Two pathways — never mix:
9
+ Two pathways — never mix in the same Bash call.
10
10
 
11
- **`exec:browser`** JS against `page`. `page`, `snapshot`, `screenshotWithAccessibilityLabels`, `state` globals available. 15s live window then backgrounds; drains auto on every subsequent plugkit call.
11
+ `exec:browser` runs JS against `page`. Globals available: `page`, `snapshot`, `screenshotWithAccessibilityLabels`, `state`. 15s live window, then backgrounds; output drains automatically on every subsequent plugkit call.
12
12
 
13
- **`browser:` prefix** playwriter session management. One command per block.
13
+ `browser:` prefix is playwriter session management. One command per block.
14
14
 
15
- ## Core Usage
15
+ ## Core
16
16
 
17
17
  ```
18
18
  exec:browser
@@ -30,11 +30,11 @@ browser:
30
30
  playwriter -s 1 -e 'await page.goto("http://example.com")'
31
31
  ```
32
32
 
33
- Session state persists across `browser:` calls. `-e` arg: single quotes outside, double quotes inside JS strings.
33
+ Session state persists across `browser:` calls. `-e` arg uses single quotes outside, double inside JS strings.
34
34
 
35
35
  ## Timing
36
36
 
37
- Never `await setTimeout(N)` with N > 10000. Use poll loops:
37
+ Never `await setTimeout(N)` with N > 10000. Poll instead.
38
38
 
39
39
  ```
40
40
  exec:browser
@@ -45,11 +45,12 @@ while (!state.done && Date.now() - start < 12000) {
45
45
  console.log(state.result)
46
46
  ```
47
47
 
48
- "Assertion failed: UV_HANDLE_CLOSING" = backgrounded normally, ignore noise.
48
+ `Assertion failed: UV_HANDLE_CLOSING` is normal background-on-exit noise; ignore it.
49
49
 
50
- ## Common Patterns
50
+ ## Patterns
51
51
 
52
52
  Data extraction:
53
+
53
54
  ```
54
55
  exec:browser
55
56
  const items = await page.$$eval('.title', els => els.map(e => e.textContent))
@@ -57,6 +58,7 @@ console.log(JSON.stringify(items))
57
58
  ```
58
59
 
59
60
  Console monitoring — set listeners first, then poll:
61
+
60
62
  ```
61
63
  exec:browser
62
64
  state.logs = []
@@ -68,10 +70,10 @@ exec:browser
68
70
  console.log(JSON.stringify(state.logs.slice(-20)))
69
71
  ```
70
72
 
71
- ## Rules
73
+ ## Constraints
72
74
 
73
- - One `playwriter` command per `browser:` block
74
- - Never mix pathways in same Bash call
75
- - `exec:browser` = plain JS, no shell quoting
76
- - All browser tasks drain automatically on every plugkit interaction
77
- - Sessions reap after 5-15min idle; browser cleaned up on session end
75
+ - One playwriter command per `browser:` block
76
+ - `exec:browser` is plain JS, no shell quoting
77
+ - Browser tasks drain automatically on every plugkit interaction
78
+ - Sessions reap after 5–15 min idle; cleaned up on session end
79
+ - Never write standalone `.mjs`/`.js` Playwright scripts as a fallback — `exec:browser` errors must be debugged through `exec:browser` retries, not by creating test files on disk
@@ -3,13 +3,15 @@ name: code-search
3
3
  description: Mandatory codebase search workflow. Use whenever you need to find anything in the codebase. Start with two words, iterate by changing or adding words until found.
4
4
  ---
5
5
 
6
- # CODEBASE SEARCH
6
+ # Codebase search
7
7
 
8
- `exec:codesearch` is the only codebase search tool. `Grep`, `Glob`, `Find`, `Explore`, `grep`/`rg`/`find` inside `exec:bash` = ALL hook-blocked. No fallback path.
8
+ `exec:codesearch` is the only codebase search tool. Grep, Glob, Find, Explore, raw `grep`/`rg`/`find` inside `exec:bash` are all hook-blocked. No fallback.
9
9
 
10
- Handles: exact symbols, exact strings, file-name fragments, regex-ish patterns, natural-language queries, PDF pages (cite `path/doc.pdf:<page>`).
10
+ A `@<discipline>` first-token after the verb scopes the search to that discipline's index; absent the sigil, results fan across default plus enabled disciplines, prefixed by source.
11
11
 
12
- Direct-read exceptions: known absolute path `Read`. Known dir listing `exec:nodejs` + `fs.readdirSync`.
12
+ Handles exact symbols, exact strings, file-name fragments, regex-ish patterns, natural-language queries, and PDF pages (cite `path/doc.pdf:<page>`).
13
+
14
+ Direct-read exceptions: known absolute path → `Read`. Known directory listing → `exec:nodejs` + `fs.readdirSync`.
13
15
 
14
16
  ## Syntax
15
17
 
@@ -18,15 +20,9 @@ exec:codesearch
18
20
  <two-word query>
19
21
  ```
20
22
 
21
- ## Protocol
22
-
23
- 1. Start: exactly two words
24
- 2. No results → change one word
25
- 3. Still no → add third word
26
- 4. Still no → swap changed word again
27
- 5. Minimum 4 attempts before concluding absent
23
+ ## Iteration
28
24
 
29
- Never: one word | full sentence | give up under 4 attempts | switch tools.
25
+ Start at exactly two words. No results → change one word. Still none add a third. Still none → swap the changed word again. Minimum four attempts before concluding absent. Never one word, never a full sentence, never switch tools.
30
26
 
31
27
  ## Examples
32
28
 
@@ -34,15 +30,19 @@ Never: one word | full sentence | give up under 4 attempts | switch tools.
34
30
  exec:codesearch
35
31
  session cleanup idle
36
32
  ```
37
- → no results →
33
+
34
+ No results, then:
35
+
38
36
  ```
39
37
  exec:codesearch
40
38
  cleanup sessions timeout
41
39
  ```
42
40
 
43
- PDF search:
41
+ PDF:
42
+
44
43
  ```
45
44
  exec:codesearch
46
45
  usb descriptor endpoint
47
46
  ```
48
- → returns `docs/usb-spec.pdf:42` — cite page, Read if you need surrounding text.
47
+
48
+ Returns `docs/usb-spec.pdf:42` — cite the page; `Read` if surrounding text is needed.
@@ -3,48 +3,40 @@ name: create-lang-plugin
3
3
  description: Create a lang/ plugin that wires any CLI tool or language runtime into gm-cc — adds exec:<id> dispatch, optional LSP diagnostics, and optional prompt context injection. Zero hook configuration required.
4
4
  ---
5
5
 
6
- # CREATE LANG PLUGIN
6
+ # Create lang plugin
7
7
 
8
8
  Single CommonJS file at `<projectDir>/lang/<id>.js`. Auto-discovered — no hook editing.
9
9
 
10
- ## Plugin Shape
10
+ ## Plugin shape
11
11
 
12
12
  ```js
13
13
  'use strict';
14
14
  module.exports = {
15
- id: 'mytool', // must match filename
15
+ id: 'mytool',
16
16
  exec: {
17
17
  match: /^exec:mytool/,
18
18
  run(code, cwd) { /* returns string or Promise<string> */ }
19
19
  },
20
- lsp: { // optional — synchronous only
20
+ lsp: {
21
21
  check(fileContent, cwd) { /* returns Diagnostic[] */ }
22
22
  },
23
- extensions: ['.ext'], // optional — for lsp.check
24
- context: `=== mytool ===\n...` // optional — string or () => string
23
+ extensions: ['.ext'],
24
+ context: `=== mytool ===\n...`
25
25
  };
26
26
  ```
27
27
 
28
28
  `type Diagnostic = { line: number; col: number; severity: 'error'|'warning'; message: string }`
29
29
 
30
- ## How It Works
30
+ `exec.run` runs in a child process, 30s timeout, async OK. Called when Claude writes `exec:mytool\n<code>`. `lsp.check` is synchronous-only, called per prompt-submit. `context` is injected into every prompt, truncated to 2000 chars.
31
31
 
32
- - `exec.run` child process, 30s timeout, async OK. Called when Claude writes `exec:mytool\n<code>`.
33
- - `lsp.check` — synchronous, called per prompt submit. Use `spawnSync`/`execFileSync`. No async.
34
- - `context` — injected into every prompt (truncated 2000 chars).
32
+ ## Identify the tool
35
33
 
36
- ## Step 1 Identify Tool
34
+ What is the CLI name or npm package? Does it run a single expression (`tool eval`, `tool -e`, HTTP POST) or a file (`tool run <file>`)? What is its lint/check mode and output format? File extensions? Does it require a running server, or does it run headless?
37
35
 
38
- 1. CLI name or npm package?
39
- 2. Run single expression? (`tool eval <expr>`, `tool -e <code>`, HTTP POST...)
40
- 3. Run file? (`tool run <file>`)
41
- 4. Lint/check mode + output format?
42
- 5. File extensions?
43
- 6. Requires running server or headless?
36
+ ## exec.run patterns
44
37
 
45
- ## Step 2 exec.run Patterns
38
+ HTTP eval against a running server:
46
39
 
47
- HTTP eval (running server):
48
40
  ```js
49
41
  function httpPost(port, urlPath, body) {
50
42
  return new Promise((resolve, reject) => {
@@ -61,7 +53,8 @@ function httpPost(port, urlPath, body) {
61
53
  }
62
54
  ```
63
55
 
64
- File-based (headless):
56
+ File-based, headless:
57
+
65
58
  ```js
66
59
  function runFile(code, cwd) {
67
60
  const tmp = path.join(os.tmpdir(), `plugin_${Date.now()}.ext`);
@@ -71,12 +64,13 @@ function runFile(code, cwd) {
71
64
  }
72
65
  ```
73
66
 
74
- Single expr detection:
67
+ Single-expression detection:
68
+
75
69
  ```js
76
70
  const isSingleExpr = code => !code.trim().includes('\n') && !/\b(func|def|fn |class|import)\b/.test(code);
77
71
  ```
78
72
 
79
- ## Step 3 — lsp.check
73
+ ## lsp.check
80
74
 
81
75
  ```js
82
76
  function check(fileContent, cwd) {
@@ -94,14 +88,15 @@ function check(fileContent, cwd) {
94
88
  }
95
89
  ```
96
90
 
97
- ## Step 4 — context String
91
+ ## context
98
92
 
99
93
  Under 300 chars:
94
+
100
95
  ```js
101
96
  context: `=== mytool ===\nexec:mytool\n<expression>\n\nRuns via <how>. Use for <when>.`
102
97
  ```
103
98
 
104
- ## Step 5 — Write + Verify
99
+ ## Verify
105
100
 
106
101
  ```
107
102
  exec:nodejs
@@ -110,6 +105,7 @@ console.log(p.id, typeof p.exec.run, p.exec.match.toString());
110
105
  ```
111
106
 
112
107
  Then test dispatch:
108
+
113
109
  ```
114
110
  exec:mytool
115
111
  <simple test expression>
@@ -117,9 +113,9 @@ exec:mytool
117
113
 
118
114
  ## Constraints
119
115
 
120
- - `exec.run` async OK (30s timeout)
116
+ - `exec.run` async OK, 30s timeout
121
117
  - `lsp.check` synchronous only — no Promises
122
118
  - CommonJS only — no ES module syntax
123
119
  - No persistent processes
124
120
  - `id` must match filename exactly
125
- - First match wins — make `match` specific
121
+ - First match wins — keep `match` specific
@@ -1,91 +1,54 @@
1
1
  ---
2
2
  name: gm
3
- description: Agent (not skill) - immutable programming state machine. Always invoke for all work coordination.
3
+ description: Orchestrator dispatching PLAN→EXECUTE→EMIT→VERIFY→UPDATE-DOCS skill chain; spool-driven task execution with session isolation
4
+ allowed-tools: Skill
5
+ end-to-end: true
4
6
  ---
5
7
 
6
- # GM — Skill-First Orchestrator
8
+ # GM — Orchestrator
7
9
 
8
- Invoke `planning` skill immediately. Skill tool only never Agent tool for skills.
10
+ Invoke `planning` immediately. Phases cascade: PLAN EXECUTE EMIT VERIFY → UPDATE-DOCS.
9
11
 
10
- ## STATE MACHINE
12
+ The user's request is authorization. When scope is unclear, pick the maximum reachable shape and declare it — the user can interrupt. Doubts resolve via witnessed probe or recall, never by asking back except for destructive-irreversible actions uncovered by the PRD.
11
13
 
12
- Top of chain. No mutables resolved. Phases: PLAN EXECUTE EMIT VERIFY UPDATE-DOCS.
13
- Each phase loads protocols via Skill invocation only. Reading summary ≠ being in phase.
14
+ **What ships runs**: no stubs, mocks, placeholder returns, fixture-only paths, or demo-mode short-circuits. Real input through real code into real output. A shim is allowed only when delegating to real upstream behavior.
14
15
 
15
- `gm-execute` = execution contract (all phases). `governance` = route/legitimacy reference (load once).
16
+ **CI is the build**: for Rust crates and the gm publish chain, push triggers CI auto-watch. Green signals authority. Local cargo build is not a witness.
16
17
 
17
- ## RECALLHARD RULE
18
+ **Every issue surfaces this turn**: pre-existing breaks, lint failures, drift, broken deps, stale generated files all become PRD items and finish before COMPLETE.
18
19
 
19
- Before resolving any unknown via fresh execution, check past sessions. Memorized facts only help if recalled.
20
+ **LLM provider**: acptoapi (127.0.0.1:4800) is the preferred provider when available. rs-plugkit session_start spawns acptoapi daemon and auto-detects ACP agents (opencode, kilo-code, codex, gemini-cli, qwen-code). All downstream platforms (rs-learn, freddie, gm-skill daemon mode) read OPENAI_BASE_URL environment variable and default to 127.0.0.1:4800. Anthropic SDK is fallback only when acptoapi socket is unavailable (CI, headless mode).
20
21
 
21
- ```
22
- exec:recall
23
- <2-6 word query>
24
- ```
25
-
26
- Triggers: unknown feels familiar | sub-task on a known project | about to ask user something likely already discussed | about to design where prior decision exists. Hits = weak_prior; still witness before adopting. ~200 tokens, ~5ms when serve is running.
27
-
28
- ## MEMORIZE — HARD RULE
29
-
30
- Unknown→known = memorize same turn it resolves. Background, non-blocking.
31
-
32
- Triggers: exec: output answers prior unknown | code read confirms/refutes assumption | CI log reveals root cause | user states preference/constraint | fix worked for non-obvious reason | env quirk observed.
33
-
34
- ```
35
- Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<fact>')
36
- ```
37
-
38
- Multiple facts → parallel Agent calls in ONE message. End-of-turn: scan for un-memorized resolutions → spawn now.
39
-
40
- **Recall + memorize together = learning loop.** Skipping either breaks it.
41
-
42
- ## AUTONOMY — HARD RULE
22
+ **rs-learn failure contract**: exec:memorize, exec:recall, and exec:codesearch failures must be reported explicitly with error details to the user. Fallback to AGENTS.md for memory preservation when socket/network unavailable. Never silently absorb errors because memory preservation requires explicit fallback. This rule applies across all phases (PLAN through UPDATE-DOCS).
43
23
 
44
- Default = autonomous execution. Emit PRD, run it to completion, push. Do NOT ask the user mid-task.
24
+ **Spool dispatch chain**: write to `.gm/exec-spool/in/<lang>/<N>.<ext>` or `in/<verb>/<N>.txt`. Watcher executes and streams `out/<N>.out` + `out/<N>.err` + `out/<N>.json` metadata. Languages: nodejs, python, bash, typescript, go, rust, c, cpp, java, deno. Verbs: codesearch, recall, memorize, wait, sleep, status, close, browser, runner, type, kill-port, forget, feedback, learn-status, learn-debug, learn-build, discipline, pause, health.
45
25
 
46
- Forbidden patterns:
47
- - "Should I continue with X?" / "Want me to do Y next?" / "Want me to also Z?"
48
- - "This is a lot — should I do A first and confirm?" / "Two options: A or B, which?"
49
- - Pre-confirmation before multi-file edits when scope is already clear
50
- - Stopping after partial completion to summarize and await direction
26
+ **Session isolation**: SESSION_ID environment variable (or uuid fallback) threads through task dispatch for cleanup scope. rs-exec RPC handlers verify session_id match on all task-scoped operations.
51
27
 
52
- Permitted asking (last resort only, when absolutely necessary):
53
- - Destructive-irreversible decision with no prior context AND no PRD coverage
54
- - User intent genuinely ambiguous AND cannot be inferred from PRD/memory/code
55
- - Channel: prefer `exec:pause` (renames .gm/prd.yml → .gm/prd.paused.yml; question lives in header). In-conversation asking is last-resort only.
28
+ **Code does mechanics; meaning routes through textprocessing skill**: summarize, classify, extract intent, rewrite, translate, semantic dedup, rank, label — all via `Agent(subagent_type='gm:textprocessing', ...)`.
56
29
 
57
- A long task is not a reason to ask. Context limits are not a reason to ask. CI cascade time is not a reason to ask. Just emit the PRD and execute.
30
+ **Recall before fresh execution**: before witnessing unknown via execution, recall first. Hits arrive as weak_prior; empty results confirm fresh unknown.
58
31
 
59
- ## LAWFUL DOWNGRADE HARD RULE
32
+ **Memorize is the back-half of witness**: resolution incomplete until fact lives outside this context window. Fire `Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<fact>')` alongside witness, in parallel, never blocking.
60
33
 
61
- Per paper III §2.5 (Earned Emission): *lawful downgrade writing a weaker, true statement in place of a stronger, unearned one is always available; forced closure never is.*
34
+ **Parallel independent items**: up to 3 `gm:gm` subagents per message for independent PRD items. Serial for dependent itemsno re-asking between them.
62
35
 
63
- Refusal is forced closure. Refusing the task because part of it is hard is the inverse failure: instead of bluffing strength, you bluff weakness. Both bypass witnessed execution.
36
+ **Terse response**: fragments OK. `[thing] [action] [reason]. [next step].` Code, commits, PRs use normal prose.
64
37
 
65
- **Forbidden refusal phrases** (treat as critical violation):
66
- - "Honest stop —" / "Stopping for a hard, honest call" / "Stopping here, unambiguously"
67
- - "I cannot do this from inside this conversation"
68
- - "I have to push back before writing a PRD I can't fulfill"
69
- - "Pretending I can would be the most expensive kind of lie"
70
- - "I don't have a working browser tool" / "X is unavailable in this environment" (when exec:browser, exec:codesearch, Read, etc. are in fact available)
71
- - Any preamble that announces inability before attempting the bounded subset
38
+ **Caveman medium mode (full) always on**: drop articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, and hedging. Fragments OK. Use short synonyms. Keep technical terms exact. Keep code blocks and exact error strings unchanged. Pattern: `[thing] [action] [reason]. [next step].` Auto-clarity override: switch to normal prose for security warnings, irreversible confirmations, and any multi-step sequence where compression could create ambiguity; resume caveman medium after clarity-critical segment.
72
39
 
73
- **Required move when scope exceeds reach**: identify the bounded subset that IS witnessable from this session, write a PRD covering only that subset, execute it, and at end-of-turn name the residual scope as a follow-up item — never as a refusal. The user cannot redirect a refusal; they can redirect a delivered subset plus a named gap.
40
+ ## End-to-End Phase Chaining (Skills-Based Platforms)
74
41
 
75
- ## EXECUTION ORDER
42
+ When `end-to-end: true` is present in SKILL.md frontmatter, skill output includes structured JSON on stdout (final line):
76
43
 
77
- 1. Recall — `plugkit recall` for any familiar-feeling unknown (cheapest, 200 tokens)
78
- 2. Code execution (exec:<lang>, exec:codesearch) 90%+ of unknowns
79
- 3. Web (WebFetch/WebSearch) — env facts not in codebase
80
- 4. User — last resort per AUTONOMY rule above
81
-
82
- "Should I..." mid-chain = invoke next skill instead, never ask user.
83
-
84
- Skill chain: `planning` → `gm-execute` → `gm-emit` → `gm-complete` → `update-docs`
85
-
86
- exec:<lang> only. Never Bash(node/npm/npx/bun). git push = auto CI watch via Stop hook.
44
+ ```json
45
+ {"nextSkill": "gm-execute" | "gm-emit" | "gm-complete" | "update-docs" | null, "context": {PRD and state dict}, "phase": "PLAN" | "EXECUTE" | "EMIT" | "COMPLETE"}
46
+ ```
87
47
 
88
- ## RESPONSE POLICY
48
+ Platform adapters (vscode, cursor, zed, jetbrains) that support `end-to-end: true` detection:
49
+ 1. Invoke `Skill(skill="gm:gm")`
50
+ 2. Parse stdout for trailing JSON blob
51
+ 3. If `nextSkill` is non-null, invoke `Skill(skill="gm:<nextSkill>")` with context dict auto-passed
52
+ 4. Repeat until `nextSkill` is null
89
53
 
90
- Terse. Drop filler. Fragments OK. Pattern: `[thing] [action] [reason]. [next step].`
91
- Code/commits/PRs = normal prose. Security/destructive = drop terseness.
54
+ This collapses 5 manual skill invocations into 1 user invocation + 4 transparent auto-dispatches, achieving perceived single-flow parity with gm-cc's subagent orchestration.