litgrok-ai 0.2.7 → 0.2.8

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.
Files changed (27) hide show
  1. package/.grok/skills/lit-scientific-visualization/SKILL.md +19 -19
  2. package/.grok/skills/lit-scientific-visualization/scripts/verify-canonical-corpus.mjs +26 -3
  3. package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/_canonical-corpus/manifest.json +10 -0
  4. package/.grok/vendor/NOTICE.md +16 -0
  5. package/.grok/vendor/licenses/045_scientific-visualization-MIT.txt +21 -0
  6. package/.grok/vendor/provenance/045_scientific-visualization.md +37 -0
  7. package/CHANGELOG.md +7 -0
  8. package/README.md +8 -8
  9. package/README_ko-KR.md +8 -8
  10. package/bin/litgrok.mjs +91 -9
  11. package/package.json +2 -1
  12. package/plugin.json +1 -1
  13. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/assets/color_palettes.py +0 -0
  14. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/assets/nature.mplstyle +0 -0
  15. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/assets/presentation.mplstyle +0 -0
  16. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/assets/publication.mplstyle +0 -0
  17. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/evals/evals.json +0 -0
  18. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/color_palettes.md +0 -0
  19. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/journal_requirements.md +0 -0
  20. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/matplotlib_examples.md +0 -0
  21. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/mdanalysis_martini_visualization.md +0 -0
  22. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/publication_guidelines.md +0 -0
  23. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/references/seaborn_for_publications.md +0 -0
  24. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/scripts/figure_export.py +0 -0
  25. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/scripts/style_presets.py +0 -0
  26. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/tests/test_figure_export.py +0 -0
  27. /package/.grok/{skills/lit-scientific-visualization → vendor/045_scientific-visualization}/tests/test_style_presets.py +0 -0
@@ -32,7 +32,7 @@ artifact_type: grok_build_skill
32
32
  surface: .grok/skills/lit-scientific-visualization/SKILL.md
33
33
  invocation: user-invocable skill or an explicit scientific-visualization request
34
34
  activation_banner: "🔥 LITBURN IGNITED · lit-scientific-visualization 🔥"
35
- resource_root: this skill directory
35
+ resource_root: ../../vendor/045_scientific-visualization
36
36
  verdicts: [PASS, DEGRADED, FAIL, BLOCKED]
37
37
  ```
38
38
 
@@ -62,20 +62,20 @@ Resolve all resource paths relative to this entrypoint's directory. The followin
62
62
  shipped resources; load only what the request needs, but run the verifier before relying on any
63
63
  helper or style:
64
64
 
65
- - Load `references/matplotlib_examples.md` when a worked plotting pattern is needed.
66
- - Load `references/publication_guidelines.md` when choosing publication geometry or export rules.
67
- - Load `references/journal_requirements.md` when a venue-specific requirement is in scope.
68
- - Load `references/color_palettes.md` when choosing categorical or accessible colors.
69
- - Load `references/seaborn_for_publications.md` when a seaborn workflow is requested.
70
- - Load `references/mdanalysis_martini_visualization.md` when a molecular trajectory is in scope.
71
- - [style presets](scripts/style_presets.py), [figure export helpers](scripts/figure_export.py),
65
+ - Load `../../vendor/045_scientific-visualization/references/matplotlib_examples.md` when a worked plotting pattern is needed.
66
+ - Load `../../vendor/045_scientific-visualization/references/publication_guidelines.md` when choosing publication geometry or export rules.
67
+ - Load `../../vendor/045_scientific-visualization/references/journal_requirements.md` when a venue-specific requirement is in scope.
68
+ - Load `../../vendor/045_scientific-visualization/references/color_palettes.md` when choosing categorical or accessible colors.
69
+ - Load `../../vendor/045_scientific-visualization/references/seaborn_for_publications.md` when a seaborn workflow is requested.
70
+ - Load `../../vendor/045_scientific-visualization/references/mdanalysis_martini_visualization.md` when a molecular trajectory is in scope.
71
+ - [style presets](../../vendor/045_scientific-visualization/scripts/style_presets.py), [figure export helpers](../../vendor/045_scientific-visualization/scripts/figure_export.py),
72
72
  and the [canonical corpus verifier](scripts/verify-canonical-corpus.mjs).
73
- - [color palettes](assets/color_palettes.py), [publication style](assets/publication.mplstyle),
74
- [Nature style](assets/nature.mplstyle), and [presentation style](assets/presentation.mplstyle).
75
- - [evaluation cases](evals/evals.json) describe the behavioral checks this resource set is meant
76
- to support. The [source manifest](references/_canonical-corpus/manifest.json) pins the 15
77
- companion files and their digests. The Python [helper tests](tests/test_style_presets.py) and
78
- [export tests](tests/test_figure_export.py) are regression fixtures, not user data.
73
+ - [color palettes](../../vendor/045_scientific-visualization/assets/color_palettes.py), [publication style](../../vendor/045_scientific-visualization/assets/publication.mplstyle),
74
+ [Nature style](../../vendor/045_scientific-visualization/assets/nature.mplstyle), and [presentation style](../../vendor/045_scientific-visualization/assets/presentation.mplstyle).
75
+ - [evaluation cases](../../vendor/045_scientific-visualization/evals/evals.json) describe the behavioral checks this resource set is meant
76
+ to support. The [source manifest](../../vendor/045_scientific-visualization/references/_canonical-corpus/manifest.json) pins the 15
77
+ companion files and their digests. The Python [helper tests](../../vendor/045_scientific-visualization/tests/test_style_presets.py) and
78
+ [export tests](../../vendor/045_scientific-visualization/tests/test_figure_export.py) are regression fixtures, not user data.
79
79
 
80
80
  Run `node scripts/verify-canonical-corpus.mjs` from this skill directory before relying on any
81
81
  helper. A nonzero result is a `BLOCKED` source-integrity condition: do not run a modified helper
@@ -143,11 +143,11 @@ from pathlib import Path
143
143
  import sys
144
144
 
145
145
  PROJECT_ROOT = Path.cwd().resolve()
146
- SKILL_ROOT = PROJECT_ROOT / ".grok" / "skills" / "lit-scientific-visualization"
147
- if not (SKILL_ROOT / "SKILL.md").is_file():
148
- raise FileNotFoundError(f"package-owned visualization skill is missing: {SKILL_ROOT}")
149
- SCRIPTS = SKILL_ROOT / "scripts"
150
- ASSETS = SKILL_ROOT / "assets"
146
+ CORPUS_ROOT = PROJECT_ROOT / ".grok" / "vendor" / "045_scientific-visualization"
147
+ if not (CORPUS_ROOT / "references" / "_canonical-corpus" / "manifest.json").is_file():
148
+ raise FileNotFoundError(f"package-owned visualization corpus is missing: {CORPUS_ROOT}")
149
+ SCRIPTS = CORPUS_ROOT / "scripts"
150
+ ASSETS = CORPUS_ROOT / "assets"
151
151
  sys.path.insert(0, str(SCRIPTS))
152
152
  sys.path.insert(0, str(ASSETS))
153
153
 
@@ -5,10 +5,18 @@ import { existsSync, lstatSync, readdirSync, readFileSync } from 'node:fs';
5
5
  import { dirname, join, relative, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
- const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
8
+ const SKILL_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../../../vendor/045_scientific-visualization');
9
9
  const MANIFEST_RELATIVE = 'references/_canonical-corpus/manifest.json';
10
10
  const EXPECTED = Object.freeze({
11
11
  schemaVersion: 'litgrok.scientific-visualization-corpus/v1',
12
+ license: 'MIT',
13
+ author: 'Woojin',
14
+ upstreamCommit: '235ed3af614a7becaee6ef1d1a18e5c4b13994f4',
15
+ omittedFile: Object.freeze({
16
+ path: 'SKILL.md',
17
+ sha256: 'd6084a7e3adf283157820ea20dbe1b46fa22fa1be17b138ab1203be550f4ef68',
18
+ reason: 'deliberately replaced by the Grok-native adapter',
19
+ }),
12
20
  fileCount: 15,
13
21
  byteCount: 114577,
14
22
  aggregateSha256: 'bf4719645e2c784f788993bb1d9f17d99dfb26301b1df474b1d26e9fcb9b4962',
@@ -58,7 +66,7 @@ function listFiles(directory, prefix = '') {
58
66
  function parseRoot(argv) {
59
67
  if (argv.length === 0) return SKILL_ROOT;
60
68
  if (argv.length === 2 && argv[0] === '--root' && argv[1] && !argv[1].startsWith('-')) return resolve(argv[1]);
61
- throw new Error('usage: verify-canonical-corpus.mjs [--root <skill-directory>]');
69
+ throw new Error('usage: verify-canonical-corpus.mjs [--root <corpus-directory>]');
62
70
  }
63
71
 
64
72
  function verify(skillRoot) {
@@ -73,11 +81,26 @@ function verify(skillRoot) {
73
81
  return [`manifest unreadable: ${error instanceof Error ? error.message : String(error)}`];
74
82
  }
75
83
 
76
- const expectedManifestKeys = ['aggregate_sha256', 'byte_count', 'file_count', 'files', 'schema_version', 'source'];
84
+ const expectedManifestKeys = [
85
+ 'aggregate_sha256',
86
+ 'author',
87
+ 'byte_count',
88
+ 'file_count',
89
+ 'files',
90
+ 'license',
91
+ 'omitted_files',
92
+ 'schema_version',
93
+ 'source',
94
+ 'upstream_commit',
95
+ ];
77
96
  if (JSON.stringify(Object.keys(manifest).sort()) !== JSON.stringify(expectedManifestKeys.sort())) {
78
97
  failures.push('manifest keys mismatch');
79
98
  }
80
99
  if (manifest.schema_version !== EXPECTED.schemaVersion) failures.push('schema_version mismatch');
100
+ if (manifest.license !== EXPECTED.license) failures.push('license mismatch');
101
+ if (manifest.author !== EXPECTED.author) failures.push('author mismatch');
102
+ if (manifest.upstream_commit !== EXPECTED.upstreamCommit) failures.push('upstream_commit mismatch');
103
+ if (JSON.stringify(manifest.omitted_files) !== JSON.stringify([EXPECTED.omittedFile])) failures.push('omitted_files mismatch');
81
104
  if (manifest.file_count !== EXPECTED.fileCount) failures.push(`file_count expected ${EXPECTED.fileCount}, got ${manifest.file_count}`);
82
105
  if (manifest.byte_count !== EXPECTED.byteCount) failures.push(`byte_count expected ${EXPECTED.byteCount}, got ${manifest.byte_count}`);
83
106
  if (manifest.aggregate_sha256 !== EXPECTED.aggregateSha256) failures.push('aggregate_sha256 mismatch');
@@ -5,6 +5,16 @@
5
5
  "reviewed_on": "2026-08-30",
6
6
  "selection": "15 companion files retained; the skill entrypoint is a Grok-native adapter"
7
7
  },
8
+ "license": "MIT",
9
+ "author": "Woojin",
10
+ "upstream_commit": "235ed3af614a7becaee6ef1d1a18e5c4b13994f4",
11
+ "omitted_files": [
12
+ {
13
+ "path": "SKILL.md",
14
+ "sha256": "d6084a7e3adf283157820ea20dbe1b46fa22fa1be17b138ab1203be550f4ef68",
15
+ "reason": "deliberately replaced by the Grok-native adapter"
16
+ }
17
+ ],
8
18
  "file_count": 15,
9
19
  "byte_count": 114577,
10
20
  "aggregate_sha256": "bf4719645e2c784f788993bb1d9f17d99dfb26301b1df474b1d26e9fcb9b4962",
@@ -0,0 +1,16 @@
1
+ # Scientific visualization notice
2
+
3
+ The LitGrok `lit-scientific-visualization` skill includes 15 retained companion files from the
4
+ owner-authorized 16-file canonical source snapshot. They are distributed under the adjacent MIT
5
+ license with explicit authorization from the owner.
6
+
7
+ The upstream `SKILL.md` has SHA-256
8
+ `d6084a7e3adf283157820ea20dbe1b46fa22fa1be17b138ab1203be550f4ef68` and is deliberately omitted,
9
+ replaced by the Grok-native adapter at `.grok/skills/lit-scientific-visualization/SKILL.md`. The
10
+ retained-file hashes and this omission are recorded in
11
+ `045_scientific-visualization/references/_canonical-corpus/manifest.json` and
12
+ `provenance/045_scientific-visualization.md`.
13
+
14
+ The corpus contains scientific guidance, examples, and references to external tools and publishers.
15
+ Those names do not imply endorsement; external software, websites, datasets, and author instructions
16
+ remain subject to their own terms and should be checked at the time of use.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Woojin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,37 @@
1
+ # Lit scientific visualization provenance
2
+
3
+ - Source repository: `~/skills` (local canonical source; path is provenance only, never a runtime dependency)
4
+ - Packaged corpus root: `.grok/vendor/045_scientific-visualization/`
5
+ - Source commit: `235ed3af614a7becaee6ef1d1a18e5c4b13994f4`
6
+ - Distribution authorization: public MIT inclusion authorized by the owner for LitFamily packaging.
7
+ - License: MIT, Copyright (c) 2026 Woojin
8
+ - Canonical file count: 16 Git-tracked authored files.
9
+ - Retained file count: 15 companion files.
10
+ - Omitted file: upstream `SKILL.md`, SHA-256 `d6084a7e3adf283157820ea20dbe1b46fa22fa1be17b138ab1203be550f4ef68`, deliberately replaced by the Grok-native adapter at `.grok/skills/lit-scientific-visualization/SKILL.md`.
11
+ - Approved retained-byte manifest SHA-256: `bf4719645e2c784f788993bb1d9f17d99dfb26301b1df474b1d26e9fcb9b4962`.
12
+
13
+ The retained-file manifest is SHA-256 over records of the form
14
+ `<sha256(raw bytes)><two spaces><repo-relative path><LF>`. Modes, sizes, xattrs,
15
+ and generated caches are excluded.
16
+
17
+ | Relative path | SHA-256 |
18
+ | --- | --- |
19
+ | `assets/color_palettes.py` | `ffea28da930406ecb11bbeaebfc530dfac40b772827a7653f449cb3b0bb35309` |
20
+ | `assets/nature.mplstyle` | `6a7343788bf772b7e1bc813d094f7bafa97c1e5544586e7b76002ad8547229b6` |
21
+ | `assets/presentation.mplstyle` | `e3ee23f0470d7fb07a0be75cd1210e231becfc2f5267aa404e4186aa077a3339` |
22
+ | `assets/publication.mplstyle` | `18447af3bc47310d23fc27255413c23d8bbe3ff441463cc54fcecdfacd205bea` |
23
+ | `evals/evals.json` | `366dc61b6e042f08f28bf33f2534feea80219d771b84497ec7094b30263e935b` |
24
+ | `references/color_palettes.md` | `0298691c8de8379570488a7b7768663971bc20af1fb05d464c5438d43a21dcfa` |
25
+ | `references/journal_requirements.md` | `56fdde590a9d778547dbcb609b77d86f1f31865e803bcecca5d8c4c72b91b3c7` |
26
+ | `references/matplotlib_examples.md` | `c99cd4f83e2452773e9580e2fa0984e61433c7a9b57ca0d2562dc400dfe4f83d` |
27
+ | `references/mdanalysis_martini_visualization.md` | `abcb3c61f1c3984ba9014d9ae197b726d23c1df844dc90988ecc4d8f0e349bfe` |
28
+ | `references/publication_guidelines.md` | `d9f5d0f115872c4c190a11d83432d44635e38ef9f1740db471fcc70f4c91dd2c` |
29
+ | `references/seaborn_for_publications.md` | `2da2147ae8974b4b5d16096c1484b982d5d1e5f91113808ebfd12111a0a6597a` |
30
+ | `scripts/figure_export.py` | `b22c7708afaf2a1cfa4f821eb9230d4262f1d52948af7f0815855aa9d0960403` |
31
+ | `scripts/style_presets.py` | `e9d450bd4ab6b11303b02d5029177c8d49466cc597648d12de0ecdb7620f64c4` |
32
+ | `tests/test_figure_export.py` | `b18414369e6721ad93d417914114d71af006248675eb20bb1f4989c48ec9a58e` |
33
+ | `tests/test_style_presets.py` | `ff0e190196480848f1fea2398220038771f386ee7967a0ef122b0dfbca3aed46` |
34
+
35
+ The Grok-native adapter is outside the retained companion-file table. The omitted upstream
36
+ entrypoint remains identified in the manifest so the 15 retained files and the 16-file canonical
37
+ source are both auditable.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.8 (pending) — 2026-09-02
4
+
5
+ - Move the scientific-visualization corpus to `.grok/vendor/` so the skill
6
+ adapter stays a wrapper over the original files.
7
+ - Count vendor license, provenance, and NOTICE companions in family
8
+ payload-parity so packed skills keep the material they name.
9
+
3
10
  ## 0.2.7 (pending) — 2026-09-02
4
11
 
5
12
  - Repair payload upgrades across the ownership-manifest transition: installs now
package/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
  </p>
23
23
  <p align="center">
24
24
  <img src="https://img.shields.io/badge/npm-litgrok--ai-cb3837" alt="npm: litgrok-ai" />
25
- <img src="https://img.shields.io/badge/version-0.2.7-2ea44f" alt="version 0.2.7" />
25
+ <img src="https://img.shields.io/badge/version-0.2.8-2ea44f" alt="version 0.2.8" />
26
26
  <img src="https://img.shields.io/badge/Grok%20Build-skills%20%2B%20rules-111827" alt="Grok Build skills and project rules" />
27
27
  <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" />
28
28
  </p>
@@ -105,7 +105,7 @@ npx --yes litgrok-ai@latest install
105
105
  Pin a version when you need a reproducible install:
106
106
 
107
107
  ```bash
108
- npx --yes litgrok-ai@0.2.7 install
108
+ npx --yes litgrok-ai@0.2.8 install
109
109
  ```
110
110
 
111
111
  Preview without writing files:
@@ -198,12 +198,12 @@ Review is proposal-only. `autoApply` is always false, transcript text is inert d
198
198
  From an installed project, use the package CLI directly when you want a replayable foreground command:
199
199
 
200
200
  ```bash
201
- npx --yes litgrok-ai@0.2.7 skill-loop review <session-id>
202
- npx --yes litgrok-ai@0.2.7 skill-loop list
203
- npx --yes litgrok-ai@0.2.7 skill-loop apply <proposal-id>
204
- npx --yes litgrok-ai@0.2.7 skill-loop reject <proposal-id>
205
- npx --yes litgrok-ai@0.2.7 skill-loop rollback <ledger-id>
206
- npx --yes litgrok-ai@0.2.7 skill-loop curator
201
+ npx --yes litgrok-ai@0.2.8 skill-loop review <session-id>
202
+ npx --yes litgrok-ai@0.2.8 skill-loop list
203
+ npx --yes litgrok-ai@0.2.8 skill-loop apply <proposal-id>
204
+ npx --yes litgrok-ai@0.2.8 skill-loop reject <proposal-id>
205
+ npx --yes litgrok-ai@0.2.8 skill-loop rollback <ledger-id>
206
+ npx --yes litgrok-ai@0.2.8 skill-loop curator
207
207
  ```
208
208
 
209
209
  `apply` prints the ledger id needed for rollback. The deterministic curator is also user-invoked: by default it runs at most once every seven days, requires at least two idle hours, marks eligible unpinned agent-owned skills stale after 30 idle days, and archives them outside discovery after 90 idle days. It makes a full backup before a transition and never deletes a skill package; `--force` bypasses only the seven-day run interval for an explicit test or maintenance invocation.
package/README_ko-KR.md CHANGED
@@ -22,7 +22,7 @@
22
22
  </p>
23
23
  <p align="center">
24
24
  <img src="https://img.shields.io/badge/npm-litgrok--ai-cb3837" alt="npm: litgrok-ai" />
25
- <img src="https://img.shields.io/badge/version-0.2.7-2ea44f" alt="version 0.2.7" />
25
+ <img src="https://img.shields.io/badge/version-0.2.8-2ea44f" alt="version 0.2.8" />
26
26
  <img src="https://img.shields.io/badge/Grok%20Build-skills%20%2B%20rules-111827" alt="Grok Build skills and project rules" />
27
27
  <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" />
28
28
  </p>
@@ -105,7 +105,7 @@ npx --yes litgrok-ai@latest install
105
105
  재현 가능한 설치는 버전을 고정합니다.
106
106
 
107
107
  ```bash
108
- npx --yes litgrok-ai@0.2.7 install
108
+ npx --yes litgrok-ai@0.2.8 install
109
109
  ```
110
110
 
111
111
  파일을 쓰지 않고 미리보기:
@@ -198,12 +198,12 @@ Review는 proposal만 만듭니다. `autoApply`는 항상 false이고 transcript
198
198
  설치된 project에서는 다음 package CLI를 foreground command로 실행할 수 있습니다.
199
199
 
200
200
  ```bash
201
- npx --yes litgrok-ai@0.2.7 skill-loop review <session-id>
202
- npx --yes litgrok-ai@0.2.7 skill-loop list
203
- npx --yes litgrok-ai@0.2.7 skill-loop apply <proposal-id>
204
- npx --yes litgrok-ai@0.2.7 skill-loop reject <proposal-id>
205
- npx --yes litgrok-ai@0.2.7 skill-loop rollback <ledger-id>
206
- npx --yes litgrok-ai@0.2.7 skill-loop curator
201
+ npx --yes litgrok-ai@0.2.8 skill-loop review <session-id>
202
+ npx --yes litgrok-ai@0.2.8 skill-loop list
203
+ npx --yes litgrok-ai@0.2.8 skill-loop apply <proposal-id>
204
+ npx --yes litgrok-ai@0.2.8 skill-loop reject <proposal-id>
205
+ npx --yes litgrok-ai@0.2.8 skill-loop rollback <ledger-id>
206
+ npx --yes litgrok-ai@0.2.8 skill-loop curator
207
207
  ```
208
208
 
209
209
  `apply`는 rollback에 필요한 ledger id를 출력합니다. Deterministic curator도 user-invoked입니다. 기본적으로 7일에 한 번만 실행되고, 마지막 activity 뒤 최소 2시간이 지나야 하며, pin되지 않은 agent-owned skill을 30일 idle 뒤 stale로 표시하고 90일 idle 뒤 discovery 밖으로 archive합니다. Transition 전에는 전체 backup을 만들고 skill package를 삭제하지 않습니다. `--force`는 명시적인 test 또는 maintenance 실행에서 7일 interval만 건너뜁니다.
package/bin/litgrok.mjs CHANGED
@@ -13,9 +13,8 @@ const INSTALL_MANIFEST_SCHEMA = 'litgrok.install-manifest/v1';
13
13
  const PACKAGE_NAME = 'litgrok-ai';
14
14
 
15
15
  // 0.2.5 was the last release before ownership manifests existed. These are the
16
- // only payload hashes changed by the current security release, so a pristine
17
- // 0.2.5 install can migrate while no manifest exists without treating its
18
- // seven security-fix files as user conflicts.
16
+ // payload hashes changed since that release, so a pristine 0.2.5 install can
17
+ // migrate while no manifest exists without treating package-owned files as conflicts.
19
18
  const PRE_MANIFEST_PAYLOAD_HASHES = Object.freeze({
20
19
  'skills/autoconference/references/_canonical-corpus/manifest.json': '4554ee4041b73577a844abc27a97db91e941b8412f1888209203251dc1fee500',
21
20
  'skills/autoconference/scripts/init_conference.py': 'cb83623c1338b7e3a5be7a7beac7a17b8ae362fc24fbc01d1caff634db290dfc',
@@ -23,8 +22,29 @@ const PRE_MANIFEST_PAYLOAD_HASHES = Object.freeze({
23
22
  'skills/autoresearch/references/_canonical-corpus/manifest.json': '9667f852081d4877c579d14e63c0759ebbe863e4170a9c3d5e6487cdb1f0c323',
24
23
  'skills/autoresearch/scripts/init_research.py': 'a5434711928eb4d0487d933df5e1b374f8553140004c6ab8e38fe577ae074d05',
25
24
  'skills/autoresearch/scripts/verify-canonical-corpus.mjs': '80a85ed4ba0c168bd7f7abef5754c4089a629975a827b6ddb3f01cd813602274',
25
+ 'skills/lit-scientific-visualization/SKILL.md': 'ffc3b2ea49dd7e7c4c7d4568f289df294a3a30f953c11039f98aaf6f8fb983ee',
26
+ 'skills/lit-scientific-visualization/references/_canonical-corpus/manifest.json': '9cafbdc5e1259aea053a5bf637e18d034f8e169be74b2c5732fc5bfd30f7c5bd',
27
+ 'skills/lit-scientific-visualization/scripts/verify-canonical-corpus.mjs': 'a1cfe0578195098dc4afc2d25f0d391f38aeaa57cd3970fa7dca51e20cbf929d',
26
28
  'skills/skill-observer/scripts/skill-loop.mjs': '3f3f5265928c0d71175b0f23f71b836d1dc05e7efba407bfdc2d263c6aaed0ce',
27
29
  });
30
+ const PRE_MANIFEST_LEGACY_PAYLOAD_HASHES = Object.freeze({
31
+ 'skills/lit-scientific-visualization/assets/color_palettes.py': 'ffea28da930406ecb11bbeaebfc530dfac40b772827a7653f449cb3b0bb35309',
32
+ 'skills/lit-scientific-visualization/assets/nature.mplstyle': '6a7343788bf772b7e1bc813d094f7bafa97c1e5544586e7b76002ad8547229b6',
33
+ 'skills/lit-scientific-visualization/assets/presentation.mplstyle': 'e3ee23f0470d7fb07a0be75cd1210e231becfc2f5267aa404e4186aa077a3339',
34
+ 'skills/lit-scientific-visualization/assets/publication.mplstyle': '18447af3bc47310d23fc27255413c23d8bbe3ff441463cc54fcecdfacd205bea',
35
+ 'skills/lit-scientific-visualization/evals/evals.json': '366dc61b6e042f08f28bf33f2534feea80219d771b84497ec7094b30263e935b',
36
+ 'skills/lit-scientific-visualization/references/_canonical-corpus/manifest.json': '9cafbdc5e1259aea053a5bf637e18d034f8e169be74b2c5732fc5bfd30f7c5bd',
37
+ 'skills/lit-scientific-visualization/references/color_palettes.md': '0298691c8de8379570488a7b7768663971bc20af1fb05d464c5438d43a21dcfa',
38
+ 'skills/lit-scientific-visualization/references/journal_requirements.md': '56fdde590a9d778547dbcb609b77d86f1f31865e803bcecca5d8c4c72b91b3c7',
39
+ 'skills/lit-scientific-visualization/references/matplotlib_examples.md': 'c99cd4f83e2452773e9580e2fa0984e61433c7a9b57ca0d2562dc400dfe4f83d',
40
+ 'skills/lit-scientific-visualization/references/mdanalysis_martini_visualization.md': 'abcb3c61f1c3984ba9014d9ae197b726d23c1df844dc90988ecc4d8f0e349bfe',
41
+ 'skills/lit-scientific-visualization/references/publication_guidelines.md': 'd9f5d0f115872c4c190a11d83432d44635e38ef9f1740db471fcc70f4c91dd2c',
42
+ 'skills/lit-scientific-visualization/references/seaborn_for_publications.md': '2da2147ae8974b4b5d16096c1484b982d5d1e5f91113808ebfd12111a0a6597a',
43
+ 'skills/lit-scientific-visualization/scripts/figure_export.py': 'b22c7708afaf2a1cfa4f821eb9230d4262f1d52948af7f0815855aa9d0960403',
44
+ 'skills/lit-scientific-visualization/scripts/style_presets.py': 'e9d450bd4ab6b11303b02d5029177c8d49466cc597648d12de0ecdb7620f64c4',
45
+ 'skills/lit-scientific-visualization/tests/test_figure_export.py': 'b18414369e6721ad93d417914114d71af006248675eb20bb1f4989c48ec9a58e',
46
+ 'skills/lit-scientific-visualization/tests/test_style_presets.py': 'ff0e190196480848f1fea2398220038771f386ee7967a0ef122b0dfbca3aed46',
47
+ });
28
48
  const USAGE = 'Usage: litgrok [install|uninstall] [--user|--project] [--dry-run] [--no-color] [--yes]\n litgrok skill-loop <review|propose|list|apply|reject|rollback|curator> ...\n';
29
49
  const BRAILLE_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
30
50
  const SPINNER_INTERVAL_MS = 80;
@@ -337,6 +357,42 @@ function targetState(source, target, relativePath, manifest) {
337
357
  }
338
358
  }
339
359
 
360
+ function legacyTargetState(root, relativePath, expectedHash) {
361
+ const target = join(root, relativePath);
362
+ let ancestor = dirname(target);
363
+ while (ancestor !== root) {
364
+ try {
365
+ const ancestorStat = lstatSync(ancestor);
366
+ if (ancestorStat.isSymbolicLink() || !ancestorStat.isDirectory()) return 'conflict';
367
+ } catch (error) {
368
+ if (error?.code === 'ENOENT') break;
369
+ throw error;
370
+ }
371
+ ancestor = dirname(ancestor);
372
+ }
373
+
374
+ try {
375
+ const targetStat = lstatSync(target);
376
+ if (!targetStat.isFile()) return 'conflict';
377
+ return sha256File(target) === expectedHash ? 'owned' : 'conflict';
378
+ } catch (error) {
379
+ if (error?.code === 'ENOENT') return 'missing';
380
+ throw error;
381
+ }
382
+ }
383
+
384
+ function removeLegacyFiles(entries) {
385
+ let removed = 0;
386
+ for (const entry of entries) {
387
+ const state = legacyTargetState(entry.root, entry.relativePath, entry.expectedHash);
388
+ if (state === 'missing') continue;
389
+ if (state !== 'owned') throw new Error(`Refusing to remove different existing file: ${entry.target}`);
390
+ unlinkSync(entry.target);
391
+ removed += 1;
392
+ }
393
+ return removed;
394
+ }
395
+
340
396
  function manifestContent(files) {
341
397
  const hashes = Object.fromEntries(
342
398
  files
@@ -546,25 +602,48 @@ export async function run(args, context = {}) {
546
602
  const states = runStep(progress, 'OWNERSHIP', () => {
547
603
  const manifest = readOwnershipManifest(root);
548
604
  const owned = files.map(({ relativePath, source, target }) => targetState(source, target, relativePath, manifest));
605
+ const legacyEntries = manifest === null
606
+ ? Object.entries(PRE_MANIFEST_LEGACY_PAYLOAD_HASHES).map(([relativePath, expectedHash]) => ({
607
+ root,
608
+ relativePath,
609
+ expectedHash,
610
+ target: join(root, relativePath),
611
+ }))
612
+ : [];
613
+ const legacyStates = legacyEntries.map(({ relativePath, expectedHash }) => legacyTargetState(root, relativePath, expectedHash));
549
614
  const counts = {
550
615
  missing: owned.filter((state) => state === 'missing').length,
551
616
  current: owned.filter((state) => state === 'current').length,
552
617
  owned: owned.filter((state) => state === 'owned').length,
553
618
  conflicts: owned.filter((state) => state === 'conflict').length,
554
619
  };
555
- if (counts.conflicts > 0) {
620
+ const legacyCounts = {
621
+ missing: legacyStates.filter((state) => state === 'missing').length,
622
+ owned: legacyStates.filter((state) => state === 'owned').length,
623
+ conflicts: legacyStates.filter((state) => state === 'conflict').length,
624
+ };
625
+ if (counts.conflicts > 0 || legacyCounts.conflicts > 0) {
556
626
  const stderrLines = [];
557
627
  for (let index = 0; index < files.length; index += 1) {
558
628
  if (owned[index] === 'conflict') stderrLines.push(`Refusing to ${options.command === 'install' ? 'overwrite' : 'remove'} different existing file: ${files[index].target}`);
559
629
  }
560
- const error = new Error(`${counts.missing} missing · ${counts.current} already-current · ${counts.owned} owned · ${counts.conflicts} conflicts`);
630
+ for (let index = 0; index < legacyEntries.length; index += 1) {
631
+ if (legacyStates[index] === 'conflict') stderrLines.push(`Refusing to ${options.command === 'install' ? 'overwrite' : 'remove'} different existing file: ${legacyEntries[index].target}`);
632
+ }
633
+ const legacyDetail = legacyEntries.length === 0
634
+ ? ''
635
+ : ` · ${legacyCounts.missing} legacy missing · ${legacyCounts.owned} legacy owned · ${legacyCounts.conflicts} legacy conflicts`;
636
+ const error = new Error(`${counts.missing} missing · ${counts.current} already-current · ${counts.owned} owned · ${counts.conflicts} conflicts${legacyDetail}`);
561
637
  error.step = 'OWNERSHIP';
562
638
  error.stderrLines = stderrLines;
563
639
  throw error;
564
640
  }
641
+ const legacyDetail = legacyEntries.length === 0
642
+ ? ''
643
+ : ` · ${legacyCounts.missing} legacy missing · ${legacyCounts.owned} legacy owned · ${legacyCounts.conflicts} legacy conflicts`;
565
644
  return {
566
- value: { states: owned, counts, manifest },
567
- detail: `${counts.missing} missing · ${counts.current} already-current · ${counts.owned} owned · ${counts.conflicts} conflicts`,
645
+ value: { states: owned, counts, manifest, legacyEntries, legacyStates, legacyCounts },
646
+ detail: `${counts.missing} missing · ${counts.current} already-current · ${counts.owned} owned · ${counts.conflicts} conflicts${legacyDetail}`,
568
647
  };
569
648
  });
570
649
 
@@ -579,6 +658,7 @@ export async function run(args, context = {}) {
579
658
  unlinkSync(files[index].target);
580
659
  removed += 1;
581
660
  }
661
+ removed += removeLegacyFiles(states.legacyEntries);
582
662
  removeOwnershipManifest(root, states.manifest);
583
663
  progress.finish('ok', 'WRITE', `${removed} removed · ${states.counts.missing} already absent`, elapsedSince(writeStarted));
584
664
  } catch (error) {
@@ -592,7 +672,7 @@ export async function run(args, context = {}) {
592
672
  return 0;
593
673
  }
594
674
 
595
- if (states.states.every((state) => state === 'current')) {
675
+ if (states.states.every((state) => state === 'current') && states.legacyStates.every((state) => state === 'missing')) {
596
676
  try {
597
677
  writeOwnershipManifest(root, files, states.manifest);
598
678
  } catch (error) {
@@ -618,8 +698,10 @@ export async function run(args, context = {}) {
618
698
  else copyFileSync(source, target, constants.COPYFILE_EXCL);
619
699
  installed += 1;
620
700
  }
701
+ const removedLegacy = removeLegacyFiles(states.legacyEntries);
621
702
  writeOwnershipManifest(root, files, states.manifest);
622
- progress.finish('ok', 'WRITE', `${installed} written · ${states.counts.current} already-current · ${states.counts.owned} owned`, elapsedSince(writeStarted));
703
+ const legacyDetail = removedLegacy === 0 ? '' : ` · ${removedLegacy} legacy removed`;
704
+ progress.finish('ok', 'WRITE', `${installed} written · ${states.counts.current} already-current · ${states.counts.owned} owned${legacyDetail}`, elapsedSince(writeStarted));
623
705
  } catch (error) {
624
706
  progress.finish('failed', 'WRITE', errorText(error), elapsedSince(writeStarted));
625
707
  if (error && typeof error === 'object') error.step = 'WRITE';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litgrok-ai",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Grok Build skills, project rules, and hooks installer.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,7 @@
14
14
  "files": [
15
15
  "plugin.json",
16
16
  ".grok/skills",
17
+ ".grok/vendor",
17
18
  ".grok/agents",
18
19
  ".grok/rules",
19
20
  ".grok/hooks",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litgrok",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Grok Build skills, project rules, and bounded lifecycle hooks for evidence-first lit work.",
5
5
  "author": {
6
6
  "name": "LitGrok contributors"