@clipboard-health/groundcrew 1.7.4 → 1.8.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <h1 align="center">groundcrew</h1>
2
2
  <p align="center">
3
- <img alt="Groundcrew logo." height="250px" src="../../static/groundcrew.svg">
3
+ <img alt="Groundcrew logo." height="250px" src="./static/groundcrew.svg">
4
4
  </p>
5
5
 
6
6
  Watch a Linear project and farm out ready tickets to coding-agent CLIs running in workspaces backed by git worktrees. Workspaces are [`cmux`](https://github.com/clayton-cole/cmux) panes on macOS or `tmux` windows on Linux/macOS.
@@ -58,7 +58,7 @@ This installs the `crew` binary. `@clipboard-health/clearance` is pulled in tran
58
58
 
59
59
  Local setup fails before creating a worktree when the host is not macOS or `safehouse` is missing. `models.isolation`, per-model `isolation`, and per-model `sandbox` are legacy keys and now fail config validation.
60
60
 
61
- 6. **Set the clearance allowlist for local macOS runs.** Groundcrew starts `clearance` from `@clipboard-health/clearance` on `http://127.0.0.1:19999` (skipping the launch if something is already listening) and runs the agent through the bundled `safehouse-clearance` wrapper. Clearance refuses to start without an allowlist — see [its README](../clearance/README.md) for the proxy's env vars, log paths, and DNS rules. The shortest path is to set the env before `crew run`:
61
+ 6. **Set the clearance allowlist for local macOS runs.** Groundcrew starts `clearance` from `@clipboard-health/clearance` on `http://127.0.0.1:19999` (skipping the launch if something is already listening) and runs the agent through the bundled `safehouse-clearance` wrapper. Clearance refuses to start without an allowlist — see [its README](https://github.com/ClipboardHealth/core-utils/tree/main/packages/clearance) for the proxy's env vars, log paths, and DNS rules. The shortest path is to set the env before `crew run`:
62
62
 
63
63
  ```bash
64
64
  CLEARANCE_ALLOW_HOSTS="api.openai.com,auth.openai.com,api.anthropic.com,mcp.linear.app,api.linear.app" \
@@ -82,8 +82,8 @@ This installs the `crew` binary. `@clipboard-health/clearance` is pulled in tran
82
82
  --codex \
83
83
  --copy-local-codex-auth \
84
84
  --github \
85
- --git-name "Rocky Warren" \
86
- --git-email "1085683+therockstorm@users.noreply.github.com" \
85
+ --git-name "Your Name" \
86
+ --git-email "you@users.noreply.github.com" \
87
87
  --mcp linear \
88
88
  --mcp slack \
89
89
  --checkpoint
@@ -167,6 +167,7 @@ crew cleanup <TICKET>
167
167
  - **Safehouse-already-wrapped commands are not re-wrapped.** If a `models.definitions.<name>.cmd` already starts with `safehouse`, groundcrew assumes that command owns its Safehouse flags and does not add the `safehouse-clearance` wrapper a second time. Changing the proxy's allowlist after it's running requires killing the PID in `${XDG_CACHE_HOME:-$HOME/.cache}/clearance/clearance.pid` so the next launch picks up the new env.
168
168
  - **Legacy Docker Sandboxes state is unmanaged.** Groundcrew no longer discovers or cleans `.sbx` worktrees or persistent Docker Sandboxes containers. If you have old state, inspect and remove it manually with `sbx`.
169
169
  - **Remote cleanup is also conservative.** `crew cleanup` removes tracked remote worktrees and branches, but it does not kill active remote sessions. Use `crew remote sessions [<runner-name>]` to inspect sessions and, with the Sprite provider, `sprite sessions kill -s <runner-name> <session-id>` when Git reports a worktree is busy.
170
+ - **Dead tmux windows vanish by default.** When a wrapped agent command fails (e.g. `safehouse-clearance` not found, `npm install` crash), the tmux window closes immediately and the error scrolls into the void. Set `GROUNDCREW_KEEP_DEAD_WINDOWS=1` (any non-empty value works) in the env you launch `crew` from to flip the per-window `remain-on-exit` to `on`; the window stays open with the error visible. Close it manually with `tmux kill-window -t groundcrew:<ticket>` after diagnosis. tmux backend only.
170
171
  - **Long-running remote shell tools block agent input.** Claude Code and similar TUI agents cannot accept a new prompt while one of their shell tools is still running. Use `crew remote ps <runner-name>` to inspect the remote process tree; interrupt the tool's child `PGID`, not the agent session `PGID`, with `crew remote interrupt <PGID> --runner <runner-name>`.
171
172
  - **Codex auth in remote runners may need auth-file copy.** If `crew remote setup <runner-name> --codex` finishes interactive login but `codex login status` still fails inside the remote runner, rerun with `--copy-local-codex-auth` after confirming local Codex auth works.
172
173
  - **Usage source defaults are OS-aware.** `codexbar` usage uses `--source auto` on macOS so CodexBar can prefer account/web sources and fall back as it supports. On Linux/WSL it uses `--source cli`, so install the CodexBar Linux CLI and authenticate the provider CLIs inside that environment.
@@ -182,10 +183,10 @@ crew cleanup <TICKET>
182
183
 
183
184
  ## Hacking on groundcrew
184
185
 
185
- For developers working on the package itself, the source lives in [`ClipboardHealth/core-utils`](https://github.com/ClipboardHealth/core-utils). Clone it, run `npm install`, and the repo's `crew` / `crew:op` scripts execute groundcrew straight from TypeScript source — no build step. The bin's `runCli` helper re-execs node with `--conditions @clipboard-health/source` so `@clipboard-health/clearance` also resolves to source.
186
+ For developers working on the package itself, clone this repo, run `npm install`, and the repo's `crew` / `crew:op` scripts execute groundcrew straight from TypeScript source — no build step. Package dependencies, including `@clipboard-health/clearance`, resolve through normal npm package exports.
186
187
 
187
188
  ```bash
188
- cd ~/dev/c/core-utils
189
+ cd ~/dev/c/groundcrew
189
190
  node --run crew -- doctor
190
191
 
191
192
  # With 1Password for LINEAR_API_KEY:
@@ -196,4 +197,4 @@ Both forms read `${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/config.ts` by defa
196
197
 
197
198
  Logs land in `${XDG_STATE_HOME:-$HOME/.local/state}/groundcrew/groundcrew.log` by default (override via `logging.file` in your config). The "Loaded config from …" line at startup tells you which config won.
198
199
 
199
- Source edits in `packages/{clearance,groundcrew}/src/**` are picked up on the next invocation. Requires Node ≥ 24.3 (the version with native `.ts` type stripping enabled by default).
200
+ Source edits in `src/**` are picked up on the next invocation. Requires Node ≥ 24.3 (the version with native `.ts` type stripping enabled by default).
package/bin/runCli.js CHANGED
@@ -7,9 +7,8 @@ import { pathToFileURL } from "node:url";
7
7
  /**
8
8
  * Load a side-effecting entrypoint by basename. In published/built mode,
9
9
  * dynamically imports the compiled `dist/${name}.js` in-process. In source/dev
10
- * mode (no compiled output present), spawns a child node that loads the `.ts` source with
11
- * `--conditions @clipboard-health/source` so cross-package bare imports of
12
- * `@clipboard-health/*` workspace deps also resolve to source.
10
+ * mode (no compiled output present), spawns a child node that loads the `.ts`
11
+ * source while dependencies resolve through normal package exports.
13
12
  *
14
13
  * @param {string} packageRoot
15
14
  * @param {string} name
@@ -22,11 +21,9 @@ export async function runCli(packageRoot, name) {
22
21
  }
23
22
 
24
23
  const sourcePath = join(packageRoot, "src", `${name}.ts`);
25
- const result = spawnSync(
26
- process.execPath,
27
- ["--conditions", "@clipboard-health/source", sourcePath, ...process.argv.slice(2)],
28
- { stdio: "inherit" },
29
- );
24
+ const result = spawnSync(process.execPath, [sourcePath, ...process.argv.slice(2)], {
25
+ stdio: "inherit",
26
+ });
30
27
 
31
28
  if (result.error !== undefined) {
32
29
  throw result.error;
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/lib/workspaces.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG1E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAoL7C,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,oBAAoB,CAAC;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,GAAG,mBAAmB,CAUtF;AA8ND,iBAAe,eAAe,CAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAezB;AAED,eAAO,MAAM,UAAU;IACf,IAAI,SAAS,cAAc,QAAQ,QAAQ,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,KAAK;IACC,KAAK,SAAS,cAAc,QAAQ,MAAM,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAIvF,CAAC"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/lib/workspaces.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG1E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAoL7C,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,oBAAoB,CAAC;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,gBAAgB,GAAG,mBAAmB,CAUtF;AAgOD,iBAAe,eAAe,CAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAezB;AAED,eAAO,MAAM,UAAU;IACf,IAAI,SAAS,cAAc,QAAQ,QAAQ,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvF,KAAK;IACC,KAAK,SAAS,cAAc,QAAQ,MAAM,WAAW,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAIvF,CAAC"}
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { runCommandAsync } from "./commandRunner.js";
8
8
  import { detectHostCapabilities } from "./host.js";
9
- import { errorMessage, log } from "./util.js";
9
+ import { errorMessage, log, readEnvironmentVariable } from "./util.js";
10
10
  async function runWorkspaceCommand(command, arguments_, signal) {
11
11
  return signal === undefined
12
12
  ? await runCommandAsync(command, arguments_)
@@ -272,6 +272,8 @@ const tmuxAdapter = {
272
272
  async open(spec, signal) {
273
273
  await ensureTmuxSession(signal);
274
274
  const target = `${TMUX_SESSION}:${spec.name}`;
275
+ const keepDeadWindowsEnv = readEnvironmentVariable("GROUNDCREW_KEEP_DEAD_WINDOWS");
276
+ const keepDeadWindows = keepDeadWindowsEnv !== undefined && keepDeadWindowsEnv.length > 0;
275
277
  await runWorkspaceCommand("tmux", [
276
278
  "new-window",
277
279
  "-d",
@@ -287,7 +289,7 @@ const tmuxAdapter = {
287
289
  "-t",
288
290
  target,
289
291
  "remain-on-exit",
290
- "off",
292
+ keepDeadWindows ? "on" : "off",
291
293
  ";",
292
294
  "set-window-option",
293
295
  "-t",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/groundcrew",
3
- "version": "1.7.4",
3
+ "version": "1.8.0",
4
4
  "description": "Linear-driven orchestrator that launches AI coding agents in git worktrees, with workspace lifecycle, remote runners, and usage tracking.",
5
5
  "keywords": [
6
6
  "agent",
@@ -11,12 +11,11 @@
11
11
  "orchestrator",
12
12
  "worktree"
13
13
  ],
14
- "bugs": "https://github.com/ClipboardHealth/core-utils/issues",
14
+ "bugs": "https://github.com/ClipboardHealth/groundcrew/issues",
15
15
  "license": "MIT",
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "git+https://github.com/ClipboardHealth/core-utils.git",
19
- "directory": "packages/groundcrew"
18
+ "url": "git+https://github.com/ClipboardHealth/groundcrew.git"
20
19
  },
21
20
  "bin": {
22
21
  "crew": "./bin/run.js"
@@ -26,7 +25,8 @@
26
25
  "bin",
27
26
  "clearance-allow-hosts",
28
27
  "configExample.ts",
29
- "dist"
28
+ "dist",
29
+ "static"
30
30
  ],
31
31
  "type": "module",
32
32
  "main": "./dist/index.js",
@@ -36,7 +36,6 @@
36
36
  "exports": {
37
37
  "./package.json": "./package.json",
38
38
  ".": {
39
- "@clipboard-health/source": "./src/index.ts",
40
39
  "types": "./dist/index.d.ts",
41
40
  "import": "./dist/index.js",
42
41
  "default": "./dist/index.js"
@@ -46,11 +45,60 @@
46
45
  "access": "public"
47
46
  },
48
47
  "scripts": {
49
- "prepack": "tsgo --build --force tsconfig.lib.json"
48
+ "architecture:check": "depcruise src bin configExample.ts vitest.config.ts",
49
+ "build": "tsgo --build --force tsconfig.lib.json",
50
+ "cpd": "jscpd .",
51
+ "crew": "node ./bin/run.js",
52
+ "crew:op": "op run --env-file \"${XDG_CONFIG_HOME:-$HOME/.config}/groundcrew/op.env\" -- node ./bin/run.js",
53
+ "format": "oxfmt",
54
+ "format:check": "oxfmt --check",
55
+ "hook:pre-commit": "lint-staged",
56
+ "hook:pre-push": "node --run verify",
57
+ "knip": "knip",
58
+ "lint": "oxlint --deny-warnings",
59
+ "markdown:lint": "markdownlint-cli2",
60
+ "prepack": "node --run build",
61
+ "prepare": "husky",
62
+ "spell:check": "cspell --no-summary --no-progress --no-must-find-files",
63
+ "sync-ai-rules": "node ./node_modules/@clipboard-health/ai-rules/scripts/sync.js common",
64
+ "syncpack:lint": "syncpack lint",
65
+ "test": "vitest run --coverage",
66
+ "verify": "node scripts/verifyAll.mts"
50
67
  },
51
68
  "dependencies": {
52
69
  "@clipboard-health/clearance": "1.0.6",
53
70
  "@linear/sdk": "84.0.0",
54
71
  "tslib": "2.8.1"
72
+ },
73
+ "devDependencies": {
74
+ "@clipboard-health/ai-rules": "2.18.4",
75
+ "@clipboard-health/oxlint-config": "1.7.0",
76
+ "@nx/js": "22.7.1",
77
+ "@tsconfig/node24": "24.0.4",
78
+ "@tsconfig/strictest": "2.0.8",
79
+ "@types/node": "24.12.2",
80
+ "@typescript/native-preview": "7.0.0-dev.20260430.1",
81
+ "@vitest/coverage-v8": "4.1.5",
82
+ "cspell": "10.0.0",
83
+ "dependency-cruiser": "17.4.0",
84
+ "husky": "9.1.7",
85
+ "jscpd": "4.0.9",
86
+ "knip": "6.9.0",
87
+ "lint-staged": "16.4.0",
88
+ "markdownlint-cli2": "0.22.1",
89
+ "nx": "22.7.1",
90
+ "oxfmt": "0.47.0",
91
+ "oxlint": "1.60.0",
92
+ "oxlint-tsgolint": "0.21.1",
93
+ "syncpack": "15.0.0",
94
+ "vite": "8.0.10",
95
+ "vitest": "4.1.5"
96
+ },
97
+ "engines": {
98
+ "node": "24.14.1",
99
+ "npm": "~11.11.0"
100
+ },
101
+ "nx": {
102
+ "name": "groundcrew"
55
103
  }
56
104
  }
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="225 230 575 530" width="1024.0pt" height="944.0pt">
4
+ <path d="M 491.97 239.05 C 526.13 236.93 560.37 240.48 593.00 251.00 C 626.41 261.79 657.69 279.64 683.66 303.32 C 707.08 325.06 726.40 351.86 738.47 381.51 C 744.03 394.32 747.45 407.46 750.90 420.93 C 762.33 420.53 773.79 425.00 781.76 433.25 C 788.68 441.04 792.39 451.62 792.07 462.00 C 792.08 487.67 792.17 513.33 792.05 539.00 C 792.27 545.73 790.51 552.54 787.54 558.55 C 783.74 566.04 777.45 571.67 770.09 575.55 C 769.92 579.70 770.08 583.85 769.99 588.00 C 768.69 602.43 766.81 616.79 757.36 628.43 C 756.74 632.58 757.53 636.52 755.44 640.46 C 752.06 648.40 745.48 652.22 738.31 656.27 C 732.17 659.48 726.14 662.23 719.02 660.89 C 712.87 659.35 707.07 655.43 704.53 649.45 C 703.05 645.51 702.46 641.30 703.50 637.16 C 704.33 631.93 708.45 627.64 712.25 624.25 C 716.71 620.56 721.78 617.56 726.88 614.85 C 732.77 611.92 740.93 611.14 746.43 615.32 C 747.51 614.30 747.88 613.62 748.20 612.15 C 751.08 601.64 751.97 590.54 751.90 579.68 C 745.31 580.33 738.62 579.86 732.00 580.03 C 720.74 580.20 709.30 575.59 703.14 565.80 C 699.76 560.81 698.29 554.97 697.99 549.01 C 698.02 514.60 697.92 480.42 698.18 446.00 C 698.56 440.21 699.47 434.75 703.08 430.01 C 706.08 425.60 710.41 423.81 715.11 421.80 C 706.69 386.13 686.06 353.49 659.23 328.77 C 646.53 316.55 632.06 306.71 616.51 298.46 C 593.44 285.91 568.21 277.82 542.16 274.50 C 536.07 273.94 530.13 272.79 524.00 272.97 C 517.66 272.59 511.34 272.32 504.99 272.77 C 499.95 273.21 495.01 272.70 490.00 273.58 C 454.29 276.95 418.96 289.01 389.27 309.26 C 362.61 326.89 340.47 351.37 325.30 379.49 C 319.33 390.66 314.19 402.41 310.72 414.61 C 309.94 417.28 308.92 419.78 308.91 422.62 C 318.36 424.43 324.44 433.67 324.21 443.00 C 324.27 477.65 324.12 512.34 324.20 547.00 C 324.14 550.61 324.24 554.28 323.83 557.87 C 321.66 565.85 315.98 572.12 308.64 575.78 C 300.05 580.18 291.39 580.22 282.00 580.01 C 267.62 580.66 253.23 576.52 243.12 565.88 C 234.68 557.31 231.16 545.84 230.97 534.00 C 231.02 512.33 230.96 490.67 231.00 469.00 C 231.03 464.43 230.69 460.00 231.64 455.49 C 233.10 443.19 240.79 431.64 251.69 425.73 C 258.00 422.14 265.62 420.75 272.81 420.86 C 278.14 395.31 287.67 370.76 301.76 348.76 C 308.87 337.50 316.93 326.73 326.09 317.05 C 330.25 312.27 334.65 307.58 339.54 303.53 C 365.80 279.49 398.14 261.74 432.05 251.14 C 451.47 244.59 471.61 240.98 491.97 239.05 Z" fill="#78716c" />
5
+ <path d="M 356.00 444.19 C 452.27 444.23 548.55 444.15 644.82 444.23 C 649.66 444.23 654.22 444.56 657.84 448.15 C 661.26 451.27 662.52 455.45 662.47 459.99 C 662.31 525.35 662.51 590.59 662.40 656.00 C 662.38 661.55 662.63 667.04 661.94 672.56 C 659.55 678.86 653.83 683.18 647.00 683.04 C 547.66 683.01 448.31 683.05 348.96 683.02 C 340.58 682.87 333.60 675.32 333.95 667.00 C 333.95 599.00 333.96 531.00 333.94 463.00 C 333.95 460.46 333.79 457.81 334.22 455.29 C 335.23 451.68 337.14 448.37 340.50 446.48 C 345.39 443.64 350.60 444.17 356.00 444.19 Z" fill="#78716c" />
6
+ <path d="M 389.00 483.91 C 392.46 483.66 394.50 486.02 397.14 487.82 C 416.17 501.83 435.17 515.92 454.42 529.63 C 456.37 531.09 458.13 532.56 458.89 534.98 C 459.10 537.05 459.34 539.53 458.56 541.50 C 457.15 543.90 454.68 545.81 452.49 547.46 C 434.16 560.87 415.99 574.32 397.64 587.70 C 395.69 589.05 393.38 590.56 391.00 590.95 C 386.00 590.89 381.37 587.28 381.55 581.96 C 381.26 576.63 385.28 574.69 388.98 571.94 C 404.61 560.64 420.06 549.02 435.97 538.11 C 419.10 525.62 402.11 513.26 385.25 500.75 C 382.37 498.55 379.93 495.86 380.05 491.99 C 380.79 487.65 384.18 483.40 389.00 483.91 Z" fill="#77d94e" />
7
+ <path d="M 672.78 521.32 C 677.82 520.86 682.12 520.21 686.27 523.73 C 691.33 527.85 690.31 533.17 690.62 539.00 C 690.46 604.02 690.92 668.98 690.42 734.01 C 690.17 739.13 688.58 744.11 684.46 747.42 C 681.30 750.32 677.21 751.32 673.00 751.12 C 577.34 751.12 481.66 751.13 386.00 751.08 C 377.59 751.55 369.36 743.47 369.97 735.00 C 370.03 721.31 369.99 707.63 369.97 693.94 C 460.31 694.02 550.66 693.99 641.00 693.96 C 652.00 694.60 663.63 688.89 669.36 679.38 C 672.64 674.56 672.40 668.57 672.51 663.00 C 672.55 618.67 672.51 574.33 672.55 530.00 C 672.50 527.10 672.50 524.21 672.78 521.32 Z" fill="#78716c" />
8
+ <path d="M 473.99 577.90 C 490.65 577.77 507.33 577.94 524.00 577.84 C 527.49 577.86 531.25 577.49 534.68 578.19 C 539.56 579.86 541.50 585.54 539.02 590.00 C 537.21 593.42 533.72 594.68 530.03 594.77 C 512.35 594.96 494.68 594.68 477.00 594.87 C 473.37 594.93 470.04 594.29 467.64 591.35 C 465.40 589.27 465.80 585.98 466.16 583.24 C 467.44 580.11 470.43 577.60 473.99 577.90 Z" fill="#77d94e" />
9
+ </svg>