ai-ops-cli 1.5.0 → 1.5.1
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.
|
@@ -32,6 +32,14 @@ update_when:
|
|
|
32
32
|
- project-owned 문서가 비어 있거나 stale하면 실제 코드, 설정, schema, runtime 파일을 우선한다.
|
|
33
33
|
- 문서 상태가 애매하면 `docs/docs-status.md`와 각 문서 frontmatter를 함께 확인한다.
|
|
34
34
|
|
|
35
|
+
## Reference-Backed Implementation
|
|
36
|
+
|
|
37
|
+
reference 문서에 근거해 구현할 때는 문서의 핵심 제약을 먼저 검증 가능한 acceptance condition으로 바꾼다.
|
|
38
|
+
|
|
39
|
+
- `must`, `required`, `top-level`, `cannot mix`, `does not compose` 같은 강제 제약은 그냥 읽고 넘어가지 않는다.
|
|
40
|
+
- config, schema, parser, runtime이 직접 해석하는 구조와 permission, sandbox, credential, network, filesystem boundary는 테스트, fixture, smoke command, audit check 중 하나로 고정한다.
|
|
41
|
+
- 문서의 중요한 문장을 테스트 이름으로 바꾼다.
|
|
42
|
+
|
|
35
43
|
## 보존 원칙
|
|
36
44
|
|
|
37
45
|
- 사용자 변경으로 보이는 diff는 되돌리지 않는다.
|
package/dist/bin/index.js
CHANGED
|
@@ -1246,6 +1246,25 @@ var replaceOrAppendBlock = (content, start, end, block) => {
|
|
|
1246
1246
|
const separator = content.trim().length > 0 && !content.endsWith("\n") ? "\n\n" : content.length > 0 ? "\n" : "";
|
|
1247
1247
|
return `${content}${separator}${cleanBlock}`;
|
|
1248
1248
|
};
|
|
1249
|
+
var insertBlockBeforeFirstTable = (content, block) => {
|
|
1250
|
+
const cleanBlock = block.endsWith("\n") ? block : `${block}
|
|
1251
|
+
`;
|
|
1252
|
+
if (content.trim().length === 0) {
|
|
1253
|
+
return cleanBlock;
|
|
1254
|
+
}
|
|
1255
|
+
const lines = content.split("\n");
|
|
1256
|
+
const firstTableIndex = lines.findIndex(
|
|
1257
|
+
(line) => !line.trimStart().startsWith("#") && /^\s*\[[^\]]+\]\s*(?:#.*)?$/.test(line)
|
|
1258
|
+
);
|
|
1259
|
+
if (firstTableIndex < 0) {
|
|
1260
|
+
const separator = content.endsWith("\n") ? "\n" : "\n\n";
|
|
1261
|
+
return `${content}${separator}${cleanBlock}`;
|
|
1262
|
+
}
|
|
1263
|
+
const before = lines.slice(0, firstTableIndex).join("\n").trimEnd();
|
|
1264
|
+
const after = lines.slice(firstTableIndex).join("\n").trimStart();
|
|
1265
|
+
return `${[before, cleanBlock.trimEnd(), after].filter((section) => section.length > 0).join("\n\n")}
|
|
1266
|
+
`;
|
|
1267
|
+
};
|
|
1249
1268
|
var quoteTomlString = (value) => JSON.stringify(value);
|
|
1250
1269
|
var readActiveStringAssignment = (content, key) => {
|
|
1251
1270
|
for (const line of content.split("\n")) {
|
|
@@ -1259,6 +1278,22 @@ var readActiveStringAssignment = (content, key) => {
|
|
|
1259
1278
|
}
|
|
1260
1279
|
return null;
|
|
1261
1280
|
};
|
|
1281
|
+
var readTopLevelStringAssignment = (content, key) => {
|
|
1282
|
+
for (const line of content.split("\n")) {
|
|
1283
|
+
const trimmed = line.trim();
|
|
1284
|
+
if (trimmed.length === 0 || trimmed.startsWith("#")) {
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1287
|
+
if (/^\[[^\]]+\]\s*(?:#.*)?$/.test(trimmed)) {
|
|
1288
|
+
return null;
|
|
1289
|
+
}
|
|
1290
|
+
const match = new RegExp(`^\\s*${key}\\s*=\\s*["']([^"']+)["']`).exec(line);
|
|
1291
|
+
if (match) {
|
|
1292
|
+
return match[1];
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
return null;
|
|
1296
|
+
};
|
|
1262
1297
|
var hasActiveTable = (content, tableName) => {
|
|
1263
1298
|
const tablePattern = new RegExp(`^\\s*\\[${escapeRegExp(tableName)}\\]\\s*(?:#.*)?$`);
|
|
1264
1299
|
return content.split("\n").some((line) => !line.trimStart().startsWith("#") && tablePattern.test(line));
|
|
@@ -1450,7 +1485,7 @@ var cleanupLegacySandboxConfig = (content) => removeLegacyManagedSandboxWorkspac
|
|
|
1450
1485
|
var editConfigForInstall = (content, paths) => {
|
|
1451
1486
|
const withoutCurrentProfileBlock = stripBlock(content, PROFILE_BLOCK_START, PROFILE_BLOCK_END);
|
|
1452
1487
|
const withoutLegacy = cleanupLegacySandboxConfig(withoutCurrentProfileBlock);
|
|
1453
|
-
const activeDefaultPermissions =
|
|
1488
|
+
const activeDefaultPermissions = readTopLevelStringAssignment(withoutLegacy, "default_permissions");
|
|
1454
1489
|
if (readActiveStringAssignment(withoutLegacy, "sandbox_mode") || hasActiveTable(withoutLegacy, "sandbox_workspace_write")) {
|
|
1455
1490
|
return {
|
|
1456
1491
|
content,
|
|
@@ -1475,12 +1510,9 @@ var editConfigForInstall = (content, paths) => {
|
|
|
1475
1510
|
conflict: CONFIG_CONFLICT_EXISTING_PROFILE
|
|
1476
1511
|
};
|
|
1477
1512
|
}
|
|
1478
|
-
const
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
PROFILE_BLOCK_END,
|
|
1482
|
-
buildPermissionProfileBlock(paths, activeDefaultPermissions !== SAFE_LOCAL_CODEX_PERMISSION_NAME)
|
|
1483
|
-
);
|
|
1513
|
+
const shouldWriteDefaultPermissions = activeDefaultPermissions !== SAFE_LOCAL_CODEX_PERMISSION_NAME;
|
|
1514
|
+
const profileBlock = buildPermissionProfileBlock(paths, shouldWriteDefaultPermissions);
|
|
1515
|
+
const nextContent = shouldWriteDefaultPermissions ? insertBlockBeforeFirstTable(withoutLegacy, profileBlock) : replaceOrAppendBlock(withoutLegacy, PROFILE_BLOCK_START, PROFILE_BLOCK_END, profileBlock);
|
|
1484
1516
|
return {
|
|
1485
1517
|
content: nextContent,
|
|
1486
1518
|
installed: true,
|