Merge pull request #12251 from Kilo-Org/chore/jetbrains-cli-pin-v7.4.9

chore(jetbrains): bump CLI pin to v7.4.9
This commit is contained in:
Kirill Kalishev
2026-07-16 11:37:33 -04:00
committed by GitHub
5 changed files with 114 additions and 47 deletions
+1 -1
View File
@@ -294,7 +294,7 @@
},
"packages/kilo-jetbrains": {
"name": "@kilocode/kilo-jetbrains",
"version": "7.4.5",
"version": "7.4.9",
},
"packages/kilo-memory": {
"name": "@kilocode/kilo-memory",
@@ -264,58 +264,86 @@ class KiloBackendSessionManager(
// ------ mapping (generated API model → DTO) ------
private fun dto(s: ai.kilocode.jetbrains.api.model.Session) = SessionDto(
private fun dto(s: ai.kilocode.jetbrains.api.model.Session) = dto(
id = s.id,
projectID = s.projectID,
directory = s.directory,
parentID = s.parentID,
project = s.projectID,
dir = s.directory,
parent = s.parentID,
title = s.title,
version = s.version,
time = SessionTimeDto(
created = time(s.id, "created", s.time.created),
updated = time(s.id, "updated", s.time.updated),
archived = s.time.archived,
),
summary = s.summary?.let {
SessionSummaryDto(
additions = it.additions.safeInt(),
deletions = it.deletions.safeInt(),
files = it.files.safeInt(),
)
},
created = s.time.created,
updated = s.time.updated,
archived = s.time.archived,
summary = s.summary?.let { summary(it.additions, it.deletions, it.files) },
revert = revertDto(s.revert),
)
private fun dto(s: GlobalSession) = SessionDto(
private fun dto(s: ai.kilocode.jetbrains.api.model.Session1) = dto(
id = s.id,
projectID = s.projectID,
directory = s.directory,
parentID = s.parentID,
project = s.projectID,
dir = s.directory,
parent = s.parentID,
title = s.title,
version = s.version,
time = SessionTimeDto(
created = time(s.id, "created", s.time.created),
updated = time(s.id, "updated", s.time.updated),
archived = s.time.archived,
),
summary = s.summary?.let {
SessionSummaryDto(
additions = it.additions?.safeInt() ?: 0,
deletions = it.deletions?.safeInt() ?: 0,
files = it.files?.safeInt() ?: 0,
)
},
created = s.time.created,
updated = s.time.updated,
archived = s.time.archived,
summary = s.summary?.let { summary(it.additions, it.deletions, it.files) },
revert = revertDto(s.revert),
)
private fun dto(s: GlobalSession) = dto(
id = s.id,
project = s.projectID,
dir = s.directory,
parent = s.parentID,
title = s.title,
version = s.version,
created = s.time.created,
updated = s.time.updated,
archived = s.time.archived,
summary = s.summary?.let { summary(it.additions, it.deletions, it.files) },
revert = revertDto(s.revert),
)
private fun dto(
id: String,
project: String,
dir: String,
parent: String?,
title: String,
version: String,
created: Number?,
updated: Number?,
archived: Double?,
summary: SessionSummaryDto?,
revert: SessionRevertDto?,
) = SessionDto(
id = id,
projectID = project,
directory = dir,
parentID = parent,
title = title,
version = version,
time = SessionTimeDto(
created = time(id, "created", created),
updated = time(id, "updated", updated),
archived = archived,
),
summary = summary,
revert = revert,
)
private fun summary(add: Double?, del: Double?, files: Double?) = SessionSummaryDto(
additions = count(add),
deletions = count(del),
files = count(files),
)
private fun revertDto(s: ai.kilocode.jetbrains.api.model.SessionRevert?) = s?.let {
revertDto(it.messageID, it.partID, it.snapshot, it.diff)
}
private fun revertDto(s: ai.kilocode.jetbrains.api.model.GlobalSessionRevert?) = s?.let {
revertDto(it.messageID, it.partID, it.snapshot, it.diff)
}
private fun revertDto(message: String, part: String?, snapshot: String?, diff: String?) =
SessionRevertDto(
messageID = message,
@@ -334,6 +362,8 @@ class KiloBackendSessionManager(
private fun encode(value: String) = java.net.URLEncoder.encode(value, Charsets.UTF_8)
private fun count(value: Double?) = value?.safeInt() ?: 0
private fun time(id: String, field: String, value: Number?): Double {
if (value != null) return value.toDouble()
log.warn("Session $id missing $field timestamp; defaulting to 0.0")
@@ -124,16 +124,19 @@ internal object OpenApiSpecNormalizer {
as? JsonObject ?: return root
val props = schema["properties"] as? JsonObject ?: return root
val nullable = setOf("balance", "kiloPass", "currentOrgId")
val keys = setOf("balance", "kiloPass", "currentOrgId")
val fixed = JsonObject(props.mapValues { (key, value) ->
if (key !in nullable) return@mapValues value
val obj = value as? JsonObject ?: return@mapValues value
// Skip if already wrapped (has anyOf containing {type:null}).
val existing = obj["anyOf"] as? JsonArray
if (existing != null && existing.any {
(it as? JsonObject)?.get("type")?.let { t -> (t as? JsonPrimitive)?.content } == "null"
}) return@mapValues value
JsonObject(mapOf("anyOf" to JsonArray(listOf(obj, JsonObject(mapOf("type" to JsonPrimitive("null")))))))
if (key !in keys) return@mapValues value
val wrapped = nullable(value)
when (key) {
"balance" -> nullableProps(wrapped, setOf("balance"))
"kiloPass" -> nullableProps(wrapped, setOf(
"currentPeriodBaseCreditsUsd",
"currentPeriodUsageUsd",
"currentPeriodBonusCreditsUsd",
))
else -> wrapped
}
})
// Rebuild nested objects up to root.
@@ -152,6 +155,29 @@ internal object OpenApiSpecNormalizer {
return JsonObject(root + mapOf("paths" to newPaths))
}
private fun nullable(value: JsonElement): JsonElement {
val obj = value as? JsonObject ?: return value
val any = obj["anyOf"] as? JsonArray
if (any != null && any.any(::nullSchema)) return obj
return JsonObject(mapOf("anyOf" to JsonArray(listOf(obj, JsonObject(mapOf("type" to JsonPrimitive("null")))))))
}
private fun nullableProps(value: JsonElement, names: Set<String>): JsonElement {
val obj = value as? JsonObject ?: return value
val any = obj["anyOf"] as? JsonArray
if (any != null) {
return JsonObject(obj + mapOf("anyOf" to JsonArray(any.map { nullableProps(it, names) })))
}
val props = obj["properties"] as? JsonObject ?: return obj
val fixed = JsonObject(props.mapValues { (key, prop) ->
if (key in names) nullable(prop) else prop
})
return JsonObject(obj + mapOf("properties" to fixed))
}
private fun nullSchema(value: JsonElement) =
(value as? JsonObject)?.get("type")?.let { (it as? JsonPrimitive)?.content } == "null"
/**
* Deduplicate the root-level "tags" array by name — the spec validator
* rejects repeated tag names even when they describe different things.
@@ -148,6 +148,12 @@ class OpenApiSpecNormalizerTest {
val balanceTypes = balanceAnyOf.map { (it as? JsonObject)?.get("type").let { t -> (t as? JsonPrimitive)?.content } }
assert("null" in balanceTypes) { "balance anyOf should include null but got $balanceTypes" }
assert(balanceAnyOf.any { it is JsonObject && "properties" in it }) { "balance anyOf should include the object schema" }
val balanceObject = balanceAnyOf.filterIsInstance<JsonObject>().first { "properties" in it }
val balanceValue = obj(obj(balanceObject["properties"])["balance"])
val balanceValueTypes = arr(balanceValue["anyOf"]).map {
(it as? JsonObject)?.get("type").let { t -> (t as? JsonPrimitive)?.content }
}
assert("null" in balanceValueTypes) { "inner balance value should include null but got $balanceValueTypes" }
// kiloPass must be anyOf [object, null]
val pass = obj(props["kiloPass"])
@@ -156,6 +162,11 @@ class OpenApiSpecNormalizerTest {
val passTypes = passAnyOf.map { (it as? JsonObject)?.get("type").let { t -> (t as? JsonPrimitive)?.content } }
assert("null" in passTypes) { "kiloPass anyOf should include null but got $passTypes" }
assert(passAnyOf.any { it is JsonObject && "properties" in it }) { "kiloPass anyOf should include the object schema" }
val passObject = passAnyOf.filterIsInstance<JsonObject>().first { "properties" in it }
val passProps = obj(passObject["properties"])
val base = obj(passProps["currentPeriodBaseCreditsUsd"])
val baseTypes = arr(base["anyOf"]).map { (it as? JsonObject)?.get("type").let { t -> (t as? JsonPrimitive)?.content } }
assert("null" in baseTypes) { "inner kiloPass value should include null but got $baseTypes" }
// currentOrgId must be anyOf [string, null]
val orgId = obj(props["currentOrgId"])
+1 -1
View File
@@ -8,7 +8,7 @@
"test": "./gradlew test",
"test:ci": "bun script/test-ci.ts"
},
"version": "7.4.5",
"version": "7.4.9",
"dependencies": {},
"devDependencies": {},
"peerDependencies": {}