@decencia/ch-cli 1.13.0 → 1.15.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/agent/2t-decencia-channel-issue-coder.md +1 -1
- package/agent/2t-decencia-channel-pr-merger.md +1 -1
- package/agent/2t-decencia-channel-terraformer.md +1 -1
- package/dist/client.d.ts +16 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +34 -0
- package/dist/client.js.map +1 -1
- package/dist/commands/screens.migrate.d.ts +0 -139
- package/dist/commands/screens.migrate.d.ts.map +1 -1
- package/dist/commands/screens.migrate.js +104 -429
- package/dist/commands/screens.migrate.js.map +1 -1
- package/dist/commands/specs.d.ts +2 -0
- package/dist/commands/specs.d.ts.map +1 -1
- package/dist/commands/specs.js +56 -3
- package/dist/commands/specs.js.map +1 -1
- package/package.json +1 -1
- package/skill/2t-decencia-channel-change-manager/SKILL.md +1 -1
- package/skill/2t-decencia-channel-change-propagation-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-cli-v2/SKILL.md +5 -3
- package/skill/2t-decencia-channel-db-schema-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-github-issue/SKILL.md +1 -1
- package/skill/2t-decencia-channel-orchestrator/SKILL.md +1 -1
- package/skill/2t-decencia-channel-prd-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-project-bootstrap/SKILL.md +1 -1
- package/skill/2t-decencia-channel-spec-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-sprint-builder-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-sprint-runner/SKILL.md +1 -1
- package/skill/2t-decencia-channel-sqa-v2/SKILL.md +1 -1
- package/skill/2t-decencia-channel-work-status-v2/SKILL.md +1 -1
|
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-issue-coder
|
|
|
3
3
|
description: GitHub issue 1개를 입력으로 받아 끝까지 처리하는 코딩 에이전트. 이슈 읽기 → 소통채널 spec/SQA 확인 → git worktree+브랜치에서 구현 → 자체 소프트리뷰 루프 → unittest + SQA → PR 생성 → 소통채널 workStatus·이슈 기록. 다수 병렬 실행 전제, PR까지만(머지·base 브랜치 직접 push·이슈 close는 사람).
|
|
4
4
|
tools: Read, Write, Edit, Grep, Glob, Bash, Agent
|
|
5
5
|
model: opus
|
|
6
|
-
version: 1.
|
|
6
|
+
version: 1.15.0
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 역할
|
|
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-pr-merger
|
|
|
3
3
|
description: issue-coder가 낸 PR을 기본 완전 자율로 base 브랜치(기본 브랜치 또는 sprint 통합 브랜치)에 머지하는 에이전트. 핵심 역량은 다수 병렬 worktree가 만든 충돌을 작업 의도 기반(semantic)으로 해결하는 것. CI green+충돌없음이면 바로 squash 머지, 충돌이면 의도대로 해결 후 테스트로 검증하여 머지. 재SQA·전면 재리뷰는 하지 않음. 다수 PR은 직렬 머지.
|
|
4
4
|
tools: Read, Write, Edit, Grep, Glob, Bash
|
|
5
5
|
model: opus
|
|
6
|
-
version: 1.
|
|
6
|
+
version: 1.15.0
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 역할
|
|
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-terraformer
|
|
|
3
3
|
description: 소통채널을 쓰지 않던 기존 코드베이스를 역분석하여 소통채널 프로젝트로 편입(terraforming)하는 자율 에이전트. 코드가 single source of truth — 코드를 읽어 DB 스키마 → 기능명세(spec) → PRD를 bottom-up으로 역생성한다(SQA 제외). 대량 분석은 서브에이전트 병렬, 코드로 못 메우는 의도는 [추정]으로 채우고 "사람확인 질문 리스트"를 산출물로 남긴다. PR/머지·이슈 발행은 하지 않음.
|
|
4
4
|
tools: Read, Write, Edit, Grep, Glob, Bash, Agent
|
|
5
5
|
model: opus
|
|
6
|
-
version: 1.
|
|
6
|
+
version: 1.15.0
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 역할
|
package/dist/client.d.ts
CHANGED
|
@@ -16,6 +16,22 @@ export interface ClientOptions {
|
|
|
16
16
|
}
|
|
17
17
|
export declare function getLastProjectContext(): ProjectContext | null;
|
|
18
18
|
export declare function createClient(options?: ClientOptions): AxiosInstance;
|
|
19
|
+
/**
|
|
20
|
+
* 부가 조회(probe) 전용 클라이언트 — "있으면 좋은" 읽기에만 쓴다.
|
|
21
|
+
*
|
|
22
|
+
* createClient의 인터셉터는 실패를 프로세스 결과에 그대로 반영한다: 4xx/5xx면
|
|
23
|
+
* process.exitCode=1(RC2), 연결 실패면 process.exit(1)로 프로세스를 즉시 끝낸다.
|
|
24
|
+
* 그 계약을 부가 조회에 적용하면 안 된다 — 예를 들어 `ch specs create`가 경고를
|
|
25
|
+
* 띄울지 판단하려고 프로젝트를 한 번 읽는데, 그 읽기가 실패했다고 명세 생성이
|
|
26
|
+
* 실패로 뒤집히거나 프로세스가 죽어서는 안 된다.
|
|
27
|
+
*
|
|
28
|
+
* 그래서 이 클라이언트는 에러 인터셉터를 달지 않는다(조용히 reject → 호출자가 삼킨다).
|
|
29
|
+
* 프로젝트 컨텍스트 안내·강제도 하지 않는다 — 주 요청이 이미 한다(중복 안내 방지).
|
|
30
|
+
* API Key가 없으면 null을 돌려준다(로그인 안내·종료는 주 요청의 몫).
|
|
31
|
+
*
|
|
32
|
+
* 타임아웃도 짧게 잡는다. 부가 조회 때문에 주 명령이 오래 붙들리면 안 된다.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createProbeClient(options?: ClientOptions): AxiosInstance | null;
|
|
19
35
|
/**
|
|
20
36
|
* Create a client that doesn't require projectId (for invitation endpoints)
|
|
21
37
|
*/
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAA0C,MAAM,OAAO,CAAC;AACrF,OAAO,EAKL,cAAc,EACf,MAAM,UAAU,CAAC;AAKlB;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,qBAAqB,IAAI,cAAc,GAAG,IAAI,CAE7D;AAwDD,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CAuGvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CA8B7E"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAA0C,MAAM,OAAO,CAAC;AACrF,OAAO,EAKL,cAAc,EACf,MAAM,UAAU,CAAC;AAKlB;;;;GAIG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,wBAAgB,qBAAqB,IAAI,cAAc,GAAG,IAAI,CAE7D;AAwDD,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CAuGvE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,GAAG,IAAI,CAoBnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,aAAkB,GAAG,aAAa,CA8B7E"}
|
package/dist/client.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ProjectContextRequiredError = void 0;
|
|
7
7
|
exports.getLastProjectContext = getLastProjectContext;
|
|
8
8
|
exports.createClient = createClient;
|
|
9
|
+
exports.createProbeClient = createProbeClient;
|
|
9
10
|
exports.createUnauthClient = createUnauthClient;
|
|
10
11
|
const axios_1 = __importDefault(require("axios"));
|
|
11
12
|
const config_1 = require("./config");
|
|
@@ -153,6 +154,39 @@ function createClient(options = {}) {
|
|
|
153
154
|
});
|
|
154
155
|
return instance;
|
|
155
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* 부가 조회(probe) 전용 클라이언트 — "있으면 좋은" 읽기에만 쓴다.
|
|
159
|
+
*
|
|
160
|
+
* createClient의 인터셉터는 실패를 프로세스 결과에 그대로 반영한다: 4xx/5xx면
|
|
161
|
+
* process.exitCode=1(RC2), 연결 실패면 process.exit(1)로 프로세스를 즉시 끝낸다.
|
|
162
|
+
* 그 계약을 부가 조회에 적용하면 안 된다 — 예를 들어 `ch specs create`가 경고를
|
|
163
|
+
* 띄울지 판단하려고 프로젝트를 한 번 읽는데, 그 읽기가 실패했다고 명세 생성이
|
|
164
|
+
* 실패로 뒤집히거나 프로세스가 죽어서는 안 된다.
|
|
165
|
+
*
|
|
166
|
+
* 그래서 이 클라이언트는 에러 인터셉터를 달지 않는다(조용히 reject → 호출자가 삼킨다).
|
|
167
|
+
* 프로젝트 컨텍스트 안내·강제도 하지 않는다 — 주 요청이 이미 한다(중복 안내 방지).
|
|
168
|
+
* API Key가 없으면 null을 돌려준다(로그인 안내·종료는 주 요청의 몫).
|
|
169
|
+
*
|
|
170
|
+
* 타임아웃도 짧게 잡는다. 부가 조회 때문에 주 명령이 오래 붙들리면 안 된다.
|
|
171
|
+
*/
|
|
172
|
+
function createProbeClient(options = {}) {
|
|
173
|
+
const config = (0, config_1.loadConfig)();
|
|
174
|
+
const apiKey = options.apiKey || config?.apiKey;
|
|
175
|
+
if (!apiKey)
|
|
176
|
+
return null;
|
|
177
|
+
const projectCtx = (0, config_1.getProjectContext)(options.projectId);
|
|
178
|
+
const apiUrl = options.apiUrl ||
|
|
179
|
+
config?.apiUrl ||
|
|
180
|
+
'https://ch-api-618529407342.asia-northeast3.run.app';
|
|
181
|
+
const headers = {
|
|
182
|
+
'Content-Type': 'application/json',
|
|
183
|
+
Authorization: `Bearer ${apiKey}`,
|
|
184
|
+
};
|
|
185
|
+
if (projectCtx?.projectId) {
|
|
186
|
+
headers['X-Project-Id'] = projectCtx.projectId;
|
|
187
|
+
}
|
|
188
|
+
return axios_1.default.create({ baseURL: apiUrl, timeout: 5000, headers });
|
|
189
|
+
}
|
|
156
190
|
/**
|
|
157
191
|
* Create a client that doesn't require projectId (for invitation endpoints)
|
|
158
192
|
*/
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;AAiCA,sDAEC;AAwDD,oCAuGC;AAKD,gDA8BC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,143 +1,4 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
/**
|
|
3
|
-
* `ch screens migrate` — 레거시 프로젝트를 화면 모델로 옮긴다 (SCREEN-006).
|
|
4
|
-
*
|
|
5
|
-
* 하는 일 세 가지, 이 순서로:
|
|
6
|
-
* 1. spec.ui.route를 씨앗으로 화면(screens)을 중복 없이 만든다.
|
|
7
|
-
* 2. 각 명세의 ui.screenRefs에 그 화면 ID를 더한다 (기존 ui 필드는 그대로 다시 실어 보낸다).
|
|
8
|
-
* 3. 전부 성공한 뒤에야 마지막 쓰기로 ch_projects.screensEnabled를 true로 켠다.
|
|
9
|
-
*
|
|
10
|
-
* 지키는 계약:
|
|
11
|
-
* 비파괴 — spec.ui의 기존 필드(figmaNodeId·route·file·access·interactionMap)를 지우지 않는다.
|
|
12
|
-
* PATCH /specs/:id는 ui를 통째로 교체하므로(specs.service의 `updateData['ui'] = ui`)
|
|
13
|
-
* 반드시 읽어서 병합한 뒤 통째로 다시 보낸다. 그래서 롤백은 플래그 한 개만 내리면 된다.
|
|
14
|
-
* --dry-run — 계획만 낸다. 쓰기 요청(POST/PATCH)을 한 건도 보내지 않는다. 읽기는 한다
|
|
15
|
-
* (계획을 서버 데이터로 계산하므로 — 다른 커맨드의 --dry-run과 다른 점이다).
|
|
16
|
-
* 멱등 — 같은 base route의 화면을 두 번 만들지 않고, 이미 걸린 screenRefs는 건드리지 않는다.
|
|
17
|
-
* 출력 — 기계 모드(--json)면 stdout은 계획/결과 JSON 한 문서뿐이고 사람 메시지는 stderr로 간다.
|
|
18
|
-
* 권한 — admin. screensEnabled 토글이 프로젝트 수정(PATCH /projects/current, admin 전용)이다.
|
|
19
|
-
*/
|
|
20
|
-
/** 마이그레이션이 읽는 명세의 최소 형태 (REST 응답의 부분집합). */
|
|
21
|
-
export interface MigrateSpec {
|
|
22
|
-
id: string;
|
|
23
|
-
name?: string;
|
|
24
|
-
epic?: string;
|
|
25
|
-
ui?: {
|
|
26
|
-
route?: string;
|
|
27
|
-
access?: string;
|
|
28
|
-
screenRefs?: string[];
|
|
29
|
-
[key: string]: unknown;
|
|
30
|
-
};
|
|
31
|
-
[key: string]: unknown;
|
|
32
|
-
}
|
|
33
|
-
/** 마이그레이션이 읽는 화면의 최소 형태. */
|
|
34
|
-
export interface MigrateScreen {
|
|
35
|
-
id: string;
|
|
36
|
-
name?: string;
|
|
37
|
-
route?: string;
|
|
38
|
-
order?: number;
|
|
39
|
-
epic?: string;
|
|
40
|
-
access?: string;
|
|
41
|
-
[key: string]: unknown;
|
|
42
|
-
}
|
|
43
|
-
export interface PlannedScreen {
|
|
44
|
-
/** 정규화된 base route (화면의 정체성). */
|
|
45
|
-
baseRoute: string;
|
|
46
|
-
/** create = 새로 만든다, reuse = 같은 base route 화면이 이미 있어 재사용한다. */
|
|
47
|
-
action: 'create' | 'reuse';
|
|
48
|
-
/** reuse면 기존 화면 ID. create면 적용 전까지 null (적용 후 서버가 준 ID로 채워진다). */
|
|
49
|
-
screenId: string | null;
|
|
50
|
-
name: string;
|
|
51
|
-
order: number;
|
|
52
|
-
epic?: string;
|
|
53
|
-
access?: string;
|
|
54
|
-
/** create일 때 화면에 남길 비고. reuse면 기존 비고를 보존하므로 없다. */
|
|
55
|
-
note?: string;
|
|
56
|
-
/** route에서 떼어낸 원문 주석 — 괄호 주석("PRD 탭")과 쿼리/프래그먼트("?tab=screens"). */
|
|
57
|
-
annotations: string[];
|
|
58
|
-
/** 이 base route에 묶인 명세 (ID 오름차순). */
|
|
59
|
-
specIds: string[];
|
|
60
|
-
/** 이 화면 ID를 ui.screenRefs에 새로 넣어야 하는 명세 (이미 걸린 것은 빠진다). */
|
|
61
|
-
linkSpecIds: string[];
|
|
62
|
-
/** 묶인 명세들의 epic 값이 갈릴 때의 후보 (하나로 일치하면 epic에 복사되고 여기는 1개). */
|
|
63
|
-
epicCandidates: string[];
|
|
64
|
-
/** 묶인 명세들의 ui.access 후보. */
|
|
65
|
-
accessCandidates: string[];
|
|
66
|
-
/** 같은 base route를 가진 기존 화면이 둘 이상일 때 그 ID들 (첫 화면을 재사용한다). */
|
|
67
|
-
duplicateScreenIds: string[];
|
|
68
|
-
}
|
|
69
|
-
export interface SkippedSpec {
|
|
70
|
-
id: string;
|
|
71
|
-
reason: string;
|
|
72
|
-
}
|
|
73
|
-
export interface MigrationPlan {
|
|
74
|
-
screens: PlannedScreen[];
|
|
75
|
-
skipped: SkippedSpec[];
|
|
76
|
-
screensEnabled: {
|
|
77
|
-
before: boolean;
|
|
78
|
-
after: boolean;
|
|
79
|
-
changed: boolean;
|
|
80
|
-
};
|
|
81
|
-
summary: {
|
|
82
|
-
specsTotal: number;
|
|
83
|
-
specsWithRoute: number;
|
|
84
|
-
screensToCreate: number;
|
|
85
|
-
screensToReuse: number;
|
|
86
|
-
specsToLink: number;
|
|
87
|
-
specsSkipped: number;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
export interface NormalizedRoute {
|
|
91
|
-
/** 정규화된 base route. 얻지 못하면 빈 문자열. */
|
|
92
|
-
baseRoute: string;
|
|
93
|
-
/** 정규화하며 떼어낸 원문 (괄호 주석 내용, 쿼리/프래그먼트). 버리지 않고 화면 비고로 옮긴다. */
|
|
94
|
-
annotations: string[];
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* route 문자열을 base route로 정규화한다.
|
|
98
|
-
*
|
|
99
|
-
* "/projects/[projectId]/specs (PRD 탭)" → "/projects/[projectId]/specs" + 주석 "PRD 탭"
|
|
100
|
-
* "/projects/[projectId]/specs?tab=screens" → "/projects/[projectId]/specs" + 주석 "?tab=screens"
|
|
101
|
-
* "/projects/" → "/projects"
|
|
102
|
-
* "/" → "/" (루트는 끝 슬래시 제거의 예외)
|
|
103
|
-
*
|
|
104
|
-
* 탭을 base route에서 떼는 이유: 탭은 라우트가 아니라 같은 화면의 URL 쿼리(?tab=)다. 괄호로
|
|
105
|
-
* 적혔든 쿼리로 적혔든 같은 페이지이므로 화면 하나로 묶는다. 원문은 버리지 않고 화면 비고에
|
|
106
|
-
* 남겨, 나중에 사람이 탭을 독립 화면으로 쪼갤지 판단할 근거로 쓴다.
|
|
107
|
-
*/
|
|
108
|
-
export declare function normalizeRoute(raw: unknown): NormalizedRoute;
|
|
109
|
-
/** 화면 비고: 씨앗 출처 + 묶인 명세 + 버리지 않은 route 주석 + 갈린 epic/access 후보. */
|
|
110
|
-
export declare function buildScreenNote(planned: {
|
|
111
|
-
specIds: string[];
|
|
112
|
-
annotations: string[];
|
|
113
|
-
epicCandidates: string[];
|
|
114
|
-
accessCandidates: string[];
|
|
115
|
-
epic?: string;
|
|
116
|
-
access?: string;
|
|
117
|
-
}): string;
|
|
118
|
-
/**
|
|
119
|
-
* 계획을 만든다 (읽기만 한 데이터로, 부작용 없이).
|
|
120
|
-
*
|
|
121
|
-
* - route가 없거나 ui가 없는 명세는 화면 없는 기능(배치·API·CLI)이므로 사유와 함께 건너뛴다.
|
|
122
|
-
* - 같은 base route는 화면 하나로 묶는다.
|
|
123
|
-
* - 화면 이름은 묶인 명세 중 ID 오름차순 첫 명세의 이름 (사람이 나중에 고치는 씨앗값).
|
|
124
|
-
* - 화면 순서는 base route 사전순 순번.
|
|
125
|
-
* - epic·access는 묶인 명세의 값이 하나로 일치할 때만 복사하고, 갈리면 비운 채 후보를 비고에 남긴다.
|
|
126
|
-
* - 같은 base route의 화면이 이미 있으면 만들지 않고 재사용한다 (멱등).
|
|
127
|
-
* - route를 가진 명세가 0건이면 화면도 만들지 않고 screensEnabled도 켜지 않는다 (빈 화면 탭 방지).
|
|
128
|
-
*/
|
|
129
|
-
export declare function buildMigrationPlan(specs: MigrateSpec[], existingScreens: MigrateScreen[], screensEnabledBefore: boolean): MigrationPlan;
|
|
130
|
-
/** 화면 생성 요청 바디. relatedSpecIds는 서버 전용이라 절대 싣지 않는다(보내면 조용히 버려진다). */
|
|
131
|
-
export declare function buildCreateScreenBody(planned: PlannedScreen): Record<string, unknown>;
|
|
132
|
-
/**
|
|
133
|
-
* 명세에 보낼 ui 병합 결과. 기존 ui를 통째로 다시 실어 보내면서 screenRefs에만 화면 ID를 더한다.
|
|
134
|
-
* PATCH /specs/:id가 ui를 통째로 교체하기 때문에, 이 병합을 빼먹으면 레거시 필드가
|
|
135
|
-
* 에러 없이 사라진다 (비파괴 계약 위반).
|
|
136
|
-
*/
|
|
137
|
-
export declare function mergeScreenRef(ui: Record<string, unknown> | undefined, screenId: string): {
|
|
138
|
-
ui: Record<string, unknown>;
|
|
139
|
-
changed: boolean;
|
|
140
|
-
};
|
|
141
2
|
/**
|
|
142
3
|
* `ch screens migrate` 등록. screens.ts의 register…(screens, program) 규약을 따른다.
|
|
143
4
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screens.migrate.d.ts","sourceRoot":"","sources":["../../src/commands/screens.migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"screens.migrate.d.ts","sourceRoot":"","sources":["../../src/commands/screens.migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyOpC;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACf,IAAI,CAsEN"}
|