@agentteams/cli 0.1.98 → 0.1.100
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/.eslintcache +1 -1
- package/dist/api/sentry.d.ts +7 -0
- package/dist/api/sentry.d.ts.map +1 -0
- package/dist/api/sentry.js +18 -0
- package/dist/api/sentry.js.map +1 -0
- package/dist/api/skill.d.ts +25 -0
- package/dist/api/skill.d.ts.map +1 -0
- package/dist/api/skill.js +40 -0
- package/dist/api/skill.js.map +1 -0
- package/dist/commands/codeReview.d.ts.map +1 -1
- package/dist/commands/codeReview.js +3 -3
- package/dist/commands/codeReview.js.map +1 -1
- package/dist/commands/convention.d.ts.map +1 -1
- package/dist/commands/convention.js +9 -1
- package/dist/commands/convention.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +15 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +32 -22
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +6 -4
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/sentry.d.ts +2 -0
- package/dist/commands/sentry.d.ts.map +1 -0
- package/dist/commands/sentry.js +26 -0
- package/dist/commands/sentry.js.map +1 -0
- package/dist/commands/skill.d.ts +5 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +251 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/mcp-registration/clients.d.ts.map +1 -1
- package/dist/mcp-registration/clients.js +92 -0
- package/dist/mcp-registration/clients.js.map +1 -1
- package/dist/mcp-registration/detect.d.ts +1 -0
- package/dist/mcp-registration/detect.d.ts.map +1 -1
- package/dist/mcp-registration/detect.js +25 -2
- package/dist/mcp-registration/detect.js.map +1 -1
- package/dist/mcp-registration/index.d.ts +2 -2
- package/dist/mcp-registration/index.d.ts.map +1 -1
- package/dist/mcp-registration/index.js +4 -0
- package/dist/mcp-registration/index.js.map +1 -1
- package/dist/mcp-registration/install.d.ts +2 -0
- package/dist/mcp-registration/install.d.ts.map +1 -1
- package/dist/mcp-registration/install.js +22 -2
- package/dist/mcp-registration/install.js.map +1 -1
- package/dist/mcp-registration/types.d.ts +8 -1
- package/dist/mcp-registration/types.d.ts.map +1 -1
- package/dist/mcp-registration/types.js +1 -0
- package/dist/mcp-registration/types.js.map +1 -1
- package/dist/program/codeReview.d.ts.map +1 -1
- package/dist/program/codeReview.js +4 -3
- package/dist/program/codeReview.js.map +1 -1
- package/dist/program/index.d.ts.map +1 -1
- package/dist/program/index.js +4 -0
- package/dist/program/index.js.map +1 -1
- package/dist/program/plan.d.ts.map +1 -1
- package/dist/program/plan.js +7 -6
- package/dist/program/plan.js.map +1 -1
- package/dist/program/report.d.ts.map +1 -1
- package/dist/program/report.js +2 -1
- package/dist/program/report.js.map +1 -1
- package/dist/program/sentry.d.ts +3 -0
- package/dist/program/sentry.d.ts.map +1 -0
- package/dist/program/sentry.js +19 -0
- package/dist/program/sentry.js.map +1 -0
- package/dist/program/skill.d.ts +4 -0
- package/dist/program/skill.d.ts.map +1 -0
- package/dist/program/skill.js +48 -0
- package/dist/program/skill.js.map +1 -0
- package/dist/utils/agentIdentity.d.ts +43 -0
- package/dist/utils/agentIdentity.d.ts.map +1 -1
- package/dist/utils/agentIdentity.js +45 -0
- package/dist/utils/agentIdentity.js.map +1 -1
- package/dist/utils/runnerTypes.d.ts +29 -0
- package/dist/utils/runnerTypes.d.ts.map +1 -0
- package/dist/utils/runnerTypes.js +40 -0
- package/dist/utils/runnerTypes.js.map +1 -0
- package/dist/utils/skillPackage.d.ts +80 -0
- package/dist/utils/skillPackage.d.ts.map +1 -0
- package/dist/utils/skillPackage.js +287 -0
- package/dist/utils/skillPackage.js.map +1 -0
- package/package.json +1 -1
|
@@ -21,4 +21,49 @@ export const AGENT_NAME_ENV = 'AGENTTEAMS_AGENT_NAME';
|
|
|
21
21
|
export function resolveSessionAgentConfigId(env = process.env) {
|
|
22
22
|
return toNonEmptyString(env[AGENT_NAME_ENV]);
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Execution snapshot variables the daemon exports for every session it spawns
|
|
26
|
+
* (`daemon/src/runners/session-env.ts`). They describe how *this* run is executing —
|
|
27
|
+
* which engine, which model, whether fast mode is on — as opposed to who it runs as.
|
|
28
|
+
*
|
|
29
|
+
* The daemon omits a variable entirely when it has no value, so an absent variable
|
|
30
|
+
* means "unknown", never "empty" or "false-by-default".
|
|
31
|
+
*/
|
|
32
|
+
export const RUNNER_TYPE_ENV = 'AGENTTEAMS_RUNNER_TYPE';
|
|
33
|
+
export const MODEL_ENV = 'AGENTTEAMS_MODEL';
|
|
34
|
+
export const FAST_MODE_ENV = 'AGENTTEAMS_FAST_MODE';
|
|
35
|
+
export function resolveSessionRunnerType(env = process.env) {
|
|
36
|
+
return toNonEmptyString(env[RUNNER_TYPE_ENV]);
|
|
37
|
+
}
|
|
38
|
+
export function resolveSessionModel(env = process.env) {
|
|
39
|
+
return toNonEmptyString(env[MODEL_ENV]);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fast mode is a two-state boolean flag on the CLI (`--fast`), not a tri-state, so an
|
|
43
|
+
* absent variable simply reads as off. The daemon only exports it when fast mode is on.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveSessionFastMode(env = process.env) {
|
|
46
|
+
return toNonEmptyString(env[FAST_MODE_ENV]) === 'true';
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The execution snapshot for this run: an explicit argument always wins, and the session
|
|
50
|
+
* environment fills the gap when the daemon spawned us.
|
|
51
|
+
*
|
|
52
|
+
* A resolved value can still be `undefined` — outside a daemon session nothing can tell us
|
|
53
|
+
* the model. Callers that require the snapshot must keep failing in that case; this resolver
|
|
54
|
+
* narrows *when* they fail, it does not relax the requirement.
|
|
55
|
+
*/
|
|
56
|
+
export function resolveExecutionSnapshot(options, env = process.env) {
|
|
57
|
+
return {
|
|
58
|
+
runnerType: toNonEmptyString(options.runnerType) ?? resolveSessionRunnerType(env),
|
|
59
|
+
model: toNonEmptyString(options.model) ?? resolveSessionModel(env),
|
|
60
|
+
fastMode: options.fast === true || resolveSessionFastMode(env),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Appended to the existing "required" errors so the message names the other way out. The
|
|
65
|
+
* previous wording implied passing the flags was the only path, which is wrong inside a
|
|
66
|
+
* runner session and sends agents looking for values the session already has.
|
|
67
|
+
*/
|
|
68
|
+
export const EXECUTION_SNAPSHOT_HINT = ' In a runner session these are filled in automatically from the environment.';
|
|
24
69
|
//# sourceMappingURL=agentIdentity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentIdentity.js","sourceRoot":"","sources":["../../src/utils/agentIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC9E,OAAO,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
1
|
+
{"version":3,"file":"agentIdentity.js","sourceRoot":"","sources":["../../src/utils/agentIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC9E,OAAO,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAC;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAEpD,MAAM,UAAU,wBAAwB,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC3E,OAAO,gBAAgB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACtE,OAAO,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,OAAO,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,KAAK,MAAM,CAAC;AACzD,CAAC;AAcD;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAiC,EACjC,MAAyB,OAAO,CAAC,GAAG;IAEpC,OAAO;QACL,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,wBAAwB,CAAC,GAAG,CAAC;QACjF,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC;QAClE,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,sBAAsB,CAAC,GAAG,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,8EAA8E,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runner types the platform supports, mirroring `RUNNER_TYPES` in
|
|
3
|
+
* `packages/core-constants`.
|
|
4
|
+
*
|
|
5
|
+
* The published CLI is a `cli/`-only subtree split, so the SSOT cannot be a runtime
|
|
6
|
+
* import here — the same constraint `mcp-registration/clients.ts` documents. A
|
|
7
|
+
* monorepo-only drift test (`test/runner-types.test.ts`) is what keeps this list honest.
|
|
8
|
+
*
|
|
9
|
+
* `GEMINI` is intentionally absent: it is a deprecated value kept only so historical
|
|
10
|
+
* snapshots still deserialize, never a value to advertise as selectable.
|
|
11
|
+
*/
|
|
12
|
+
export declare const RUNNER_TYPE_VALUES: readonly ["OPENCODE", "CLAUDE_CODE", "CODEX", "ANTIGRAVITY", "AMP", "COPILOT_CLI", "CURSOR_CLI", "KIMI_CLI", "KIRO_CLI", "GROK_BUILD"];
|
|
13
|
+
/**
|
|
14
|
+
* Help text for `--runner-type`. Kept as one string so every command that accepts the
|
|
15
|
+
* flag advertises the same set — previously four commands listed five stale values and
|
|
16
|
+
* four listed none, so `--help` disagreed with what the server actually accepts.
|
|
17
|
+
*
|
|
18
|
+
* The text is the bare value list — no "Runner type snapshot:" prefix — because the option
|
|
19
|
+
* name `--runner-type` already says what it is, and the per-command help byte budgets in
|
|
20
|
+
* `test/guide-command-smoke.test.ts` are tight enough that going from five values to nine
|
|
21
|
+
* does not fit otherwise. Those budgets exist because this help is agent-facing context, so
|
|
22
|
+
* its size is a token cost paid on every run; `|` separators and the dropped prefix keep the
|
|
23
|
+
* corrected list cheaper than the stale five-value sentence it replaces.
|
|
24
|
+
*
|
|
25
|
+
* The "filled in automatically from the runner session" hint deliberately lives on the error
|
|
26
|
+
* message instead of here — it is only useful at the moment the value is actually missing.
|
|
27
|
+
*/
|
|
28
|
+
export declare const RUNNER_TYPE_OPTION_DESCRIPTION: string;
|
|
29
|
+
//# sourceMappingURL=runnerTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerTypes.d.ts","sourceRoot":"","sources":["../../src/utils/runnerTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,wIAWrB,CAAC;AAEX;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,8BAA8B,QAA+B,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runner types the platform supports, mirroring `RUNNER_TYPES` in
|
|
3
|
+
* `packages/core-constants`.
|
|
4
|
+
*
|
|
5
|
+
* The published CLI is a `cli/`-only subtree split, so the SSOT cannot be a runtime
|
|
6
|
+
* import here — the same constraint `mcp-registration/clients.ts` documents. A
|
|
7
|
+
* monorepo-only drift test (`test/runner-types.test.ts`) is what keeps this list honest.
|
|
8
|
+
*
|
|
9
|
+
* `GEMINI` is intentionally absent: it is a deprecated value kept only so historical
|
|
10
|
+
* snapshots still deserialize, never a value to advertise as selectable.
|
|
11
|
+
*/
|
|
12
|
+
export const RUNNER_TYPE_VALUES = [
|
|
13
|
+
'OPENCODE',
|
|
14
|
+
'CLAUDE_CODE',
|
|
15
|
+
'CODEX',
|
|
16
|
+
'ANTIGRAVITY',
|
|
17
|
+
'AMP',
|
|
18
|
+
'COPILOT_CLI',
|
|
19
|
+
'CURSOR_CLI',
|
|
20
|
+
'KIMI_CLI',
|
|
21
|
+
'KIRO_CLI',
|
|
22
|
+
'GROK_BUILD',
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Help text for `--runner-type`. Kept as one string so every command that accepts the
|
|
26
|
+
* flag advertises the same set — previously four commands listed five stale values and
|
|
27
|
+
* four listed none, so `--help` disagreed with what the server actually accepts.
|
|
28
|
+
*
|
|
29
|
+
* The text is the bare value list — no "Runner type snapshot:" prefix — because the option
|
|
30
|
+
* name `--runner-type` already says what it is, and the per-command help byte budgets in
|
|
31
|
+
* `test/guide-command-smoke.test.ts` are tight enough that going from five values to nine
|
|
32
|
+
* does not fit otherwise. Those budgets exist because this help is agent-facing context, so
|
|
33
|
+
* its size is a token cost paid on every run; `|` separators and the dropped prefix keep the
|
|
34
|
+
* corrected list cheaper than the stale five-value sentence it replaces.
|
|
35
|
+
*
|
|
36
|
+
* The "filled in automatically from the runner session" hint deliberately lives on the error
|
|
37
|
+
* message instead of here — it is only useful at the moment the value is actually missing.
|
|
38
|
+
*/
|
|
39
|
+
export const RUNNER_TYPE_OPTION_DESCRIPTION = RUNNER_TYPE_VALUES.join('|');
|
|
40
|
+
//# sourceMappingURL=runnerTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerTypes.js","sourceRoot":"","sources":["../../src/utils/runnerTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,UAAU;IACV,aAAa;IACb,OAAO;IACP,aAAa;IACb,KAAK;IACL,aAAa;IACb,YAAY;IACZ,UAAU;IACV,UAAU;IACV,YAAY;CACJ,CAAC;AAEX;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill 패키지의 로컬 소유권과 원자적 교체. `.agentteams/skills/<slug>/`의 유일한 소유자는
|
|
3
|
+
* 이 모듈이며, `convention download`의 카테고리 sweep은 이 디렉터리를 건드리지 않는다.
|
|
4
|
+
*
|
|
5
|
+
* 계약(진입 파일, 허용 디렉터리, 크기 상한)의 SSOT는 서버가 배포하는 skill-package-guide.md다.
|
|
6
|
+
* CLI는 같은 규칙을 API 호출 **전에** 한 번 더 적용해, 잘못된 패키지가 네트워크를 타기 전에
|
|
7
|
+
* 사용자에게 이유를 알려준다. 최종 판정은 여전히 서버가 한다.
|
|
8
|
+
*/
|
|
9
|
+
/** `.agentteams` 아래 스킬 패키지 루트 디렉터리 이름. */
|
|
10
|
+
export declare const SKILL_PACKAGE_DIR = "skills";
|
|
11
|
+
/** 스킬 manifest 파일명. conventions.manifest.json 스키마는 건드리지 않는다(D7). */
|
|
12
|
+
export declare const SKILL_MANIFEST_FILE = "skills.manifest.json";
|
|
13
|
+
export declare const SKILL_ENTRY_FILE = "SKILL.md";
|
|
14
|
+
export declare const SKILL_RESOURCE_DIRS: readonly ["references", "scripts"];
|
|
15
|
+
export declare const SKILL_LIMITS: {
|
|
16
|
+
readonly entryFileBytes: number;
|
|
17
|
+
readonly resourceFileBytes: number;
|
|
18
|
+
readonly fileCount: 50;
|
|
19
|
+
readonly totalBytes: number;
|
|
20
|
+
readonly pathLength: 200;
|
|
21
|
+
};
|
|
22
|
+
export type SkillPackageFile = {
|
|
23
|
+
relativePath: string;
|
|
24
|
+
content: string;
|
|
25
|
+
};
|
|
26
|
+
/** mirror 대상. 값은 `--skill-targets` 토큰과 1:1로 대응한다. */
|
|
27
|
+
export declare const SKILL_MIRROR_TARGETS: readonly ["agents", "claude", "github"];
|
|
28
|
+
export type SkillMirrorTarget = (typeof SKILL_MIRROR_TARGETS)[number];
|
|
29
|
+
export declare const SKILL_TARGETS_NONE = "none";
|
|
30
|
+
export type SkillManifestEntry = {
|
|
31
|
+
skillId: string;
|
|
32
|
+
slug: string;
|
|
33
|
+
version: string;
|
|
34
|
+
/** 프로젝트 루트 기준 상대 경로. 이 목록에 있는 파일만 CLI가 지운다. */
|
|
35
|
+
mirrorPaths: string[];
|
|
36
|
+
};
|
|
37
|
+
export type SkillDownloadManifestV1 = {
|
|
38
|
+
version: 1;
|
|
39
|
+
generatedAt: string;
|
|
40
|
+
entries: SkillManifestEntry[];
|
|
41
|
+
};
|
|
42
|
+
export declare class SkillPackageError extends Error {
|
|
43
|
+
constructor(message: string);
|
|
44
|
+
}
|
|
45
|
+
export declare const skillPackageRoot: (projectRoot: string) => string;
|
|
46
|
+
export declare const skillManifestPath: (projectRoot: string) => string;
|
|
47
|
+
/**
|
|
48
|
+
* `--skill-targets` 파싱. 문법은 `--agent-files`와 같다: 콤마 구분 목록 또는 `none`.
|
|
49
|
+
* 지정하지 않으면 null을 돌려주고, 호출부가 마커 탐지 기본값을 쓴다.
|
|
50
|
+
*/
|
|
51
|
+
export declare const parseSkillTargetsOption: (raw: unknown) => SkillMirrorTarget[] | null;
|
|
52
|
+
/** 마커가 실재하는 클라이언트만 고른다. `.agents`는 마커 없이도 항상 포함된다. */
|
|
53
|
+
export declare const detectSkillMirrorTargets: (projectRoot: string) => SkillMirrorTarget[];
|
|
54
|
+
export declare const mirrorDirFor: (projectRoot: string, target: SkillMirrorTarget, slug: string) => string;
|
|
55
|
+
export declare const computeSkillVersion: (files: {
|
|
56
|
+
relativePath: string;
|
|
57
|
+
content: string;
|
|
58
|
+
}[]) => string;
|
|
59
|
+
/** 패키지 계약을 로컬에서 먼저 적용한다. 실패 사유는 서버 메시지와 같은 축을 쓴다. */
|
|
60
|
+
export declare const validateSkillPackageFiles: (files: SkillPackageFile[]) => void;
|
|
61
|
+
/**
|
|
62
|
+
* 로컬 디렉터리에서 패키지 파일을 모은다. symlink는 따라가지 않는다 — 링크가 패키지 밖을
|
|
63
|
+
* 가리키면 저장소 밖 파일이 업로드된다.
|
|
64
|
+
*/
|
|
65
|
+
export declare const collectSkillPackageFiles: (packageDir: string) => SkillPackageFile[];
|
|
66
|
+
export declare const readSkillManifest: (projectRoot: string) => SkillDownloadManifestV1;
|
|
67
|
+
export declare const writeSkillManifest: (projectRoot: string, manifest: SkillDownloadManifestV1) => void;
|
|
68
|
+
/**
|
|
69
|
+
* 임시 디렉터리에 전부 쓴 뒤 한 번에 교체한다. 쓰기 도중 실패하면 기존 디렉터리는
|
|
70
|
+
* byte-for-byte 그대로 남는다 — 부분 적용된 패키지는 "설치됐지만 깨진" 상태를 만든다.
|
|
71
|
+
*/
|
|
72
|
+
export declare const writePackageAtomically: (targetDir: string, files: SkillPackageFile[]) => void;
|
|
73
|
+
/** manifest에 기록된 경로만 지운다. 사용자가 mirror 디렉터리에 둔 파일은 건드리지 않는다. */
|
|
74
|
+
export declare const removeManifestPaths: (projectRoot: string, relativePaths: string[]) => void;
|
|
75
|
+
/**
|
|
76
|
+
* mirror 디렉터리를 `.gitignore`에 넣는다. mirror는 `.agentteams/skills/`에서 파생된 사본이라
|
|
77
|
+
* 커밋 대상이 아니다. `--commit-mirrors`를 준 프로젝트는 이 호출을 건너뛴다.
|
|
78
|
+
*/
|
|
79
|
+
export declare const ensureMirrorGitignore: (projectRoot: string, targets: SkillMirrorTarget[]) => void;
|
|
80
|
+
//# sourceMappingURL=skillPackage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPackage.d.ts","sourceRoot":"","sources":["../../src/utils/skillPackage.ts"],"names":[],"mappings":"AAaA;;;;;;;GAOG;AAEH,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,oEAAoE;AACpE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAC3C,eAAO,MAAM,mBAAmB,oCAAqC,CAAC;AAEtE,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,oBAAoB,yCAA0C,CAAC;AAC5E,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAgBzC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,KAAG,MAA6D,CAAC;AAErH,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,MAA+D,CAAC;AAExH;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,OAAO,KAAG,iBAAiB,EAAE,GAAG,IAmC5E,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,wBAAwB,GAAI,aAAa,MAAM,KAAG,iBAAiB,EAW/E,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,aAAa,MAAM,EAAE,QAAQ,iBAAiB,EAAE,MAAM,MAAM,KAAG,MACzC,CAAC;AAIpD,eAAO,MAAM,mBAAmB,GAAI,OAAO;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,KAAG,MAUxF,CAAC;AA0BF,qDAAqD;AACrD,eAAO,MAAM,yBAAyB,GAAI,OAAO,gBAAgB,EAAE,KAAG,IAwCrE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,YAAY,MAAM,KAAG,gBAAgB,EA2B7E,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,uBAiBvD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,EAAE,UAAU,uBAAuB,KAAG,IAI3F,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,WAAW,MAAM,EAAE,OAAO,gBAAgB,EAAE,KAAG,IAsCrF,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,EAAE,eAAe,MAAM,EAAE,KAAG,IASlF,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,aAAa,MAAM,EAAE,SAAS,iBAAiB,EAAE,KAAG,IAiBzF,CAAC"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Skill 패키지의 로컬 소유권과 원자적 교체. `.agentteams/skills/<slug>/`의 유일한 소유자는
|
|
6
|
+
* 이 모듈이며, `convention download`의 카테고리 sweep은 이 디렉터리를 건드리지 않는다.
|
|
7
|
+
*
|
|
8
|
+
* 계약(진입 파일, 허용 디렉터리, 크기 상한)의 SSOT는 서버가 배포하는 skill-package-guide.md다.
|
|
9
|
+
* CLI는 같은 규칙을 API 호출 **전에** 한 번 더 적용해, 잘못된 패키지가 네트워크를 타기 전에
|
|
10
|
+
* 사용자에게 이유를 알려준다. 최종 판정은 여전히 서버가 한다.
|
|
11
|
+
*/
|
|
12
|
+
/** `.agentteams` 아래 스킬 패키지 루트 디렉터리 이름. */
|
|
13
|
+
export const SKILL_PACKAGE_DIR = 'skills';
|
|
14
|
+
/** 스킬 manifest 파일명. conventions.manifest.json 스키마는 건드리지 않는다(D7). */
|
|
15
|
+
export const SKILL_MANIFEST_FILE = 'skills.manifest.json';
|
|
16
|
+
export const SKILL_ENTRY_FILE = 'SKILL.md';
|
|
17
|
+
export const SKILL_RESOURCE_DIRS = ['references', 'scripts'];
|
|
18
|
+
export const SKILL_LIMITS = {
|
|
19
|
+
entryFileBytes: 64 * 1024,
|
|
20
|
+
resourceFileBytes: 256 * 1024,
|
|
21
|
+
fileCount: 50,
|
|
22
|
+
totalBytes: 2 * 1024 * 1024,
|
|
23
|
+
pathLength: 200,
|
|
24
|
+
};
|
|
25
|
+
/** mirror 대상. 값은 `--skill-targets` 토큰과 1:1로 대응한다. */
|
|
26
|
+
export const SKILL_MIRROR_TARGETS = ['agents', 'claude', 'github'];
|
|
27
|
+
export const SKILL_TARGETS_NONE = 'none';
|
|
28
|
+
/**
|
|
29
|
+
* mirror 경로와 게이팅 규칙.
|
|
30
|
+
*
|
|
31
|
+
* `.agents/`는 벤더 중립 경로라 항상 쓴다(COPILOT_CLI·AMP·CODEX·OPENCODE·GROK_BUILD가 직접
|
|
32
|
+
* 읽는다 — 2026-08-15 프로브 실측. 판정 근거는 skill-package-guide.md §4).
|
|
33
|
+
* 나머지 둘은 해당 클라이언트의 마커 디렉터리가 **실재할 때만** 쓴다. 마커도 없는데 디렉터리를
|
|
34
|
+
* 만들면 그 저장소는 쓰지도 않는 도구를 위해 설정된 것처럼 보인다.
|
|
35
|
+
*/
|
|
36
|
+
const MIRROR_SPECS = {
|
|
37
|
+
agents: { dir: join('.agents', 'skills'), markerDir: null },
|
|
38
|
+
claude: { dir: join('.claude', 'skills'), markerDir: '.claude' },
|
|
39
|
+
github: { dir: join('.github', 'skills'), markerDir: '.github' },
|
|
40
|
+
};
|
|
41
|
+
export class SkillPackageError extends Error {
|
|
42
|
+
constructor(message) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = 'SkillPackageError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export const skillPackageRoot = (projectRoot) => join(projectRoot, '.agentteams', SKILL_PACKAGE_DIR);
|
|
48
|
+
export const skillManifestPath = (projectRoot) => join(projectRoot, '.agentteams', SKILL_MANIFEST_FILE);
|
|
49
|
+
/**
|
|
50
|
+
* `--skill-targets` 파싱. 문법은 `--agent-files`와 같다: 콤마 구분 목록 또는 `none`.
|
|
51
|
+
* 지정하지 않으면 null을 돌려주고, 호출부가 마커 탐지 기본값을 쓴다.
|
|
52
|
+
*/
|
|
53
|
+
export const parseSkillTargetsOption = (raw) => {
|
|
54
|
+
if (raw === undefined || raw === null)
|
|
55
|
+
return null;
|
|
56
|
+
if (typeof raw !== 'string') {
|
|
57
|
+
throw new SkillPackageError(`Invalid --skill-targets value. Expected a comma-separated list or '${SKILL_TARGETS_NONE}'.`);
|
|
58
|
+
}
|
|
59
|
+
const tokens = raw
|
|
60
|
+
.split(',')
|
|
61
|
+
.map((token) => token.trim())
|
|
62
|
+
.filter((token) => token.length > 0);
|
|
63
|
+
if (tokens.length === 0)
|
|
64
|
+
return null;
|
|
65
|
+
if (tokens.some((token) => token.toLowerCase() === SKILL_TARGETS_NONE)) {
|
|
66
|
+
if (tokens.length > 1) {
|
|
67
|
+
throw new SkillPackageError(`Invalid --skill-targets value: '${SKILL_TARGETS_NONE}' cannot be combined with other targets.`);
|
|
68
|
+
}
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const selected = [];
|
|
72
|
+
for (const token of tokens) {
|
|
73
|
+
const match = SKILL_MIRROR_TARGETS.find((value) => value === token.toLowerCase());
|
|
74
|
+
if (!match) {
|
|
75
|
+
throw new SkillPackageError(`Unknown --skill-targets value: '${token}'. Valid values: ${SKILL_MIRROR_TARGETS.join(', ')}, ${SKILL_TARGETS_NONE}.`);
|
|
76
|
+
}
|
|
77
|
+
if (!selected.includes(match))
|
|
78
|
+
selected.push(match);
|
|
79
|
+
}
|
|
80
|
+
return selected;
|
|
81
|
+
};
|
|
82
|
+
/** 마커가 실재하는 클라이언트만 고른다. `.agents`는 마커 없이도 항상 포함된다. */
|
|
83
|
+
export const detectSkillMirrorTargets = (projectRoot) => {
|
|
84
|
+
return SKILL_MIRROR_TARGETS.filter((target) => {
|
|
85
|
+
const { markerDir } = MIRROR_SPECS[target];
|
|
86
|
+
if (!markerDir)
|
|
87
|
+
return true;
|
|
88
|
+
const markerPath = join(projectRoot, markerDir);
|
|
89
|
+
try {
|
|
90
|
+
return lstatSync(markerPath).isDirectory();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
export const mirrorDirFor = (projectRoot, target, slug) => join(projectRoot, MIRROR_SPECS[target].dir, slug);
|
|
98
|
+
const sha256 = (content) => createHash('sha256').update(content, 'utf8').digest('hex');
|
|
99
|
+
export const computeSkillVersion = (files) => {
|
|
100
|
+
const normalized = [...files]
|
|
101
|
+
.map((file) => ({ relativePath: file.relativePath, hash: sha256(file.content) }))
|
|
102
|
+
.sort((left, right) => left.relativePath === right.relativePath ? 0 : left.relativePath < right.relativePath ? -1 : 1)
|
|
103
|
+
.map((file) => `${file.relativePath}:${file.hash}`)
|
|
104
|
+
.join('\n');
|
|
105
|
+
return sha256(normalized);
|
|
106
|
+
};
|
|
107
|
+
const assertSafeRelativePath = (relativePath) => {
|
|
108
|
+
if (relativePath.length === 0 || relativePath.length > SKILL_LIMITS.pathLength) {
|
|
109
|
+
throw new SkillPackageError(`Invalid path length: ${relativePath}`);
|
|
110
|
+
}
|
|
111
|
+
if (relativePath.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(relativePath) || relativePath.includes('\\')) {
|
|
112
|
+
throw new SkillPackageError(`Path must be relative and use "/" as the separator: ${relativePath}`);
|
|
113
|
+
}
|
|
114
|
+
const segments = relativePath.split('/');
|
|
115
|
+
if (segments.some((segment) => segment === '..' || segment === '.' || segment === '')) {
|
|
116
|
+
throw new SkillPackageError(`Path must be normalized and must not traverse upward: ${relativePath}`);
|
|
117
|
+
}
|
|
118
|
+
if (segments.length === 1) {
|
|
119
|
+
if (relativePath !== SKILL_ENTRY_FILE) {
|
|
120
|
+
throw new SkillPackageError(`The only file allowed at the package root is ${SKILL_ENTRY_FILE}: ${relativePath}`);
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (!SKILL_RESOURCE_DIRS.includes(segments[0])) {
|
|
125
|
+
throw new SkillPackageError(`Resource files must live under ${SKILL_RESOURCE_DIRS.join('/ or ')}/: ${relativePath}`);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/** 패키지 계약을 로컬에서 먼저 적용한다. 실패 사유는 서버 메시지와 같은 축을 쓴다. */
|
|
129
|
+
export const validateSkillPackageFiles = (files) => {
|
|
130
|
+
if (files.length === 0) {
|
|
131
|
+
throw new SkillPackageError(`A skill package must contain ${SKILL_ENTRY_FILE}`);
|
|
132
|
+
}
|
|
133
|
+
if (files.length > SKILL_LIMITS.fileCount) {
|
|
134
|
+
throw new SkillPackageError(`A skill package may contain at most ${SKILL_LIMITS.fileCount} files`);
|
|
135
|
+
}
|
|
136
|
+
const seen = new Set();
|
|
137
|
+
const seenLower = new Map();
|
|
138
|
+
let totalBytes = 0;
|
|
139
|
+
for (const file of files) {
|
|
140
|
+
assertSafeRelativePath(file.relativePath);
|
|
141
|
+
if (seen.has(file.relativePath)) {
|
|
142
|
+
throw new SkillPackageError(`Duplicate path: ${file.relativePath}`);
|
|
143
|
+
}
|
|
144
|
+
const lower = file.relativePath.toLowerCase();
|
|
145
|
+
const collision = seenLower.get(lower);
|
|
146
|
+
if (collision) {
|
|
147
|
+
throw new SkillPackageError(`Paths collide case-insensitively: ${collision} vs ${file.relativePath}`);
|
|
148
|
+
}
|
|
149
|
+
seen.add(file.relativePath);
|
|
150
|
+
seenLower.set(lower, file.relativePath);
|
|
151
|
+
const sizeBytes = Buffer.byteLength(file.content, 'utf8');
|
|
152
|
+
const limit = file.relativePath === SKILL_ENTRY_FILE ? SKILL_LIMITS.entryFileBytes : SKILL_LIMITS.resourceFileBytes;
|
|
153
|
+
if (sizeBytes > limit) {
|
|
154
|
+
throw new SkillPackageError(`${file.relativePath} exceeds ${limit} bytes`);
|
|
155
|
+
}
|
|
156
|
+
totalBytes += sizeBytes;
|
|
157
|
+
}
|
|
158
|
+
if (!seen.has(SKILL_ENTRY_FILE)) {
|
|
159
|
+
throw new SkillPackageError(`A skill package must contain ${SKILL_ENTRY_FILE}`);
|
|
160
|
+
}
|
|
161
|
+
if (totalBytes > SKILL_LIMITS.totalBytes) {
|
|
162
|
+
throw new SkillPackageError(`The package exceeds ${SKILL_LIMITS.totalBytes} bytes in total`);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* 로컬 디렉터리에서 패키지 파일을 모은다. symlink는 따라가지 않는다 — 링크가 패키지 밖을
|
|
167
|
+
* 가리키면 저장소 밖 파일이 업로드된다.
|
|
168
|
+
*/
|
|
169
|
+
export const collectSkillPackageFiles = (packageDir) => {
|
|
170
|
+
const rootPath = resolve(packageDir);
|
|
171
|
+
const files = [];
|
|
172
|
+
const walk = (currentDir) => {
|
|
173
|
+
for (const entry of readdirSync(currentDir, { withFileTypes: true })) {
|
|
174
|
+
const absolutePath = join(currentDir, entry.name);
|
|
175
|
+
const relativePath = relative(rootPath, absolutePath).split(sep).join('/');
|
|
176
|
+
if (entry.isSymbolicLink()) {
|
|
177
|
+
throw new SkillPackageError(`Symlinks are not allowed inside a skill package: ${relativePath}`);
|
|
178
|
+
}
|
|
179
|
+
if (entry.isDirectory()) {
|
|
180
|
+
walk(absolutePath);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (!entry.isFile()) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
files.push({ relativePath, content: readFileSync(absolutePath, 'utf8') });
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
walk(rootPath);
|
|
190
|
+
validateSkillPackageFiles(files);
|
|
191
|
+
return files;
|
|
192
|
+
};
|
|
193
|
+
export const readSkillManifest = (projectRoot) => {
|
|
194
|
+
const path = skillManifestPath(projectRoot);
|
|
195
|
+
if (!existsSync(path)) {
|
|
196
|
+
return { version: 1, generatedAt: new Date().toISOString(), entries: [] };
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
200
|
+
if (parsed.version !== 1 || !Array.isArray(parsed.entries)) {
|
|
201
|
+
return { version: 1, generatedAt: new Date().toISOString(), entries: [] };
|
|
202
|
+
}
|
|
203
|
+
return parsed;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// 손상된 manifest는 "아무것도 소유하지 않은 상태"로 다룬다. 여기서 실패로 끝내면
|
|
207
|
+
// 사용자가 파일을 손으로 고치기 전까지 동기화가 막힌다.
|
|
208
|
+
return { version: 1, generatedAt: new Date().toISOString(), entries: [] };
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
export const writeSkillManifest = (projectRoot, manifest) => {
|
|
212
|
+
const path = skillManifestPath(projectRoot);
|
|
213
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
214
|
+
writeFileSync(path, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* 임시 디렉터리에 전부 쓴 뒤 한 번에 교체한다. 쓰기 도중 실패하면 기존 디렉터리는
|
|
218
|
+
* byte-for-byte 그대로 남는다 — 부분 적용된 패키지는 "설치됐지만 깨진" 상태를 만든다.
|
|
219
|
+
*/
|
|
220
|
+
export const writePackageAtomically = (targetDir, files) => {
|
|
221
|
+
const stagingDir = `${targetDir}.staging-${process.pid}`;
|
|
222
|
+
const backupDir = `${targetDir}.backup-${process.pid}`;
|
|
223
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
224
|
+
mkdirSync(stagingDir, { recursive: true });
|
|
225
|
+
try {
|
|
226
|
+
for (const file of files) {
|
|
227
|
+
assertSafeRelativePath(file.relativePath);
|
|
228
|
+
const destination = join(stagingDir, ...file.relativePath.split('/'));
|
|
229
|
+
mkdirSync(dirname(destination), { recursive: true });
|
|
230
|
+
writeFileSync(destination, file.content, 'utf8');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
const hadPrevious = existsSync(targetDir);
|
|
238
|
+
if (hadPrevious) {
|
|
239
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
240
|
+
renameSync(targetDir, backupDir);
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
mkdirSync(dirname(targetDir), { recursive: true });
|
|
244
|
+
renameSync(stagingDir, targetDir);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
// 교체 자체가 실패하면 백업을 되돌려 이전 상태를 복원한다.
|
|
248
|
+
if (hadPrevious && !existsSync(targetDir)) {
|
|
249
|
+
renameSync(backupDir, targetDir);
|
|
250
|
+
}
|
|
251
|
+
rmSync(stagingDir, { recursive: true, force: true });
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
255
|
+
};
|
|
256
|
+
/** manifest에 기록된 경로만 지운다. 사용자가 mirror 디렉터리에 둔 파일은 건드리지 않는다. */
|
|
257
|
+
export const removeManifestPaths = (projectRoot, relativePaths) => {
|
|
258
|
+
for (const relativePath of relativePaths) {
|
|
259
|
+
const absolutePath = join(projectRoot, ...relativePath.split('/'));
|
|
260
|
+
// 프로젝트 루트를 벗어나는 기록은 무시한다(손상되거나 조작된 manifest 방어).
|
|
261
|
+
if (!resolve(absolutePath).startsWith(resolve(projectRoot) + sep)) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
rmSync(absolutePath, { recursive: true, force: true });
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
const GITIGNORE_MARKER = '# AgentTeams skill mirrors (generated — do not edit)';
|
|
268
|
+
/**
|
|
269
|
+
* mirror 디렉터리를 `.gitignore`에 넣는다. mirror는 `.agentteams/skills/`에서 파생된 사본이라
|
|
270
|
+
* 커밋 대상이 아니다. `--commit-mirrors`를 준 프로젝트는 이 호출을 건너뛴다.
|
|
271
|
+
*/
|
|
272
|
+
export const ensureMirrorGitignore = (projectRoot, targets) => {
|
|
273
|
+
if (targets.length === 0) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const gitignorePath = join(projectRoot, '.gitignore');
|
|
277
|
+
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf8') : '';
|
|
278
|
+
const wanted = targets.map((target) => `${MIRROR_SPECS[target].dir.split(sep).join('/')}/`);
|
|
279
|
+
const missing = wanted.filter((entry) => !existing.split(/\r?\n/).some((line) => line.trim() === entry));
|
|
280
|
+
if (missing.length === 0) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const block = existing.includes(GITIGNORE_MARKER) ? missing.join('\n') : [GITIGNORE_MARKER, ...missing].join('\n');
|
|
284
|
+
const separator = existing.length === 0 || existing.endsWith('\n') ? '' : '\n';
|
|
285
|
+
writeFileSync(gitignorePath, `${existing}${separator}${block}\n`, 'utf8');
|
|
286
|
+
};
|
|
287
|
+
//# sourceMappingURL=skillPackage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPackage.js","sourceRoot":"","sources":["../../src/utils/skillPackage.ts"],"names":[],"mappings":"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"}
|