@codexhost/cli-win32-arm64 0.6.0 → 0.6.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.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/desktop-controller.mjs +2 -1
- package/app/host-runtime.mjs +296 -147
- package/app/plugins/antigravity/plugin.mjs +6 -1
- package/app/plugins/claude-code/plugin.mjs +661 -219
- package/app/plugins/deepseek-harness/plugin.mjs +87 -18
- package/app/plugins/enabled.json +2 -1
- package/app/plugins/grok/plugin.mjs +11 -1
- package/app/plugins/kiro-cli/assets/icon.svg +5 -0
- package/app/plugins/kiro-cli/manifest.json +12 -0
- package/app/plugins/kiro-cli/plugin.mjs +23316 -0
- package/app/plugins/omp/plugin.mjs +11 -1
- package/app/plugins/opencode/plugin.mjs +297 -143
- package/app/plugins/pi/plugin.mjs +1489 -1300
- package/app/renderer-extension.js +152 -84
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
|
@@ -18252,6 +18252,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
18252
18252
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
18253
18253
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
18254
18254
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
18255
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
18256
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
18255
18257
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
18256
18258
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
18257
18259
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -19204,7 +19206,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
19204
19206
|
...tokenFields,
|
|
19205
19207
|
...safeIntegerFields,
|
|
19206
19208
|
...percentFields,
|
|
19207
|
-
"totalCostUsd"
|
|
19209
|
+
"totalCostUsd",
|
|
19210
|
+
"totalCredits",
|
|
19211
|
+
"contextUsagePercent"
|
|
19208
19212
|
]);
|
|
19209
19213
|
function isRecord(value) {
|
|
19210
19214
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -19220,6 +19224,12 @@ function parseHostUsage(value) {
|
|
|
19220
19224
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
19221
19225
|
}
|
|
19222
19226
|
}
|
|
19227
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
19228
|
+
const candidate = value[field];
|
|
19229
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
19230
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
19231
|
+
}
|
|
19232
|
+
}
|
|
19223
19233
|
for (const field of tokenFields) {
|
|
19224
19234
|
const candidate = value[field];
|
|
19225
19235
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -30792,6 +30802,7 @@ var LiveBuffer = class {
|
|
|
30792
30802
|
import { randomUUID as nodeRandomUUID } from "node:crypto";
|
|
30793
30803
|
import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
|
|
30794
30804
|
var DEEPSEEK_HARNESS_ID2 = harnessIdSchema.parse("deepseek-harness");
|
|
30805
|
+
var NATIVE_CLOSE_TIMEOUT_MS = 5e3;
|
|
30795
30806
|
var MODERN_PROMPT_CORRELATION_GRACE_MS = 5e3;
|
|
30796
30807
|
var MODERN_ACCEPTED_CORRELATION_TIMEOUT_MS = 3e5;
|
|
30797
30808
|
var MAX_TIMER_DELAY_MS2 = 2147483647;
|
|
@@ -30871,8 +30882,11 @@ var ModernHarnessSession = class {
|
|
|
30871
30882
|
#usage;
|
|
30872
30883
|
#historyBytes;
|
|
30873
30884
|
#closed = false;
|
|
30885
|
+
#closing = false;
|
|
30886
|
+
#nativeCloseTerminal;
|
|
30874
30887
|
#closedNotified = false;
|
|
30875
30888
|
#faulted;
|
|
30889
|
+
#faultMayHaveNativeWork = false;
|
|
30876
30890
|
#closePromise;
|
|
30877
30891
|
#pumpPromise;
|
|
30878
30892
|
constructor(options) {
|
|
@@ -30965,14 +30979,14 @@ var ModernHarnessSession = class {
|
|
|
30965
30979
|
this.#pumpPromise = this.#pump();
|
|
30966
30980
|
if (resumedAutonomousBuffer) {
|
|
30967
30981
|
queueMicrotask(() => {
|
|
30968
|
-
if (!this.#closed && this.#buffer === resumedAutonomousBuffer) {
|
|
30982
|
+
if (!this.#closed && !this.#closing && this.#buffer === resumedAutonomousBuffer) {
|
|
30969
30983
|
this.#activateBufferedAutonomous(true);
|
|
30970
30984
|
}
|
|
30971
30985
|
});
|
|
30972
30986
|
}
|
|
30973
30987
|
}
|
|
30974
30988
|
readSnapshot() {
|
|
30975
|
-
if (this.#closed)
|
|
30989
|
+
if (this.#closed || this.#closing)
|
|
30976
30990
|
return Promise.resolve({ ok: false, error: closedError() });
|
|
30977
30991
|
if (this.#reading)
|
|
30978
30992
|
return Promise.resolve({ ok: false, error: busyError("read history") });
|
|
@@ -30994,7 +31008,7 @@ var ModernHarnessSession = class {
|
|
|
30994
31008
|
}
|
|
30995
31009
|
}
|
|
30996
31010
|
execute(command) {
|
|
30997
|
-
if (this.#closed)
|
|
31011
|
+
if (this.#closed || this.#closing)
|
|
30998
31012
|
return Promise.resolve({ ok: false, error: closedError() });
|
|
30999
31013
|
switch (command.type) {
|
|
31000
31014
|
case "turn.start":
|
|
@@ -31012,6 +31026,13 @@ var ModernHarnessSession = class {
|
|
|
31012
31026
|
}
|
|
31013
31027
|
}
|
|
31014
31028
|
close() {
|
|
31029
|
+
const faultCleanup = this.#closePromise;
|
|
31030
|
+
if (this.#faultMayHaveNativeWork && !this.#closing && faultCleanup) {
|
|
31031
|
+
this.#closing = true;
|
|
31032
|
+
this.#closePromise = faultCleanup.then(() => {
|
|
31033
|
+
throw new Error("DeepSeek Harness native execution stop was not confirmed before the Session fault");
|
|
31034
|
+
});
|
|
31035
|
+
}
|
|
31015
31036
|
this.#closePromise ??= this.#performClose();
|
|
31016
31037
|
return this.#closePromise;
|
|
31017
31038
|
}
|
|
@@ -31026,7 +31047,7 @@ var ModernHarnessSession = class {
|
|
|
31026
31047
|
if (this.#queuedDeliveries.has(delivery.eventId) || this.#interactionByEventId.has(delivery.eventId)) {
|
|
31027
31048
|
throw new ModernEventGatewayError("protocolError", "DeepSeek Harness event delivery was duplicated");
|
|
31028
31049
|
}
|
|
31029
|
-
if (this.#closed) {
|
|
31050
|
+
if (this.#closed || this.#closing) {
|
|
31030
31051
|
this.#queuedDeliveries.set(delivery.eventId, delivery);
|
|
31031
31052
|
return;
|
|
31032
31053
|
}
|
|
@@ -31295,14 +31316,14 @@ ${question.detail}` : question.question;
|
|
|
31295
31316
|
this.#operationControllers.add(abort);
|
|
31296
31317
|
try {
|
|
31297
31318
|
const result = await operation(abort.signal);
|
|
31298
|
-
if (this.#closed)
|
|
31319
|
+
if (this.#closed || this.#closing)
|
|
31299
31320
|
return { ok: false, error: closedError() };
|
|
31300
31321
|
this.#publishConfiguration(true);
|
|
31301
31322
|
return { ok: true, value: result.value };
|
|
31302
31323
|
} catch (error51) {
|
|
31303
31324
|
if (this.#faulted)
|
|
31304
31325
|
return { ok: false, error: this.#faulted };
|
|
31305
|
-
if (this.#closed)
|
|
31326
|
+
if (this.#closed || this.#closing)
|
|
31306
31327
|
return { ok: false, error: closedError() };
|
|
31307
31328
|
const failure = configurationOrProtocolError(error51, "DeepSeek Harness configuration failed");
|
|
31308
31329
|
if (configurationFailureRequiresSessionFault(error51))
|
|
@@ -31410,7 +31431,7 @@ ${question.detail}` : question.question;
|
|
|
31410
31431
|
} catch (error51) {
|
|
31411
31432
|
if (this.#faulted)
|
|
31412
31433
|
return { ok: false, error: this.#faulted };
|
|
31413
|
-
if (this.#closed)
|
|
31434
|
+
if (this.#closed || this.#closing)
|
|
31414
31435
|
return { ok: false, error: closedError() };
|
|
31415
31436
|
if (pending.admissionObserved)
|
|
31416
31437
|
return this.#acceptPrompt(pending);
|
|
@@ -31418,7 +31439,7 @@ ${question.detail}` : question.question;
|
|
|
31418
31439
|
if (resolution.kind === "accepted") {
|
|
31419
31440
|
if (this.#faulted)
|
|
31420
31441
|
return { ok: false, error: this.#faulted };
|
|
31421
|
-
if (this.#closed)
|
|
31442
|
+
if (this.#closed || this.#closing)
|
|
31422
31443
|
return { ok: false, error: closedError() };
|
|
31423
31444
|
return this.#acceptPrompt(pending);
|
|
31424
31445
|
}
|
|
@@ -31486,12 +31507,12 @@ ${question.detail}` : question.question;
|
|
|
31486
31507
|
return true;
|
|
31487
31508
|
}
|
|
31488
31509
|
async #listHarnessCommands() {
|
|
31489
|
-
if (this.#closed)
|
|
31510
|
+
if (this.#closed || this.#closing)
|
|
31490
31511
|
return { ok: false, error: closedError() };
|
|
31491
31512
|
return { ok: true, value: deepSeekHarnessCommandCatalog() };
|
|
31492
31513
|
}
|
|
31493
31514
|
async #executeHarnessCommand(command) {
|
|
31494
|
-
if (this.#closed)
|
|
31515
|
+
if (this.#closed || this.#closing)
|
|
31495
31516
|
return { ok: false, error: closedError() };
|
|
31496
31517
|
const parsed = parseDeepSeekHarnessCommand(command);
|
|
31497
31518
|
if (!parsed.ok)
|
|
@@ -31511,7 +31532,7 @@ ${question.detail}` : question.question;
|
|
|
31511
31532
|
const catalog = await this.#listHarnessCommands();
|
|
31512
31533
|
if (!catalog.ok)
|
|
31513
31534
|
return catalog;
|
|
31514
|
-
if (this.#closed)
|
|
31535
|
+
if (this.#closed || this.#closing)
|
|
31515
31536
|
return { ok: false, error: closedError() };
|
|
31516
31537
|
if (admission.cancellationRequested) {
|
|
31517
31538
|
return { ok: false, error: invalidState3("DeepSeek Harness command was cancelled") };
|
|
@@ -31873,13 +31894,13 @@ ${question.detail}` : question.question;
|
|
|
31873
31894
|
}
|
|
31874
31895
|
#scheduleBoundTurn(pending) {
|
|
31875
31896
|
const buffer = pending.buffer;
|
|
31876
|
-
if (!buffer || !pending.admitted || pending.publishScheduled || buffer.active || this.#closed) {
|
|
31897
|
+
if (!buffer || !pending.admitted || pending.publishScheduled || buffer.active || this.#closed || this.#closing) {
|
|
31877
31898
|
return;
|
|
31878
31899
|
}
|
|
31879
31900
|
pending.publishScheduled = true;
|
|
31880
31901
|
queueMicrotask(() => queueMicrotask(() => {
|
|
31881
31902
|
pending.publishScheduled = false;
|
|
31882
|
-
if (!this.#closed && pending.admitted && pending.buffer === buffer && this.#buffer === buffer && !buffer.active) {
|
|
31903
|
+
if (!this.#closed && !this.#closing && pending.admitted && pending.buffer === buffer && this.#buffer === buffer && !buffer.active) {
|
|
31883
31904
|
this.#materialize(buffer, pending.command.turnId, pending.command.input, false, false);
|
|
31884
31905
|
}
|
|
31885
31906
|
}));
|
|
@@ -31895,7 +31916,7 @@ ${question.detail}` : question.question;
|
|
|
31895
31916
|
delete pending.buffer;
|
|
31896
31917
|
if (buffer.reachedCorrelationBoundary || buffer.events.at(-1)?.type === "turn/end") {
|
|
31897
31918
|
queueMicrotask(() => {
|
|
31898
|
-
if (!this.#closed && this.#buffer === buffer && !buffer.active && !buffer.pending) {
|
|
31919
|
+
if (!this.#closed && !this.#closing && this.#buffer === buffer && !buffer.active && !buffer.pending) {
|
|
31899
31920
|
this.#materializeAutonomous(buffer, false);
|
|
31900
31921
|
}
|
|
31901
31922
|
});
|
|
@@ -31910,12 +31931,14 @@ ${question.detail}` : question.question;
|
|
|
31910
31931
|
}
|
|
31911
31932
|
#activateBufferedAutonomous(initialReplay = false) {
|
|
31912
31933
|
const buffer = this.#buffer;
|
|
31913
|
-
if (this.#closed || !buffer || buffer.active || buffer.pending || this.#deferAutonomousTurn() || !this.#resumeNeedsAutonomousTurn(buffer) && !buffer.reachedCorrelationBoundary && buffer.events.at(-1)?.type !== "turn/end") {
|
|
31934
|
+
if (this.#closed || this.#closing || !buffer || buffer.active || buffer.pending || this.#deferAutonomousTurn() || !this.#resumeNeedsAutonomousTurn(buffer) && !buffer.reachedCorrelationBoundary && buffer.events.at(-1)?.type !== "turn/end") {
|
|
31914
31935
|
return;
|
|
31915
31936
|
}
|
|
31916
31937
|
this.#materializeAutonomous(buffer, initialReplay || buffer.initialResume);
|
|
31917
31938
|
}
|
|
31918
31939
|
#materializeAutonomous(buffer, initialReplay) {
|
|
31940
|
+
if (this.#closed || this.#closing)
|
|
31941
|
+
return;
|
|
31919
31942
|
const turnId = hostTurnIdSchema.parse(this.#randomUUID());
|
|
31920
31943
|
this.#emit({
|
|
31921
31944
|
type: "turn.autonomous.started",
|
|
@@ -32145,6 +32168,7 @@ ${question.detail}` : question.question;
|
|
|
32145
32168
|
active.terminal = true;
|
|
32146
32169
|
if (buffer.pending)
|
|
32147
32170
|
buffer.pending.terminal = true;
|
|
32171
|
+
this.#nativeCloseTerminal?.();
|
|
32148
32172
|
const checkpoint = modernCheckpointRef(this.harnessId, this.#sessionId, seq);
|
|
32149
32173
|
this.#emit({
|
|
32150
32174
|
type: "turn.completed",
|
|
@@ -32206,6 +32230,7 @@ ${question.detail}` : question.question;
|
|
|
32206
32230
|
return;
|
|
32207
32231
|
const failure = sanitizedHarnessError(error51);
|
|
32208
32232
|
const acceptedPending = this.#acceptedPending();
|
|
32233
|
+
this.#faultMayHaveNativeWork = Boolean(this.#active && !this.#active.terminal || this.#pendingByRequestId.size > 0 || this.#buffer || this.#commandAdmission || this.#activeCommand);
|
|
32209
32234
|
this.#faulted = failure;
|
|
32210
32235
|
this.#closed = true;
|
|
32211
32236
|
this.#journalLifetime.abort(new Error("DeepSeek Harness Session faulted"));
|
|
@@ -32279,6 +32304,49 @@ ${question.detail}` : question.question;
|
|
|
32279
32304
|
this.#notifyClosed();
|
|
32280
32305
|
}
|
|
32281
32306
|
async #performClose() {
|
|
32307
|
+
this.#closing = true;
|
|
32308
|
+
let stopFailure;
|
|
32309
|
+
const activeAtClose = this.#active;
|
|
32310
|
+
const pendingAtClose = new Set(this.#pendingByRequestId.values());
|
|
32311
|
+
if (this.#buffer?.pending)
|
|
32312
|
+
pendingAtClose.add(this.#buffer.pending);
|
|
32313
|
+
const correlatedPending = activeAtClose && this.#buffer?.active === activeAtClose ? this.#buffer.pending : void 0;
|
|
32314
|
+
const uncorrelatedExecution = [...pendingAtClose].some((pending) => !pending.terminal && pending !== correlatedPending) || !activeAtClose && this.#buffer !== void 0 || this.#commandAdmission !== void 0 || this.#activeCommand !== void 0;
|
|
32315
|
+
if (!this.#closed && (activeAtClose && !activeAtClose.terminal || uncorrelatedExecution)) {
|
|
32316
|
+
let timer;
|
|
32317
|
+
const terminal = new Promise((resolve2) => {
|
|
32318
|
+
this.#nativeCloseTerminal = () => {
|
|
32319
|
+
if (activeAtClose?.terminal)
|
|
32320
|
+
resolve2();
|
|
32321
|
+
};
|
|
32322
|
+
});
|
|
32323
|
+
try {
|
|
32324
|
+
await Promise.race([
|
|
32325
|
+
(async () => {
|
|
32326
|
+
const result = await (activeAtClose?.cancelPromise ?? this.#requestNativeCancel(activeAtClose));
|
|
32327
|
+
if (!result.ok)
|
|
32328
|
+
throw new Error(result.error.message);
|
|
32329
|
+
if (uncorrelatedExecution) {
|
|
32330
|
+
throw new Error("DeepSeek Harness cannot confirm stop before the native Turn is correlated");
|
|
32331
|
+
}
|
|
32332
|
+
await terminal;
|
|
32333
|
+
})(),
|
|
32334
|
+
new Promise((_, reject) => {
|
|
32335
|
+
timer = setTimeout(() => reject(new Error("DeepSeek Harness did not confirm native Turn stop before close")), NATIVE_CLOSE_TIMEOUT_MS);
|
|
32336
|
+
})
|
|
32337
|
+
]);
|
|
32338
|
+
} catch (error51) {
|
|
32339
|
+
stopFailure = error51;
|
|
32340
|
+
} finally {
|
|
32341
|
+
if (timer)
|
|
32342
|
+
clearTimeout(timer);
|
|
32343
|
+
this.#nativeCloseTerminal = void 0;
|
|
32344
|
+
}
|
|
32345
|
+
}
|
|
32346
|
+
if (this.#faulted) {
|
|
32347
|
+
await this.#performFault(this.#faulted, this.#acceptedPending(pendingAtClose));
|
|
32348
|
+
throw stopFailure ?? new Error(this.#faulted.message);
|
|
32349
|
+
}
|
|
32282
32350
|
if (!this.#closed) {
|
|
32283
32351
|
const acceptedPending = this.#acceptedPending();
|
|
32284
32352
|
this.#closed = true;
|
|
@@ -32333,6 +32401,8 @@ ${question.detail}` : question.question;
|
|
|
32333
32401
|
}
|
|
32334
32402
|
await Promise.allSettled([this.#journal.close(), this.#pumpPromise]);
|
|
32335
32403
|
this.#notifyClosed();
|
|
32404
|
+
if (stopFailure)
|
|
32405
|
+
throw stopFailure;
|
|
32336
32406
|
}
|
|
32337
32407
|
#abortOperations() {
|
|
32338
32408
|
for (const controller of this.#operationControllers) {
|
|
@@ -32345,8 +32415,7 @@ ${question.detail}` : question.question;
|
|
|
32345
32415
|
for (const unsubscribe of this.#removeControlSubscriptions.splice(0))
|
|
32346
32416
|
unsubscribe();
|
|
32347
32417
|
}
|
|
32348
|
-
#acceptedPending() {
|
|
32349
|
-
const values = new Set(this.#pendingByRequestId.values());
|
|
32418
|
+
#acceptedPending(values = new Set(this.#pendingByRequestId.values())) {
|
|
32350
32419
|
if (this.#buffer?.pending)
|
|
32351
32420
|
values.add(this.#buffer.pending);
|
|
32352
32421
|
return [...values].filter((pending) => (pending.admitted || pending.admissionObserved || pending.observed) && !pending.terminal);
|
package/app/plugins/enabled.json
CHANGED
|
@@ -14549,6 +14549,8 @@ var threadUsageSnapshotSchema = external_exports.object({
|
|
|
14549
14549
|
reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14550
14550
|
totalTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14551
14551
|
totalCostUsd: finiteNonNegativeNumberSchema.optional(),
|
|
14552
|
+
totalCredits: finiteNonNegativeNumberSchema.optional(),
|
|
14553
|
+
contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
|
|
14552
14554
|
cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
|
|
14553
14555
|
contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
14554
14556
|
contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -15444,7 +15446,9 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
15444
15446
|
...tokenFields,
|
|
15445
15447
|
...safeIntegerFields,
|
|
15446
15448
|
...percentFields,
|
|
15447
|
-
"totalCostUsd"
|
|
15449
|
+
"totalCostUsd",
|
|
15450
|
+
"totalCredits",
|
|
15451
|
+
"contextUsagePercent"
|
|
15448
15452
|
]);
|
|
15449
15453
|
function isRecord(value) {
|
|
15450
15454
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -15460,6 +15464,12 @@ function parseHostUsage(value) {
|
|
|
15460
15464
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
15461
15465
|
}
|
|
15462
15466
|
}
|
|
15467
|
+
for (const field of ["totalCredits", "contextUsagePercent"]) {
|
|
15468
|
+
const candidate = value[field];
|
|
15469
|
+
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
|
|
15470
|
+
throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
|
|
15471
|
+
}
|
|
15472
|
+
}
|
|
15463
15473
|
for (const field of tokenFields) {
|
|
15464
15474
|
const candidate = value[field];
|
|
15465
15475
|
if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none">
|
|
2
|
+
<path d="M4 3.5C4 2.67157 4.67157 2 5.5 2H8.5C9.32843 2 10 2.67157 10 3.5V20.5C10 21.3284 9.32843 22 8.5 22H5.5C4.67157 22 4 21.3284 4 20.5V3.5Z" fill="#7C3AED"/>
|
|
3
|
+
<path d="M10 11.5L16.2 3.8C16.8 3.1 17.8 3 18.5 3.6C19.2 4.2 19.3 5.2 18.7 5.9L13.8 12L19.2 18.2C19.8 18.9 19.7 19.9 19 20.5C18.3 21.1 17.3 21 16.7 20.3L10 12.5V11.5Z" fill="#A78BFA"/>
|
|
4
|
+
<circle cx="17.5" cy="12" r="2" fill="#C4B5FD"/>
|
|
5
|
+
</svg>
|