Add six portable skills with privacy-safe examples - #5
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1823d65786
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for f in sorted(dst.rglob("*")): | ||
| if not f.is_file() or f.suffix.lower() not in blocked: | ||
| continue | ||
| body = f.read_text() |
There was a problem hiding this comment.
Handle binary files passed to --convert-unknown
When --convert-unknown encounters an unrecognized binary companion such as the explicitly documented .pdf or .woff2 cases, read_text() raises UnicodeDecodeError and no package is produced. Either encode binary content safely, reject it with an actionable error, or require exclusion instead of promising conversion for every unknown extension.
Useful? React with 👍 / 👎.
| for f in sorted(d.rglob("*")): | ||
| if not f.is_file() or f.name.startswith("."): | ||
| continue | ||
| text, sub = f.read_text(), f.relative_to(d) |
There was a problem hiding this comment.
Preserve binary companions when bundling directories
If a directory selected by --bundle contains a supported binary companion such as .png or .jpg, this unconditional UTF-8 read crashes with UnicodeDecodeError. Component directories commonly contain images, so bundling them to meet the 20-file limit needs explicit binary handling or a clear validation error rather than aborting midway.
Useful? React with 👍 / 👎.
| if given_color: | ||
| shutil.copyfile(given_color, pkg / "color.png") | ||
| shutil.copyfile(given_outline, pkg / "outline.png") |
There was a problem hiding this comment.
Validate dimensions and format of supplied icons
When callers provide --icon-color and --icon-outline, arbitrary files are copied without checking that they are valid PNGs of the documented 192×192 and 32×32 sizes. The bundled validator only checks that the referenced filenames exist, so even two 1×1 PNGs are reported as valid and the resulting package reaches upload with invalid icons.
Useful? React with 👍 / 👎.
| check(not extra, "MANIFEST-01", | ||
| f"keine unerlaubten Root-Felder (additionalProperties:false) {extra if extra else ''}") | ||
| check(m.get("manifestVersion") == "1.28", "MANIFEST-02", "manifestVersion == 1.28") | ||
| check(bool(re.fullmatch(r"[0-9a-f-]{36}", str(m.get("id", "")))), "MANIFEST-03", "id ist eine GUID") |
There was a problem hiding this comment.
Validate the app ID as an actual UUID
For packages built with --app-id, this character-count regex accepts values that are not GUIDs, including a string of 36 hyphens, and reports MANIFEST-03 as passing. Such a package can therefore receive the validator's zero-error result despite having an invalid manifest ID; parse the value as a UUID or enforce the canonical UUID groups.
Useful? React with 👍 / 👎.
| md = dst / "SKILL.md" | ||
| text = md.read_text() | ||
| cleaned = re.sub(r"^disable-model-invocation:.*\n", "", text, flags=re.M) | ||
| if cleaned != text: | ||
| if not a.allow_auto_invocation: | ||
| die("Manual-only skill: review side effects before using --allow-auto-invocation") |
There was a problem hiding this comment.
Check the value of disable-model-invocation
A valid skill that explicitly sets disable-model-invocation: false is treated as manual-only because this substitution reacts to the field's presence rather than its boolean value. Building that already-auto-invocable skill consequently fails unless the caller supplies --allow-auto-invocation; parse the frontmatter value and gate only on true.
Useful? React with 👍 / 👎.
Adds six independently installable skills: chat-recall, jamie, rename, yesterday-pages, yesterday-app-style, and copilot-cowork-plugin. Existing bundles are unchanged. The catalog now contains 25 plugins, including 17 standalone skills.
The packages contain reusable instructions and synthetic examples only. Meeting examples and identifiers, personal paths and prioritization policies, editor metadata and remote font requests have been removed. The app style guide is self-contained; it does not require private design notes or distribute font files. Rename uses available title APIs and otherwise produces a proposal.
The Copilot builder requires explicit publisher metadata, rejects companion symlinks, applies exclusions before copying, cleans staging files, generates placeholder PNGs locally, and requires explicit opt-in before converting manual-only skills to automatic invocation.
Validation:
node compile.mjs; source/generated copies match and all six catalog entries exist.claude plugin validate .and each of the six compiled plugins pass. Version warnings are expected under the repository's git-SHA version policy.python3 .agents/tests/test_shared_skills.py: six passing offline tests covering hidden-file exclusion, directory exclusions, symlink rejection, invocation opt-in, transcript tool/context exclusion and root boundaries.No production meetings or real transcripts were used in testing. Copilot tenant upload and live authenticated Jamie calls were not performed; empirical extension observations remain labeled as such. No shared compiler or sister-catalog changes are required.