Antigravity 에서 스킬로 인식되지 않는다는 제보를 받고 확인했다. 설치 경로가 없었던 것이 원인이다. 공식 문서 기준 경로: 워크스페이스 <root>/.agents/skills/<이름>/ 전역 ~/.gemini/config/skills/<이름>/ .agents/skills 는 특정 제품 경로가 아니라 중립 경로라, 같은 규약을 쓰는 다른 하네스도 함께 읽는다. SKILL.md 구조(프론트매터 + references/)가 Claude Code 와 같아서 변환 없이 그대로 복사하면 된다. 프론트매터 요구사항도 맞는 것을 확인했다 — description 필수, name 선택. 우리 SKILL.md 는 둘 다 갖고 있다. - targets/antigravity.ts 추가, 설치 대상 5 → 6종 - 하위호환 경로(.agent/skills, 단수)는 감지에만 쓰고 설치는 복수형에만 한다. 두 곳에 깔면 스킬이 두 번 잡힌다 - 테스트 2개 추가: 범위별 경로, 변환 없이 싣는지 (테스트 25 → 27개) - 소개 페이지 설치 대상 목록에 반영
55 lines
2 KiB
TypeScript
55 lines
2 KiB
TypeScript
import path from "node:path";
|
|
import { exists } from "../fsx.ts";
|
|
import type { TargetAdapter, TargetContext } from "../types.ts";
|
|
import { anyExists, scopeRoot, skillDirActions } from "./common.ts";
|
|
|
|
/**
|
|
* Antigravity 와 `.agents/skills` 를 읽는 도구들.
|
|
*
|
|
* `.agents/skills/` 는 특정 제품의 경로가 아니라 **중립 경로**다.
|
|
* Antigravity 가 여기서 스킬을 읽고, 같은 규약을 쓰는 다른 하네스도 늘고 있다.
|
|
* SKILL.md 구조(프론트매터 + references/)가 Claude Code 와 같아서
|
|
* 파일을 그대로 복사하면 된다 — 변환이 필요 없다.
|
|
*
|
|
* 경로(공식 문서 기준):
|
|
* 워크스페이스 <root>/.agents/skills/<이름>/
|
|
* 전역 ~/.gemini/config/skills/<이름>/
|
|
*
|
|
* 구버전은 `.agent/skills`(단수)를 읽었고 지금도 하위호환으로 지원된다.
|
|
* 새로 설치하는 쪽은 복수형이 맞으므로 복수형에만 쓴다 — 두 곳에 같은 파일을
|
|
* 깔면 스킬이 두 번 잡힌다.
|
|
*
|
|
* 프론트매터 요구사항도 확인했다: `description` 필수, `name` 선택(없으면 폴더명).
|
|
* 우리 SKILL.md 는 둘 다 갖고 있다.
|
|
*/
|
|
export const antigravity: TargetAdapter = {
|
|
id: "antigravity",
|
|
label: "Antigravity",
|
|
hint: ".agents/skills/designpaca — 중립 경로, 같은 규약을 쓰는 도구가 함께 읽는다",
|
|
scopes: ["user", "project"],
|
|
|
|
async detect(ctx: TargetContext) {
|
|
return anyExists([
|
|
path.join(ctx.home, ".gemini", "config", "skills"),
|
|
path.join(ctx.home, ".gemini"),
|
|
path.join(ctx.cwd, ".agents"),
|
|
// 폴더 이름이 바뀌기 전에 만든 프로젝트
|
|
path.join(ctx.cwd, ".agent"),
|
|
]);
|
|
},
|
|
|
|
async plan(ctx: TargetContext) {
|
|
const root = scopeRoot(
|
|
ctx,
|
|
[".gemini", "config", "skills", "designpaca"],
|
|
[".agents", "skills", "designpaca"],
|
|
);
|
|
return {
|
|
target: this.id,
|
|
scope: ctx.scope,
|
|
root,
|
|
actions: skillDirActions(root, ctx.skill),
|
|
alreadyInstalled: await exists(path.join(root, "SKILL.md")),
|
|
};
|
|
},
|
|
};
|