hivenet 0.4.2 → 0.6.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/README.md +55 -0
- package/dist/chunk-AK23JXBN.js +32 -0
- package/dist/{chunk-WWPF6V2Y.js → chunk-DNR6HNJD.js} +484 -70
- package/dist/cli.js +323 -66
- package/dist/{doctor-CVWF7J3P.js → doctor-EA2GJRUS.js} +1 -1
- package/dist/index.cjs +868 -460
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +384 -31
- package/dist/index.d.ts +384 -31
- package/dist/index.js +863 -457
- package/dist/index.js.map +1 -1
- package/dist/owner-ZWROA7AU.js +539 -0
- package/package.json +1 -1
- package/dist/owner-N2MSYLV7.js +0 -257
package/dist/index.js
CHANGED
|
@@ -496,379 +496,9 @@ init_esm_shims();
|
|
|
496
496
|
|
|
497
497
|
// ../core/dist/index.js
|
|
498
498
|
init_esm_shims();
|
|
499
|
-
import {
|
|
500
|
-
import
|
|
501
|
-
|
|
502
|
-
// ../../node_modules/.pnpm/agent-cli-detector@0.1.5/node_modules/agent-cli-detector/dist/index.js
|
|
503
|
-
init_esm_shims();
|
|
504
|
-
import { execFileSync } from "child_process";
|
|
505
|
-
import path2 from "path";
|
|
506
|
-
var defaultAgents = [
|
|
507
|
-
{
|
|
508
|
-
id: "codex",
|
|
509
|
-
name: "Codex",
|
|
510
|
-
env: [
|
|
511
|
-
{ name: "CODEX_CI", value: "1" },
|
|
512
|
-
{ name: "CODEX_SHELL", value: "1" },
|
|
513
|
-
{ name: "CODEX_THREAD_ID" }
|
|
514
|
-
],
|
|
515
|
-
process: [{ pattern: /^codex$/i }],
|
|
516
|
-
sessionEnv: ["CODEX_THREAD_ID"]
|
|
517
|
-
},
|
|
518
|
-
{
|
|
519
|
-
id: "cursor",
|
|
520
|
-
name: "Cursor",
|
|
521
|
-
env: [
|
|
522
|
-
{ name: "CURSOR_AGENT", value: "1" },
|
|
523
|
-
{ name: "CURSOR_CONVERSATION_ID" }
|
|
524
|
-
],
|
|
525
|
-
process: [{ pattern: /^cursor$/i }],
|
|
526
|
-
sessionEnv: ["CURSOR_CONVERSATION_ID"]
|
|
527
|
-
},
|
|
528
|
-
{
|
|
529
|
-
id: "claude-code",
|
|
530
|
-
name: "Claude Code",
|
|
531
|
-
env: [
|
|
532
|
-
{ name: "CLAUDECODE", value: "1" },
|
|
533
|
-
{ name: "CLAUDE_CODE_SESSION_ID" }
|
|
534
|
-
],
|
|
535
|
-
process: [{ pattern: /^claude$/i }],
|
|
536
|
-
sessionEnv: ["CLAUDE_CODE_SESSION_ID"]
|
|
537
|
-
},
|
|
538
|
-
{
|
|
539
|
-
id: "opencode",
|
|
540
|
-
name: "OpenCode",
|
|
541
|
-
env: [
|
|
542
|
-
{ name: "OPENCODE", value: "1" },
|
|
543
|
-
{ name: "OPENCODE_PID" }
|
|
544
|
-
],
|
|
545
|
-
process: [{ pattern: /^opencode$/i }]
|
|
546
|
-
},
|
|
547
|
-
{
|
|
548
|
-
id: "devin",
|
|
549
|
-
name: "Devin",
|
|
550
|
-
process: [{ pattern: /devin/i }]
|
|
551
|
-
},
|
|
552
|
-
{
|
|
553
|
-
id: "gemini",
|
|
554
|
-
name: "Gemini CLI",
|
|
555
|
-
env: [{ name: "GEMINI_CLI", value: "1" }],
|
|
556
|
-
process: [{ pattern: /^gemini$/i }]
|
|
557
|
-
},
|
|
558
|
-
{
|
|
559
|
-
id: "antigravity",
|
|
560
|
-
name: "Antigravity",
|
|
561
|
-
env: [
|
|
562
|
-
{ name: "ANTIGRAVITY_AGENT", value: "1" },
|
|
563
|
-
{ name: "ANTIGRAVITY_TRAJECTORY_ID" }
|
|
564
|
-
],
|
|
565
|
-
process: [{ pattern: /^antigravity$/i }],
|
|
566
|
-
sessionEnv: ["ANTIGRAVITY_TRAJECTORY_ID"]
|
|
567
|
-
},
|
|
568
|
-
{
|
|
569
|
-
id: "bolt",
|
|
570
|
-
name: "Bolt",
|
|
571
|
-
env: [
|
|
572
|
-
{ name: "BOLT_ENV" },
|
|
573
|
-
{ name: "BOLT_ORIGIN" },
|
|
574
|
-
{ name: "BOLT_SERVER_URL" }
|
|
575
|
-
]
|
|
576
|
-
},
|
|
577
|
-
{
|
|
578
|
-
id: "pi",
|
|
579
|
-
name: "Pi",
|
|
580
|
-
env: [{ name: "PI_CODING_AGENT", value: "true" }]
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
id: "replit",
|
|
584
|
-
name: "Replit",
|
|
585
|
-
env: [{ name: "REPLIT_SESSION" }],
|
|
586
|
-
sessionEnv: ["REPLIT_SESSION"]
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
id: "rork",
|
|
590
|
-
name: "Rork",
|
|
591
|
-
env: [{ name: "RORK_API_URL" }]
|
|
592
|
-
},
|
|
593
|
-
{
|
|
594
|
-
id: "kiro",
|
|
595
|
-
name: "Kiro",
|
|
596
|
-
env: [{ name: "KIRO_SESSION_ID" }],
|
|
597
|
-
process: [{ pattern: /kiro/i }],
|
|
598
|
-
sessionEnv: ["KIRO_SESSION_ID"]
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
id: "cline",
|
|
602
|
-
name: "Cline",
|
|
603
|
-
env: [{ name: "CLINE_WRAPPER_PATH" }],
|
|
604
|
-
process: [{ pattern: /^cline$/i }]
|
|
605
|
-
},
|
|
606
|
-
{
|
|
607
|
-
id: "kilocode",
|
|
608
|
-
name: "Kilo Code",
|
|
609
|
-
env: [
|
|
610
|
-
{ name: "KILO", value: "1" },
|
|
611
|
-
{ name: "KILOCODE_VERSION" },
|
|
612
|
-
{ name: "KILO_RUN_ID" }
|
|
613
|
-
],
|
|
614
|
-
process: [{ pattern: /^(kilo|kilocode)$/i }],
|
|
615
|
-
sessionEnv: ["KILO_RUN_ID"]
|
|
616
|
-
},
|
|
617
|
-
{
|
|
618
|
-
id: "copilot",
|
|
619
|
-
name: "GitHub Copilot CLI",
|
|
620
|
-
env: [
|
|
621
|
-
{ name: "COPILOT_CLI", value: "1" },
|
|
622
|
-
{ name: "COPILOT_AGENT_SESSION_ID" },
|
|
623
|
-
{ name: "COPILOT_RUN_APP", value: "1" }
|
|
624
|
-
],
|
|
625
|
-
process: [{ pattern: /^(github-copilot-cli|copilot)$/i }],
|
|
626
|
-
sessionEnv: ["COPILOT_AGENT_SESSION_ID"]
|
|
627
|
-
}
|
|
628
|
-
];
|
|
629
|
-
var EnvironmentDetectionStrategy = class {
|
|
630
|
-
name = "environment";
|
|
631
|
-
detect(context) {
|
|
632
|
-
const matches = [];
|
|
633
|
-
for (const agent of context.agents) {
|
|
634
|
-
for (const signal of agent.env ?? []) {
|
|
635
|
-
const value = context.env[signal.name];
|
|
636
|
-
if (value === void 0 || !matchesEnvValue(value, signal.value)) {
|
|
637
|
-
continue;
|
|
638
|
-
}
|
|
639
|
-
matches.push(toEvidence(agent, signal, value));
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
return matches;
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
function matchesEnvValue(value, matcher) {
|
|
646
|
-
if (matcher === void 0) {
|
|
647
|
-
return true;
|
|
648
|
-
}
|
|
649
|
-
if (typeof matcher === "string") {
|
|
650
|
-
return value === matcher;
|
|
651
|
-
}
|
|
652
|
-
if (matcher instanceof RegExp) {
|
|
653
|
-
return matcher.test(value);
|
|
654
|
-
}
|
|
655
|
-
return matcher(value);
|
|
656
|
-
}
|
|
657
|
-
function toEvidence(agent, signal, value) {
|
|
658
|
-
return {
|
|
659
|
-
agent: {
|
|
660
|
-
id: agent.id,
|
|
661
|
-
name: agent.name
|
|
662
|
-
},
|
|
663
|
-
strategy: "environment",
|
|
664
|
-
signal: signal.name,
|
|
665
|
-
value
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
var PsProcessReader = class {
|
|
669
|
-
read(pid) {
|
|
670
|
-
const command = readPsField(pid, "comm");
|
|
671
|
-
const ppid = Number.parseInt(readPsField(pid, "ppid"), 10);
|
|
672
|
-
if (!command || !Number.isInteger(ppid)) {
|
|
673
|
-
return void 0;
|
|
674
|
-
}
|
|
675
|
-
return {
|
|
676
|
-
pid,
|
|
677
|
-
ppid,
|
|
678
|
-
command: normalizeCommand(command)
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
};
|
|
682
|
-
var ProcessTreeDetectionStrategy = class {
|
|
683
|
-
constructor(reader = new PsProcessReader()) {
|
|
684
|
-
this.reader = reader;
|
|
685
|
-
}
|
|
686
|
-
reader;
|
|
687
|
-
name = "process-tree";
|
|
688
|
-
detect(context) {
|
|
689
|
-
const matches = [];
|
|
690
|
-
let currentPid = context.pid;
|
|
691
|
-
for (let depth = 0; depth < context.maxProcessDepth; depth += 1) {
|
|
692
|
-
const processInfo = this.reader.read(currentPid);
|
|
693
|
-
if (processInfo === void 0) {
|
|
694
|
-
break;
|
|
695
|
-
}
|
|
696
|
-
matches.push(...matchProcess(context.agents, processInfo));
|
|
697
|
-
if (processInfo.ppid === void 0 || processInfo.ppid <= 1 || processInfo.ppid === currentPid) {
|
|
698
|
-
break;
|
|
699
|
-
}
|
|
700
|
-
currentPid = processInfo.ppid;
|
|
701
|
-
}
|
|
702
|
-
return matches;
|
|
703
|
-
}
|
|
704
|
-
};
|
|
705
|
-
function matchProcess(agents, processInfo) {
|
|
706
|
-
const matches = [];
|
|
707
|
-
const command = normalizeCommand(processInfo.command);
|
|
708
|
-
for (const agent of agents) {
|
|
709
|
-
for (const signal of agent.process ?? []) {
|
|
710
|
-
if (!signal.pattern.test(command)) {
|
|
711
|
-
continue;
|
|
712
|
-
}
|
|
713
|
-
matches.push(toEvidence2(agent, signal, { ...processInfo, command }));
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
return matches;
|
|
717
|
-
}
|
|
718
|
-
function toEvidence2(agent, signal, processInfo) {
|
|
719
|
-
return {
|
|
720
|
-
agent: {
|
|
721
|
-
id: agent.id,
|
|
722
|
-
name: agent.name
|
|
723
|
-
},
|
|
724
|
-
strategy: "process-tree",
|
|
725
|
-
signal: signal.pattern.toString(),
|
|
726
|
-
value: `${processInfo.pid}:${processInfo.command}`
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
function readPsField(pid, field) {
|
|
730
|
-
try {
|
|
731
|
-
return execFileSync("ps", ["-o", `${field}=`, "-p", String(pid)], {
|
|
732
|
-
encoding: "utf8",
|
|
733
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
734
|
-
}).trim();
|
|
735
|
-
} catch {
|
|
736
|
-
return "";
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
function normalizeCommand(command) {
|
|
740
|
-
const baseName = path2.basename(command.trim());
|
|
741
|
-
return baseName.replace(/^-+/, "");
|
|
742
|
-
}
|
|
743
|
-
function detectAgent(options = {}) {
|
|
744
|
-
const agents = options.agents ?? defaultAgents;
|
|
745
|
-
const strategies = options.strategies ?? defaultStrategies(options.experimentalProcessTree);
|
|
746
|
-
const context = {
|
|
747
|
-
env: options.env ?? process.env,
|
|
748
|
-
pid: options.pid ?? process.pid,
|
|
749
|
-
agents,
|
|
750
|
-
maxProcessDepth: options.maxProcessDepth ?? 20
|
|
751
|
-
};
|
|
752
|
-
const matches = strategies.flatMap((strategy) => strategy.detect(context));
|
|
753
|
-
const bestMatch = selectBestAgent(agents, matches, context.env);
|
|
754
|
-
if (bestMatch === void 0) {
|
|
755
|
-
return {
|
|
756
|
-
detected: false
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
return {
|
|
760
|
-
detected: true,
|
|
761
|
-
agent: bestMatch
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
function defaultStrategies(experimentalProcessTree = false) {
|
|
765
|
-
const strategies = [new EnvironmentDetectionStrategy()];
|
|
766
|
-
if (experimentalProcessTree) {
|
|
767
|
-
strategies.push(new ProcessTreeDetectionStrategy());
|
|
768
|
-
}
|
|
769
|
-
return strategies;
|
|
770
|
-
}
|
|
771
|
-
function selectBestAgent(agents, matches, env) {
|
|
772
|
-
const matchedAgentIds = new Set(matches.map((match) => match.agent.id));
|
|
773
|
-
for (const agent of agents) {
|
|
774
|
-
if (!matchedAgentIds.has(agent.id)) {
|
|
775
|
-
continue;
|
|
776
|
-
}
|
|
777
|
-
return {
|
|
778
|
-
id: agent.id,
|
|
779
|
-
name: agent.name,
|
|
780
|
-
...sessionIdProperties(agent, env)
|
|
781
|
-
};
|
|
782
|
-
}
|
|
783
|
-
return void 0;
|
|
784
|
-
}
|
|
785
|
-
function sessionIdProperties(agent, env) {
|
|
786
|
-
for (const envName of agent.sessionEnv ?? []) {
|
|
787
|
-
const value = env[envName];
|
|
788
|
-
if (value !== void 0 && value.length > 0) {
|
|
789
|
-
return { sessionId: value };
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
return {};
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// ../core/dist/index.js
|
|
796
|
-
var import_ci_info = __toESM(require_ci_info(), 1);
|
|
797
|
-
|
|
798
|
-
// ../../node_modules/.pnpm/sandbox-cli-detector@0.2.0/node_modules/sandbox-cli-detector/dist/index.js
|
|
799
|
-
init_esm_shims();
|
|
800
|
-
|
|
801
|
-
// ../../node_modules/.pnpm/sandbox-cli-detector@0.2.0/node_modules/sandbox-cli-detector/dist/chunk-HZH3SATY.js
|
|
802
|
-
init_esm_shims();
|
|
803
|
-
var defaultSandboxes = [
|
|
804
|
-
{
|
|
805
|
-
id: "replit",
|
|
806
|
-
name: "Replit",
|
|
807
|
-
env: [{ name: "REPLIT_SESSION" }, { name: "REPLIT_CONTAINER" }, { name: "REPLIT_USER" }]
|
|
808
|
-
},
|
|
809
|
-
{
|
|
810
|
-
id: "bolt",
|
|
811
|
-
name: "bolt.new",
|
|
812
|
-
env: [{ name: "BOLT_ENV" }, { name: "BOLT_ORIGIN" }, { name: "BOLT_SERVER_URL" }]
|
|
813
|
-
},
|
|
814
|
-
{
|
|
815
|
-
id: "e2b",
|
|
816
|
-
name: "E2B",
|
|
817
|
-
env: [{ name: "E2B_SANDBOX", value: "true" }]
|
|
818
|
-
},
|
|
819
|
-
{
|
|
820
|
-
id: "vercel-sandbox",
|
|
821
|
-
name: "Vercel Sandbox",
|
|
822
|
-
env: [{ name: "HOME", value: "/home/vercel-sandbox" }]
|
|
823
|
-
},
|
|
824
|
-
{
|
|
825
|
-
id: "daytona",
|
|
826
|
-
name: "Daytona",
|
|
827
|
-
env: [{ name: "DAYTONA_SANDBOX_ID" }]
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
id: "modal",
|
|
831
|
-
name: "Modal",
|
|
832
|
-
env: [{ name: "MODAL_SANDBOX_ID" }, { name: "MODAL_TASK_ID" }]
|
|
833
|
-
},
|
|
834
|
-
{
|
|
835
|
-
id: "cloudflare-sandbox",
|
|
836
|
-
name: "Cloudflare Sandbox",
|
|
837
|
-
env: [{ name: "CLOUDFLARE_DURABLE_OBJECT_ID" }]
|
|
838
|
-
},
|
|
839
|
-
{
|
|
840
|
-
id: "codespaces",
|
|
841
|
-
name: "GitHub Codespaces",
|
|
842
|
-
env: [{ name: "CODESPACES", value: "true" }]
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
id: "codesandbox",
|
|
846
|
-
name: "CodeSandbox",
|
|
847
|
-
env: [{ name: "CSB", value: "true" }, { name: "CSB_SANDBOX_ID" }]
|
|
848
|
-
}
|
|
849
|
-
];
|
|
850
|
-
function detectSandbox(options = {}) {
|
|
851
|
-
const env = options.env ?? process.env;
|
|
852
|
-
const sandboxes = options.sandboxes ?? defaultSandboxes;
|
|
853
|
-
const sandbox = sandboxes.find(
|
|
854
|
-
(candidate) => candidate.env.some((signal) => matchesEnvSignal(signal, env))
|
|
855
|
-
);
|
|
856
|
-
if (sandbox === void 0) return { detected: false };
|
|
857
|
-
return {
|
|
858
|
-
detected: true,
|
|
859
|
-
sandbox: { id: sandbox.id, name: sandbox.name }
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
function matchesEnvSignal(signal, env) {
|
|
863
|
-
const value = env[signal.name];
|
|
864
|
-
return value !== void 0 && value !== "" && (signal.value === void 0 || value === signal.value);
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
// ../core/dist/index.js
|
|
868
|
-
import { homedir } from "os";
|
|
499
|
+
import { createHash } from "crypto";
|
|
500
|
+
import { readFile, stat } from "fs/promises";
|
|
869
501
|
import path3 from "path";
|
|
870
|
-
import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
871
|
-
import path32 from "path";
|
|
872
502
|
|
|
873
503
|
// ../spec/dist/index.js
|
|
874
504
|
init_esm_shims();
|
|
@@ -1652,10 +1282,10 @@ function mergeDefs(...defs) {
|
|
|
1652
1282
|
function cloneDef(schema) {
|
|
1653
1283
|
return mergeDefs(schema._zod.def);
|
|
1654
1284
|
}
|
|
1655
|
-
function getElementAtPath(obj,
|
|
1656
|
-
if (!
|
|
1285
|
+
function getElementAtPath(obj, path6) {
|
|
1286
|
+
if (!path6)
|
|
1657
1287
|
return obj;
|
|
1658
|
-
return
|
|
1288
|
+
return path6.reduce((acc, key) => acc?.[key], obj);
|
|
1659
1289
|
}
|
|
1660
1290
|
function promiseAllObject(promisesObj) {
|
|
1661
1291
|
const keys = Object.keys(promisesObj);
|
|
@@ -2064,11 +1694,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
2064
1694
|
}
|
|
2065
1695
|
return false;
|
|
2066
1696
|
}
|
|
2067
|
-
function prefixIssues(
|
|
1697
|
+
function prefixIssues(path6, issues) {
|
|
2068
1698
|
return issues.map((iss) => {
|
|
2069
1699
|
var _a3;
|
|
2070
1700
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
2071
|
-
iss.path.unshift(
|
|
1701
|
+
iss.path.unshift(path6);
|
|
2072
1702
|
return iss;
|
|
2073
1703
|
});
|
|
2074
1704
|
}
|
|
@@ -2215,16 +1845,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2215
1845
|
}
|
|
2216
1846
|
function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
2217
1847
|
const fieldErrors = { _errors: [] };
|
|
2218
|
-
const processError = (error52,
|
|
1848
|
+
const processError = (error52, path6 = []) => {
|
|
2219
1849
|
for (const issue2 of error52.issues) {
|
|
2220
1850
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
2221
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1851
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
2222
1852
|
} else if (issue2.code === "invalid_key") {
|
|
2223
|
-
processError({ issues: issue2.issues }, [...
|
|
1853
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
2224
1854
|
} else if (issue2.code === "invalid_element") {
|
|
2225
|
-
processError({ issues: issue2.issues }, [...
|
|
1855
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
2226
1856
|
} else {
|
|
2227
|
-
const fullpath = [...
|
|
1857
|
+
const fullpath = [...path6, ...issue2.path];
|
|
2228
1858
|
if (fullpath.length === 0) {
|
|
2229
1859
|
fieldErrors._errors.push(mapper(issue2));
|
|
2230
1860
|
} else {
|
|
@@ -2251,17 +1881,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2251
1881
|
}
|
|
2252
1882
|
function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
2253
1883
|
const result = { errors: [] };
|
|
2254
|
-
const processError = (error52,
|
|
1884
|
+
const processError = (error52, path6 = []) => {
|
|
2255
1885
|
var _a3, _b;
|
|
2256
1886
|
for (const issue2 of error52.issues) {
|
|
2257
1887
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
2258
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
1888
|
+
issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
|
|
2259
1889
|
} else if (issue2.code === "invalid_key") {
|
|
2260
|
-
processError({ issues: issue2.issues }, [...
|
|
1890
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
2261
1891
|
} else if (issue2.code === "invalid_element") {
|
|
2262
|
-
processError({ issues: issue2.issues }, [...
|
|
1892
|
+
processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
|
|
2263
1893
|
} else {
|
|
2264
|
-
const fullpath = [...
|
|
1894
|
+
const fullpath = [...path6, ...issue2.path];
|
|
2265
1895
|
if (fullpath.length === 0) {
|
|
2266
1896
|
result.errors.push(mapper(issue2));
|
|
2267
1897
|
continue;
|
|
@@ -2293,8 +1923,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
|
|
|
2293
1923
|
}
|
|
2294
1924
|
function toDotPath(_path) {
|
|
2295
1925
|
const segs = [];
|
|
2296
|
-
const
|
|
2297
|
-
for (const seg of
|
|
1926
|
+
const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1927
|
+
for (const seg of path6) {
|
|
2298
1928
|
if (typeof seg === "number")
|
|
2299
1929
|
segs.push(`[${seg}]`);
|
|
2300
1930
|
else if (typeof seg === "symbol")
|
|
@@ -15067,13 +14697,13 @@ function resolveRef(ref, ctx) {
|
|
|
15067
14697
|
if (!ref.startsWith("#")) {
|
|
15068
14698
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
15069
14699
|
}
|
|
15070
|
-
const
|
|
15071
|
-
if (
|
|
14700
|
+
const path6 = ref.slice(1).split("/").filter(Boolean);
|
|
14701
|
+
if (path6.length === 0) {
|
|
15072
14702
|
return ctx.rootSchema;
|
|
15073
14703
|
}
|
|
15074
14704
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
15075
|
-
if (
|
|
15076
|
-
const key =
|
|
14705
|
+
if (path6[0] === defsKey) {
|
|
14706
|
+
const key = path6[1];
|
|
15077
14707
|
if (!key || !ctx.defs[key]) {
|
|
15078
14708
|
throw new Error(`Reference not found: ${ref}`);
|
|
15079
14709
|
}
|
|
@@ -15478,11 +15108,107 @@ function bigint3(params) {
|
|
|
15478
15108
|
function date4(params) {
|
|
15479
15109
|
return _coercedDate(ZodDate, params);
|
|
15480
15110
|
}
|
|
15481
|
-
|
|
15482
|
-
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
15483
|
-
config(en_default());
|
|
15484
|
-
|
|
15485
|
-
// ../spec/dist/index.js
|
|
15111
|
+
|
|
15112
|
+
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
15113
|
+
config(en_default());
|
|
15114
|
+
|
|
15115
|
+
// ../spec/dist/index.js
|
|
15116
|
+
var MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
15117
|
+
var MAX_ATTACHMENTS = 10;
|
|
15118
|
+
var MAX_ATTACHMENT_DESCRIPTION_LENGTH = 1e3;
|
|
15119
|
+
var ATTACHMENT_UPLOAD_PATH = "/v1/attachments";
|
|
15120
|
+
var attachmentDescriptionSchema = external_exports.string().trim().min(1).max(MAX_ATTACHMENT_DESCRIPTION_LENGTH).describe("Optional plain text: what this file shows and why it matters.");
|
|
15121
|
+
var attachmentIdSchema = external_exports.string().regex(/^att_[a-f0-9]{32}$/);
|
|
15122
|
+
var ATTACHMENT_TARGET_TYPES = [
|
|
15123
|
+
"event",
|
|
15124
|
+
"issue",
|
|
15125
|
+
"question",
|
|
15126
|
+
"eval",
|
|
15127
|
+
"investigation",
|
|
15128
|
+
"investigation_question",
|
|
15129
|
+
"investigation_reply"
|
|
15130
|
+
];
|
|
15131
|
+
var attachmentTargetSchema = external_exports.object({
|
|
15132
|
+
type: external_exports.enum(ATTACHMENT_TARGET_TYPES),
|
|
15133
|
+
id: external_exports.string().min(1).max(64)
|
|
15134
|
+
});
|
|
15135
|
+
var attachmentManifestSchema = external_exports.object({
|
|
15136
|
+
filename: external_exports.string().min(1).max(180).refine(
|
|
15137
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: Reject control characters in filenames and HTTP headers.
|
|
15138
|
+
(name) => !/[\\/\u0000-\u001f\u007f]/.test(name) && name !== "." && name !== "..",
|
|
15139
|
+
"Use a filename without directories or control characters."
|
|
15140
|
+
),
|
|
15141
|
+
mediaType: external_exports.string().max(127).regex(/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/),
|
|
15142
|
+
size: external_exports.number().int().min(1).max(MAX_ATTACHMENT_BYTES),
|
|
15143
|
+
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/)
|
|
15144
|
+
});
|
|
15145
|
+
var prepareAttachmentSchema = attachmentManifestSchema.extend({
|
|
15146
|
+
to: external_exports.string().min(1).max(253).optional(),
|
|
15147
|
+
scope: external_exports.enum(["reporter", "owner"]).default("reporter"),
|
|
15148
|
+
/** Self-reported agent name for reporter uploads. */
|
|
15149
|
+
uploader: external_exports.string().min(1).max(128).optional()
|
|
15150
|
+
});
|
|
15151
|
+
var preparedAttachmentSchema = external_exports.object({
|
|
15152
|
+
reference: external_exports.object({
|
|
15153
|
+
id: attachmentIdSchema,
|
|
15154
|
+
token: external_exports.string().regex(/^hva_[a-f0-9]{64}$/)
|
|
15155
|
+
}),
|
|
15156
|
+
uploadUrl: external_exports.url(),
|
|
15157
|
+
expiresAt: external_exports.string()
|
|
15158
|
+
});
|
|
15159
|
+
var attachmentReferenceSchema = preparedAttachmentSchema.shape.reference.extend({
|
|
15160
|
+
description: attachmentDescriptionSchema.optional()
|
|
15161
|
+
});
|
|
15162
|
+
var attachmentReferencesSchema = external_exports.array(attachmentReferenceSchema).max(MAX_ATTACHMENTS).refine(
|
|
15163
|
+
(refs) => new Set(refs.map((ref) => ref.id)).size === refs.length,
|
|
15164
|
+
"Each file can be attached once."
|
|
15165
|
+
);
|
|
15166
|
+
var attachFilesSchema = external_exports.object({
|
|
15167
|
+
target: attachmentTargetSchema,
|
|
15168
|
+
attachments: attachmentReferencesSchema.min(1)
|
|
15169
|
+
});
|
|
15170
|
+
var attachmentSchema = attachmentManifestSchema.extend({
|
|
15171
|
+
id: attachmentIdSchema,
|
|
15172
|
+
createdAt: external_exports.string(),
|
|
15173
|
+
source: external_exports.enum(["reporter", "owner"]),
|
|
15174
|
+
/** Reporter names are self-reported; owner uploads are authenticated. */
|
|
15175
|
+
uploader: external_exports.string().nullable(),
|
|
15176
|
+
/** The record the file belongs to — a report when shown on its issue or eval. */
|
|
15177
|
+
target: attachmentTargetSchema,
|
|
15178
|
+
description: attachmentDescriptionSchema.optional()
|
|
15179
|
+
});
|
|
15180
|
+
var deliveredAttachmentSchema = attachmentSchema.extend({
|
|
15181
|
+
url: external_exports.url(),
|
|
15182
|
+
expiresAt: external_exports.string()
|
|
15183
|
+
});
|
|
15184
|
+
var MEDIA_TYPES = {
|
|
15185
|
+
png: "image/png",
|
|
15186
|
+
jpg: "image/jpeg",
|
|
15187
|
+
jpeg: "image/jpeg",
|
|
15188
|
+
gif: "image/gif",
|
|
15189
|
+
webp: "image/webp",
|
|
15190
|
+
svg: "image/svg+xml",
|
|
15191
|
+
mp4: "video/mp4",
|
|
15192
|
+
webm: "video/webm",
|
|
15193
|
+
mp3: "audio/mpeg",
|
|
15194
|
+
m4a: "audio/mp4",
|
|
15195
|
+
wav: "audio/wav",
|
|
15196
|
+
ogg: "audio/ogg",
|
|
15197
|
+
pdf: "application/pdf",
|
|
15198
|
+
json: "application/json",
|
|
15199
|
+
jsonl: "application/x-ndjson",
|
|
15200
|
+
ndjson: "application/x-ndjson",
|
|
15201
|
+
txt: "text/plain",
|
|
15202
|
+
log: "text/plain",
|
|
15203
|
+
md: "text/markdown",
|
|
15204
|
+
csv: "text/csv",
|
|
15205
|
+
zip: "application/zip",
|
|
15206
|
+
html: "text/html"
|
|
15207
|
+
};
|
|
15208
|
+
function mediaTypeForFilename(filename) {
|
|
15209
|
+
const extension = /\.([^./\\]+)$/.exec(filename)?.[1]?.toLowerCase();
|
|
15210
|
+
return extension && MEDIA_TYPES[extension] || "application/octet-stream";
|
|
15211
|
+
}
|
|
15486
15212
|
var PROTOCOL_VERSION = 1;
|
|
15487
15213
|
var MAX_FEEDBACK_LENGTH = 5e3;
|
|
15488
15214
|
var MAX_SUBJECT_LENGTH = 500;
|
|
@@ -15502,10 +15228,18 @@ var FEEDBACK_CATEGORIES = [
|
|
|
15502
15228
|
"cli",
|
|
15503
15229
|
"api",
|
|
15504
15230
|
"model",
|
|
15505
|
-
"eval",
|
|
15506
15231
|
"ux",
|
|
15507
15232
|
"other"
|
|
15508
15233
|
];
|
|
15234
|
+
var createQuestionInputSchema = external_exports.object({
|
|
15235
|
+
prompt: external_exports.string().trim().min(8).max(500).describe('The question, e.g. "If you used <feature>: what broke or was missing?"'),
|
|
15236
|
+
category: external_exports.enum(FEEDBACK_CATEGORIES).optional().describe("Only ask agents whose submission carries this category."),
|
|
15237
|
+
attachments: attachmentReferencesSchema.optional().describe("Uploaded files, each {id, token, description?}; every agent asked can open them."),
|
|
15238
|
+
idempotencyKey: external_exports.string().regex(/^[A-Za-z0-9_-]{8,64}$/).optional().describe(
|
|
15239
|
+
"Same key + same project = the same question, so a retried publish never duplicates."
|
|
15240
|
+
)
|
|
15241
|
+
});
|
|
15242
|
+
var LEGACY_CATEGORIES = ["eval"];
|
|
15509
15243
|
var EVENT_STATUSES = [
|
|
15510
15244
|
"new",
|
|
15511
15245
|
"seen",
|
|
@@ -15514,10 +15248,19 @@ var EVENT_STATUSES = [
|
|
|
15514
15248
|
"wont_fix",
|
|
15515
15249
|
"spam"
|
|
15516
15250
|
];
|
|
15517
|
-
var ISSUE_STATUSES = [
|
|
15251
|
+
var ISSUE_STATUSES = [
|
|
15252
|
+
"open",
|
|
15253
|
+
"in_progress",
|
|
15254
|
+
"needs_review",
|
|
15255
|
+
"resolved",
|
|
15256
|
+
"wont_fix",
|
|
15257
|
+
"spam"
|
|
15258
|
+
];
|
|
15259
|
+
var issueStatusSchema = external_exports.enum(ISSUE_STATUSES);
|
|
15518
15260
|
var VENDOR_CATEGORY_PATTERN = /^x-[a-z0-9][a-z0-9-]{0,38}$/;
|
|
15519
15261
|
var categorySchema = external_exports.union([
|
|
15520
15262
|
external_exports.enum(FEEDBACK_CATEGORIES),
|
|
15263
|
+
external_exports.enum(LEGACY_CATEGORIES),
|
|
15521
15264
|
external_exports.string().regex(VENDOR_CATEGORY_PATTERN, "vendor categories must match x-<kebab-case>")
|
|
15522
15265
|
]);
|
|
15523
15266
|
var sentimentSchema = external_exports.enum(["positive", "negative", "neutral"]);
|
|
@@ -15579,6 +15322,10 @@ var feedbackEventSchema = external_exports.object({
|
|
|
15579
15322
|
author: authorSchema.optional(),
|
|
15580
15323
|
thread: external_exports.object({ id: external_exports.string().regex(THREAD_ID_PATTERN) }),
|
|
15581
15324
|
eval: evalReportSchema.optional(),
|
|
15325
|
+
/** Id of an owner/system question this submission answers (from a prior response's `ask`). */
|
|
15326
|
+
question: external_exports.string().max(64).optional(),
|
|
15327
|
+
/** Uploaded files, committed with the event or not at all. Bytes never travel in feedback JSON. */
|
|
15328
|
+
attachments: attachmentReferencesSchema.optional(),
|
|
15582
15329
|
context: feedbackContextSchema.optional(),
|
|
15583
15330
|
metadata: metadataSchema.optional(),
|
|
15584
15331
|
/** Client-minted retry key: same key + same project = same stored event. */
|
|
@@ -15589,6 +15336,31 @@ var feedbackEventSchema = external_exports.object({
|
|
|
15589
15336
|
}),
|
|
15590
15337
|
consent: external_exports.object({ telemetry: external_exports.boolean() })
|
|
15591
15338
|
});
|
|
15339
|
+
var knownIssueSchema = external_exports.object({
|
|
15340
|
+
title: external_exports.string().max(120),
|
|
15341
|
+
/** wont_fix is disclosed only when the owner attached a closing note. */
|
|
15342
|
+
status: external_exports.enum(["open", "wont_fix"]),
|
|
15343
|
+
/** This very report flipped a resolved issue back open — already recorded. */
|
|
15344
|
+
reopened: external_exports.boolean().optional(),
|
|
15345
|
+
/** Total reports on this issue, including this one. */
|
|
15346
|
+
reports: external_exports.number().int().positive(),
|
|
15347
|
+
/** The owner's closing note, verbatim — their explanation of the decision. */
|
|
15348
|
+
note: external_exports.string().max(MAX_GUIDANCE_LENGTH).optional(),
|
|
15349
|
+
/** Server-composed next step for the submitting agent. */
|
|
15350
|
+
hint: external_exports.string().max(300)
|
|
15351
|
+
});
|
|
15352
|
+
var ownerIssueSchema = external_exports.object({
|
|
15353
|
+
id: external_exports.string(),
|
|
15354
|
+
title: external_exports.string(),
|
|
15355
|
+
summary: external_exports.string().nullable(),
|
|
15356
|
+
status: issueStatusSchema,
|
|
15357
|
+
fingerprint: external_exports.string().nullable(),
|
|
15358
|
+
event_count: external_exports.number(),
|
|
15359
|
+
reopened_count: external_exports.number(),
|
|
15360
|
+
first_seen: external_exports.string(),
|
|
15361
|
+
last_seen: external_exports.string(),
|
|
15362
|
+
links_json: external_exports.string()
|
|
15363
|
+
});
|
|
15592
15364
|
var ingestResponseSchema = external_exports.object({
|
|
15593
15365
|
id: external_exports.string().max(64),
|
|
15594
15366
|
thread: external_exports.string().regex(THREAD_ID_PATTERN),
|
|
@@ -15596,6 +15368,19 @@ var ingestResponseSchema = external_exports.object({
|
|
|
15596
15368
|
resume: external_exports.string().max(512).optional(),
|
|
15597
15369
|
/** Vendor-configured answer back to the submitting agent (known issues, workarounds). */
|
|
15598
15370
|
guidance: external_exports.string().max(MAX_GUIDANCE_LENGTH).optional(),
|
|
15371
|
+
/** The report matched an already-tracked issue; recorded — don't file variants. */
|
|
15372
|
+
known_issue: knownIssueSchema.optional(),
|
|
15373
|
+
/**
|
|
15374
|
+
* A question from the project's team, delivered at most one per response.
|
|
15375
|
+
* Answering is optional and must be grounded in what the agent actually did;
|
|
15376
|
+
* `command` is ready to run and files the answer on this thread.
|
|
15377
|
+
*/
|
|
15378
|
+
ask: external_exports.object({
|
|
15379
|
+
id: external_exports.string().max(64),
|
|
15380
|
+
prompt: external_exports.string().max(500),
|
|
15381
|
+
command: external_exports.string().max(512),
|
|
15382
|
+
attachments: external_exports.array(deliveredAttachmentSchema).optional()
|
|
15383
|
+
}).optional(),
|
|
15599
15384
|
/** True when idempotencyKey matched an already-stored event; id/thread are the original's. */
|
|
15600
15385
|
duplicate: external_exports.boolean().optional()
|
|
15601
15386
|
});
|
|
@@ -15624,50 +15409,546 @@ var repoEntrySchema = external_exports.object({
|
|
|
15624
15409
|
var repoListSchema = external_exports.array(repoEntrySchema).max(20);
|
|
15625
15410
|
function formatIssues(error51) {
|
|
15626
15411
|
return error51.issues.map((issue2) => {
|
|
15627
|
-
const
|
|
15628
|
-
return
|
|
15412
|
+
const path6 = issue2.path.join(".");
|
|
15413
|
+
return path6 ? `${path6}: ${issue2.message}` : issue2.message;
|
|
15629
15414
|
});
|
|
15630
15415
|
}
|
|
15631
|
-
function validateFeedbackEvent(input) {
|
|
15632
|
-
const result = feedbackEventSchema.safeParse(input);
|
|
15633
|
-
return result.success ? { ok: true, data: result.data } : { ok: false, errors: formatIssues(result.error) };
|
|
15416
|
+
function validateFeedbackEvent(input) {
|
|
15417
|
+
const result = feedbackEventSchema.safeParse(input);
|
|
15418
|
+
return result.success ? { ok: true, data: result.data } : { ok: false, errors: formatIssues(result.error) };
|
|
15419
|
+
}
|
|
15420
|
+
function validateDescriptor(input) {
|
|
15421
|
+
const result = descriptorSchema.safeParse(input);
|
|
15422
|
+
return result.success ? { ok: true, data: result.data } : { ok: false, errors: formatIssues(result.error) };
|
|
15423
|
+
}
|
|
15424
|
+
function validateIngestResponse(input) {
|
|
15425
|
+
const result = ingestResponseSchema.safeParse(input);
|
|
15426
|
+
return result.success ? { ok: true, data: result.data } : { ok: false, errors: formatIssues(result.error) };
|
|
15427
|
+
}
|
|
15428
|
+
function feedbackEventJsonSchema() {
|
|
15429
|
+
return external_exports.toJSONSchema(feedbackEventSchema);
|
|
15430
|
+
}
|
|
15431
|
+
function descriptorJsonSchema() {
|
|
15432
|
+
return external_exports.toJSONSchema(descriptorSchema);
|
|
15433
|
+
}
|
|
15434
|
+
|
|
15435
|
+
// ../core/dist/index.js
|
|
15436
|
+
import { readFileSync } from "fs";
|
|
15437
|
+
import path32 from "path";
|
|
15438
|
+
|
|
15439
|
+
// ../../node_modules/.pnpm/agent-cli-detector@0.1.5/node_modules/agent-cli-detector/dist/index.js
|
|
15440
|
+
init_esm_shims();
|
|
15441
|
+
import { execFileSync } from "child_process";
|
|
15442
|
+
import path2 from "path";
|
|
15443
|
+
var defaultAgents = [
|
|
15444
|
+
{
|
|
15445
|
+
id: "codex",
|
|
15446
|
+
name: "Codex",
|
|
15447
|
+
env: [
|
|
15448
|
+
{ name: "CODEX_CI", value: "1" },
|
|
15449
|
+
{ name: "CODEX_SHELL", value: "1" },
|
|
15450
|
+
{ name: "CODEX_THREAD_ID" }
|
|
15451
|
+
],
|
|
15452
|
+
process: [{ pattern: /^codex$/i }],
|
|
15453
|
+
sessionEnv: ["CODEX_THREAD_ID"]
|
|
15454
|
+
},
|
|
15455
|
+
{
|
|
15456
|
+
id: "cursor",
|
|
15457
|
+
name: "Cursor",
|
|
15458
|
+
env: [
|
|
15459
|
+
{ name: "CURSOR_AGENT", value: "1" },
|
|
15460
|
+
{ name: "CURSOR_CONVERSATION_ID" }
|
|
15461
|
+
],
|
|
15462
|
+
process: [{ pattern: /^cursor$/i }],
|
|
15463
|
+
sessionEnv: ["CURSOR_CONVERSATION_ID"]
|
|
15464
|
+
},
|
|
15465
|
+
{
|
|
15466
|
+
id: "claude-code",
|
|
15467
|
+
name: "Claude Code",
|
|
15468
|
+
env: [
|
|
15469
|
+
{ name: "CLAUDECODE", value: "1" },
|
|
15470
|
+
{ name: "CLAUDE_CODE_SESSION_ID" }
|
|
15471
|
+
],
|
|
15472
|
+
process: [{ pattern: /^claude$/i }],
|
|
15473
|
+
sessionEnv: ["CLAUDE_CODE_SESSION_ID"]
|
|
15474
|
+
},
|
|
15475
|
+
{
|
|
15476
|
+
id: "opencode",
|
|
15477
|
+
name: "OpenCode",
|
|
15478
|
+
env: [
|
|
15479
|
+
{ name: "OPENCODE", value: "1" },
|
|
15480
|
+
{ name: "OPENCODE_PID" }
|
|
15481
|
+
],
|
|
15482
|
+
process: [{ pattern: /^opencode$/i }]
|
|
15483
|
+
},
|
|
15484
|
+
{
|
|
15485
|
+
id: "devin",
|
|
15486
|
+
name: "Devin",
|
|
15487
|
+
process: [{ pattern: /devin/i }]
|
|
15488
|
+
},
|
|
15489
|
+
{
|
|
15490
|
+
id: "gemini",
|
|
15491
|
+
name: "Gemini CLI",
|
|
15492
|
+
env: [{ name: "GEMINI_CLI", value: "1" }],
|
|
15493
|
+
process: [{ pattern: /^gemini$/i }]
|
|
15494
|
+
},
|
|
15495
|
+
{
|
|
15496
|
+
id: "antigravity",
|
|
15497
|
+
name: "Antigravity",
|
|
15498
|
+
env: [
|
|
15499
|
+
{ name: "ANTIGRAVITY_AGENT", value: "1" },
|
|
15500
|
+
{ name: "ANTIGRAVITY_TRAJECTORY_ID" }
|
|
15501
|
+
],
|
|
15502
|
+
process: [{ pattern: /^antigravity$/i }],
|
|
15503
|
+
sessionEnv: ["ANTIGRAVITY_TRAJECTORY_ID"]
|
|
15504
|
+
},
|
|
15505
|
+
{
|
|
15506
|
+
id: "bolt",
|
|
15507
|
+
name: "Bolt",
|
|
15508
|
+
env: [
|
|
15509
|
+
{ name: "BOLT_ENV" },
|
|
15510
|
+
{ name: "BOLT_ORIGIN" },
|
|
15511
|
+
{ name: "BOLT_SERVER_URL" }
|
|
15512
|
+
]
|
|
15513
|
+
},
|
|
15514
|
+
{
|
|
15515
|
+
id: "pi",
|
|
15516
|
+
name: "Pi",
|
|
15517
|
+
env: [{ name: "PI_CODING_AGENT", value: "true" }]
|
|
15518
|
+
},
|
|
15519
|
+
{
|
|
15520
|
+
id: "replit",
|
|
15521
|
+
name: "Replit",
|
|
15522
|
+
env: [{ name: "REPLIT_SESSION" }],
|
|
15523
|
+
sessionEnv: ["REPLIT_SESSION"]
|
|
15524
|
+
},
|
|
15525
|
+
{
|
|
15526
|
+
id: "rork",
|
|
15527
|
+
name: "Rork",
|
|
15528
|
+
env: [{ name: "RORK_API_URL" }]
|
|
15529
|
+
},
|
|
15530
|
+
{
|
|
15531
|
+
id: "kiro",
|
|
15532
|
+
name: "Kiro",
|
|
15533
|
+
env: [{ name: "KIRO_SESSION_ID" }],
|
|
15534
|
+
process: [{ pattern: /kiro/i }],
|
|
15535
|
+
sessionEnv: ["KIRO_SESSION_ID"]
|
|
15536
|
+
},
|
|
15537
|
+
{
|
|
15538
|
+
id: "cline",
|
|
15539
|
+
name: "Cline",
|
|
15540
|
+
env: [{ name: "CLINE_WRAPPER_PATH" }],
|
|
15541
|
+
process: [{ pattern: /^cline$/i }]
|
|
15542
|
+
},
|
|
15543
|
+
{
|
|
15544
|
+
id: "kilocode",
|
|
15545
|
+
name: "Kilo Code",
|
|
15546
|
+
env: [
|
|
15547
|
+
{ name: "KILO", value: "1" },
|
|
15548
|
+
{ name: "KILOCODE_VERSION" },
|
|
15549
|
+
{ name: "KILO_RUN_ID" }
|
|
15550
|
+
],
|
|
15551
|
+
process: [{ pattern: /^(kilo|kilocode)$/i }],
|
|
15552
|
+
sessionEnv: ["KILO_RUN_ID"]
|
|
15553
|
+
},
|
|
15554
|
+
{
|
|
15555
|
+
id: "copilot",
|
|
15556
|
+
name: "GitHub Copilot CLI",
|
|
15557
|
+
env: [
|
|
15558
|
+
{ name: "COPILOT_CLI", value: "1" },
|
|
15559
|
+
{ name: "COPILOT_AGENT_SESSION_ID" },
|
|
15560
|
+
{ name: "COPILOT_RUN_APP", value: "1" }
|
|
15561
|
+
],
|
|
15562
|
+
process: [{ pattern: /^(github-copilot-cli|copilot)$/i }],
|
|
15563
|
+
sessionEnv: ["COPILOT_AGENT_SESSION_ID"]
|
|
15564
|
+
}
|
|
15565
|
+
];
|
|
15566
|
+
var EnvironmentDetectionStrategy = class {
|
|
15567
|
+
name = "environment";
|
|
15568
|
+
detect(context) {
|
|
15569
|
+
const matches = [];
|
|
15570
|
+
for (const agent of context.agents) {
|
|
15571
|
+
for (const signal of agent.env ?? []) {
|
|
15572
|
+
const value = context.env[signal.name];
|
|
15573
|
+
if (value === void 0 || !matchesEnvValue(value, signal.value)) {
|
|
15574
|
+
continue;
|
|
15575
|
+
}
|
|
15576
|
+
matches.push(toEvidence(agent, signal, value));
|
|
15577
|
+
}
|
|
15578
|
+
}
|
|
15579
|
+
return matches;
|
|
15580
|
+
}
|
|
15581
|
+
};
|
|
15582
|
+
function matchesEnvValue(value, matcher) {
|
|
15583
|
+
if (matcher === void 0) {
|
|
15584
|
+
return true;
|
|
15585
|
+
}
|
|
15586
|
+
if (typeof matcher === "string") {
|
|
15587
|
+
return value === matcher;
|
|
15588
|
+
}
|
|
15589
|
+
if (matcher instanceof RegExp) {
|
|
15590
|
+
return matcher.test(value);
|
|
15591
|
+
}
|
|
15592
|
+
return matcher(value);
|
|
15593
|
+
}
|
|
15594
|
+
function toEvidence(agent, signal, value) {
|
|
15595
|
+
return {
|
|
15596
|
+
agent: {
|
|
15597
|
+
id: agent.id,
|
|
15598
|
+
name: agent.name
|
|
15599
|
+
},
|
|
15600
|
+
strategy: "environment",
|
|
15601
|
+
signal: signal.name,
|
|
15602
|
+
value
|
|
15603
|
+
};
|
|
15604
|
+
}
|
|
15605
|
+
var PsProcessReader = class {
|
|
15606
|
+
read(pid) {
|
|
15607
|
+
const command = readPsField(pid, "comm");
|
|
15608
|
+
const ppid = Number.parseInt(readPsField(pid, "ppid"), 10);
|
|
15609
|
+
if (!command || !Number.isInteger(ppid)) {
|
|
15610
|
+
return void 0;
|
|
15611
|
+
}
|
|
15612
|
+
return {
|
|
15613
|
+
pid,
|
|
15614
|
+
ppid,
|
|
15615
|
+
command: normalizeCommand(command)
|
|
15616
|
+
};
|
|
15617
|
+
}
|
|
15618
|
+
};
|
|
15619
|
+
var ProcessTreeDetectionStrategy = class {
|
|
15620
|
+
constructor(reader = new PsProcessReader()) {
|
|
15621
|
+
this.reader = reader;
|
|
15622
|
+
}
|
|
15623
|
+
reader;
|
|
15624
|
+
name = "process-tree";
|
|
15625
|
+
detect(context) {
|
|
15626
|
+
const matches = [];
|
|
15627
|
+
let currentPid = context.pid;
|
|
15628
|
+
for (let depth = 0; depth < context.maxProcessDepth; depth += 1) {
|
|
15629
|
+
const processInfo = this.reader.read(currentPid);
|
|
15630
|
+
if (processInfo === void 0) {
|
|
15631
|
+
break;
|
|
15632
|
+
}
|
|
15633
|
+
matches.push(...matchProcess(context.agents, processInfo));
|
|
15634
|
+
if (processInfo.ppid === void 0 || processInfo.ppid <= 1 || processInfo.ppid === currentPid) {
|
|
15635
|
+
break;
|
|
15636
|
+
}
|
|
15637
|
+
currentPid = processInfo.ppid;
|
|
15638
|
+
}
|
|
15639
|
+
return matches;
|
|
15640
|
+
}
|
|
15641
|
+
};
|
|
15642
|
+
function matchProcess(agents, processInfo) {
|
|
15643
|
+
const matches = [];
|
|
15644
|
+
const command = normalizeCommand(processInfo.command);
|
|
15645
|
+
for (const agent of agents) {
|
|
15646
|
+
for (const signal of agent.process ?? []) {
|
|
15647
|
+
if (!signal.pattern.test(command)) {
|
|
15648
|
+
continue;
|
|
15649
|
+
}
|
|
15650
|
+
matches.push(toEvidence2(agent, signal, { ...processInfo, command }));
|
|
15651
|
+
}
|
|
15652
|
+
}
|
|
15653
|
+
return matches;
|
|
15654
|
+
}
|
|
15655
|
+
function toEvidence2(agent, signal, processInfo) {
|
|
15656
|
+
return {
|
|
15657
|
+
agent: {
|
|
15658
|
+
id: agent.id,
|
|
15659
|
+
name: agent.name
|
|
15660
|
+
},
|
|
15661
|
+
strategy: "process-tree",
|
|
15662
|
+
signal: signal.pattern.toString(),
|
|
15663
|
+
value: `${processInfo.pid}:${processInfo.command}`
|
|
15664
|
+
};
|
|
15634
15665
|
}
|
|
15635
|
-
function
|
|
15636
|
-
|
|
15637
|
-
|
|
15666
|
+
function readPsField(pid, field) {
|
|
15667
|
+
try {
|
|
15668
|
+
return execFileSync("ps", ["-o", `${field}=`, "-p", String(pid)], {
|
|
15669
|
+
encoding: "utf8",
|
|
15670
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15671
|
+
}).trim();
|
|
15672
|
+
} catch {
|
|
15673
|
+
return "";
|
|
15674
|
+
}
|
|
15638
15675
|
}
|
|
15639
|
-
function
|
|
15640
|
-
const
|
|
15641
|
-
return
|
|
15676
|
+
function normalizeCommand(command) {
|
|
15677
|
+
const baseName = path2.basename(command.trim());
|
|
15678
|
+
return baseName.replace(/^-+/, "");
|
|
15642
15679
|
}
|
|
15643
|
-
function
|
|
15644
|
-
|
|
15680
|
+
function detectAgent(options = {}) {
|
|
15681
|
+
const agents = options.agents ?? defaultAgents;
|
|
15682
|
+
const strategies = options.strategies ?? defaultStrategies(options.experimentalProcessTree);
|
|
15683
|
+
const context = {
|
|
15684
|
+
env: options.env ?? process.env,
|
|
15685
|
+
pid: options.pid ?? process.pid,
|
|
15686
|
+
agents,
|
|
15687
|
+
maxProcessDepth: options.maxProcessDepth ?? 20
|
|
15688
|
+
};
|
|
15689
|
+
const matches = strategies.flatMap((strategy) => strategy.detect(context));
|
|
15690
|
+
const bestMatch = selectBestAgent(agents, matches, context.env);
|
|
15691
|
+
if (bestMatch === void 0) {
|
|
15692
|
+
return {
|
|
15693
|
+
detected: false
|
|
15694
|
+
};
|
|
15695
|
+
}
|
|
15696
|
+
return {
|
|
15697
|
+
detected: true,
|
|
15698
|
+
agent: bestMatch
|
|
15699
|
+
};
|
|
15645
15700
|
}
|
|
15646
|
-
function
|
|
15647
|
-
|
|
15701
|
+
function defaultStrategies(experimentalProcessTree = false) {
|
|
15702
|
+
const strategies = [new EnvironmentDetectionStrategy()];
|
|
15703
|
+
if (experimentalProcessTree) {
|
|
15704
|
+
strategies.push(new ProcessTreeDetectionStrategy());
|
|
15705
|
+
}
|
|
15706
|
+
return strategies;
|
|
15707
|
+
}
|
|
15708
|
+
function selectBestAgent(agents, matches, env) {
|
|
15709
|
+
const matchedAgentIds = new Set(matches.map((match) => match.agent.id));
|
|
15710
|
+
for (const agent of agents) {
|
|
15711
|
+
if (!matchedAgentIds.has(agent.id)) {
|
|
15712
|
+
continue;
|
|
15713
|
+
}
|
|
15714
|
+
return {
|
|
15715
|
+
id: agent.id,
|
|
15716
|
+
name: agent.name,
|
|
15717
|
+
...sessionIdProperties(agent, env)
|
|
15718
|
+
};
|
|
15719
|
+
}
|
|
15720
|
+
return void 0;
|
|
15721
|
+
}
|
|
15722
|
+
function sessionIdProperties(agent, env) {
|
|
15723
|
+
for (const envName of agent.sessionEnv ?? []) {
|
|
15724
|
+
const value = env[envName];
|
|
15725
|
+
if (value !== void 0 && value.length > 0) {
|
|
15726
|
+
return { sessionId: value };
|
|
15727
|
+
}
|
|
15728
|
+
}
|
|
15729
|
+
return {};
|
|
15730
|
+
}
|
|
15731
|
+
|
|
15732
|
+
// ../core/dist/index.js
|
|
15733
|
+
var import_ci_info = __toESM(require_ci_info(), 1);
|
|
15734
|
+
|
|
15735
|
+
// ../../node_modules/.pnpm/sandbox-cli-detector@0.2.0/node_modules/sandbox-cli-detector/dist/index.js
|
|
15736
|
+
init_esm_shims();
|
|
15737
|
+
|
|
15738
|
+
// ../../node_modules/.pnpm/sandbox-cli-detector@0.2.0/node_modules/sandbox-cli-detector/dist/chunk-HZH3SATY.js
|
|
15739
|
+
init_esm_shims();
|
|
15740
|
+
var defaultSandboxes = [
|
|
15741
|
+
{
|
|
15742
|
+
id: "replit",
|
|
15743
|
+
name: "Replit",
|
|
15744
|
+
env: [{ name: "REPLIT_SESSION" }, { name: "REPLIT_CONTAINER" }, { name: "REPLIT_USER" }]
|
|
15745
|
+
},
|
|
15746
|
+
{
|
|
15747
|
+
id: "bolt",
|
|
15748
|
+
name: "bolt.new",
|
|
15749
|
+
env: [{ name: "BOLT_ENV" }, { name: "BOLT_ORIGIN" }, { name: "BOLT_SERVER_URL" }]
|
|
15750
|
+
},
|
|
15751
|
+
{
|
|
15752
|
+
id: "e2b",
|
|
15753
|
+
name: "E2B",
|
|
15754
|
+
env: [{ name: "E2B_SANDBOX", value: "true" }]
|
|
15755
|
+
},
|
|
15756
|
+
{
|
|
15757
|
+
id: "vercel-sandbox",
|
|
15758
|
+
name: "Vercel Sandbox",
|
|
15759
|
+
env: [{ name: "HOME", value: "/home/vercel-sandbox" }]
|
|
15760
|
+
},
|
|
15761
|
+
{
|
|
15762
|
+
id: "daytona",
|
|
15763
|
+
name: "Daytona",
|
|
15764
|
+
env: [{ name: "DAYTONA_SANDBOX_ID" }]
|
|
15765
|
+
},
|
|
15766
|
+
{
|
|
15767
|
+
id: "modal",
|
|
15768
|
+
name: "Modal",
|
|
15769
|
+
env: [{ name: "MODAL_SANDBOX_ID" }, { name: "MODAL_TASK_ID" }]
|
|
15770
|
+
},
|
|
15771
|
+
{
|
|
15772
|
+
id: "cloudflare-sandbox",
|
|
15773
|
+
name: "Cloudflare Sandbox",
|
|
15774
|
+
env: [{ name: "CLOUDFLARE_DURABLE_OBJECT_ID" }]
|
|
15775
|
+
},
|
|
15776
|
+
{
|
|
15777
|
+
id: "codespaces",
|
|
15778
|
+
name: "GitHub Codespaces",
|
|
15779
|
+
env: [{ name: "CODESPACES", value: "true" }]
|
|
15780
|
+
},
|
|
15781
|
+
{
|
|
15782
|
+
id: "codesandbox",
|
|
15783
|
+
name: "CodeSandbox",
|
|
15784
|
+
env: [{ name: "CSB", value: "true" }, { name: "CSB_SANDBOX_ID" }]
|
|
15785
|
+
}
|
|
15786
|
+
];
|
|
15787
|
+
function detectSandbox(options = {}) {
|
|
15788
|
+
const env = options.env ?? process.env;
|
|
15789
|
+
const sandboxes = options.sandboxes ?? defaultSandboxes;
|
|
15790
|
+
const sandbox = sandboxes.find(
|
|
15791
|
+
(candidate) => candidate.env.some((signal) => matchesEnvSignal(signal, env))
|
|
15792
|
+
);
|
|
15793
|
+
if (sandbox === void 0) return { detected: false };
|
|
15794
|
+
return {
|
|
15795
|
+
detected: true,
|
|
15796
|
+
sandbox: { id: sandbox.id, name: sandbox.name }
|
|
15797
|
+
};
|
|
15798
|
+
}
|
|
15799
|
+
function matchesEnvSignal(signal, env) {
|
|
15800
|
+
const value = env[signal.name];
|
|
15801
|
+
return value !== void 0 && value !== "" && (signal.value === void 0 || value === signal.value);
|
|
15648
15802
|
}
|
|
15649
15803
|
|
|
15650
15804
|
// ../core/dist/index.js
|
|
15651
|
-
import {
|
|
15805
|
+
import { homedir } from "os";
|
|
15806
|
+
import path22 from "path";
|
|
15807
|
+
import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
15652
15808
|
import path4 from "path";
|
|
15809
|
+
import { randomUUID } from "crypto";
|
|
15810
|
+
import { appendFileSync, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync3, renameSync, rmSync } from "fs";
|
|
15811
|
+
import path5 from "path";
|
|
15653
15812
|
import { randomBytes } from "crypto";
|
|
15654
15813
|
import { createRequire } from "module";
|
|
15814
|
+
var FeedbackError = class extends Error {
|
|
15815
|
+
constructor(message) {
|
|
15816
|
+
super(message);
|
|
15817
|
+
this.name = "FeedbackError";
|
|
15818
|
+
}
|
|
15819
|
+
};
|
|
15820
|
+
async function readLocalAttachments(inputs, cwd = process.cwd()) {
|
|
15821
|
+
if (inputs.length > MAX_ATTACHMENTS)
|
|
15822
|
+
throw new FeedbackError(`At most ${MAX_ATTACHMENTS} files can be attached.`);
|
|
15823
|
+
const files = [];
|
|
15824
|
+
for (const input of inputs) {
|
|
15825
|
+
const selected = typeof input === "string" ? input : input.path;
|
|
15826
|
+
const filename = path3.basename(selected);
|
|
15827
|
+
const description = attachmentDescriptionSchema.optional().safeParse(typeof input === "string" ? void 0 : input.description);
|
|
15828
|
+
if (!description.success)
|
|
15829
|
+
throw new FeedbackError(
|
|
15830
|
+
`Invalid description for "${filename}": ${description.error.issues.map((issue2) => issue2.message).join("; ")}`
|
|
15831
|
+
);
|
|
15832
|
+
const file2 = path3.resolve(cwd, selected);
|
|
15833
|
+
const info = await stat(file2).catch(() => null);
|
|
15834
|
+
if (!info?.isFile())
|
|
15835
|
+
throw new FeedbackError(`Cannot attach "${selected}": choose an existing, readable file.`);
|
|
15836
|
+
if (info.size < 1 || info.size > MAX_ATTACHMENT_BYTES)
|
|
15837
|
+
throw new FeedbackError(`"${filename}" must be between 1 byte and 20 MiB.`);
|
|
15838
|
+
const bytes = new Uint8Array(
|
|
15839
|
+
await readFile(file2).catch(() => {
|
|
15840
|
+
throw new FeedbackError(`Cannot read "${selected}".`);
|
|
15841
|
+
})
|
|
15842
|
+
);
|
|
15843
|
+
const manifest = attachmentManifestSchema.safeParse({
|
|
15844
|
+
filename,
|
|
15845
|
+
mediaType: mediaTypeForFilename(filename),
|
|
15846
|
+
size: bytes.length,
|
|
15847
|
+
sha256: createHash("sha256").update(bytes).digest("hex")
|
|
15848
|
+
});
|
|
15849
|
+
if (!manifest.success)
|
|
15850
|
+
throw new FeedbackError(
|
|
15851
|
+
`Cannot attach "${filename}": ${manifest.error.issues.map((issue2) => issue2.message).join("; ")}`
|
|
15852
|
+
);
|
|
15853
|
+
files.push({
|
|
15854
|
+
manifest: manifest.data,
|
|
15855
|
+
bytes,
|
|
15856
|
+
...description.data ? { description: description.data } : {}
|
|
15857
|
+
});
|
|
15858
|
+
}
|
|
15859
|
+
return files;
|
|
15860
|
+
}
|
|
15861
|
+
var AttachmentUploadError = class extends FeedbackError {
|
|
15862
|
+
constructor(message, rejected) {
|
|
15863
|
+
super(message);
|
|
15864
|
+
this.rejected = rejected;
|
|
15865
|
+
this.name = "AttachmentUploadError";
|
|
15866
|
+
}
|
|
15867
|
+
rejected;
|
|
15868
|
+
};
|
|
15869
|
+
async function send(fetchImpl, url2, init, timeoutMs) {
|
|
15870
|
+
let response;
|
|
15871
|
+
try {
|
|
15872
|
+
response = await fetchImpl(url2, {
|
|
15873
|
+
...init,
|
|
15874
|
+
redirect: "error",
|
|
15875
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
15876
|
+
});
|
|
15877
|
+
} catch {
|
|
15878
|
+
throw new AttachmentUploadError("Could not reach the server to upload files.", false);
|
|
15879
|
+
}
|
|
15880
|
+
if (response.ok) return response;
|
|
15881
|
+
const body = await response.json().catch(() => null);
|
|
15882
|
+
const errors = Array.isArray(body?.errors) ? body.errors.map(String).join("; ") : void 0;
|
|
15883
|
+
if (response.status === 404 && !errors)
|
|
15884
|
+
throw new AttachmentUploadError("This server does not accept files.", false);
|
|
15885
|
+
throw new AttachmentUploadError(
|
|
15886
|
+
errors ?? `File upload failed (${response.status}).`,
|
|
15887
|
+
!(response.status >= 500 || response.status === 429 || response.status === 408)
|
|
15888
|
+
);
|
|
15889
|
+
}
|
|
15890
|
+
async function uploadFiles(options) {
|
|
15891
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
15892
|
+
const timeoutMs = options.timeoutMs ?? 6e4;
|
|
15893
|
+
const origin = new URL(options.endpoint).origin;
|
|
15894
|
+
const references = [];
|
|
15895
|
+
for (const file2 of options.files) {
|
|
15896
|
+
const response = await send(
|
|
15897
|
+
fetchImpl,
|
|
15898
|
+
`${origin}${ATTACHMENT_UPLOAD_PATH}`,
|
|
15899
|
+
{
|
|
15900
|
+
method: "POST",
|
|
15901
|
+
headers: {
|
|
15902
|
+
"content-type": "application/json",
|
|
15903
|
+
...options.secretKey ? { authorization: `Bearer ${options.secretKey}` } : {},
|
|
15904
|
+
...options.writeKey ? { [WRITE_KEY_HEADER]: options.writeKey } : {}
|
|
15905
|
+
},
|
|
15906
|
+
body: JSON.stringify({
|
|
15907
|
+
...file2.manifest,
|
|
15908
|
+
to: options.to,
|
|
15909
|
+
scope: options.secretKey ? "owner" : "reporter",
|
|
15910
|
+
uploader: options.uploader
|
|
15911
|
+
})
|
|
15912
|
+
},
|
|
15913
|
+
timeoutMs
|
|
15914
|
+
);
|
|
15915
|
+
const prepared = preparedAttachmentSchema.safeParse(await response.json().catch(() => null));
|
|
15916
|
+
if (!prepared.success || new URL(prepared.data.uploadUrl).origin !== origin)
|
|
15917
|
+
throw new AttachmentUploadError("The server returned an invalid upload response.", true);
|
|
15918
|
+
await send(
|
|
15919
|
+
fetchImpl,
|
|
15920
|
+
prepared.data.uploadUrl,
|
|
15921
|
+
{
|
|
15922
|
+
method: "PUT",
|
|
15923
|
+
headers: { authorization: `Bearer ${prepared.data.reference.token}` },
|
|
15924
|
+
body: file2.bytes
|
|
15925
|
+
},
|
|
15926
|
+
// At least 100 KB/s: a 20 MiB file on a slow link still gets about 3.5 minutes.
|
|
15927
|
+
Math.max(timeoutMs, file2.bytes.length / 100)
|
|
15928
|
+
);
|
|
15929
|
+
references.push({
|
|
15930
|
+
...prepared.data.reference,
|
|
15931
|
+
...file2.description ? { description: file2.description } : {}
|
|
15932
|
+
});
|
|
15933
|
+
}
|
|
15934
|
+
return references;
|
|
15935
|
+
}
|
|
15655
15936
|
var DSN_ENV_VAR = "HIVENET_DSN";
|
|
15656
15937
|
var REGISTRY_ENV_VAR = "HIVENET_REGISTRY";
|
|
15657
15938
|
var HOME_ENV_VAR = "HIVENET_HOME";
|
|
15658
15939
|
var NO_TELEMETRY_ENV_VAR = "HIVENET_NO_TELEMETRY";
|
|
15659
15940
|
function feedbackHomeDir(env = process.env) {
|
|
15660
15941
|
const override = env[HOME_ENV_VAR];
|
|
15661
|
-
return override?.trim() ? override :
|
|
15942
|
+
return override?.trim() ? override : path22.join(homedir(), ".hivenet");
|
|
15662
15943
|
}
|
|
15663
15944
|
function isTelemetryDisabled(extraOptOutEnvVars = [], env = process.env) {
|
|
15664
15945
|
const vars = ["DO_NOT_TRACK", NO_TELEMETRY_ENV_VAR, ...extraOptOutEnvVars];
|
|
15665
15946
|
return vars.some((name) => env[name] === "1" || env[name] === "true");
|
|
15666
15947
|
}
|
|
15667
15948
|
var MAX_SESSION_ID_LENGTH = 256;
|
|
15668
|
-
function detectAgentSafe() {
|
|
15949
|
+
function detectAgentSafe(env) {
|
|
15669
15950
|
try {
|
|
15670
|
-
const result = detectAgent();
|
|
15951
|
+
const result = detectAgent({ env });
|
|
15671
15952
|
if (result.detected && result.agent) {
|
|
15672
15953
|
return {
|
|
15673
15954
|
id: result.agent.id,
|
|
@@ -15679,9 +15960,9 @@ function detectAgentSafe() {
|
|
|
15679
15960
|
}
|
|
15680
15961
|
return void 0;
|
|
15681
15962
|
}
|
|
15682
|
-
function detectSandboxSafe() {
|
|
15963
|
+
function detectSandboxSafe(env) {
|
|
15683
15964
|
try {
|
|
15684
|
-
const result = detectSandbox();
|
|
15965
|
+
const result = detectSandbox({ env });
|
|
15685
15966
|
if (result.detected && result.sandbox) {
|
|
15686
15967
|
return {
|
|
15687
15968
|
id: result.sandbox.id,
|
|
@@ -15746,7 +16027,7 @@ function resolveSessions(sources, projectRoot, env) {
|
|
|
15746
16027
|
}
|
|
15747
16028
|
const value = "envVar" in source ? normalizeSessionId(env[source.envVar]) : normalizeSessionId(
|
|
15748
16029
|
readDotenvKey(
|
|
15749
|
-
|
|
16030
|
+
path32.resolve(projectRoot, source.dotenvFile),
|
|
15750
16031
|
source.dotenvKey ?? source.key
|
|
15751
16032
|
)
|
|
15752
16033
|
);
|
|
@@ -15762,8 +16043,8 @@ async function collectContext(options = {}) {
|
|
|
15762
16043
|
return void 0;
|
|
15763
16044
|
}
|
|
15764
16045
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
15765
|
-
const agent = detectAgentSafe();
|
|
15766
|
-
const sandbox = detectSandboxSafe();
|
|
16046
|
+
const agent = detectAgentSafe(env);
|
|
16047
|
+
const sandbox = detectSandboxSafe(env);
|
|
15767
16048
|
const ci = detectCi();
|
|
15768
16049
|
const session = resolveSessions(options.sessions ?? [], projectRoot, env);
|
|
15769
16050
|
let project;
|
|
@@ -15786,12 +16067,6 @@ async function collectContext(options = {}) {
|
|
|
15786
16067
|
function inferAuthor(context) {
|
|
15787
16068
|
return context?.agent ? "agent" : void 0;
|
|
15788
16069
|
}
|
|
15789
|
-
var FeedbackError = class extends Error {
|
|
15790
|
-
constructor(message) {
|
|
15791
|
-
super(message);
|
|
15792
|
-
this.name = "FeedbackError";
|
|
15793
|
-
}
|
|
15794
|
-
};
|
|
15795
16070
|
var CONFIG_FILE_NAME = "feedback.config.json";
|
|
15796
16071
|
var DESCRIPTOR_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
15797
16072
|
var RESOLVE_TIMEOUT_MS = 5e3;
|
|
@@ -15816,9 +16091,9 @@ function parseDsn(dsn) {
|
|
|
15816
16091
|
};
|
|
15817
16092
|
}
|
|
15818
16093
|
function findConfigFile(startDir) {
|
|
15819
|
-
let current =
|
|
16094
|
+
let current = path4.resolve(startDir);
|
|
15820
16095
|
while (true) {
|
|
15821
|
-
const candidate =
|
|
16096
|
+
const candidate = path4.join(current, CONFIG_FILE_NAME);
|
|
15822
16097
|
try {
|
|
15823
16098
|
const raw = readFileSync2(candidate, "utf8");
|
|
15824
16099
|
const parsed = JSON.parse(raw);
|
|
@@ -15827,7 +16102,7 @@ function findConfigFile(startDir) {
|
|
|
15827
16102
|
}
|
|
15828
16103
|
} catch {
|
|
15829
16104
|
}
|
|
15830
|
-
const parent =
|
|
16105
|
+
const parent = path4.dirname(current);
|
|
15831
16106
|
if (parent === current) {
|
|
15832
16107
|
return void 0;
|
|
15833
16108
|
}
|
|
@@ -15835,7 +16110,7 @@ function findConfigFile(startDir) {
|
|
|
15835
16110
|
}
|
|
15836
16111
|
}
|
|
15837
16112
|
function cacheFilePath(cacheDir) {
|
|
15838
|
-
return
|
|
16113
|
+
return path4.join(cacheDir, "descriptors.json");
|
|
15839
16114
|
}
|
|
15840
16115
|
function readCache(cacheDir) {
|
|
15841
16116
|
try {
|
|
@@ -15960,7 +16235,7 @@ async function postEvent(options) {
|
|
|
15960
16235
|
error: error51 instanceof Error ? error51.message : String(error51)
|
|
15961
16236
|
};
|
|
15962
16237
|
}
|
|
15963
|
-
if (response.status >= 500) {
|
|
16238
|
+
if (response.status >= 500 || response.status === 429 || response.status === 408) {
|
|
15964
16239
|
return { kind: "unreachable", error: `server error (${response.status})` };
|
|
15965
16240
|
}
|
|
15966
16241
|
if (!response.ok) {
|
|
@@ -15988,13 +16263,14 @@ async function postEvent(options) {
|
|
|
15988
16263
|
}
|
|
15989
16264
|
var OUTBOX_FILE = "outbox.jsonl";
|
|
15990
16265
|
var MAX_OUTBOX_ENTRIES = 100;
|
|
16266
|
+
var STALE_CLAIM_MS = 30 * 60 * 1e3;
|
|
15991
16267
|
function outboxPath(env = process.env) {
|
|
15992
|
-
return
|
|
16268
|
+
return path5.join(feedbackHomeDir(env), OUTBOX_FILE);
|
|
15993
16269
|
}
|
|
15994
16270
|
function appendToOutbox(entry, env = process.env) {
|
|
15995
16271
|
try {
|
|
15996
16272
|
const file2 = outboxPath(env);
|
|
15997
|
-
mkdirSync2(
|
|
16273
|
+
mkdirSync2(path5.dirname(file2), { recursive: true });
|
|
15998
16274
|
appendFileSync(file2, `${JSON.stringify(entry)}
|
|
15999
16275
|
`);
|
|
16000
16276
|
return true;
|
|
@@ -16002,19 +16278,43 @@ function appendToOutbox(entry, env = process.env) {
|
|
|
16002
16278
|
return false;
|
|
16003
16279
|
}
|
|
16004
16280
|
}
|
|
16005
|
-
function
|
|
16281
|
+
function readEntries(file2) {
|
|
16282
|
+
try {
|
|
16283
|
+
return readFileSync3(file2, "utf8").split("\n").filter((line) => line.trim()).flatMap((line) => {
|
|
16284
|
+
try {
|
|
16285
|
+
return [JSON.parse(line)];
|
|
16286
|
+
} catch {
|
|
16287
|
+
return [];
|
|
16288
|
+
}
|
|
16289
|
+
});
|
|
16290
|
+
} catch {
|
|
16291
|
+
return [];
|
|
16292
|
+
}
|
|
16293
|
+
}
|
|
16294
|
+
function claimQueue(env) {
|
|
16295
|
+
const file2 = outboxPath(env);
|
|
16296
|
+
let names;
|
|
16006
16297
|
try {
|
|
16007
|
-
|
|
16298
|
+
names = readdirSync(path5.dirname(file2));
|
|
16008
16299
|
} catch {
|
|
16009
16300
|
return [];
|
|
16010
16301
|
}
|
|
16302
|
+
const claims = names.filter((name) => {
|
|
16303
|
+
const claimedAt = Number(/\.flushing-(\d+)-/.exec(name)?.[1]);
|
|
16304
|
+
return name.startsWith(OUTBOX_FILE) && Date.now() - claimedAt > STALE_CLAIM_MS;
|
|
16305
|
+
}).map((name) => path5.join(path5.dirname(file2), name));
|
|
16306
|
+
const fresh = `${file2}.flushing-${Date.now()}-${randomUUID()}`;
|
|
16307
|
+
try {
|
|
16308
|
+
renameSync(file2, fresh);
|
|
16309
|
+
claims.push(fresh);
|
|
16310
|
+
} catch {
|
|
16311
|
+
}
|
|
16312
|
+
return claims;
|
|
16011
16313
|
}
|
|
16012
16314
|
async function flushOutbox(options = {}) {
|
|
16013
16315
|
const env = options.env ?? process.env;
|
|
16014
|
-
const
|
|
16015
|
-
|
|
16016
|
-
return { delivered: 0, remaining: 0 };
|
|
16017
|
-
}
|
|
16316
|
+
const claims = claimQueue(env);
|
|
16317
|
+
const entries = claims.flatMap(readEntries).slice(-MAX_OUTBOX_ENTRIES);
|
|
16018
16318
|
const failures = [];
|
|
16019
16319
|
let delivered = 0;
|
|
16020
16320
|
for (const entry of entries) {
|
|
@@ -16031,12 +16331,13 @@ async function flushOutbox(options = {}) {
|
|
|
16031
16331
|
failures.push(entry);
|
|
16032
16332
|
}
|
|
16033
16333
|
}
|
|
16034
|
-
|
|
16035
|
-
|
|
16036
|
-
|
|
16037
|
-
|
|
16038
|
-
|
|
16039
|
-
|
|
16334
|
+
if (failures.every((entry) => appendToOutbox(entry, env))) {
|
|
16335
|
+
for (const claim of claims) {
|
|
16336
|
+
try {
|
|
16337
|
+
rmSync(claim, { force: true });
|
|
16338
|
+
} catch {
|
|
16339
|
+
}
|
|
16340
|
+
}
|
|
16040
16341
|
}
|
|
16041
16342
|
return { delivered, remaining: failures.length };
|
|
16042
16343
|
}
|
|
@@ -16056,10 +16357,10 @@ function ownerApi(options) {
|
|
|
16056
16357
|
const origin = (options.apiOrigin ?? new URL(DEFAULT_REGISTRY_URL).origin).replace(/\/$/, "");
|
|
16057
16358
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
16058
16359
|
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
16059
|
-
async function request(
|
|
16360
|
+
async function request(path6, init) {
|
|
16060
16361
|
let response;
|
|
16061
16362
|
try {
|
|
16062
|
-
response = await fetchImpl(`${origin}${
|
|
16363
|
+
response = await fetchImpl(`${origin}${path6}`, {
|
|
16063
16364
|
...init,
|
|
16064
16365
|
signal: AbortSignal.timeout(timeoutMs),
|
|
16065
16366
|
headers: {
|
|
@@ -16087,7 +16388,34 @@ function ownerApi(options) {
|
|
|
16087
16388
|
}
|
|
16088
16389
|
return body;
|
|
16089
16390
|
}
|
|
16391
|
+
async function upload(paths, cwd) {
|
|
16392
|
+
return uploadFiles({
|
|
16393
|
+
endpoint: origin,
|
|
16394
|
+
files: await readLocalAttachments(paths, cwd),
|
|
16395
|
+
secretKey: options.secretKey,
|
|
16396
|
+
fetchImpl,
|
|
16397
|
+
timeoutMs: Math.max(timeoutMs, 6e4)
|
|
16398
|
+
});
|
|
16399
|
+
}
|
|
16090
16400
|
return {
|
|
16401
|
+
/** Upload local files and attach them to a record (at most 10 files per record). */
|
|
16402
|
+
async attachFiles(target, paths, cwd) {
|
|
16403
|
+
if (!paths.length) throw new FeedbackError("Select at least one file.");
|
|
16404
|
+
const attachments = await upload(paths, cwd);
|
|
16405
|
+
return request("/v1/attachments/attach", {
|
|
16406
|
+
method: "POST",
|
|
16407
|
+
body: JSON.stringify({ target, attachments })
|
|
16408
|
+
});
|
|
16409
|
+
},
|
|
16410
|
+
/** A record's files; issues and evals include their reports' files. */
|
|
16411
|
+
async listAttachments(target, offset = 0) {
|
|
16412
|
+
return request(
|
|
16413
|
+
`/v1/attachments?${new URLSearchParams({ type: target.type, id: target.id, offset: String(offset) })}`
|
|
16414
|
+
);
|
|
16415
|
+
},
|
|
16416
|
+
async deleteAttachment(id) {
|
|
16417
|
+
return request(`/v1/attachments/${encodeURIComponent(id)}`, { method: "DELETE" });
|
|
16418
|
+
},
|
|
16091
16419
|
async listFeedback(filters = {}) {
|
|
16092
16420
|
const params = new URLSearchParams();
|
|
16093
16421
|
if (filters.status) params.set("status", filters.status);
|
|
@@ -16124,10 +16452,53 @@ function ownerApi(options) {
|
|
|
16124
16452
|
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16125
16453
|
});
|
|
16126
16454
|
},
|
|
16455
|
+
async listQuestions(filters = {}) {
|
|
16456
|
+
const query = filters.status ? `?status=${filters.status}` : "";
|
|
16457
|
+
return request(`/v1/questions${query}`);
|
|
16458
|
+
},
|
|
16459
|
+
/** Files are shared with every agent that receives the question. */
|
|
16460
|
+
async createQuestion(prompt, category, options2 = {}) {
|
|
16461
|
+
const attachments = options2.files?.length ? await upload(options2.files, options2.cwd) : [];
|
|
16462
|
+
return request("/v1/questions", {
|
|
16463
|
+
method: "POST",
|
|
16464
|
+
body: JSON.stringify({
|
|
16465
|
+
prompt,
|
|
16466
|
+
...category ? { category } : {},
|
|
16467
|
+
...attachments.length ? { attachments } : {},
|
|
16468
|
+
...options2.idempotencyKey ? { idempotencyKey: options2.idempotencyKey } : {}
|
|
16469
|
+
})
|
|
16470
|
+
});
|
|
16471
|
+
},
|
|
16472
|
+
async closeQuestion(id) {
|
|
16473
|
+
return request(`/v1/questions/${encodeURIComponent(id)}`, {
|
|
16474
|
+
method: "PATCH",
|
|
16475
|
+
body: JSON.stringify({ status: "closed" })
|
|
16476
|
+
});
|
|
16477
|
+
},
|
|
16478
|
+
async listEvals(filters = {}) {
|
|
16479
|
+
const query = filters.status ? `?status=${filters.status}` : "";
|
|
16480
|
+
return request(`/v1/evals${query}`);
|
|
16481
|
+
},
|
|
16482
|
+
async getEval(id) {
|
|
16483
|
+
return request(`/v1/evals/${encodeURIComponent(id)}`);
|
|
16484
|
+
},
|
|
16485
|
+
/** Promote a failed-task report (category=eval event) into the eval corpus. */
|
|
16486
|
+
async promoteEval(eventId) {
|
|
16487
|
+
return request("/v1/evals", {
|
|
16488
|
+
method: "POST",
|
|
16489
|
+
body: JSON.stringify({ event_id: eventId })
|
|
16490
|
+
});
|
|
16491
|
+
},
|
|
16492
|
+
async setEvalStatus(id, status, note) {
|
|
16493
|
+
return request(`/v1/evals/${encodeURIComponent(id)}`, {
|
|
16494
|
+
method: "PATCH",
|
|
16495
|
+
body: JSON.stringify({ status, ...note !== void 0 ? { note } : {} })
|
|
16496
|
+
});
|
|
16497
|
+
},
|
|
16127
16498
|
/** Attach an external link (Slack message, Linear/GitHub issue, PR) to evt_… or iss_…. */
|
|
16128
16499
|
async addLink(id, url2, label) {
|
|
16129
|
-
const
|
|
16130
|
-
return request(
|
|
16500
|
+
const path6 = id.startsWith("iss_") ? `/v1/issues/${id}` : `/v1/events/${id}`;
|
|
16501
|
+
return request(path6, {
|
|
16131
16502
|
method: "PATCH",
|
|
16132
16503
|
body: JSON.stringify({ addLink: { url: url2, ...label !== void 0 ? { label } : {} } })
|
|
16133
16504
|
});
|
|
@@ -16155,9 +16526,10 @@ function resolveThreadId(resume) {
|
|
|
16155
16526
|
}
|
|
16156
16527
|
return { id: generateThreadId(), resumed: false };
|
|
16157
16528
|
}
|
|
16158
|
-
async function
|
|
16529
|
+
async function prepareFeedback(options) {
|
|
16159
16530
|
const env = options.env ?? process.env;
|
|
16160
16531
|
const cwd = options.cwd ?? process.cwd();
|
|
16532
|
+
const files = await readLocalAttachments(options.attachments ?? [], cwd);
|
|
16161
16533
|
const config2 = findConfigFile(cwd)?.config;
|
|
16162
16534
|
const resolveOptions = {
|
|
16163
16535
|
...options.to !== void 0 ? { to: options.to } : {},
|
|
@@ -16193,6 +16565,7 @@ async function sendFeedback(options) {
|
|
|
16193
16565
|
...author ? { author } : {},
|
|
16194
16566
|
thread: { id: thread.id },
|
|
16195
16567
|
...options.eval ? { eval: options.eval } : {},
|
|
16568
|
+
...options.question ? { question: options.question } : {},
|
|
16196
16569
|
...context ? { context } : {},
|
|
16197
16570
|
...options.metadata && Object.keys(options.metadata).length > 0 ? { metadata: options.metadata } : {},
|
|
16198
16571
|
// Minted before the first attempt so outbox retries replay the SAME event
|
|
@@ -16208,7 +16581,32 @@ async function sendFeedback(options) {
|
|
|
16208
16581
|
if (!validated.ok) {
|
|
16209
16582
|
throw new FeedbackError(`Invalid feedback event: ${validated.errors.join("; ")}`);
|
|
16210
16583
|
}
|
|
16211
|
-
|
|
16584
|
+
return { event: validated.data, destination, resumed: thread.resumed, files };
|
|
16585
|
+
}
|
|
16586
|
+
async function sendFeedback(options) {
|
|
16587
|
+
const env = options.env ?? process.env;
|
|
16588
|
+
const { event, destination, resumed, files } = await prepareFeedback(options);
|
|
16589
|
+
const names = files.map((file2) => file2.manifest.filename);
|
|
16590
|
+
let filesNotAttached;
|
|
16591
|
+
if (files.length) {
|
|
16592
|
+
try {
|
|
16593
|
+
event.attachments = await uploadFiles({
|
|
16594
|
+
endpoint: destination.endpoint,
|
|
16595
|
+
files,
|
|
16596
|
+
...destination.to ? { to: destination.to } : {},
|
|
16597
|
+
...destination.writeKey ? { writeKey: destination.writeKey } : {},
|
|
16598
|
+
...event.context?.agent?.id ? { uploader: event.context.agent.id } : {},
|
|
16599
|
+
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}
|
|
16600
|
+
});
|
|
16601
|
+
} catch (error51) {
|
|
16602
|
+
if (!(error51 instanceof AttachmentUploadError) || error51.rejected) {
|
|
16603
|
+
throw new FeedbackError(
|
|
16604
|
+
`${error51 instanceof Error ? error51.message : String(error51)} Nothing was sent.`
|
|
16605
|
+
);
|
|
16606
|
+
}
|
|
16607
|
+
filesNotAttached = { files: names, reason: error51.message };
|
|
16608
|
+
}
|
|
16609
|
+
}
|
|
16212
16610
|
const result = await postEvent({
|
|
16213
16611
|
endpoint: destination.endpoint,
|
|
16214
16612
|
...destination.writeKey ? { writeKey: destination.writeKey } : {},
|
|
@@ -16222,12 +16620,17 @@ async function sendFeedback(options) {
|
|
|
16222
16620
|
response: result.response,
|
|
16223
16621
|
event,
|
|
16224
16622
|
destination,
|
|
16225
|
-
resumed
|
|
16623
|
+
resumed,
|
|
16624
|
+
...filesNotAttached ? { filesNotAttached } : {}
|
|
16226
16625
|
};
|
|
16227
16626
|
}
|
|
16228
16627
|
if (result.kind === "rejected") {
|
|
16229
16628
|
throw new FeedbackError(`Feedback rejected: ${result.errors.join("; ")}`);
|
|
16230
16629
|
}
|
|
16630
|
+
if (event.attachments) {
|
|
16631
|
+
delete event.attachments;
|
|
16632
|
+
filesNotAttached = { files: names, reason: result.error };
|
|
16633
|
+
}
|
|
16231
16634
|
const queued = options.outbox !== false && appendToOutbox(
|
|
16232
16635
|
{
|
|
16233
16636
|
endpoint: destination.endpoint,
|
|
@@ -16243,7 +16646,8 @@ async function sendFeedback(options) {
|
|
|
16243
16646
|
error: result.error,
|
|
16244
16647
|
event,
|
|
16245
16648
|
destination,
|
|
16246
|
-
resumed
|
|
16649
|
+
resumed,
|
|
16650
|
+
...filesNotAttached ? { filesNotAttached } : {}
|
|
16247
16651
|
};
|
|
16248
16652
|
}
|
|
16249
16653
|
export {
|
|
@@ -16256,6 +16660,8 @@ export {
|
|
|
16256
16660
|
FeedbackError,
|
|
16257
16661
|
HOME_ENV_VAR,
|
|
16258
16662
|
ISSUE_STATUSES,
|
|
16663
|
+
MAX_ATTACHMENTS,
|
|
16664
|
+
MAX_ATTACHMENT_BYTES,
|
|
16259
16665
|
MAX_FEEDBACK_LENGTH,
|
|
16260
16666
|
MAX_GUIDANCE_LENGTH,
|
|
16261
16667
|
MAX_SUBJECT_LENGTH,
|