@bstage-sdk/ai-toolkit 0.6.0 → 0.6.2

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/dist/index.cjs CHANGED
@@ -31,6 +31,7 @@ __export(index_exports, {
31
31
  designGuideSection: () => designGuideSection,
32
32
  designMeta: () => meta,
33
33
  designRulesBrief: () => designRulesBrief,
34
+ extractManagedBlock: () => extractManagedBlock,
34
35
  freeRegionScaffold: () => freeRegionScaffold,
35
36
  parseAgentsIdentity: () => parseAgentsIdentity,
36
37
  planInstall: () => planInstall,
@@ -48,7 +49,7 @@ __export(index_exports, {
48
49
  module.exports = __toCommonJS(index_exports);
49
50
 
50
51
  // src/version.ts
51
- var VERSION = "0.6.0";
52
+ var VERSION = "0.6.2";
52
53
 
53
54
  // src/skills/deploy.ts
54
55
  function deploySkillMd() {
@@ -738,6 +739,7 @@ ${designGuideSection(target)}
738
739
  - **\`__bstage_fetch__\` \uACC4\uC57D**: \uD50C\uB7AB\uD3FC\uC774 \uC778\uC99D fetch\uB97C \uC804\uC5ED\uC73C\uB85C \uC8FC\uC785\uD55C\uB2E4. \`BstageClient\`\uAC00 \uC774\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD558\uBBC0\uB85C, fetch \uACBD\uB85C\uB97C \uC6B0\uD68C\uD558\uC9C0 \uB9D0 \uAC83.
739
740
  - **\`slot.context\`\uB294 \uB2E8\uBC29\uD5A5\xB7read-only**: \uD638\uC2A4\uD2B8\u2192\uC704\uC82F 1\uD68C \uC804\uB2EC. \uC704\uC82F\uC774 \uB418\uB3CC\uB824 \uC4F0\uC9C0 \uC54A\uB294\uB2E4.
740
741
  - **\`createTemplate()\` \uD638\uCD9C \uD615\uD0DC \uC720\uC9C0**: \uBE4C\uB4DC \uD30C\uC774\uD504\uB77C\uC778\uC774 \uC18C\uC2A4\uC5D0\uC11C \`createTemplate(\` \uD638\uCD9C\uC744 \uD30C\uC2F1\uD574 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uBF51\uB294\uB2E4. \uC778\uC790 \uAD6C\uC870\uB97C \uC784\uC758 \uBCC0\uD615\uD558\uBA74 \uD30C\uC2F1 \uC2E4\uD328.
742
+ - **\uD398\uC774\uC9C0 \uD3F4\uB354 \`user\`\xB7\`admin\`\uC740 \uC608\uC57D\uC774\uB2E4**: \uC774 \uB808\uD3EC\uC5D0 liquid \uD15C\uD50C\uB9BF(\`public/{user|admin}/{\uC774\uB984}/template.liquid\`)\uC774 \uD568\uAED8 \uC788\uC73C\uBA74 \`src/pages/user/\u2026\`\xB7\`src/pages/admin/\u2026\` \uC740 \uB9CC\uB4E4 \uC218 \uC5C6\uB2E4(\uB300\uC18C\uBB38\uC790 \uBB34\uC2DC). \uD398\uC774\uC9C0 \uC0B0\uCD9C\uBB3C\uC774 \`dist/{\uD3F4\uB354 \uACBD\uB85C}/\` \uB85C \uB098\uAC00 liquid \uC790\uB9AC\uC640 \uAC19\uC740 \uD2B8\uB9AC\uC5D0 \uB193\uC774\uACE0, \uD55C \uB514\uB809\uD130\uB9AC\uC5D0 \uB450 \uC885\uB958\uAC00 \uB193\uC774\uBA74 \uD3EC\uD138\uC774 sdk\uB85C\uB9CC \uD310\uC815\uD574 liquid\uAC00 \uC870\uC6A9\uD788 \uC0AC\uB77C\uC9C4\uB2E4. \`bstage build\` \uC640 \uD3EC\uD138 \uBE4C\uB4DC\uAC00 \uC885\uB8CC \uCF54\uB4DC 2\uB85C \uB9C9\uB294\uB2E4. \uC704\uC82F(\`src/slots\`)\uC740 \uC2AC\uB86F id\uB85C \uB098\uAC00\uBBC0\uB85C \uD574\uB2F9 \uC5C6\uB2E4. liquid \uD15C\uD50C\uB9BF\uC774 \uC5C6\uB294 \uB808\uD3EC\uC5D0\uC11C\uB294 \uC81C\uC57D\uC774 \uC5C6\uC9C0\uB9CC, \uB098\uC911\uC5D0 \uCD94\uAC00\uD558\uBA74 \uADF8\uB54C \uB9C9\uD788\uBBC0\uB85C \uCC98\uC74C\uBD80\uD130 \uB2E4\uB978 \uC774\uB984\uC744 \uC4F4\uB2E4.
741
743
 
742
744
  # \uD558\uC9C0 \uB9D0 \uAC83
743
745
 
@@ -745,6 +747,7 @@ ${designGuideSection(target)}
745
747
  - \`customElements.define()\` / \`attachShadow\` \uC9C1\uC811 \uD638\uCD9C (createTemplate\uC774 \uCC98\uB9AC)
746
748
  - \`@bstage-sdk/core\`\uC758 \`createWebComponent()\` \uC9C1\uC811 \uC0AC\uC6A9 \u2014 react \uD328\uD0A4\uC9C0 API\uB9CC
747
749
  - UI \uC0C9\xB7\uD0C0\uC774\uD3EC\xB7\uADF8\uB9BC\uC790\uB97C hex/rgb\uB85C \uD558\uB4DC\uCF54\uB529 \u2014 \uB514\uC790\uC778 \uD1A0\uD070(\uC704 3\uBC88) \uC0AC\uC6A9
750
+ - liquid \uD15C\uD50C\uB9BF\uC774 \uD568\uAED8 \uC788\uB294 \uB808\uD3EC\uC5D0\uC11C \`src/pages/user\`\xB7\`src/pages/admin\` \uB9CC\uB4E4\uAE30 \u2014 liquid \uC0B0\uCD9C\uBB3C \uC790\uB9AC\uC640 \uACB9\uCE5C\uB2E4(\uC704 \uD568\uC815)
748
751
  - \uC2DC\uADF8\uB2C8\uCC98\uB97C \uAE30\uC5B5\uC5D0 \uC758\uC874\uD574 \uCD94\uCE21 \u2014 \uC704 docs/.d.ts\uC5D0\uC11C \uD655\uC778
749
752
  `;
750
753
  }
@@ -834,6 +837,12 @@ function agentsMdStatus(content) {
834
837
  if (v === null) return "legacy";
835
838
  return v < AGENTS_MANAGED_VERSION ? "stale" : "ok";
836
839
  }
840
+ function extractManagedBlock(content) {
841
+ const s = findMarker(content, START_TOKEN);
842
+ const e = findMarker(content, END_TOKEN);
843
+ if (!s || !e || e.end <= s.start) return null;
844
+ return content.slice(s.start, e.end);
845
+ }
837
846
  function swapManagedBlock(existing, newWrappedBlock) {
838
847
  const s = findMarker(existing, START_TOKEN);
839
848
  const e = findMarker(existing, END_TOKEN);
@@ -1195,6 +1204,8 @@ var CLAUDE_FILE = "CLAUDE.md";
1195
1204
  var LEGACY_NOTE = "\uAD00\uB9AC \uC601\uC5ED \uB9C8\uCEE4 \uC5C6\uC74C \u2014 bstage-migrate \uC2A4\uD0AC\uB85C reconcile";
1196
1205
  var HAND_EDIT_NOTE = "\uBC84\uC804\uC740 \uAC19\uC740\uB370 \uBCF8\uBB38\uC774 \uB2E4\uB985\uB2C8\uB2E4(\uC190\uC218\uC815) \u2014 SDK \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9AC\uACE0 \uAE30\uC874 \uBCF8\uBB38\uC740 SKILL.md.bak \uC73C\uB85C \uB0A8\uAE41\uB2C8\uB2E4. \uD504\uB85C\uC81D\uD2B8 \uACE0\uC720 \uADDC\uCE59\uC740 AGENTS.md \uC790\uC720 \uC601\uC5ED\uC5D0 \uC801\uC73C\uC138\uC694.";
1197
1206
  var NEWER_NOTE = "\uC124\uCE58\uBCF8\uC774 \uC774 toolkit\uBCF4\uB2E4 \uC0C8 \uBC84\uC804\uC785\uB2C8\uB2E4 \u2014 \uC774 CLI\uAC00 \uC624\uB798\uB3FC \uC61B \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4(\uD558\uD5A5). \uCD5C\uC2E0 CLI(npx @bstage-sdk/cli@latest ai update)\uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.";
1207
+ var KIND_DRIFT_NOTE = "\uAD00\uB9AC \uC601\uC5ED \uBC84\uC804\uC740 \uCD5C\uC2E0\uC778\uB370 \uBCF8\uBB38\uC774 \uC774 \uD504\uB85C\uC81D\uD2B8 \uC885\uB958\uC758 \uAC83\uACFC \uB2E4\uB985\uB2C8\uB2E4(\uC885\uB958\uAC00 \uBC14\uB00C\uC5C8\uAC70\uB098 \uAD00\uB9AC \uC601\uC5ED\uC744 \uC190\uC73C\uB85C \uACE0\uCE68) \u2014 \uD604\uC7AC \uC885\uB958\uC758 \uBCF8\uBB38\uC73C\uB85C \uAC31\uC2E0\uD569\uB2C8\uB2E4. \uC790\uC720 \uC601\uC5ED\uC740 \uBCF4\uC874\uB429\uB2C8\uB2E4.";
1208
+ var AGENTS_NEWER_NOTE = "AGENTS.md \uAD00\uB9AC \uC601\uC5ED\uC774 \uC774 toolkit\uBCF4\uB2E4 \uC0C8 \uBC84\uC804\uC785\uB2C8\uB2E4 \u2014 \uC774 CLI\uAC00 \uC624\uB798\uB3FC \uC61B \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4(\uD558\uD5A5). \uCD5C\uC2E0 CLI(npx @bstage-sdk/cli@latest ai update)\uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.";
1198
1209
  function planInstall(input) {
1199
1210
  const actions = [...planSkills(input), planAgentsMd(input), planClaudeMd(input.existing.claudeMd)];
1200
1211
  return [...actions].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -1247,7 +1258,6 @@ function planAgentsMd(input) {
1247
1258
  if (status === "legacy") {
1248
1259
  return { path: AGENTS_FILE, content: null, reason: "legacy", note: LEGACY_NOTE };
1249
1260
  }
1250
- if (status === "ok") return { path: AGENTS_FILE, content: null, reason: "keep" };
1251
1261
  const identity = parseAgentsIdentity(current);
1252
1262
  const block = renderManagedBlock({
1253
1263
  space: sanitizeIdentity(identity.space) ?? space,
@@ -1255,10 +1265,23 @@ function planAgentsMd(input) {
1255
1265
  target,
1256
1266
  kind
1257
1267
  });
1268
+ if (status === "ok" && extractManagedBlock(current) === block) {
1269
+ return { path: AGENTS_FILE, content: null, reason: "keep" };
1270
+ }
1258
1271
  const swapped = swapManagedBlock(current, block);
1259
1272
  if (swapped === null) {
1260
1273
  return { path: AGENTS_FILE, content: null, reason: "legacy", note: LEGACY_NOTE };
1261
1274
  }
1275
+ if (status === "ok") {
1276
+ const fileVersion = readManagedVersion(current);
1277
+ const newer = fileVersion !== null && fileVersion > AGENTS_MANAGED_VERSION;
1278
+ return {
1279
+ path: AGENTS_FILE,
1280
+ content: swapped,
1281
+ reason: "update",
1282
+ note: newer ? AGENTS_NEWER_NOTE : KIND_DRIFT_NOTE
1283
+ };
1284
+ }
1262
1285
  return { path: AGENTS_FILE, content: swapped, reason: "update" };
1263
1286
  }
1264
1287
  function planClaudeMd(current) {
@@ -1278,6 +1301,7 @@ function planClaudeMd(current) {
1278
1301
  designGuideSection,
1279
1302
  designMeta,
1280
1303
  designRulesBrief,
1304
+ extractManagedBlock,
1281
1305
  freeRegionScaffold,
1282
1306
  parseAgentsIdentity,
1283
1307
  planInstall,
package/dist/index.d.cts CHANGED
@@ -111,6 +111,12 @@ type AgentsMdStatus = 'missing' | 'legacy' | 'stale' | 'ok';
111
111
  declare function readManagedVersion(content: string): number | null;
112
112
  /** AGENTS.md 내용으로 갱신 상태를 판정한다. */
113
113
  declare function agentsMdStatus(content: string): Exclude<AgentsMdStatus, 'missing'>;
114
+ /**
115
+ * 기존 파일의 관리 영역(마커 포함, START~END)을 그대로 돌려준다. 마커가 없거나 순서가 어긋나면 null.
116
+ * `renderManagedBlock` 결과와 문자열로 비교해 "버전은 같은데 본문이 다른" 상태(레포 종류가 바뀐 뒤의
117
+ * 옛 kind 본문, 관리 영역 안 손수정)를 잡는 데 쓴다 — 버전 마커만 보면 이 둘은 `ok`로 보인다.
118
+ */
119
+ declare function extractManagedBlock(content: string): string | null;
114
120
  /**
115
121
  * 기존 파일의 관리 영역(START~END)을 새 블록으로 치환한다. START/END 바깥(자유 영역 등)은
116
122
  * 그대로 보존한다. 마커가 없으면(레거시) null을 반환 — 호출부가 reconcile 경로로 분기한다.
@@ -223,4 +229,4 @@ declare function designRulesBrief(target: DesignTarget): string;
223
229
  */
224
230
  declare function designGuideSection(target: DesignTarget): string;
225
231
 
226
- export { AGENTS_MANAGED_VERSION, type ActionReason, type AgentsMdStatus, BSTAGE_SKILLS, type BstageSkill, type DesignTarget, type InstallAction, type InstallInput, type ProjectKind, type SkillContext, VERSION, agentsManagedBody, agentsMd, agentsMdStatus, claudeMd, compareVersions, designGuideSection, meta as designMeta, designRulesBrief, freeRegionScaffold, parseAgentsIdentity, planInstall, readManagedVersion, readSkillStamp, renderManagedBlock, sanitizeIdentity, skillFilePath, skillStamp, skillsFor, swapManagedBlock, withStamp, wrapManaged };
232
+ export { AGENTS_MANAGED_VERSION, type ActionReason, type AgentsMdStatus, BSTAGE_SKILLS, type BstageSkill, type DesignTarget, type InstallAction, type InstallInput, type ProjectKind, type SkillContext, VERSION, agentsManagedBody, agentsMd, agentsMdStatus, claudeMd, compareVersions, designGuideSection, meta as designMeta, designRulesBrief, extractManagedBlock, freeRegionScaffold, parseAgentsIdentity, planInstall, readManagedVersion, readSkillStamp, renderManagedBlock, sanitizeIdentity, skillFilePath, skillStamp, skillsFor, swapManagedBlock, withStamp, wrapManaged };
package/dist/index.d.ts CHANGED
@@ -111,6 +111,12 @@ type AgentsMdStatus = 'missing' | 'legacy' | 'stale' | 'ok';
111
111
  declare function readManagedVersion(content: string): number | null;
112
112
  /** AGENTS.md 내용으로 갱신 상태를 판정한다. */
113
113
  declare function agentsMdStatus(content: string): Exclude<AgentsMdStatus, 'missing'>;
114
+ /**
115
+ * 기존 파일의 관리 영역(마커 포함, START~END)을 그대로 돌려준다. 마커가 없거나 순서가 어긋나면 null.
116
+ * `renderManagedBlock` 결과와 문자열로 비교해 "버전은 같은데 본문이 다른" 상태(레포 종류가 바뀐 뒤의
117
+ * 옛 kind 본문, 관리 영역 안 손수정)를 잡는 데 쓴다 — 버전 마커만 보면 이 둘은 `ok`로 보인다.
118
+ */
119
+ declare function extractManagedBlock(content: string): string | null;
114
120
  /**
115
121
  * 기존 파일의 관리 영역(START~END)을 새 블록으로 치환한다. START/END 바깥(자유 영역 등)은
116
122
  * 그대로 보존한다. 마커가 없으면(레거시) null을 반환 — 호출부가 reconcile 경로로 분기한다.
@@ -223,4 +229,4 @@ declare function designRulesBrief(target: DesignTarget): string;
223
229
  */
224
230
  declare function designGuideSection(target: DesignTarget): string;
225
231
 
226
- export { AGENTS_MANAGED_VERSION, type ActionReason, type AgentsMdStatus, BSTAGE_SKILLS, type BstageSkill, type DesignTarget, type InstallAction, type InstallInput, type ProjectKind, type SkillContext, VERSION, agentsManagedBody, agentsMd, agentsMdStatus, claudeMd, compareVersions, designGuideSection, meta as designMeta, designRulesBrief, freeRegionScaffold, parseAgentsIdentity, planInstall, readManagedVersion, readSkillStamp, renderManagedBlock, sanitizeIdentity, skillFilePath, skillStamp, skillsFor, swapManagedBlock, withStamp, wrapManaged };
232
+ export { AGENTS_MANAGED_VERSION, type ActionReason, type AgentsMdStatus, BSTAGE_SKILLS, type BstageSkill, type DesignTarget, type InstallAction, type InstallInput, type ProjectKind, type SkillContext, VERSION, agentsManagedBody, agentsMd, agentsMdStatus, claudeMd, compareVersions, designGuideSection, meta as designMeta, designRulesBrief, extractManagedBlock, freeRegionScaffold, parseAgentsIdentity, planInstall, readManagedVersion, readSkillStamp, renderManagedBlock, sanitizeIdentity, skillFilePath, skillStamp, skillsFor, swapManagedBlock, withStamp, wrapManaged };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.6.0";
2
+ var VERSION = "0.6.2";
3
3
 
4
4
  // src/skills/deploy.ts
5
5
  function deploySkillMd() {
@@ -689,6 +689,7 @@ ${designGuideSection(target)}
689
689
  - **\`__bstage_fetch__\` \uACC4\uC57D**: \uD50C\uB7AB\uD3FC\uC774 \uC778\uC99D fetch\uB97C \uC804\uC5ED\uC73C\uB85C \uC8FC\uC785\uD55C\uB2E4. \`BstageClient\`\uAC00 \uC774\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD558\uBBC0\uB85C, fetch \uACBD\uB85C\uB97C \uC6B0\uD68C\uD558\uC9C0 \uB9D0 \uAC83.
690
690
  - **\`slot.context\`\uB294 \uB2E8\uBC29\uD5A5\xB7read-only**: \uD638\uC2A4\uD2B8\u2192\uC704\uC82F 1\uD68C \uC804\uB2EC. \uC704\uC82F\uC774 \uB418\uB3CC\uB824 \uC4F0\uC9C0 \uC54A\uB294\uB2E4.
691
691
  - **\`createTemplate()\` \uD638\uCD9C \uD615\uD0DC \uC720\uC9C0**: \uBE4C\uB4DC \uD30C\uC774\uD504\uB77C\uC778\uC774 \uC18C\uC2A4\uC5D0\uC11C \`createTemplate(\` \uD638\uCD9C\uC744 \uD30C\uC2F1\uD574 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uBF51\uB294\uB2E4. \uC778\uC790 \uAD6C\uC870\uB97C \uC784\uC758 \uBCC0\uD615\uD558\uBA74 \uD30C\uC2F1 \uC2E4\uD328.
692
+ - **\uD398\uC774\uC9C0 \uD3F4\uB354 \`user\`\xB7\`admin\`\uC740 \uC608\uC57D\uC774\uB2E4**: \uC774 \uB808\uD3EC\uC5D0 liquid \uD15C\uD50C\uB9BF(\`public/{user|admin}/{\uC774\uB984}/template.liquid\`)\uC774 \uD568\uAED8 \uC788\uC73C\uBA74 \`src/pages/user/\u2026\`\xB7\`src/pages/admin/\u2026\` \uC740 \uB9CC\uB4E4 \uC218 \uC5C6\uB2E4(\uB300\uC18C\uBB38\uC790 \uBB34\uC2DC). \uD398\uC774\uC9C0 \uC0B0\uCD9C\uBB3C\uC774 \`dist/{\uD3F4\uB354 \uACBD\uB85C}/\` \uB85C \uB098\uAC00 liquid \uC790\uB9AC\uC640 \uAC19\uC740 \uD2B8\uB9AC\uC5D0 \uB193\uC774\uACE0, \uD55C \uB514\uB809\uD130\uB9AC\uC5D0 \uB450 \uC885\uB958\uAC00 \uB193\uC774\uBA74 \uD3EC\uD138\uC774 sdk\uB85C\uB9CC \uD310\uC815\uD574 liquid\uAC00 \uC870\uC6A9\uD788 \uC0AC\uB77C\uC9C4\uB2E4. \`bstage build\` \uC640 \uD3EC\uD138 \uBE4C\uB4DC\uAC00 \uC885\uB8CC \uCF54\uB4DC 2\uB85C \uB9C9\uB294\uB2E4. \uC704\uC82F(\`src/slots\`)\uC740 \uC2AC\uB86F id\uB85C \uB098\uAC00\uBBC0\uB85C \uD574\uB2F9 \uC5C6\uB2E4. liquid \uD15C\uD50C\uB9BF\uC774 \uC5C6\uB294 \uB808\uD3EC\uC5D0\uC11C\uB294 \uC81C\uC57D\uC774 \uC5C6\uC9C0\uB9CC, \uB098\uC911\uC5D0 \uCD94\uAC00\uD558\uBA74 \uADF8\uB54C \uB9C9\uD788\uBBC0\uB85C \uCC98\uC74C\uBD80\uD130 \uB2E4\uB978 \uC774\uB984\uC744 \uC4F4\uB2E4.
692
693
 
693
694
  # \uD558\uC9C0 \uB9D0 \uAC83
694
695
 
@@ -696,6 +697,7 @@ ${designGuideSection(target)}
696
697
  - \`customElements.define()\` / \`attachShadow\` \uC9C1\uC811 \uD638\uCD9C (createTemplate\uC774 \uCC98\uB9AC)
697
698
  - \`@bstage-sdk/core\`\uC758 \`createWebComponent()\` \uC9C1\uC811 \uC0AC\uC6A9 \u2014 react \uD328\uD0A4\uC9C0 API\uB9CC
698
699
  - UI \uC0C9\xB7\uD0C0\uC774\uD3EC\xB7\uADF8\uB9BC\uC790\uB97C hex/rgb\uB85C \uD558\uB4DC\uCF54\uB529 \u2014 \uB514\uC790\uC778 \uD1A0\uD070(\uC704 3\uBC88) \uC0AC\uC6A9
700
+ - liquid \uD15C\uD50C\uB9BF\uC774 \uD568\uAED8 \uC788\uB294 \uB808\uD3EC\uC5D0\uC11C \`src/pages/user\`\xB7\`src/pages/admin\` \uB9CC\uB4E4\uAE30 \u2014 liquid \uC0B0\uCD9C\uBB3C \uC790\uB9AC\uC640 \uACB9\uCE5C\uB2E4(\uC704 \uD568\uC815)
699
701
  - \uC2DC\uADF8\uB2C8\uCC98\uB97C \uAE30\uC5B5\uC5D0 \uC758\uC874\uD574 \uCD94\uCE21 \u2014 \uC704 docs/.d.ts\uC5D0\uC11C \uD655\uC778
700
702
  `;
701
703
  }
@@ -785,6 +787,12 @@ function agentsMdStatus(content) {
785
787
  if (v === null) return "legacy";
786
788
  return v < AGENTS_MANAGED_VERSION ? "stale" : "ok";
787
789
  }
790
+ function extractManagedBlock(content) {
791
+ const s = findMarker(content, START_TOKEN);
792
+ const e = findMarker(content, END_TOKEN);
793
+ if (!s || !e || e.end <= s.start) return null;
794
+ return content.slice(s.start, e.end);
795
+ }
788
796
  function swapManagedBlock(existing, newWrappedBlock) {
789
797
  const s = findMarker(existing, START_TOKEN);
790
798
  const e = findMarker(existing, END_TOKEN);
@@ -1146,6 +1154,8 @@ var CLAUDE_FILE = "CLAUDE.md";
1146
1154
  var LEGACY_NOTE = "\uAD00\uB9AC \uC601\uC5ED \uB9C8\uCEE4 \uC5C6\uC74C \u2014 bstage-migrate \uC2A4\uD0AC\uB85C reconcile";
1147
1155
  var HAND_EDIT_NOTE = "\uBC84\uC804\uC740 \uAC19\uC740\uB370 \uBCF8\uBB38\uC774 \uB2E4\uB985\uB2C8\uB2E4(\uC190\uC218\uC815) \u2014 SDK \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9AC\uACE0 \uAE30\uC874 \uBCF8\uBB38\uC740 SKILL.md.bak \uC73C\uB85C \uB0A8\uAE41\uB2C8\uB2E4. \uD504\uB85C\uC81D\uD2B8 \uACE0\uC720 \uADDC\uCE59\uC740 AGENTS.md \uC790\uC720 \uC601\uC5ED\uC5D0 \uC801\uC73C\uC138\uC694.";
1148
1156
  var NEWER_NOTE = "\uC124\uCE58\uBCF8\uC774 \uC774 toolkit\uBCF4\uB2E4 \uC0C8 \uBC84\uC804\uC785\uB2C8\uB2E4 \u2014 \uC774 CLI\uAC00 \uC624\uB798\uB3FC \uC61B \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4(\uD558\uD5A5). \uCD5C\uC2E0 CLI(npx @bstage-sdk/cli@latest ai update)\uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.";
1157
+ var KIND_DRIFT_NOTE = "\uAD00\uB9AC \uC601\uC5ED \uBC84\uC804\uC740 \uCD5C\uC2E0\uC778\uB370 \uBCF8\uBB38\uC774 \uC774 \uD504\uB85C\uC81D\uD2B8 \uC885\uB958\uC758 \uAC83\uACFC \uB2E4\uB985\uB2C8\uB2E4(\uC885\uB958\uAC00 \uBC14\uB00C\uC5C8\uAC70\uB098 \uAD00\uB9AC \uC601\uC5ED\uC744 \uC190\uC73C\uB85C \uACE0\uCE68) \u2014 \uD604\uC7AC \uC885\uB958\uC758 \uBCF8\uBB38\uC73C\uB85C \uAC31\uC2E0\uD569\uB2C8\uB2E4. \uC790\uC720 \uC601\uC5ED\uC740 \uBCF4\uC874\uB429\uB2C8\uB2E4.";
1158
+ var AGENTS_NEWER_NOTE = "AGENTS.md \uAD00\uB9AC \uC601\uC5ED\uC774 \uC774 toolkit\uBCF4\uB2E4 \uC0C8 \uBC84\uC804\uC785\uB2C8\uB2E4 \u2014 \uC774 CLI\uAC00 \uC624\uB798\uB3FC \uC61B \uBCF8\uBB38\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4(\uD558\uD5A5). \uCD5C\uC2E0 CLI(npx @bstage-sdk/cli@latest ai update)\uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.";
1149
1159
  function planInstall(input) {
1150
1160
  const actions = [...planSkills(input), planAgentsMd(input), planClaudeMd(input.existing.claudeMd)];
1151
1161
  return [...actions].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -1198,7 +1208,6 @@ function planAgentsMd(input) {
1198
1208
  if (status === "legacy") {
1199
1209
  return { path: AGENTS_FILE, content: null, reason: "legacy", note: LEGACY_NOTE };
1200
1210
  }
1201
- if (status === "ok") return { path: AGENTS_FILE, content: null, reason: "keep" };
1202
1211
  const identity = parseAgentsIdentity(current);
1203
1212
  const block = renderManagedBlock({
1204
1213
  space: sanitizeIdentity(identity.space) ?? space,
@@ -1206,10 +1215,23 @@ function planAgentsMd(input) {
1206
1215
  target,
1207
1216
  kind
1208
1217
  });
1218
+ if (status === "ok" && extractManagedBlock(current) === block) {
1219
+ return { path: AGENTS_FILE, content: null, reason: "keep" };
1220
+ }
1209
1221
  const swapped = swapManagedBlock(current, block);
1210
1222
  if (swapped === null) {
1211
1223
  return { path: AGENTS_FILE, content: null, reason: "legacy", note: LEGACY_NOTE };
1212
1224
  }
1225
+ if (status === "ok") {
1226
+ const fileVersion = readManagedVersion(current);
1227
+ const newer = fileVersion !== null && fileVersion > AGENTS_MANAGED_VERSION;
1228
+ return {
1229
+ path: AGENTS_FILE,
1230
+ content: swapped,
1231
+ reason: "update",
1232
+ note: newer ? AGENTS_NEWER_NOTE : KIND_DRIFT_NOTE
1233
+ };
1234
+ }
1213
1235
  return { path: AGENTS_FILE, content: swapped, reason: "update" };
1214
1236
  }
1215
1237
  function planClaudeMd(current) {
@@ -1228,6 +1250,7 @@ export {
1228
1250
  designGuideSection,
1229
1251
  meta as designMeta,
1230
1252
  designRulesBrief,
1253
+ extractManagedBlock,
1231
1254
  freeRegionScaffold,
1232
1255
  parseAgentsIdentity,
1233
1256
  planInstall,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bstage-sdk/ai-toolkit",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "bstage SDK ai-toolkit — 에이전트용 스킬·AGENTS.md 콘텐츠(cli가 소비)",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -34,7 +34,7 @@
34
34
  "@types/node": "^25.5.0",
35
35
  "tsup": "^8.0.0",
36
36
  "typescript": "^5.5.0",
37
- "@bstage-sdk/design": "0.6.0"
37
+ "@bstage-sdk/design": "0.6.2"
38
38
  },
39
39
  "license": "MIT",
40
40
  "scripts": {