copilotkit 4.9.50 → 4.10.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 +44 -4
- package/cli-build-info.json +7 -7
- package/index.js +1810 -354
- package/onboarding/index.json +81 -18
- package/onboarding/prompts/authenticate/start.md +56 -190
- package/onboarding/prompts/conversion/plan.md +3 -3
- package/onboarding/prompts/credentials/finalize-plan.md +25 -98
- package/onboarding/prompts/credentials/plan.md +20 -20
- package/onboarding/prompts/credentials/settle-credentials.md +153 -0
- package/onboarding/prompts/credentials/write-plan.md +93 -0
- package/onboarding/prompts/fallback/best-effort.md +12 -9
- package/onboarding/prompts/feature/a2ui/implement.md +35 -6
- package/onboarding/prompts/feature/a2ui/proof.md +30 -6
- package/onboarding/prompts/feature/a2ui/start.md +29 -6
- package/onboarding/prompts/feature/chat-suggestions/implement.md +36 -6
- package/onboarding/prompts/feature/chat-suggestions/proof.md +30 -5
- package/onboarding/prompts/feature/chat-suggestions/start.md +29 -6
- package/onboarding/prompts/feature/complete.md +11 -0
- package/onboarding/prompts/feature/learning/implement.md +102 -11
- package/onboarding/prompts/feature/learning/proof.md +53 -9
- package/onboarding/prompts/feature/learning/start.md +35 -8
- package/onboarding/prompts/feature/open-generative-ui/implement.md +37 -6
- package/onboarding/prompts/feature/open-generative-ui/proof.md +30 -5
- package/onboarding/prompts/feature/open-generative-ui/start.md +29 -6
- package/onboarding/prompts/feature/realtime-sync/implement.md +36 -7
- package/onboarding/prompts/feature/realtime-sync/proof.md +29 -5
- package/onboarding/prompts/feature/realtime-sync/start.md +28 -5
- package/onboarding/prompts/feature/rich-threads/implement.md +37 -8
- package/onboarding/prompts/feature/rich-threads/proof.md +31 -5
- package/onboarding/prompts/feature/rich-threads/start.md +28 -5
- package/onboarding/prompts/feature/stop.md +10 -7
- package/onboarding/prompts/feature/voice/implement.md +35 -6
- package/onboarding/prompts/feature/voice/proof.md +30 -5
- package/onboarding/prompts/feature/voice/start.md +29 -6
- package/onboarding/prompts/framework/ag2.md +2 -2
- package/onboarding/prompts/framework/agno.md +2 -2
- package/onboarding/prompts/framework/built-in.md +2 -2
- package/onboarding/prompts/framework/claude-sdk-python.md +2 -2
- package/onboarding/prompts/framework/claude-sdk-typescript.md +2 -2
- package/onboarding/prompts/framework/crewai-flows.md +2 -2
- package/onboarding/prompts/framework/deep-agents.md +2 -2
- package/onboarding/prompts/framework/google-adk.md +2 -2
- package/onboarding/prompts/framework/langgraph-fastapi.md +2 -2
- package/onboarding/prompts/framework/langgraph-python.md +2 -2
- package/onboarding/prompts/framework/langgraph-typescript.md +2 -2
- package/onboarding/prompts/framework/llamaindex.md +2 -2
- package/onboarding/prompts/framework/mastra.md +2 -2
- package/onboarding/prompts/framework/ms-agent-dotnet.md +2 -2
- package/onboarding/prompts/framework/ms-agent-harness-dotnet.md +2 -2
- package/onboarding/prompts/framework/ms-agent-python.md +2 -2
- package/onboarding/prompts/framework/pydantic-ai.md +2 -2
- package/onboarding/prompts/framework/strands-python.md +2 -2
- package/onboarding/prompts/framework/strands-typescript.md +2 -2
- package/onboarding/prompts/frontend/angular.md +3 -3
- package/onboarding/prompts/frontend/nextjs.md +3 -3
- package/onboarding/prompts/frontend/plan.md +6 -6
- package/onboarding/prompts/frontend/react-native.md +2 -2
- package/onboarding/prompts/frontend/react-spa.md +2 -2
- package/onboarding/prompts/frontend/vue.md +2 -2
- package/onboarding/prompts/implementation/build-and-validate.md +122 -12
- package/onboarding/prompts/proof/complete.md +23 -10
- package/onboarding/prompts/proof/oss-baseline.md +17 -7
- package/onboarding/prompts/proof/round-trip.md +33 -13
- package/onboarding/prompts/research/gather.md +121 -0
- package/onboarding/prompts/research/route.md +81 -0
- package/onboarding/prompts/starter/clone.md +18 -9
- package/onboarding/prompts/stopped/run-failed.md +44 -0
- package/onboarding/prompts/subagent/create-plan.md +32 -1
- package/onboarding/prompts/subagent/implement-and-validate.md +9 -1
- package/onboarding/prompts/subagent/prove-oss-baseline.md +1 -1
- package/onboarding/prompts/subagent/prove-round-trip.md +59 -12
- package/onboarding/prompts/unsupported/no-validated-path.md +10 -7
- package/package.json +1 -1
- package/release/release-tool.js +39 -3
package/index.js
CHANGED
|
@@ -96,14 +96,14 @@ function getTelemetryEndpointUrl() {
|
|
|
96
96
|
}
|
|
97
97
|
function getBuildInfo() {
|
|
98
98
|
return {
|
|
99
|
-
version: true ? "4.
|
|
100
|
-
buildNumber: true ? "
|
|
101
|
-
commitSha: true ? "
|
|
99
|
+
version: true ? "4.10.0" : "dev",
|
|
100
|
+
buildNumber: true ? "35011911410" : "dev",
|
|
101
|
+
commitSha: true ? "c8e38c8634104047e47545c1ed45a21c259a8658" : "dev",
|
|
102
102
|
copilotKitCommit: getTemplateRef()
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
function getTemplateRef() {
|
|
106
|
-
return true ? "
|
|
106
|
+
return true ? "ce490419d046abe697438b070a99ad5d674365cc" : "main";
|
|
107
107
|
}
|
|
108
108
|
function getC15tBackendUrl() {
|
|
109
109
|
return true ? "https://calm-hazelnut-joy-copilotkit.inth.app" : "";
|
|
@@ -1033,6 +1033,12 @@ function classifyError(err2, depth = 0) {
|
|
|
1033
1033
|
if (err2.name === "AbortError") {
|
|
1034
1034
|
return "timeout";
|
|
1035
1035
|
}
|
|
1036
|
+
const apiErrorCode = err2.code;
|
|
1037
|
+
if (apiErrorCode === "LEARNING_NOT_ENABLED")
|
|
1038
|
+
return "learning_not_enabled";
|
|
1039
|
+
if (apiErrorCode === "LEARNING_CONTAINER_NOT_FOUND") {
|
|
1040
|
+
return "learning_container_absent";
|
|
1041
|
+
}
|
|
1036
1042
|
const status = err2.status;
|
|
1037
1043
|
if (err2.name === "ApiClientError" && typeof status === "number") {
|
|
1038
1044
|
if (status === 401 || status === 403)
|
|
@@ -1070,7 +1076,7 @@ function classifyError(err2, depth = 0) {
|
|
|
1070
1076
|
return "validation";
|
|
1071
1077
|
if (code === "ONBOARDING_PROMPT_UNREADABLE")
|
|
1072
1078
|
return "filesystem";
|
|
1073
|
-
if (code === "CLI_PRODUCT_BINARY_TOO_LARGE" || code === "LEARNING_CANDIDATE_CONFLICT" || code === "LEARNING_CANDIDATE_SETTLED" || code === "LEARNING_CANDIDATE_ID_INVALID" || code === "LEARNING_CONTAINER_ID_INVALID" || code === "LEARNING_CONTAINER_INPUT_INVALID" || code === "
|
|
1079
|
+
if (code === "CLI_PRODUCT_BINARY_TOO_LARGE" || code === "LEARNING_CANDIDATE_CONFLICT" || code === "LEARNING_CANDIDATE_SETTLED" || code === "LEARNING_CANDIDATE_ID_INVALID" || code === "LEARNING_CONTAINER_ID_INVALID" || code === "LEARNING_CONTAINER_INPUT_INVALID" || code === "LEARNING_CONTAINER_RESPONSE_INVALID" || code === "LEARNING_PROJECT_ID_INVALID" || code === "LEARNING_RESPONSE_INVALID" || code === "LEARNING_SKILLS_BUNDLE_INVALID" || code === "LEARNING_SKILLS_INTEGRITY_FAILED" || code === "LEARNING_SKILLS_OUTPUT_EXISTS") {
|
|
1074
1080
|
return "validation";
|
|
1075
1081
|
}
|
|
1076
1082
|
if (code === "KEY_PROVISION_FAILED")
|
|
@@ -28858,6 +28864,29 @@ function recordServedPrompt(dependencies, runId, promptName) {
|
|
|
28858
28864
|
route: [...previous, promptName]
|
|
28859
28865
|
});
|
|
28860
28866
|
}
|
|
28867
|
+
function markRunEnded(dependencies, runId) {
|
|
28868
|
+
const key = stateKey("route", resolveAnchoredRoot(dependencies));
|
|
28869
|
+
const stored = readStoredRoute(dependencies.store, key);
|
|
28870
|
+
if (stored === void 0 || stored.runId !== runId)
|
|
28871
|
+
return;
|
|
28872
|
+
dependencies.store.set(key, { ...stored, ended: true });
|
|
28873
|
+
}
|
|
28874
|
+
function readAbandonedRun(dependencies, currentRunId) {
|
|
28875
|
+
const stored = readStoredRoute(
|
|
28876
|
+
dependencies.store,
|
|
28877
|
+
stateKey("route", resolveAnchoredRoot(dependencies))
|
|
28878
|
+
);
|
|
28879
|
+
if (stored === void 0)
|
|
28880
|
+
return void 0;
|
|
28881
|
+
if (stored.runId === currentRunId)
|
|
28882
|
+
return void 0;
|
|
28883
|
+
if (stored.ended === true)
|
|
28884
|
+
return void 0;
|
|
28885
|
+
const lastPrompt = stored.route[stored.route.length - 1];
|
|
28886
|
+
if (lastPrompt === void 0)
|
|
28887
|
+
return void 0;
|
|
28888
|
+
return { runId: stored.runId, lastPrompt, steps: stored.route.length };
|
|
28889
|
+
}
|
|
28861
28890
|
function readOnboardingRoute(dependencies) {
|
|
28862
28891
|
const root2 = resolveAnchoredRoot(dependencies);
|
|
28863
28892
|
const stored = readStoredRoute(dependencies.store, stateKey("route", root2));
|
|
@@ -28868,6 +28897,57 @@ function readOnboardingRoute(dependencies) {
|
|
|
28868
28897
|
return [];
|
|
28869
28898
|
return stored.route;
|
|
28870
28899
|
}
|
|
28900
|
+
function readStoredProofs(store, key) {
|
|
28901
|
+
const stored = store.get(key);
|
|
28902
|
+
if (typeof stored !== "object" || stored === null)
|
|
28903
|
+
return void 0;
|
|
28904
|
+
if (typeof stored.runId !== "string")
|
|
28905
|
+
return void 0;
|
|
28906
|
+
return typeof stored.proofs === "object" && stored.proofs !== null ? stored : void 0;
|
|
28907
|
+
}
|
|
28908
|
+
function recordProofOutcome(dependencies, runId, step, proof) {
|
|
28909
|
+
const key = stateKey("proof", resolveAnchoredRoot(dependencies));
|
|
28910
|
+
const stored = readStoredProofs(dependencies.store, key);
|
|
28911
|
+
const previous = stored?.runId === runId ? stored.proofs : {};
|
|
28912
|
+
dependencies.store.set(key, {
|
|
28913
|
+
runId,
|
|
28914
|
+
proofs: { ...previous, [step]: proof }
|
|
28915
|
+
});
|
|
28916
|
+
}
|
|
28917
|
+
function readProofOutcome(dependencies, step) {
|
|
28918
|
+
const root2 = resolveAnchoredRoot(dependencies);
|
|
28919
|
+
const stored = readStoredProofs(dependencies.store, stateKey("proof", root2));
|
|
28920
|
+
if (stored === void 0)
|
|
28921
|
+
return void 0;
|
|
28922
|
+
const bound = readBoundRun(dependencies.store, root2);
|
|
28923
|
+
if (bound.state === "live" && bound.runId !== stored.runId)
|
|
28924
|
+
return void 0;
|
|
28925
|
+
return stored.proofs[step];
|
|
28926
|
+
}
|
|
28927
|
+
function readStoredCodingAgent(store, key) {
|
|
28928
|
+
const stored = store.get(key);
|
|
28929
|
+
if (typeof stored !== "object" || stored === null)
|
|
28930
|
+
return void 0;
|
|
28931
|
+
if (typeof stored.runId !== "string")
|
|
28932
|
+
return void 0;
|
|
28933
|
+
return typeof stored.codingAgent === "string" ? stored : void 0;
|
|
28934
|
+
}
|
|
28935
|
+
function recordCodingAgent(dependencies, runId, codingAgent) {
|
|
28936
|
+
dependencies.store.set(stateKey("agent", resolveAnchoredRoot(dependencies)), {
|
|
28937
|
+
codingAgent: normalizeCodingAgent(codingAgent),
|
|
28938
|
+
runId
|
|
28939
|
+
});
|
|
28940
|
+
}
|
|
28941
|
+
function readCodingAgent(dependencies) {
|
|
28942
|
+
const root2 = resolveAnchoredRoot(dependencies);
|
|
28943
|
+
const stored = readStoredCodingAgent(dependencies.store, stateKey("agent", root2));
|
|
28944
|
+
if (stored === void 0)
|
|
28945
|
+
return void 0;
|
|
28946
|
+
const bound = readBoundRun(dependencies.store, root2);
|
|
28947
|
+
if (bound.state === "live" && bound.runId !== stored.runId)
|
|
28948
|
+
return void 0;
|
|
28949
|
+
return stored.codingAgent;
|
|
28950
|
+
}
|
|
28871
28951
|
function readOnboardingRunId(dependencies) {
|
|
28872
28952
|
try {
|
|
28873
28953
|
const bound = readBoundRun(
|
|
@@ -28890,21 +28970,6 @@ function readOnboardingIntent(dependencies) {
|
|
|
28890
28970
|
return void 0;
|
|
28891
28971
|
}
|
|
28892
28972
|
}
|
|
28893
|
-
function resolveOnboardingRun(dependencies) {
|
|
28894
|
-
const root2 = resolveAnchoredRoot(dependencies);
|
|
28895
|
-
const bound = readBoundRun(dependencies.store, root2);
|
|
28896
|
-
if (bound.state === "live") {
|
|
28897
|
-
return {
|
|
28898
|
-
runId: bound.runId,
|
|
28899
|
-
started: false,
|
|
28900
|
-
idOrigin: "minted",
|
|
28901
|
-
...bound.intent === void 0 ? {} : { intent: bound.intent }
|
|
28902
|
-
};
|
|
28903
|
-
}
|
|
28904
|
-
const generatedRun = mintRunId(dependencies);
|
|
28905
|
-
dependencies.store.set(stateKey("run", root2), generatedRun);
|
|
28906
|
-
return { runId: generatedRun, started: true, idOrigin: "minted" };
|
|
28907
|
-
}
|
|
28908
28973
|
function startOnboardingRun(dependencies, requestedRunId, requestedIntent) {
|
|
28909
28974
|
if (requestedIntent !== void 0 && !ONBOARDING_INTENT_PATTERN.test(requestedIntent)) {
|
|
28910
28975
|
throw new Error("Requested onboarding intent is invalid");
|
|
@@ -29761,7 +29826,7 @@ var require_redact = __commonJS({
|
|
|
29761
29826
|
} = options;
|
|
29762
29827
|
validatePaths(paths);
|
|
29763
29828
|
const pathStructure = buildPathStructure(paths);
|
|
29764
|
-
return function
|
|
29829
|
+
return function redact2(obj) {
|
|
29765
29830
|
if (strict2 && (obj === null || typeof obj !== "object")) {
|
|
29766
29831
|
if (obj === null || obj === void 0) {
|
|
29767
29832
|
return serialize3 ? serialize3(obj) : obj;
|
|
@@ -33238,7 +33303,7 @@ var require_pino = __commonJS({
|
|
|
33238
33303
|
if (opts.level && typeof opts.level === "string" && DEFAULT_LEVELS[opts.level.toLowerCase()] !== void 0)
|
|
33239
33304
|
opts.level = opts.level.toLowerCase();
|
|
33240
33305
|
const {
|
|
33241
|
-
redact,
|
|
33306
|
+
redact: redact2,
|
|
33242
33307
|
crlf,
|
|
33243
33308
|
serializers: serializers2,
|
|
33244
33309
|
timestamp: timestamp2,
|
|
@@ -33272,8 +33337,8 @@ var require_pino = __commonJS({
|
|
|
33272
33337
|
const stringifyFn = stringify4.bind({
|
|
33273
33338
|
[stringifySafeSym]: stringifySafe
|
|
33274
33339
|
});
|
|
33275
|
-
const stringifiers =
|
|
33276
|
-
const formatOpts =
|
|
33340
|
+
const stringifiers = redact2 ? redaction(redact2, stringifyFn) : {};
|
|
33341
|
+
const formatOpts = redact2 ? { stringify: stringifiers[redactFmtSym] } : { stringify: stringifyFn };
|
|
33277
33342
|
const end = "}" + (crlf ? "\r\n" : "\n");
|
|
33278
33343
|
const coreChindings = asChindings.bind(null, {
|
|
33279
33344
|
[chindingsSym]: "",
|
|
@@ -91416,6 +91481,19 @@ function describeCredentialWriteDirectory(dir, ceilingDir) {
|
|
|
91416
91481
|
return `Wrote the project key to ${envPath}. ${subject} ${named} ${verb} env files from its own directory, so re-run \`copilotkit project select\` from ${target} to put the key where the app process reads it.
|
|
91417
91482
|
`;
|
|
91418
91483
|
}
|
|
91484
|
+
function envFileLoaderDeclaredIn(appDir, ceiling) {
|
|
91485
|
+
const filesystemRoot = path11.parse(appDir).root;
|
|
91486
|
+
let candidate = appDir;
|
|
91487
|
+
while (true) {
|
|
91488
|
+
if (readAppManifest(candidate)?.declaresEnvFileLoader === true) {
|
|
91489
|
+
return candidate;
|
|
91490
|
+
}
|
|
91491
|
+
if (candidate === ceiling || candidate === filesystemRoot) {
|
|
91492
|
+
return void 0;
|
|
91493
|
+
}
|
|
91494
|
+
candidate = path11.dirname(candidate);
|
|
91495
|
+
}
|
|
91496
|
+
}
|
|
91419
91497
|
function resolveCredentialLoad(inputs) {
|
|
91420
91498
|
if (inputs.variableName === void 0) {
|
|
91421
91499
|
return { kind: "no-key" };
|
|
@@ -91428,8 +91506,12 @@ function resolveCredentialLoad(inputs) {
|
|
|
91428
91506
|
return { apps: apps2, kind: "ambiguous" };
|
|
91429
91507
|
}
|
|
91430
91508
|
const appDir = apps2[0];
|
|
91431
|
-
|
|
91432
|
-
|
|
91509
|
+
const declaredIn = envFileLoaderDeclaredIn(
|
|
91510
|
+
appDir,
|
|
91511
|
+
canonicalizeDir(inputs.ceiling)
|
|
91512
|
+
);
|
|
91513
|
+
if (declaredIn !== void 0) {
|
|
91514
|
+
return { appDir, declaredIn, kind: "loader-declared" };
|
|
91433
91515
|
}
|
|
91434
91516
|
if (inputs.source === void 0) {
|
|
91435
91517
|
return { appDir, kind: "process-environment" };
|
|
@@ -91648,7 +91730,7 @@ function formatTelemetryNotice(privacyPolicyUrl) {
|
|
|
91648
91730
|
return [
|
|
91649
91731
|
"The CopilotKit CLI collects usage data to help improve the product.",
|
|
91650
91732
|
"While you are signed in, that data is linked to your CopilotKit account.",
|
|
91651
|
-
"The onboarding
|
|
91733
|
+
"The onboarding friction command sends up to 2,048 UTF-8 bytes of text.",
|
|
91652
91734
|
"",
|
|
91653
91735
|
" Disable anytime: copilotkit telemetry disable (or set DO_NOT_TRACK=1)",
|
|
91654
91736
|
` Privacy policy: ${privacyPolicyUrl}`,
|
|
@@ -91695,6 +91777,15 @@ function createTelemetryService(deps) {
|
|
|
91695
91777
|
return typeof deps.installationId === "function" ? deps.installationId() : deps.installationId;
|
|
91696
91778
|
}
|
|
91697
91779
|
async function sendOne(prepared) {
|
|
91780
|
+
if (prepared.installationId === "") {
|
|
91781
|
+
deps.logger.error({
|
|
91782
|
+
msg: "telemetry.dropped.no_identity",
|
|
91783
|
+
event: prepared.body.event,
|
|
91784
|
+
outcome: prepared.outcome,
|
|
91785
|
+
command: prepared.command
|
|
91786
|
+
});
|
|
91787
|
+
return { status: "no_identity" };
|
|
91788
|
+
}
|
|
91698
91789
|
const controller = new AbortController();
|
|
91699
91790
|
const timer = setTimeout(() => controller.abort(), perRequestTimeoutMs);
|
|
91700
91791
|
timer.unref?.();
|
|
@@ -91710,33 +91801,38 @@ function createTelemetryService(deps) {
|
|
|
91710
91801
|
signal: controller.signal
|
|
91711
91802
|
});
|
|
91712
91803
|
if (!res.ok) {
|
|
91804
|
+
const latencyMs = Date.now() - started;
|
|
91713
91805
|
deps.logger.warn({
|
|
91714
91806
|
msg: "telemetry.sink.failed",
|
|
91807
|
+
event: prepared.body.event,
|
|
91715
91808
|
status: res.status,
|
|
91716
|
-
latency_ms:
|
|
91809
|
+
latency_ms: latencyMs,
|
|
91717
91810
|
outcome: prepared.outcome,
|
|
91718
91811
|
command: prepared.command
|
|
91719
91812
|
});
|
|
91720
|
-
return
|
|
91813
|
+
return { status: "http_error", httpStatus: res.status, latencyMs };
|
|
91721
91814
|
}
|
|
91722
91815
|
deps.logger.debug({
|
|
91723
91816
|
msg: "telemetry.sink.succeeded",
|
|
91817
|
+
event: prepared.body.event,
|
|
91724
91818
|
status: res.status,
|
|
91725
91819
|
latency_ms: Date.now() - started,
|
|
91726
91820
|
outcome: prepared.outcome,
|
|
91727
91821
|
command: prepared.command
|
|
91728
91822
|
});
|
|
91729
|
-
return
|
|
91823
|
+
return { status: "sent" };
|
|
91730
91824
|
} catch (err2) {
|
|
91731
91825
|
const isAbort = err2 instanceof Error && err2.name === "AbortError";
|
|
91826
|
+
const latencyMs = Date.now() - started;
|
|
91732
91827
|
deps.logger.warn({
|
|
91733
91828
|
msg: "telemetry.sink.failed",
|
|
91734
|
-
|
|
91829
|
+
event: prepared.body.event,
|
|
91830
|
+
latency_ms: latencyMs,
|
|
91735
91831
|
outcome: prepared.outcome,
|
|
91736
91832
|
command: prepared.command,
|
|
91737
91833
|
error_code: isAbort ? "timeout" : "network"
|
|
91738
91834
|
});
|
|
91739
|
-
return
|
|
91835
|
+
return isAbort ? { status: "timeout", timeoutMs: perRequestTimeoutMs, latencyMs } : { status: "network", latencyMs };
|
|
91740
91836
|
} finally {
|
|
91741
91837
|
clearTimeout(timer);
|
|
91742
91838
|
}
|
|
@@ -91763,6 +91859,7 @@ function createTelemetryService(deps) {
|
|
|
91763
91859
|
if (inFlight.size >= maxInFlight) {
|
|
91764
91860
|
deps.logger.error({
|
|
91765
91861
|
msg: "telemetry.dropped.queue_full",
|
|
91862
|
+
event: event.event ?? CLI_TELEMETRY_EVENT_NAME,
|
|
91766
91863
|
outcome: event.properties.outcome,
|
|
91767
91864
|
command: event.properties.command
|
|
91768
91865
|
});
|
|
@@ -91778,8 +91875,17 @@ function createTelemetryService(deps) {
|
|
|
91778
91875
|
});
|
|
91779
91876
|
}
|
|
91780
91877
|
async function submitEvent(event) {
|
|
91781
|
-
if (!deps.enabled
|
|
91782
|
-
return
|
|
91878
|
+
if (!deps.enabled)
|
|
91879
|
+
return { status: "disabled" };
|
|
91880
|
+
if (inFlight.size >= maxInFlight) {
|
|
91881
|
+
deps.logger.error({
|
|
91882
|
+
msg: "telemetry.dropped.queue_full",
|
|
91883
|
+
event: event.event ?? CLI_TELEMETRY_EVENT_NAME,
|
|
91884
|
+
outcome: event.properties.outcome,
|
|
91885
|
+
command: event.properties.command
|
|
91886
|
+
});
|
|
91887
|
+
return { status: "queue_full", inFlight: inFlight.size };
|
|
91888
|
+
}
|
|
91783
91889
|
const promise3 = (async () => {
|
|
91784
91890
|
await new Promise((resolve9) => setImmediate(resolve9));
|
|
91785
91891
|
return await sendOne(prepareEvent(event));
|
|
@@ -91821,8 +91927,10 @@ __export(telemetry_exports, {
|
|
|
91821
91927
|
cliLogTelemetryLogger: () => cliLogTelemetryLogger,
|
|
91822
91928
|
currentAuthIdentity: () => currentAuthIdentity,
|
|
91823
91929
|
currentCliStateProperties: () => currentCliStateProperties,
|
|
91930
|
+
currentOnboardingCodingAgent: () => currentOnboardingCodingAgent,
|
|
91824
91931
|
currentOnboardingRunProperties: () => currentOnboardingRunProperties,
|
|
91825
91932
|
currentProjectIdentity: () => currentProjectIdentity,
|
|
91933
|
+
describeSubmissionError: () => describeSubmissionError,
|
|
91826
91934
|
exitWithFlush: () => exitWithFlush,
|
|
91827
91935
|
flushTelemetry: () => flushTelemetry,
|
|
91828
91936
|
getCliConsentProvider: () => getCliConsentProvider,
|
|
@@ -91831,6 +91939,7 @@ __export(telemetry_exports, {
|
|
|
91831
91939
|
hasStandaloneTelemetryIdentityConsent: () => hasStandaloneTelemetryIdentityConsent,
|
|
91832
91940
|
linkConsentSubjectToUser: () => linkConsentSubjectToUser,
|
|
91833
91941
|
recordTelemetryEvent: () => recordTelemetryEvent,
|
|
91942
|
+
resolveReturnedOutcome: () => resolveReturnedOutcome,
|
|
91834
91943
|
submitTelemetryEvent: () => submitTelemetryEvent,
|
|
91835
91944
|
withTelemetry: () => withTelemetry
|
|
91836
91945
|
});
|
|
@@ -91906,6 +92015,9 @@ function currentOnboardingRunProperties() {
|
|
|
91906
92015
|
});
|
|
91907
92016
|
return runId === void 0 ? {} : { onboarding_run_id: runId };
|
|
91908
92017
|
}
|
|
92018
|
+
function currentOnboardingCodingAgent() {
|
|
92019
|
+
return readCodingAgent({ cwd: process.cwd(), store: configStore });
|
|
92020
|
+
}
|
|
91909
92021
|
function currentAuthIdentity() {
|
|
91910
92022
|
return resolveAuthIdentityProperties({
|
|
91911
92023
|
readStoredAuth: () => authStore.get()
|
|
@@ -91956,8 +92068,54 @@ async function submitTelemetryEvent(event) {
|
|
|
91956
92068
|
noticeShown: hasShownTelemetryNotice(configStore)
|
|
91957
92069
|
});
|
|
91958
92070
|
if (!gate.send)
|
|
91959
|
-
return
|
|
91960
|
-
|
|
92071
|
+
return { status: "declined" };
|
|
92072
|
+
try {
|
|
92073
|
+
const delivery = await getTelemetry().submitEvent(
|
|
92074
|
+
withProjectIdentity(event)
|
|
92075
|
+
);
|
|
92076
|
+
return describeDelivery(delivery);
|
|
92077
|
+
} catch (error98) {
|
|
92078
|
+
return { status: "failed", detail: describeSubmissionError(error98) };
|
|
92079
|
+
}
|
|
92080
|
+
}
|
|
92081
|
+
function describeDelivery(delivery) {
|
|
92082
|
+
switch (delivery.status) {
|
|
92083
|
+
case "sent":
|
|
92084
|
+
return { status: "sent" };
|
|
92085
|
+
case "disabled":
|
|
92086
|
+
return { status: "declined" };
|
|
92087
|
+
case "no_identity":
|
|
92088
|
+
return {
|
|
92089
|
+
status: "failed",
|
|
92090
|
+
detail: "this install has no telemetry id, so nothing was sent"
|
|
92091
|
+
};
|
|
92092
|
+
case "queue_full":
|
|
92093
|
+
return {
|
|
92094
|
+
status: "failed",
|
|
92095
|
+
detail: `the send queue was full at ${delivery.inFlight} requests, so nothing was sent`
|
|
92096
|
+
};
|
|
92097
|
+
case "http_error":
|
|
92098
|
+
return {
|
|
92099
|
+
status: "failed",
|
|
92100
|
+
detail: `the sink refused the event with HTTP ${delivery.httpStatus}`
|
|
92101
|
+
};
|
|
92102
|
+
case "timeout":
|
|
92103
|
+
return {
|
|
92104
|
+
status: "failed",
|
|
92105
|
+
detail: `the send timed out after ${delivery.timeoutMs}ms`
|
|
92106
|
+
};
|
|
92107
|
+
case "network":
|
|
92108
|
+
return {
|
|
92109
|
+
status: "failed",
|
|
92110
|
+
detail: "the network request failed before the sink answered"
|
|
92111
|
+
};
|
|
92112
|
+
}
|
|
92113
|
+
}
|
|
92114
|
+
function describeSubmissionError(error98) {
|
|
92115
|
+
if (error98 instanceof Error && error98.message !== "")
|
|
92116
|
+
return error98.message;
|
|
92117
|
+
const described = String(error98);
|
|
92118
|
+
return described === "" ? "the telemetry transport threw" : described;
|
|
91961
92119
|
}
|
|
91962
92120
|
async function flushTelemetry(timeoutMs = DEFAULT_FLUSH_TIMEOUT_MS) {
|
|
91963
92121
|
if (!instance)
|
|
@@ -91968,6 +92126,17 @@ async function exitWithFlush(code) {
|
|
|
91968
92126
|
await flushTelemetry();
|
|
91969
92127
|
process.exit(code);
|
|
91970
92128
|
}
|
|
92129
|
+
function resolveReturnedOutcome(input) {
|
|
92130
|
+
if (input.declaredFailure !== null) {
|
|
92131
|
+
return {
|
|
92132
|
+
outcome: "failed",
|
|
92133
|
+
...input.declaredFailure.errorCode === void 0 ? {} : { errorCode: input.declaredFailure.errorCode }
|
|
92134
|
+
};
|
|
92135
|
+
}
|
|
92136
|
+
const { exitCode } = input;
|
|
92137
|
+
const failedByExit = exitCode !== void 0 && exitCode !== 0 && exitCode !== "0";
|
|
92138
|
+
return failedByExit ? { outcome: "failed" } : { outcome: "succeeded" };
|
|
92139
|
+
}
|
|
91971
92140
|
async function withTelemetry(base, fn) {
|
|
91972
92141
|
const buildInfo = getBuildInfo();
|
|
91973
92142
|
const provider = getConsentProvider();
|
|
@@ -91988,9 +92157,13 @@ async function withTelemetry(base, fn) {
|
|
|
91988
92157
|
}
|
|
91989
92158
|
const startedAt = Date.now();
|
|
91990
92159
|
let extra = {};
|
|
92160
|
+
let declaredFailure = null;
|
|
91991
92161
|
const ctx = {
|
|
91992
92162
|
setProperties(next) {
|
|
91993
92163
|
extra = { ...extra, ...next };
|
|
92164
|
+
},
|
|
92165
|
+
reportFailure(input) {
|
|
92166
|
+
declaredFailure = input ?? {};
|
|
91994
92167
|
}
|
|
91995
92168
|
};
|
|
91996
92169
|
recordTelemetryEvent({
|
|
@@ -92003,14 +92176,19 @@ async function withTelemetry(base, fn) {
|
|
|
92003
92176
|
});
|
|
92004
92177
|
try {
|
|
92005
92178
|
const result = await fn(ctx);
|
|
92179
|
+
const verdict = resolveReturnedOutcome({
|
|
92180
|
+
declaredFailure,
|
|
92181
|
+
exitCode: process.exitCode
|
|
92182
|
+
});
|
|
92006
92183
|
recordTelemetryEvent({
|
|
92007
92184
|
properties: {
|
|
92008
92185
|
...base,
|
|
92009
92186
|
...currentCliStateProperties(base.command),
|
|
92010
92187
|
...currentOnboardingRunProperties(),
|
|
92011
92188
|
...extra,
|
|
92012
|
-
outcome:
|
|
92013
|
-
duration_ms: Date.now() - startedAt
|
|
92189
|
+
outcome: verdict.outcome,
|
|
92190
|
+
duration_ms: Date.now() - startedAt,
|
|
92191
|
+
...verdict.errorCode === void 0 ? {} : { error_code: verdict.errorCode }
|
|
92014
92192
|
}
|
|
92015
92193
|
});
|
|
92016
92194
|
return result;
|
|
@@ -93755,6 +93933,9 @@ async function login(options = {}) {
|
|
|
93755
93933
|
if (options.authHandoff) {
|
|
93756
93934
|
loginParams.set("source", options.authHandoff.source);
|
|
93757
93935
|
loginParams.set("mode", options.authHandoff.mode);
|
|
93936
|
+
if (options.authHandoff.agent !== void 0) {
|
|
93937
|
+
loginParams.set("agent", options.authHandoff.agent);
|
|
93938
|
+
}
|
|
93758
93939
|
}
|
|
93759
93940
|
const loginUrl = `${getOpsFrontendUrl()}/cli-auth?${loginParams.toString()}`;
|
|
93760
93941
|
diagnostics.logPhase("login.browser-url-prepared", {
|
|
@@ -94804,13 +94985,25 @@ import * as fs18 from "node:fs";
|
|
|
94804
94985
|
import * as path14 from "node:path";
|
|
94805
94986
|
import * as os7 from "node:os";
|
|
94806
94987
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
94988
|
+
function isCredentialEnvFile(entry) {
|
|
94989
|
+
if (!entry.startsWith(".env"))
|
|
94990
|
+
return false;
|
|
94991
|
+
if (ENV_TEMPLATE_SUFFIXES.some((suffix) => entry.endsWith(suffix)))
|
|
94992
|
+
return false;
|
|
94993
|
+
return entry === ".env" || entry.startsWith(".env.");
|
|
94994
|
+
}
|
|
94995
|
+
function entryHoldsProject(entry) {
|
|
94996
|
+
if (isCredentialEnvFile(entry))
|
|
94997
|
+
return true;
|
|
94998
|
+
return PROJECT_DIRECTORY_NAMES.has(entry) || PROJECT_MANIFEST_NAMES.has(entry);
|
|
94999
|
+
}
|
|
94807
95000
|
function isProjectDirOccupied(projectDir) {
|
|
94808
|
-
return fs18.existsSync(projectDir) && fs18.readdirSync(projectDir).
|
|
95001
|
+
return fs18.existsSync(projectDir) && fs18.readdirSync(projectDir).some(entryHoldsProject);
|
|
94809
95002
|
}
|
|
94810
95003
|
function assertProjectDirAvailable(projectDir) {
|
|
94811
95004
|
if (isProjectDirOccupied(projectDir)) {
|
|
94812
95005
|
throw tagError(
|
|
94813
|
-
new Error(`${projectDir} already
|
|
95006
|
+
new Error(`${projectDir} already holds a project`),
|
|
94814
95007
|
TELEMETRY_ERROR_CODES.PREREQUISITE_MISSING
|
|
94815
95008
|
);
|
|
94816
95009
|
}
|
|
@@ -95060,12 +95253,36 @@ async function initializeProjectGit(projectDir) {
|
|
|
95060
95253
|
}
|
|
95061
95254
|
return { kind: "initialized" };
|
|
95062
95255
|
}
|
|
95063
|
-
var TEST_HARNESS_ARTIFACTS, LICENSE_TOKEN_LINE_RE;
|
|
95256
|
+
var PROJECT_DIRECTORY_NAMES, PROJECT_MANIFEST_NAMES, ENV_TEMPLATE_SUFFIXES, TEST_HARNESS_ARTIFACTS, LICENSE_TOKEN_LINE_RE;
|
|
95064
95257
|
var init_project_scaffold = __esm({
|
|
95065
95258
|
"apps/cli/src/services/project-scaffold.ts"() {
|
|
95066
95259
|
"use strict";
|
|
95067
95260
|
init_repository_root();
|
|
95068
95261
|
init_event_properties();
|
|
95262
|
+
PROJECT_DIRECTORY_NAMES = /* @__PURE__ */ new Set([
|
|
95263
|
+
"agent",
|
|
95264
|
+
"api",
|
|
95265
|
+
"app",
|
|
95266
|
+
"components",
|
|
95267
|
+
"lib",
|
|
95268
|
+
"packages",
|
|
95269
|
+
"pages",
|
|
95270
|
+
"server",
|
|
95271
|
+
"src",
|
|
95272
|
+
"web"
|
|
95273
|
+
]);
|
|
95274
|
+
PROJECT_MANIFEST_NAMES = /* @__PURE__ */ new Set([
|
|
95275
|
+
"Cargo.toml",
|
|
95276
|
+
"Gemfile",
|
|
95277
|
+
"build.gradle",
|
|
95278
|
+
"composer.json",
|
|
95279
|
+
"go.mod",
|
|
95280
|
+
"package.json",
|
|
95281
|
+
"pom.xml",
|
|
95282
|
+
"pyproject.toml",
|
|
95283
|
+
"requirements.txt"
|
|
95284
|
+
]);
|
|
95285
|
+
ENV_TEMPLATE_SUFFIXES = [".example", ".sample", ".template"];
|
|
95069
95286
|
TEST_HARNESS_ARTIFACTS = [
|
|
95070
95287
|
"docker",
|
|
95071
95288
|
".dockerignore",
|
|
@@ -95890,6 +96107,27 @@ var init_project_list = __esm({
|
|
|
95890
96107
|
});
|
|
95891
96108
|
|
|
95892
96109
|
// apps/cli/src/services/hosted-project-name.ts
|
|
96110
|
+
function suggestFreeProjectName(raw2, existing) {
|
|
96111
|
+
const name = raw2.trim();
|
|
96112
|
+
const taken = new Set(
|
|
96113
|
+
existing.map((project) => project.name.trim().toLowerCase())
|
|
96114
|
+
);
|
|
96115
|
+
if (!taken.has(name.toLowerCase())) {
|
|
96116
|
+
return name;
|
|
96117
|
+
}
|
|
96118
|
+
const stripped = name.replace(NUMERIC_SUFFIX, "");
|
|
96119
|
+
const base = stripped === "" ? name : stripped;
|
|
96120
|
+
let candidate = base;
|
|
96121
|
+
for (let counter = 2; counter < SUGGESTION_ATTEMPTS + 2; counter += 1) {
|
|
96122
|
+
const suffix = `-${String(counter)}`;
|
|
96123
|
+
const room = MAX_PROJECT_NAME_LENGTH - suffix.length;
|
|
96124
|
+
candidate = `${base.slice(0, room)}${suffix}`;
|
|
96125
|
+
if (!taken.has(candidate.toLowerCase())) {
|
|
96126
|
+
return candidate;
|
|
96127
|
+
}
|
|
96128
|
+
}
|
|
96129
|
+
return candidate;
|
|
96130
|
+
}
|
|
95893
96131
|
function validateProjectName(raw2, existing) {
|
|
95894
96132
|
const name = raw2.trim();
|
|
95895
96133
|
if (name === "") {
|
|
@@ -95914,16 +96152,19 @@ function validateProjectName(raw2, existing) {
|
|
|
95914
96152
|
ok: false,
|
|
95915
96153
|
reason: "duplicate",
|
|
95916
96154
|
message: `You already have a project named "${duplicate.name}".`,
|
|
95917
|
-
duplicate
|
|
96155
|
+
duplicate,
|
|
96156
|
+
suggestion: suggestFreeProjectName(name, existing)
|
|
95918
96157
|
};
|
|
95919
96158
|
}
|
|
95920
96159
|
return { ok: true, name };
|
|
95921
96160
|
}
|
|
95922
|
-
var MAX_PROJECT_NAME_LENGTH;
|
|
96161
|
+
var MAX_PROJECT_NAME_LENGTH, NUMERIC_SUFFIX, SUGGESTION_ATTEMPTS;
|
|
95923
96162
|
var init_hosted_project_name = __esm({
|
|
95924
96163
|
"apps/cli/src/services/hosted-project-name.ts"() {
|
|
95925
96164
|
"use strict";
|
|
95926
96165
|
MAX_PROJECT_NAME_LENGTH = 100;
|
|
96166
|
+
NUMERIC_SUFFIX = /-\d+$/;
|
|
96167
|
+
SUGGESTION_ATTEMPTS = 1e3;
|
|
95927
96168
|
}
|
|
95928
96169
|
});
|
|
95929
96170
|
|
|
@@ -95953,6 +96194,12 @@ function defer() {
|
|
|
95953
96194
|
function ProjectExplainer({ dim = false }) {
|
|
95954
96195
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { dimColor: dim, children: "An Intelligence project is where this app's threads, messages, and analytics are stored." });
|
|
95955
96196
|
}
|
|
96197
|
+
function describeNameRefusal(validation) {
|
|
96198
|
+
if (validation.suggestion === void 0) {
|
|
96199
|
+
return validation.message;
|
|
96200
|
+
}
|
|
96201
|
+
return `${validation.message} "${validation.suggestion}" is free \u2014 press Enter to use it, type a different name, or cancel (Esc) and select the existing one from the list.`;
|
|
96202
|
+
}
|
|
95956
96203
|
function HostedProjectSelect({
|
|
95957
96204
|
apiClient,
|
|
95958
96205
|
onResolved,
|
|
@@ -95967,6 +96214,7 @@ function HostedProjectSelect({
|
|
|
95967
96214
|
const nameDirtyRef = (0, import_react37.useRef)(false);
|
|
95968
96215
|
const [nameDirty, setNameDirty] = (0, import_react37.useState)(false);
|
|
95969
96216
|
const [nameError, setNameError] = (0, import_react37.useState)("");
|
|
96217
|
+
const offeredNameRef = (0, import_react37.useRef)(null);
|
|
95970
96218
|
const pickerIndexRef = (0, import_react37.useRef)(0);
|
|
95971
96219
|
const [pickerIndex, setPickerIndex] = (0, import_react37.useState)(0);
|
|
95972
96220
|
const choiceRef = (0, import_react37.useRef)(null);
|
|
@@ -95998,6 +96246,8 @@ function HostedProjectSelect({
|
|
|
95998
96246
|
setNameDisplay(defaultName);
|
|
95999
96247
|
nameDirtyRef.current = false;
|
|
96000
96248
|
setNameDirty(false);
|
|
96249
|
+
offeredNameRef.current = null;
|
|
96250
|
+
setNameError("");
|
|
96001
96251
|
setView({ kind: "name" });
|
|
96002
96252
|
return deferred.promise;
|
|
96003
96253
|
}
|
|
@@ -96081,22 +96331,30 @@ function HostedProjectSelect({
|
|
|
96081
96331
|
nameDirtyRef.current = true;
|
|
96082
96332
|
setNameDirty(true);
|
|
96083
96333
|
}
|
|
96334
|
+
const offered = offeredNameRef.current;
|
|
96335
|
+
if (offered !== null && textBeforeNewline === "") {
|
|
96336
|
+
offeredNameRef.current = null;
|
|
96337
|
+
setNameError("");
|
|
96338
|
+
nameRef.current?.resolve(offered);
|
|
96339
|
+
return;
|
|
96340
|
+
}
|
|
96084
96341
|
const validation = validateProjectName(
|
|
96085
96342
|
nameBufferRef.current,
|
|
96086
96343
|
projectsRef.current
|
|
96087
96344
|
);
|
|
96088
96345
|
if (!validation.ok) {
|
|
96089
|
-
|
|
96090
|
-
|
|
96091
|
-
);
|
|
96346
|
+
offeredNameRef.current = validation.suggestion ?? null;
|
|
96347
|
+
setNameError(describeNameRefusal(validation));
|
|
96092
96348
|
telemetry?.onCreateNameRejected?.(validation.reason);
|
|
96093
96349
|
return;
|
|
96094
96350
|
}
|
|
96351
|
+
offeredNameRef.current = null;
|
|
96095
96352
|
setNameError("");
|
|
96096
96353
|
nameRef.current?.resolve(validation.name);
|
|
96097
96354
|
return;
|
|
96098
96355
|
}
|
|
96099
96356
|
if (key.backspace || key.delete) {
|
|
96357
|
+
offeredNameRef.current = null;
|
|
96100
96358
|
const updated = nameDirtyRef.current ? nameBufferRef.current.slice(0, -1) : "";
|
|
96101
96359
|
nameDirtyRef.current = true;
|
|
96102
96360
|
setNameDirty(true);
|
|
@@ -96105,6 +96363,7 @@ function HostedProjectSelect({
|
|
|
96105
96363
|
return;
|
|
96106
96364
|
}
|
|
96107
96365
|
if (input && !key.ctrl && !key.meta) {
|
|
96366
|
+
offeredNameRef.current = null;
|
|
96108
96367
|
const base = nameDirtyRef.current ? nameBufferRef.current : "";
|
|
96109
96368
|
nameDirtyRef.current = true;
|
|
96110
96369
|
setNameDirty(true);
|
|
@@ -96645,7 +96904,8 @@ function createFlagPrompts(request) {
|
|
|
96645
96904
|
kind: "name-rejected",
|
|
96646
96905
|
reason: validation.reason,
|
|
96647
96906
|
message: validation.message,
|
|
96648
|
-
...validation.duplicate ? { duplicateSlug: validation.duplicate.slug } : {}
|
|
96907
|
+
...validation.duplicate ? { duplicateSlug: validation.duplicate.slug } : {},
|
|
96908
|
+
...validation.suggestion === void 0 ? {} : { suggestedName: validation.suggestion }
|
|
96649
96909
|
};
|
|
96650
96910
|
return null;
|
|
96651
96911
|
}
|
|
@@ -96688,7 +96948,8 @@ function createFlagPrompts(request) {
|
|
|
96688
96948
|
}
|
|
96689
96949
|
function formatFlagRefusal(refusal, command2 = "project select") {
|
|
96690
96950
|
if (refusal.kind === "name-rejected") {
|
|
96691
|
-
const
|
|
96951
|
+
const free = refusal.suggestedName === void 0 ? "Pass a different --create name" : `\`--create "${refusal.suggestedName}"\` is free`;
|
|
96952
|
+
const remedy = refusal.duplicateSlug === void 0 ? `${free}.` : `${free}, or select the existing project with \`copilotkit ${command2} --project ${refusal.duplicateSlug}\`.`;
|
|
96692
96953
|
return `${refusal.message} ${remedy}
|
|
96693
96954
|
`;
|
|
96694
96955
|
}
|
|
@@ -96821,9 +97082,19 @@ async function driveFlagSelect(apiClient, request) {
|
|
|
96821
97082
|
return withoutSelection({ kind: "canceled" });
|
|
96822
97083
|
}
|
|
96823
97084
|
process.stderr.write(formatFlagRefusal(recorded));
|
|
96824
|
-
|
|
96825
|
-
|
|
96826
|
-
|
|
97085
|
+
if (recorded.kind === "not-found") {
|
|
97086
|
+
return withoutSelection({
|
|
97087
|
+
kind: "not-found",
|
|
97088
|
+
requested: recorded.requested
|
|
97089
|
+
});
|
|
97090
|
+
}
|
|
97091
|
+
return withoutSelection({
|
|
97092
|
+
kind: "name-rejected",
|
|
97093
|
+
// The refused name and the free one, in the message the payload carries.
|
|
97094
|
+
// A caller reading only `error` still learns which name to retry with.
|
|
97095
|
+
message: recorded.suggestedName === void 0 ? recorded.message : `${recorded.message} "${recorded.suggestedName}" is free.`,
|
|
97096
|
+
...recorded.suggestedName === void 0 ? {} : { suggestedName: recorded.suggestedName }
|
|
97097
|
+
});
|
|
96827
97098
|
}
|
|
96828
97099
|
return await completeSelection(apiClient, result);
|
|
96829
97100
|
}
|
|
@@ -96906,8 +97177,13 @@ async function runProjectSelectJson(options = {}) {
|
|
|
96906
97177
|
throw exitError;
|
|
96907
97178
|
}
|
|
96908
97179
|
const error98 = exitError ?? new Error("Project selection did not complete.");
|
|
97180
|
+
const suggestedName = outcome.kind === "name-rejected" ? outcome.suggestedName : void 0;
|
|
96909
97181
|
process.stdout.write(
|
|
96910
|
-
`${JSON.stringify({
|
|
97182
|
+
`${JSON.stringify({
|
|
97183
|
+
error: error98.message,
|
|
97184
|
+
...suggestedName === void 0 ? {} : { suggested_name: suggestedName },
|
|
97185
|
+
type: "failed"
|
|
97186
|
+
})}
|
|
96911
97187
|
`
|
|
96912
97188
|
);
|
|
96913
97189
|
throw error98;
|
|
@@ -99859,13 +100135,115 @@ var init_learning = __esm({
|
|
|
99859
100135
|
}
|
|
99860
100136
|
});
|
|
99861
100137
|
|
|
100138
|
+
// libs/app-api-contracts/src/learning-schedule.ts
|
|
100139
|
+
var localTimeSchema, timeZoneSchema, learningScheduleInputSchema, learningScheduleSchema, learningScheduleResponseSchema, projectLearningScheduleSchema, projectLearningScheduleResponseSchema;
|
|
100140
|
+
var init_learning_schedule = __esm({
|
|
100141
|
+
"libs/app-api-contracts/src/learning-schedule.ts"() {
|
|
100142
|
+
"use strict";
|
|
100143
|
+
init_zod();
|
|
100144
|
+
localTimeSchema = external_exports.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/, {
|
|
100145
|
+
message: "Use a local time in HH:mm format."
|
|
100146
|
+
}).length(5);
|
|
100147
|
+
timeZoneSchema = external_exports.string().min(1).max(255).refine(
|
|
100148
|
+
(timeZone) => {
|
|
100149
|
+
if (/^[+-]/.test(timeZone) || timeZone.trim() !== timeZone)
|
|
100150
|
+
return false;
|
|
100151
|
+
try {
|
|
100152
|
+
new Intl.DateTimeFormat("en-US", { timeZone }).format(0);
|
|
100153
|
+
return true;
|
|
100154
|
+
} catch {
|
|
100155
|
+
return false;
|
|
100156
|
+
}
|
|
100157
|
+
},
|
|
100158
|
+
{ message: "Use a valid IANA time zone." }
|
|
100159
|
+
);
|
|
100160
|
+
learningScheduleInputSchema = external_exports.object({
|
|
100161
|
+
localTime: localTimeSchema,
|
|
100162
|
+
timeZone: timeZoneSchema
|
|
100163
|
+
}).strict();
|
|
100164
|
+
learningScheduleSchema = learningScheduleInputSchema.extend({
|
|
100165
|
+
organizationId: external_exports.string(),
|
|
100166
|
+
nextRunAt: external_exports.string().datetime(),
|
|
100167
|
+
updatedAt: external_exports.string().datetime()
|
|
100168
|
+
});
|
|
100169
|
+
learningScheduleResponseSchema = external_exports.object({
|
|
100170
|
+
schedule: learningScheduleSchema
|
|
100171
|
+
}).strict();
|
|
100172
|
+
projectLearningScheduleSchema = learningScheduleSchema.extend({
|
|
100173
|
+
projectId: external_exports.number().int().positive(),
|
|
100174
|
+
source: external_exports.enum(["organization", "project"]),
|
|
100175
|
+
automationEnabled: external_exports.boolean().optional()
|
|
100176
|
+
});
|
|
100177
|
+
projectLearningScheduleResponseSchema = external_exports.object({ schedule: projectLearningScheduleSchema }).strict();
|
|
100178
|
+
}
|
|
100179
|
+
});
|
|
100180
|
+
|
|
100181
|
+
// libs/app-api-contracts/src/learning-automation.ts
|
|
100182
|
+
var learningAutomationReadinessSchema, learningAutomationReadinessResponseSchema;
|
|
100183
|
+
var init_learning_automation = __esm({
|
|
100184
|
+
"libs/app-api-contracts/src/learning-automation.ts"() {
|
|
100185
|
+
"use strict";
|
|
100186
|
+
init_zod();
|
|
100187
|
+
learningAutomationReadinessSchema = external_exports.object({
|
|
100188
|
+
containerId: external_exports.string().min(1).max(64),
|
|
100189
|
+
projectId: external_exports.number().int().positive(),
|
|
100190
|
+
enabled: external_exports.boolean(),
|
|
100191
|
+
eligibleThreadCount: external_exports.number().int().nonnegative(),
|
|
100192
|
+
requiredThreadCount: external_exports.number().int().positive(),
|
|
100193
|
+
blocked: external_exports.boolean(),
|
|
100194
|
+
activeRun: external_exports.boolean()
|
|
100195
|
+
});
|
|
100196
|
+
learningAutomationReadinessResponseSchema = external_exports.object({
|
|
100197
|
+
automation: learningAutomationReadinessSchema
|
|
100198
|
+
}).strict();
|
|
100199
|
+
}
|
|
100200
|
+
});
|
|
100201
|
+
|
|
99862
100202
|
// libs/app-api-contracts/src/threads.ts
|
|
99863
|
-
var threadIdSchema;
|
|
100203
|
+
var threadIdSchema, appUserAliasSchema, collapseAppUserAliases, refuseInternalAppUserForms, threadAppUserSchema, threadReadQuerySchema;
|
|
99864
100204
|
var init_threads = __esm({
|
|
99865
100205
|
"libs/app-api-contracts/src/threads.ts"() {
|
|
99866
100206
|
"use strict";
|
|
99867
100207
|
init_zod();
|
|
99868
100208
|
threadIdSchema = external_exports.string().uuid();
|
|
100209
|
+
appUserAliasSchema = external_exports.object({
|
|
100210
|
+
endUserId: external_exports.string().trim().min(1).optional(),
|
|
100211
|
+
end_user_id: external_exports.string().trim().min(1).optional(),
|
|
100212
|
+
userId: external_exports.string().trim().min(1).optional(),
|
|
100213
|
+
createdById: external_exports.string().trim().min(1).optional(),
|
|
100214
|
+
created_by_id: external_exports.string().trim().min(1).optional(),
|
|
100215
|
+
appUserId: external_exports.string().trim().min(1).optional(),
|
|
100216
|
+
app_user_id: external_exports.string().trim().min(1).optional()
|
|
100217
|
+
});
|
|
100218
|
+
collapseAppUserAliases = (data) => ({
|
|
100219
|
+
endUserId: data.endUserId ?? data.end_user_id ?? data.userId,
|
|
100220
|
+
createdById: data.createdById ?? data.created_by_id,
|
|
100221
|
+
appUserId: data.appUserId ?? data.app_user_id
|
|
100222
|
+
});
|
|
100223
|
+
refuseInternalAppUserForms = (data, ctx) => {
|
|
100224
|
+
if (data.createdById) {
|
|
100225
|
+
ctx.addIssue({
|
|
100226
|
+
code: external_exports.ZodIssueCode.custom,
|
|
100227
|
+
message: "createdById is internal; pass bare endUserId instead."
|
|
100228
|
+
});
|
|
100229
|
+
}
|
|
100230
|
+
if (data.appUserId) {
|
|
100231
|
+
ctx.addIssue({
|
|
100232
|
+
code: external_exports.ZodIssueCode.custom,
|
|
100233
|
+
message: "appUserId is not accepted; pass endUserId instead."
|
|
100234
|
+
});
|
|
100235
|
+
}
|
|
100236
|
+
};
|
|
100237
|
+
threadAppUserSchema = appUserAliasSchema.transform(collapseAppUserAliases).superRefine((data, ctx) => {
|
|
100238
|
+
if (!data.endUserId) {
|
|
100239
|
+
ctx.addIssue({
|
|
100240
|
+
code: external_exports.ZodIssueCode.custom,
|
|
100241
|
+
message: "endUserId is required."
|
|
100242
|
+
});
|
|
100243
|
+
}
|
|
100244
|
+
refuseInternalAppUserForms(data, ctx);
|
|
100245
|
+
}).transform((data) => ({ endUserId: data.endUserId }));
|
|
100246
|
+
threadReadQuerySchema = appUserAliasSchema.transform(collapseAppUserAliases).superRefine(refuseInternalAppUserForms).transform((data) => ({ endUserId: data.endUserId }));
|
|
99869
100247
|
}
|
|
99870
100248
|
});
|
|
99871
100249
|
|
|
@@ -99932,6 +100310,8 @@ var init_src6 = __esm({
|
|
|
99932
100310
|
init_inspector_metadata();
|
|
99933
100311
|
init_inspector_learning();
|
|
99934
100312
|
init_learning();
|
|
100313
|
+
init_learning_schedule();
|
|
100314
|
+
init_learning_automation();
|
|
99935
100315
|
init_threads();
|
|
99936
100316
|
init_usage();
|
|
99937
100317
|
}
|
|
@@ -100096,7 +100476,7 @@ async function loadLearningCommandContext() {
|
|
|
100096
100476
|
productCredential: auth2.productCredential,
|
|
100097
100477
|
productOrganizationId: auth2.clerkOrgId
|
|
100098
100478
|
});
|
|
100099
|
-
return { client: client2, projectId: project.projectId };
|
|
100479
|
+
return { client: client2, projectId: project.projectId, projectSlug: project.projectSlug };
|
|
100100
100480
|
}
|
|
100101
100481
|
var init_learning_command_context = __esm({
|
|
100102
100482
|
"apps/cli/src/services/learning-command-context.ts"() {
|
|
@@ -100435,6 +100815,21 @@ async function runLearningInsightsCommand(command2, dependencies) {
|
|
|
100435
100815
|
command2.candidateId,
|
|
100436
100816
|
command2.action
|
|
100437
100817
|
);
|
|
100818
|
+
if (command2.yes) {
|
|
100819
|
+
dependencies.telemetry.onReviewViewed({
|
|
100820
|
+
action: command2.action,
|
|
100821
|
+
durationMs: Date.now() - startedAt,
|
|
100822
|
+
operation: review.operation,
|
|
100823
|
+
reviewMode
|
|
100824
|
+
});
|
|
100825
|
+
dependencies.telemetry.onReviewDecided({
|
|
100826
|
+
action: command2.action,
|
|
100827
|
+
decision: "confirmed",
|
|
100828
|
+
durationMs: 0,
|
|
100829
|
+
operation: review.operation,
|
|
100830
|
+
reviewMode
|
|
100831
|
+
});
|
|
100832
|
+
}
|
|
100438
100833
|
dependencies.telemetry.setProperties({
|
|
100439
100834
|
candidate_operation: review.operation,
|
|
100440
100835
|
review_mode: reviewMode,
|
|
@@ -100581,11 +100976,27 @@ var init_learning_containers_api = __esm({
|
|
|
100581
100976
|
}
|
|
100582
100977
|
});
|
|
100583
100978
|
|
|
100979
|
+
// apps/cli/src/services/learning-default-container.ts
|
|
100980
|
+
function defaultContainerIdFromProjectSlug(projectSlug) {
|
|
100981
|
+
const reshaped = projectSlug.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "");
|
|
100982
|
+
if (reshaped === "")
|
|
100983
|
+
return void 0;
|
|
100984
|
+
const bounded = reshaped.slice(0, MAX_ID_LENGTH).replace(/-+$/u, "");
|
|
100985
|
+
return bounded === "" ? void 0 : bounded;
|
|
100986
|
+
}
|
|
100987
|
+
var MAX_ID_LENGTH;
|
|
100988
|
+
var init_learning_default_container = __esm({
|
|
100989
|
+
"apps/cli/src/services/learning-default-container.ts"() {
|
|
100990
|
+
"use strict";
|
|
100991
|
+
MAX_ID_LENGTH = 64;
|
|
100992
|
+
}
|
|
100993
|
+
});
|
|
100994
|
+
|
|
100584
100995
|
// apps/cli/src/ui/learning-container-prompts.tsx
|
|
100585
100996
|
function LearningContainerCreatePrompt(props) {
|
|
100586
100997
|
const firstStep = props.initial.id === void 0 ? "id" : props.initial.name === void 0 ? "name" : "prompt";
|
|
100587
100998
|
const [step, setStep] = (0, import_react43.useState)(firstStep);
|
|
100588
|
-
const [id, setId] = (0, import_react43.useState)(props.initial.id ?? "");
|
|
100999
|
+
const [id, setId] = (0, import_react43.useState)(props.initial.id ?? props.initial.proposedId ?? "");
|
|
100589
101000
|
const [name, setName] = (0, import_react43.useState)(props.initial.name ?? "");
|
|
100590
101001
|
const [promptContext, setPromptContext] = (0, import_react43.useState)(
|
|
100591
101002
|
props.initial.promptContext ?? ""
|
|
@@ -100757,6 +101168,66 @@ function LearningContainerDeletePrompt(props) {
|
|
|
100757
101168
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "(y/N) " })
|
|
100758
101169
|
] });
|
|
100759
101170
|
}
|
|
101171
|
+
function LearningContainerSelectPrompt(props) {
|
|
101172
|
+
const createIndex = props.containers.length;
|
|
101173
|
+
const moreIndex = props.hasMore ? createIndex + 1 : -1;
|
|
101174
|
+
const itemCount = createIndex + (props.hasMore ? 2 : 1);
|
|
101175
|
+
const [index2, setIndex] = (0, import_react43.useState)(0);
|
|
101176
|
+
const indexRef = (0, import_react43.useRef)(0);
|
|
101177
|
+
const finished2 = (0, import_react43.useRef)(false);
|
|
101178
|
+
const move = (delta) => {
|
|
101179
|
+
const next = (indexRef.current + delta + itemCount) % itemCount;
|
|
101180
|
+
indexRef.current = next;
|
|
101181
|
+
setIndex(next);
|
|
101182
|
+
};
|
|
101183
|
+
const finish = (selection) => {
|
|
101184
|
+
if (finished2.current)
|
|
101185
|
+
return;
|
|
101186
|
+
finished2.current = true;
|
|
101187
|
+
props.onComplete(selection);
|
|
101188
|
+
};
|
|
101189
|
+
use_input_default((_input, key) => {
|
|
101190
|
+
if (key.downArrow) {
|
|
101191
|
+
move(1);
|
|
101192
|
+
return;
|
|
101193
|
+
}
|
|
101194
|
+
if (key.upArrow) {
|
|
101195
|
+
move(-1);
|
|
101196
|
+
return;
|
|
101197
|
+
}
|
|
101198
|
+
if (key.escape) {
|
|
101199
|
+
if (finished2.current)
|
|
101200
|
+
return;
|
|
101201
|
+
finished2.current = true;
|
|
101202
|
+
props.onCancel();
|
|
101203
|
+
return;
|
|
101204
|
+
}
|
|
101205
|
+
if (!key.return)
|
|
101206
|
+
return;
|
|
101207
|
+
const position = indexRef.current;
|
|
101208
|
+
if (position === moreIndex) {
|
|
101209
|
+
finish({ kind: "more" });
|
|
101210
|
+
return;
|
|
101211
|
+
}
|
|
101212
|
+
if (position === createIndex) {
|
|
101213
|
+
finish({ kind: "create" });
|
|
101214
|
+
return;
|
|
101215
|
+
}
|
|
101216
|
+
const container = props.containers[position];
|
|
101217
|
+
if (container === void 0)
|
|
101218
|
+
return;
|
|
101219
|
+
finish({ containerId: container.id, kind: "chosen" });
|
|
101220
|
+
});
|
|
101221
|
+
const marker = (position) => position === index2 ? ">" : " ";
|
|
101222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
101223
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { bold: true, children: "Select a Learning Container" }),
|
|
101224
|
+
props.containers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: "This project has none yet." }) : null,
|
|
101225
|
+
props.containers.map((container, position) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: `${marker(position)} ${container.id} ${container.name}` }, container.id)),
|
|
101226
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: `${marker(createIndex)} Create a new container` }),
|
|
101227
|
+
props.hasMore ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: `${marker(moreIndex)} Show more` }) : null,
|
|
101228
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: "Up and down move, Enter selects, Esc cancels." })
|
|
101229
|
+
] });
|
|
101230
|
+
}
|
|
100760
101231
|
var import_react43, import_jsx_runtime13;
|
|
100761
101232
|
var init_learning_container_prompts = __esm({
|
|
100762
101233
|
async "apps/cli/src/ui/learning-container-prompts.tsx"() {
|
|
@@ -100806,6 +101277,22 @@ async function promptUpdate(container) {
|
|
|
100806
101277
|
await app.waitUntilExit();
|
|
100807
101278
|
return result;
|
|
100808
101279
|
}
|
|
101280
|
+
async function promptSelect(input) {
|
|
101281
|
+
let result = null;
|
|
101282
|
+
const app = render_default(
|
|
101283
|
+
(0, import_react44.createElement)(LearningContainerSelectPrompt, {
|
|
101284
|
+
containers: input.containers,
|
|
101285
|
+
hasMore: input.hasMore,
|
|
101286
|
+
onCancel: () => setTimeout(() => app.unmount(), 0),
|
|
101287
|
+
onComplete: (selection) => {
|
|
101288
|
+
result = selection;
|
|
101289
|
+
setTimeout(() => app.unmount(), 0);
|
|
101290
|
+
}
|
|
101291
|
+
})
|
|
101292
|
+
);
|
|
101293
|
+
await app.waitUntilExit();
|
|
101294
|
+
return result;
|
|
101295
|
+
}
|
|
100809
101296
|
async function confirmDelete(container) {
|
|
100810
101297
|
let confirmed = false;
|
|
100811
101298
|
const app = render_default(
|
|
@@ -100823,12 +101310,13 @@ async function confirmDelete(container) {
|
|
|
100823
101310
|
function createLearningContainersCommandDependencies() {
|
|
100824
101311
|
return {
|
|
100825
101312
|
interactive: process.stdin.isTTY === true && process.stdout.isTTY === true,
|
|
100826
|
-
interaction: { confirmDelete, promptCreate, promptUpdate },
|
|
101313
|
+
interaction: { confirmDelete, promptCreate, promptSelect, promptUpdate },
|
|
100827
101314
|
loadContext: async () => {
|
|
100828
|
-
const { client: client2, projectId } = await loadLearningCommandContext();
|
|
101315
|
+
const { client: client2, projectId, projectSlug } = await loadLearningCommandContext();
|
|
100829
101316
|
return {
|
|
100830
101317
|
api: createLearningContainersApi(client2),
|
|
100831
|
-
projectId
|
|
101318
|
+
projectId,
|
|
101319
|
+
projectSlug
|
|
100832
101320
|
};
|
|
100833
101321
|
},
|
|
100834
101322
|
writeStdout: (text2) => {
|
|
@@ -100973,6 +101461,59 @@ Created: ${container.createdAt}
|
|
|
100973
101461
|
Updated: ${container.updatedAt}
|
|
100974
101462
|
`;
|
|
100975
101463
|
}
|
|
101464
|
+
async function selectLearningContainer(dependencies, projectId) {
|
|
101465
|
+
const { api, projectSlug } = await dependencies.loadContext();
|
|
101466
|
+
const proposedId = projectSlug === void 0 ? void 0 : defaultContainerIdFromProjectSlug(projectSlug);
|
|
101467
|
+
const seen = [];
|
|
101468
|
+
let cursor;
|
|
101469
|
+
let exhausted = false;
|
|
101470
|
+
let pagesRead = 0;
|
|
101471
|
+
const reportSurvey = (selection) => {
|
|
101472
|
+
dependencies.telemetry?.setProperties({
|
|
101473
|
+
container_count: seen.length,
|
|
101474
|
+
container_more_pages: !exhausted,
|
|
101475
|
+
container_pages_read: pagesRead,
|
|
101476
|
+
...selection === void 0 ? {} : { container_selection: selection }
|
|
101477
|
+
});
|
|
101478
|
+
};
|
|
101479
|
+
for (; ; ) {
|
|
101480
|
+
if (!exhausted) {
|
|
101481
|
+
const page = await api.list(projectId, cursor);
|
|
101482
|
+
pagesRead += 1;
|
|
101483
|
+
seen.push(...page.containers);
|
|
101484
|
+
cursor = page.nextCursor ?? void 0;
|
|
101485
|
+
exhausted = cursor === void 0;
|
|
101486
|
+
}
|
|
101487
|
+
const answer = await dependencies.interaction.promptSelect({
|
|
101488
|
+
containers: [...seen],
|
|
101489
|
+
hasMore: !exhausted
|
|
101490
|
+
});
|
|
101491
|
+
if (answer === null) {
|
|
101492
|
+
reportSurvey();
|
|
101493
|
+
dependencies.writeStdout("Canceled.\n");
|
|
101494
|
+
throw userAbortedError2();
|
|
101495
|
+
}
|
|
101496
|
+
if (answer.kind === "more")
|
|
101497
|
+
continue;
|
|
101498
|
+
if (answer.kind === "create") {
|
|
101499
|
+
reportSurvey("created");
|
|
101500
|
+
const input = await dependencies.interaction.promptCreate(
|
|
101501
|
+
proposedId === void 0 ? {} : { proposedId }
|
|
101502
|
+
);
|
|
101503
|
+
if (input === null) {
|
|
101504
|
+
dependencies.writeStdout("Canceled.\n");
|
|
101505
|
+
throw userAbortedError2();
|
|
101506
|
+
}
|
|
101507
|
+
return api.create(projectId, input);
|
|
101508
|
+
}
|
|
101509
|
+
reportSurvey("chosen");
|
|
101510
|
+
const chosen = seen.find((held) => held.id === answer.containerId);
|
|
101511
|
+
if (chosen === void 0) {
|
|
101512
|
+
throw containerNotFoundError(answer.containerId);
|
|
101513
|
+
}
|
|
101514
|
+
return chosen;
|
|
101515
|
+
}
|
|
101516
|
+
}
|
|
100976
101517
|
async function runLearningContainersCommand(command2, dependencies) {
|
|
100977
101518
|
try {
|
|
100978
101519
|
validateLearningContainersCommandFlags(command2);
|
|
@@ -100991,9 +101532,19 @@ async function runLearningContainersCommand(command2, dependencies) {
|
|
|
100991
101532
|
"Learning Container delete needs --yes when confirmation is unavailable."
|
|
100992
101533
|
);
|
|
100993
101534
|
}
|
|
101535
|
+
if (command2.action === "select" && (command2.json || !dependencies.interactive)) {
|
|
101536
|
+
throw nonInteractiveError(
|
|
101537
|
+
"Learning Container select needs a terminal. Read them with `learning containers list --json` and make one with `learning containers create --id <id> --name <name>`."
|
|
101538
|
+
);
|
|
101539
|
+
}
|
|
100994
101540
|
const { api, projectId } = await dependencies.loadContext();
|
|
100995
101541
|
if (command2.action === "list") {
|
|
100996
101542
|
const page = await api.list(projectId, command2.cursor);
|
|
101543
|
+
dependencies.telemetry?.setProperties({
|
|
101544
|
+
container_count: page.containers.length,
|
|
101545
|
+
container_more_pages: page.nextCursor !== null,
|
|
101546
|
+
container_pages_read: 1
|
|
101547
|
+
});
|
|
100997
101548
|
if (command2.json) {
|
|
100998
101549
|
writeJson2(dependencies, {
|
|
100999
101550
|
command: "learning containers list",
|
|
@@ -101024,6 +101575,11 @@ async function runLearningContainersCommand(command2, dependencies) {
|
|
|
101024
101575
|
}
|
|
101025
101576
|
return;
|
|
101026
101577
|
}
|
|
101578
|
+
if (command2.action === "select") {
|
|
101579
|
+
const container2 = await selectLearningContainer(dependencies, projectId);
|
|
101580
|
+
dependencies.writeStdout(renderLearningContainer(container2));
|
|
101581
|
+
return;
|
|
101582
|
+
}
|
|
101027
101583
|
if (command2.action === "create") {
|
|
101028
101584
|
let input;
|
|
101029
101585
|
if (command2.id !== void 0 && command2.name !== void 0) {
|
|
@@ -101148,6 +101704,7 @@ var init_learning_containers = __esm({
|
|
|
101148
101704
|
init_src6();
|
|
101149
101705
|
init_learning_containers_api();
|
|
101150
101706
|
init_learning_command_context();
|
|
101707
|
+
init_learning_default_container();
|
|
101151
101708
|
await init_build2();
|
|
101152
101709
|
import_react44 = __toESM(require_react(), 1);
|
|
101153
101710
|
await init_learning_container_prompts();
|
|
@@ -101548,7 +102105,7 @@ function apiKeyPresentCheck(variableName, source, envSearch) {
|
|
|
101548
102105
|
title
|
|
101549
102106
|
};
|
|
101550
102107
|
}
|
|
101551
|
-
function apiKeyLoadableCheck(facts) {
|
|
102108
|
+
function apiKeyLoadableCheck(facts, runtime) {
|
|
101552
102109
|
const title = "The app can load the project API key";
|
|
101553
102110
|
const id = "api_key_loadable_by_app";
|
|
101554
102111
|
switch (facts.kind) {
|
|
@@ -101575,7 +102132,7 @@ function apiKeyLoadableCheck(facts) {
|
|
|
101575
102132
|
};
|
|
101576
102133
|
case "loader-declared":
|
|
101577
102134
|
return {
|
|
101578
|
-
detail: `A script in ${facts.appDir} names an env file itself, so which file that app loads is decided there rather than by its framework's default. This check does not read it.`,
|
|
102135
|
+
detail: facts.declaredIn === facts.appDir ? `A script in ${facts.appDir} names an env file itself, so which file that app loads is decided there rather than by its framework's default. This check does not read it.` : `A script in ${facts.declaredIn} names an env file itself and starts the app in ${facts.appDir}, so which file that app loads is decided there rather than by its framework's default. This check does not read it.`,
|
|
101579
102136
|
id,
|
|
101580
102137
|
status: "undetermined",
|
|
101581
102138
|
title
|
|
@@ -101594,13 +102151,24 @@ function apiKeyLoadableCheck(facts) {
|
|
|
101594
102151
|
status: "pass",
|
|
101595
102152
|
title
|
|
101596
102153
|
};
|
|
101597
|
-
case "not-loadable":
|
|
102154
|
+
case "not-loadable": {
|
|
102155
|
+
const located = `The key is in ${facts.foundIn}, which this command found by searching upward. The app in ${facts.appDir} loads env files from its own directory only, and nothing there sets ${eitherKeyName()}.`;
|
|
102156
|
+
const remedy = `Write it to ${facts.expectedFile}, or re-run \`copilotkit project select\` from ${facts.appDir}.`;
|
|
102157
|
+
if (runtime.kind === "ok" && reportsIntelligenceClient(runtime.info)) {
|
|
102158
|
+
return {
|
|
102159
|
+
detail: `${located} A runtime answered and reports an Intelligence entitlement, so some process did load a key \u2014 from a mechanism this check does not read, or from a different process than the app in ${facts.appDir}. Which it was is not decidable from here. If the runtime you probed is not that app: ${remedy}`,
|
|
102160
|
+
id,
|
|
102161
|
+
status: "undetermined",
|
|
102162
|
+
title
|
|
102163
|
+
};
|
|
102164
|
+
}
|
|
101598
102165
|
return {
|
|
101599
|
-
detail:
|
|
102166
|
+
detail: `${located} So the running application never sees it. ${remedy}`,
|
|
101600
102167
|
id,
|
|
101601
102168
|
status: "fail",
|
|
101602
102169
|
title
|
|
101603
102170
|
};
|
|
102171
|
+
}
|
|
101604
102172
|
}
|
|
101605
102173
|
}
|
|
101606
102174
|
function apiKeyAuthenticatesCheck(probe) {
|
|
@@ -101758,12 +102326,59 @@ function intelligenceConsumedCheck(credential, runtime) {
|
|
|
101758
102326
|
};
|
|
101759
102327
|
}
|
|
101760
102328
|
return {
|
|
101761
|
-
detail: `The runtime holds an Intelligence client and ${describeIntelligenceEntitlement(runtime.info)},
|
|
102329
|
+
detail: `The runtime holds an Intelligence client and ${describeIntelligenceEntitlement(runtime.info)}. That is a declaration, not proof of a successful call \u2014 see the deployment check below for whether it is pointed at the host this key belongs to.`,
|
|
101762
102330
|
id: "intelligence_consumed",
|
|
101763
102331
|
status: "pass",
|
|
101764
102332
|
title
|
|
101765
102333
|
};
|
|
101766
102334
|
}
|
|
102335
|
+
function deploymentHost(url4) {
|
|
102336
|
+
let hostname5;
|
|
102337
|
+
try {
|
|
102338
|
+
hostname5 = new URL(url4).hostname.toLowerCase();
|
|
102339
|
+
} catch {
|
|
102340
|
+
return void 0;
|
|
102341
|
+
}
|
|
102342
|
+
return LOOPBACK_HOSTNAMES.has(hostname5) ? "localhost" : hostname5;
|
|
102343
|
+
}
|
|
102344
|
+
function intelligenceHostAgreementChecks(input) {
|
|
102345
|
+
const { credential, intelligenceTarget, runtime } = input;
|
|
102346
|
+
if (runtime.kind !== "ok" || credential.kind !== "ok")
|
|
102347
|
+
return [];
|
|
102348
|
+
if (!reportsIntelligenceClient(runtime.info))
|
|
102349
|
+
return [];
|
|
102350
|
+
const reportedGateway = runtime.info.intelligenceWsUrl;
|
|
102351
|
+
if (reportedGateway === void 0)
|
|
102352
|
+
return [];
|
|
102353
|
+
const observed = deploymentHost(reportedGateway);
|
|
102354
|
+
const verified = deploymentHost(intelligenceTarget.verifiedUrl);
|
|
102355
|
+
if (observed === void 0 || verified === void 0)
|
|
102356
|
+
return [];
|
|
102357
|
+
const accepted = new Set(
|
|
102358
|
+
[verified, ...intelligenceTarget.pairedGatewayUrls.map(deploymentHost)].filter(
|
|
102359
|
+
(host) => host !== void 0
|
|
102360
|
+
)
|
|
102361
|
+
);
|
|
102362
|
+
if (accepted.has(observed)) {
|
|
102363
|
+
return [
|
|
102364
|
+
{
|
|
102365
|
+
detail: `The runtime reports its Intelligence gateway on ${observed}, which belongs to the deployment this command proved the key against (${verified}).`,
|
|
102366
|
+
id: "intelligence_host_agreement",
|
|
102367
|
+
status: "pass",
|
|
102368
|
+
title: HOST_AGREEMENT_TITLE
|
|
102369
|
+
}
|
|
102370
|
+
];
|
|
102371
|
+
}
|
|
102372
|
+
const unnamed = intelligenceTarget.source === "cli-default" ? ` This project names no INTELLIGENCE_API_URL, so ${verified} is only this CLI's own default and the runtime fell back to its own.` : "";
|
|
102373
|
+
return [
|
|
102374
|
+
{
|
|
102375
|
+
detail: `The key was proven against ${verified}, but the runtime reports its Intelligence gateway on ${observed} \u2014 a different deployment.${unnamed} Every check above tested a host the runtime never calls, so a valid key still gets 401 AUTH_UNAUTHENTICATED on every request. Set INTELLIGENCE_API_URL=${intelligenceTarget.verifiedUrl} in the env file the app loads, and INTELLIGENCE_GATEWAY_WS_URL to that deployment's gateway.`,
|
|
102376
|
+
id: "intelligence_host_agreement",
|
|
102377
|
+
status: "fail",
|
|
102378
|
+
title: HOST_AGREEMENT_TITLE
|
|
102379
|
+
}
|
|
102380
|
+
];
|
|
102381
|
+
}
|
|
101767
102382
|
function ossRuntimeModeCheck(runtime) {
|
|
101768
102383
|
const title = "The runtime uses the expected OSS mode";
|
|
101769
102384
|
if (runtime.kind !== "ok") {
|
|
@@ -101799,7 +102414,11 @@ function intelligenceThreadRoutesCheck(runtime) {
|
|
|
101799
102414
|
title
|
|
101800
102415
|
};
|
|
101801
102416
|
}
|
|
101802
|
-
const {
|
|
102417
|
+
const {
|
|
102418
|
+
intelligenceWsUrl,
|
|
102419
|
+
singleRouteResourceOperations,
|
|
102420
|
+
threadMutationsEnabled
|
|
102421
|
+
} = runtime.info;
|
|
101803
102422
|
if (!reportsIntelligenceClient(runtime.info)) {
|
|
101804
102423
|
return {
|
|
101805
102424
|
detail: "Not attempted: the runtime reports no Intelligence entitlement, so it has no Intelligence routes to serve. The check above names that.",
|
|
@@ -101808,6 +102427,14 @@ function intelligenceThreadRoutesCheck(runtime) {
|
|
|
101808
102427
|
title
|
|
101809
102428
|
};
|
|
101810
102429
|
}
|
|
102430
|
+
if (runtime.transport === "single-route" && singleRouteResourceOperations === void 0) {
|
|
102431
|
+
return {
|
|
102432
|
+
detail: "The runtime answers a single-route envelope and reports nothing about what that mount serves. Its top-level `threadEndpoints` describes the `info` call that carried the answer, not the mount, so it cannot be read either way. Upgrade @copilotkit/runtime to 1.70.2 or later: from there a single-route mount serves `threads/*` and `memories/*` over its `resource/request` method and says so.",
|
|
102433
|
+
id: "intelligence_thread_routes",
|
|
102434
|
+
status: "undetermined",
|
|
102435
|
+
title
|
|
102436
|
+
};
|
|
102437
|
+
}
|
|
101811
102438
|
if (threadMutationsEnabled === void 0) {
|
|
101812
102439
|
return {
|
|
101813
102440
|
detail: "The runtime reports no thread-endpoint state. Runtimes that predate the `threadEndpoints` field in /info omit it, so this could not be read either way. Upgrade @copilotkit/runtime to have it reported.",
|
|
@@ -101818,14 +102445,14 @@ function intelligenceThreadRoutesCheck(runtime) {
|
|
|
101818
102445
|
}
|
|
101819
102446
|
if (!threadMutationsEnabled) {
|
|
101820
102447
|
return {
|
|
101821
|
-
detail:
|
|
102448
|
+
detail: intelligenceWsUrl === void 0 ? "The runtime reports a license but serves no thread routes and no gateway URL, which is an Intelligence runtime built without `identifyUser`. That gates the whole web surface. Pass `identifyUser` where the runtime is constructed." : "The runtime reports a license and a gateway URL but still serves no thread routes, so saved Threads cannot be listed or written from the browser \u2014 https://docs.copilotkit.ai/backend/runtime-endpoints#enable-rich-threads-routes",
|
|
101822
102449
|
id: "intelligence_thread_routes",
|
|
101823
102450
|
status: "fail",
|
|
101824
102451
|
title
|
|
101825
102452
|
};
|
|
101826
102453
|
}
|
|
101827
102454
|
return {
|
|
101828
|
-
detail: "The runtime serves the thread routes, so saved Threads load.",
|
|
102455
|
+
detail: runtime.transport === "single-route" ? "The runtime serves the thread routes over its single-route envelope, as the `resource/request` method rather than as REST paths, so saved Threads load." : "The runtime serves the thread routes, so saved Threads load.",
|
|
101829
102456
|
id: "intelligence_thread_routes",
|
|
101830
102457
|
status: "pass",
|
|
101831
102458
|
title
|
|
@@ -102014,11 +102641,12 @@ function runVerifyChecks(input, expectedRuntime = "intelligence") {
|
|
|
102014
102641
|
input.apiKeySource,
|
|
102015
102642
|
input.envSearch
|
|
102016
102643
|
),
|
|
102017
|
-
apiKeyLoadableCheck(input.credentialLoad),
|
|
102644
|
+
apiKeyLoadableCheck(input.credentialLoad, input.runtime),
|
|
102018
102645
|
apiKeyAuthenticatesCheck(input.credential),
|
|
102019
102646
|
runtimeReachableCheck(input.runtime, input.runtimeUrl),
|
|
102020
102647
|
runtimeAgentsCheck(input.runtime, input.runtimeUrl),
|
|
102021
102648
|
intelligenceConsumedCheck(input.credential, input.runtime),
|
|
102649
|
+
...intelligenceHostAgreementChecks(input),
|
|
102022
102650
|
intelligenceThreadRoutesCheck(input.runtime),
|
|
102023
102651
|
...frontendAssetChecks(input),
|
|
102024
102652
|
...corsChecks(input),
|
|
@@ -102032,7 +102660,7 @@ function runVerifyChecks(input, expectedRuntime = "intelligence") {
|
|
|
102032
102660
|
ok: checks.every((check4) => check4.status === "pass")
|
|
102033
102661
|
};
|
|
102034
102662
|
}
|
|
102035
|
-
var API_KEY_VARIABLE_NAMES, VERSIONS_CHECK_TITLE, CORS_CHECK_TITLE;
|
|
102663
|
+
var API_KEY_VARIABLE_NAMES, LOOPBACK_HOSTNAMES, HOST_AGREEMENT_TITLE, VERSIONS_CHECK_TITLE, CORS_CHECK_TITLE;
|
|
102036
102664
|
var init_verify_checks = __esm({
|
|
102037
102665
|
"apps/cli/src/services/verify-checks.ts"() {
|
|
102038
102666
|
"use strict";
|
|
@@ -102043,6 +102671,14 @@ var init_verify_checks = __esm({
|
|
|
102043
102671
|
"COPILOTKIT_API_KEY",
|
|
102044
102672
|
"INTELLIGENCE_API_KEY"
|
|
102045
102673
|
];
|
|
102674
|
+
LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
102675
|
+
"localhost",
|
|
102676
|
+
"127.0.0.1",
|
|
102677
|
+
"[::1]",
|
|
102678
|
+
"::1",
|
|
102679
|
+
"0.0.0.0"
|
|
102680
|
+
]);
|
|
102681
|
+
HOST_AGREEMENT_TITLE = "The runtime and this command address the same Intelligence deployment";
|
|
102046
102682
|
VERSIONS_CHECK_TITLE = "The installed packages match the runtime";
|
|
102047
102683
|
CORS_CHECK_TITLE = "The runtime accepts the frontend origin";
|
|
102048
102684
|
}
|
|
@@ -377720,6 +378356,9 @@ var init_telemetry2 = __esm({
|
|
|
377720
378356
|
});
|
|
377721
378357
|
|
|
377722
378358
|
// apps/cli/src/services/round-trip-checks.ts
|
|
378359
|
+
function describeReadVia(readVia) {
|
|
378360
|
+
return readVia === "app-mount" ? "Read back through the app, so the answer belongs to the caller the app identified." : "Read back from app-api, because this mount serves no thread route: the run and its answer are proved, the end user it belonged to is not.";
|
|
378361
|
+
}
|
|
377723
378362
|
function runRoundTripCheck(agentId, probe, runtimeUrlSource) {
|
|
377724
378363
|
const check4 = decideRoundTrip(agentId, probe);
|
|
377725
378364
|
if (runtimeUrlSource !== "default" || probe.kind === "unreachable") {
|
|
@@ -377731,10 +378370,11 @@ function decideRoundTrip(agentId, probe) {
|
|
|
377731
378370
|
if (probe.kind === "answered") {
|
|
377732
378371
|
const toolNote = probe.toolCallNames.length > 0 ? ` It called ${probe.toolCallNames.join(", ")}.` : "";
|
|
377733
378372
|
return {
|
|
377734
|
-
detail: `Agent "${agentId}" answered with ${String(probe.text.length)} characters, recorded on thread ${probe.threadId}.${toolNote}`,
|
|
378373
|
+
detail: `Agent "${agentId}" answered with ${String(probe.text.length)} characters, recorded on thread ${probe.threadId}.${toolNote} ${describeReadVia(probe.readVia)}`,
|
|
377735
378374
|
evidence: {
|
|
377736
378375
|
agentId,
|
|
377737
378376
|
answerCharacters: probe.text.length,
|
|
378377
|
+
readVia: probe.readVia,
|
|
377738
378378
|
threadId: probe.threadId,
|
|
377739
378379
|
toolCallNames: probe.toolCallNames
|
|
377740
378380
|
},
|
|
@@ -377768,7 +378408,7 @@ function decideRoundTrip(agentId, probe) {
|
|
|
377768
378408
|
};
|
|
377769
378409
|
}
|
|
377770
378410
|
return {
|
|
377771
|
-
detail: `The run started but nothing from agent "${agentId}" was ever recorded on thread ${probe.threadId}. The agent accepted the request and produced no answer \u2014 check its own logs for a failure after start-up
|
|
378411
|
+
detail: `The run started but nothing from agent "${agentId}" was ever recorded on thread ${probe.threadId}. The agent accepted the request and produced no answer \u2014 check its own logs for a failure after start-up. ${describeReadVia(probe.readVia)}`,
|
|
377772
378412
|
id: "agent_answers",
|
|
377773
378413
|
status: "fail",
|
|
377774
378414
|
title: TITLE
|
|
@@ -377813,13 +378453,26 @@ async function pollForAnswer(params, threadId) {
|
|
|
377813
378453
|
const deadline = now() + (params.timeoutMs ?? DEFAULT_ROUND_TRIP_TIMEOUT_MS);
|
|
377814
378454
|
for (; ; ) {
|
|
377815
378455
|
const attempt = await readAnswer(params, threadId);
|
|
377816
|
-
if (attempt.kind
|
|
377817
|
-
|
|
377818
|
-
|
|
377819
|
-
|
|
378456
|
+
if (attempt.kind === "read-refused") {
|
|
378457
|
+
if (!isRetryableRead(attempt.status))
|
|
378458
|
+
return refusedRead(attempt);
|
|
378459
|
+
if (now() >= deadline)
|
|
378460
|
+
return refusedRead(attempt);
|
|
378461
|
+
} else {
|
|
378462
|
+
if (attempt.kind !== "no-answer")
|
|
378463
|
+
return attempt;
|
|
378464
|
+
if (now() >= deadline)
|
|
378465
|
+
return attempt;
|
|
378466
|
+
}
|
|
377820
378467
|
await sleep3(POLL_INTERVAL_MS);
|
|
377821
378468
|
}
|
|
377822
378469
|
}
|
|
378470
|
+
function isRetryableRead(status) {
|
|
378471
|
+
return status === 404 || status >= 500;
|
|
378472
|
+
}
|
|
378473
|
+
function refusedRead(attempt) {
|
|
378474
|
+
return { kind: "unreachable", message: attempt.message };
|
|
378475
|
+
}
|
|
377823
378476
|
async function startRun(params, sentThreadId) {
|
|
377824
378477
|
const body = {
|
|
377825
378478
|
context: [],
|
|
@@ -377836,14 +378489,14 @@ async function startRun(params, sentThreadId) {
|
|
|
377836
378489
|
threadId: sentThreadId,
|
|
377837
378490
|
tools: []
|
|
377838
378491
|
};
|
|
377839
|
-
const
|
|
377840
|
-
|
|
377841
|
-
|
|
377842
|
-
|
|
377843
|
-
|
|
377844
|
-
|
|
377845
|
-
|
|
377846
|
-
);
|
|
378492
|
+
const singleRoute = params.transport === "single-route";
|
|
378493
|
+
const url4 = singleRoute ? params.runtimeUrl.replace(/\/+$/u, "") : runtimeRouteUrl(params.runtimeUrl, `agent/${params.agentId}/run`);
|
|
378494
|
+
const payload = singleRoute ? { body, method: "agent/run", params: { agentId: params.agentId } } : body;
|
|
378495
|
+
const response = await params.fetchImpl(url4, {
|
|
378496
|
+
body: JSON.stringify(payload),
|
|
378497
|
+
headers: { "content-type": "application/json", ...params.headers },
|
|
378498
|
+
method: "POST"
|
|
378499
|
+
});
|
|
377847
378500
|
if (!response.ok) {
|
|
377848
378501
|
const message = await refusalMessage(response);
|
|
377849
378502
|
return isIdentityRefusal(message) ? { kind: "user-not-identified", message } : { kind: "run-error", message };
|
|
@@ -377896,13 +378549,49 @@ async function drain(response) {
|
|
|
377896
378549
|
}
|
|
377897
378550
|
}
|
|
377898
378551
|
async function readAnswer(params, threadId) {
|
|
377899
|
-
const
|
|
377900
|
-
|
|
377901
|
-
|
|
377902
|
-
|
|
377903
|
-
|
|
378552
|
+
const platform4 = params.transport === "single-route" ? params.platform : void 0;
|
|
378553
|
+
const readVia = platform4 === void 0 ? "app-mount" : "app-api";
|
|
378554
|
+
const request = platform4 === void 0 ? {
|
|
378555
|
+
init: params.headers === void 0 ? void 0 : { headers: params.headers },
|
|
378556
|
+
url: runtimeRouteUrl(params.runtimeUrl, `threads/${threadId}/messages`)
|
|
378557
|
+
} : {
|
|
378558
|
+
init: {
|
|
378559
|
+
headers: {
|
|
378560
|
+
accept: "application/json",
|
|
378561
|
+
authorization: `Bearer ${platform4.apiKey}`
|
|
378562
|
+
}
|
|
378563
|
+
},
|
|
378564
|
+
url: `${platform4.appApiUrl.replace(/\/+$/u, "")}/api/threads/${threadId}/messages`
|
|
378565
|
+
};
|
|
378566
|
+
const response = await params.fetchImpl(request.url, request.init);
|
|
378567
|
+
if (!response.ok) {
|
|
378568
|
+
return {
|
|
378569
|
+
kind: "read-refused",
|
|
378570
|
+
message: `${request.url} answered ${String(response.status)}${await refusalDetail(response)}`,
|
|
378571
|
+
status: response.status
|
|
378572
|
+
};
|
|
378573
|
+
}
|
|
378574
|
+
let payload;
|
|
378575
|
+
try {
|
|
378576
|
+
payload = await response.json();
|
|
378577
|
+
} catch {
|
|
378578
|
+
return {
|
|
378579
|
+
kind: "read-refused",
|
|
378580
|
+
message: `${request.url} did not answer JSON`,
|
|
378581
|
+
status: response.status
|
|
378582
|
+
};
|
|
378583
|
+
}
|
|
377904
378584
|
const answer = lastAssistantAnswer(payload);
|
|
377905
|
-
return answer === void 0 ? { kind: "no-answer", threadId } : { kind: "answered", threadId, ...answer };
|
|
378585
|
+
return answer === void 0 ? { kind: "no-answer", readVia, threadId } : { kind: "answered", readVia, threadId, ...answer };
|
|
378586
|
+
}
|
|
378587
|
+
async function refusalDetail(response) {
|
|
378588
|
+
try {
|
|
378589
|
+
const body = await response.json();
|
|
378590
|
+
const code = typeof body === "object" && body !== null && typeof body.error === "object" && body.error !== null && typeof body.error.code === "string" ? body.error.code : void 0;
|
|
378591
|
+
return code === void 0 ? "" : ` (${code})`;
|
|
378592
|
+
} catch {
|
|
378593
|
+
return "";
|
|
378594
|
+
}
|
|
377906
378595
|
}
|
|
377907
378596
|
function lastAssistantAnswer(payload) {
|
|
377908
378597
|
const messages = typeof payload === "object" && payload !== null && "messages" in payload && Array.isArray(payload.messages) ? payload.messages : [];
|
|
@@ -377933,6 +378622,68 @@ var init_round_trip_probe = __esm({
|
|
|
377933
378622
|
}
|
|
377934
378623
|
});
|
|
377935
378624
|
|
|
378625
|
+
// apps/cli/src/services/learning-container-check.ts
|
|
378626
|
+
function redact(text2, apiKey) {
|
|
378627
|
+
return text2.split(apiKey).join("[redacted]");
|
|
378628
|
+
}
|
|
378629
|
+
async function checkLearningContainer(params) {
|
|
378630
|
+
const { apiKey } = params;
|
|
378631
|
+
if (apiKey === void 0) {
|
|
378632
|
+
return {
|
|
378633
|
+
kind: "not-attempted",
|
|
378634
|
+
message: "Not attempted: no Intelligence API key was resolved, and the thread read needs one."
|
|
378635
|
+
};
|
|
378636
|
+
}
|
|
378637
|
+
const url4 = `${params.appApiUrl.replace(/\/+$/u, "")}/api/threads/${params.threadId}`;
|
|
378638
|
+
let response;
|
|
378639
|
+
try {
|
|
378640
|
+
response = await params.fetchImpl(url4, {
|
|
378641
|
+
headers: { accept: "application/json", authorization: `Bearer ${apiKey}` },
|
|
378642
|
+
method: "GET"
|
|
378643
|
+
});
|
|
378644
|
+
} catch (error98) {
|
|
378645
|
+
const detail = error98 instanceof Error ? error98.message : String(error98);
|
|
378646
|
+
return {
|
|
378647
|
+
kind: "unreachable",
|
|
378648
|
+
message: `could not reach ${url4} (${redact(detail, apiKey)})`
|
|
378649
|
+
};
|
|
378650
|
+
}
|
|
378651
|
+
if (!response.ok) {
|
|
378652
|
+
return {
|
|
378653
|
+
kind: "unreachable",
|
|
378654
|
+
message: `${url4} answered ${String(response.status)}`
|
|
378655
|
+
};
|
|
378656
|
+
}
|
|
378657
|
+
let body;
|
|
378658
|
+
try {
|
|
378659
|
+
body = await response.json();
|
|
378660
|
+
} catch {
|
|
378661
|
+
return { kind: "unreachable", message: `${url4} did not answer JSON` };
|
|
378662
|
+
}
|
|
378663
|
+
const thread = typeof body === "object" && body !== null && typeof body.thread === "object" && body.thread !== null ? body.thread : void 0;
|
|
378664
|
+
if (thread === void 0) {
|
|
378665
|
+
return {
|
|
378666
|
+
kind: "unreachable",
|
|
378667
|
+
message: `${url4} answered 200 without a thread`
|
|
378668
|
+
};
|
|
378669
|
+
}
|
|
378670
|
+
const actual = typeof thread["learningContainerId"] === "string" ? thread["learningContainerId"] : void 0;
|
|
378671
|
+
if (actual === params.expected) {
|
|
378672
|
+
return { containerId: actual, kind: "proved", threadId: params.threadId };
|
|
378673
|
+
}
|
|
378674
|
+
return {
|
|
378675
|
+
actual,
|
|
378676
|
+
expected: params.expected,
|
|
378677
|
+
kind: "mismatch",
|
|
378678
|
+
threadId: params.threadId
|
|
378679
|
+
};
|
|
378680
|
+
}
|
|
378681
|
+
var init_learning_container_check = __esm({
|
|
378682
|
+
"apps/cli/src/services/learning-container-check.ts"() {
|
|
378683
|
+
"use strict";
|
|
378684
|
+
}
|
|
378685
|
+
});
|
|
378686
|
+
|
|
377936
378687
|
// apps/cli/src/services/installed-packages.ts
|
|
377937
378688
|
import { readFileSync as readFileSync16 } from "node:fs";
|
|
377938
378689
|
import { dirname as dirname10, join as join21, sep } from "node:path";
|
|
@@ -378088,7 +378839,8 @@ function toRuntimeProbe(body, status, transport) {
|
|
|
378088
378839
|
}
|
|
378089
378840
|
);
|
|
378090
378841
|
const wsUrl = parsed.data.intelligence?.wsUrl;
|
|
378091
|
-
const
|
|
378842
|
+
const singleRoute = parsed.data.singleRoute;
|
|
378843
|
+
const mutations = singleRoute === void 0 ? parsed.data.threadEndpoints?.mutations : singleRoute.threadEndpoints?.mutations;
|
|
378092
378844
|
const info = {
|
|
378093
378845
|
agents,
|
|
378094
378846
|
...parsed.data.audioFileTranscriptionEnabled === void 0 ? {} : {
|
|
@@ -378098,6 +378850,7 @@ function toRuntimeProbe(body, status, transport) {
|
|
|
378098
378850
|
...parsed.data.licenseStatus === void 0 ? {} : { licenseStatus: parsed.data.licenseStatus },
|
|
378099
378851
|
...parsed.data.runtimeEntitlements === void 0 ? {} : { runtimeEntitlements: parsed.data.runtimeEntitlements },
|
|
378100
378852
|
openGenerativeUIEnabled: parsed.data.openGenerativeUIEnabled ?? false,
|
|
378853
|
+
...singleRoute?.resourceOperations === void 0 ? {} : { singleRouteResourceOperations: singleRoute.resourceOperations },
|
|
378101
378854
|
...mutations === void 0 ? {} : { threadMutationsEnabled: mutations },
|
|
378102
378855
|
version: parsed.data.version
|
|
378103
378856
|
};
|
|
@@ -378241,6 +378994,15 @@ var init_verify_probes = __esm({
|
|
|
378241
378994
|
licenseStatus: external_exports.string().optional(),
|
|
378242
378995
|
runtimeEntitlements: external_exports.object({ status: external_exports.string().optional() }).loose().optional(),
|
|
378243
378996
|
openGenerativeUIEnabled: external_exports.boolean().optional(),
|
|
378997
|
+
/**
|
|
378998
|
+
* Reported only by a single-route mount, from `@copilotkit/runtime` 1.70.2
|
|
378999
|
+
* onward. Its `threadEndpoints` describes the mount; the top-level one
|
|
379000
|
+
* describes the `info` call that carried this payload (OSS-1166).
|
|
379001
|
+
*/
|
|
379002
|
+
singleRoute: external_exports.object({
|
|
379003
|
+
resourceOperations: external_exports.boolean().optional(),
|
|
379004
|
+
threadEndpoints: external_exports.object({ mutations: external_exports.boolean().optional() }).loose().optional()
|
|
379005
|
+
}).loose().optional(),
|
|
378244
379006
|
threadEndpoints: external_exports.object({ mutations: external_exports.boolean().optional() }).loose().optional(),
|
|
378245
379007
|
version: external_exports.string()
|
|
378246
379008
|
});
|
|
@@ -378325,8 +379087,8 @@ function factRows(facts) {
|
|
|
378325
379087
|
}
|
|
378326
379088
|
return rows;
|
|
378327
379089
|
}
|
|
378328
|
-
function renderSummary(result, roundTrip) {
|
|
378329
|
-
const all = [...result.checks, ...roundTrip ? [roundTrip] : []];
|
|
379090
|
+
function renderSummary(result, roundTrip, extra = []) {
|
|
379091
|
+
const all = [...result.checks, ...roundTrip ? [roundTrip] : [], ...extra];
|
|
378330
379092
|
const passed = all.filter((check4) => check4.status === "pass").length;
|
|
378331
379093
|
const failed2 = all.filter((check4) => check4.status === "fail").length;
|
|
378332
379094
|
const unknown3 = all.filter(
|
|
@@ -378341,7 +379103,7 @@ function renderSummary(result, roundTrip) {
|
|
|
378341
379103
|
}
|
|
378342
379104
|
return parts.join(", ");
|
|
378343
379105
|
}
|
|
378344
|
-
function renderVerifyReport(result, context3, roundTrip) {
|
|
379106
|
+
function renderVerifyReport(result, context3, roundTrip, extra = []) {
|
|
378345
379107
|
const urlNote = `Runtime URL: ${context3.runtimeUrl} ${describeRuntimeUrlSource(context3)}`;
|
|
378346
379108
|
const frontendNote = context3.frontendUrl.url === void 0 ? "Frontend URL: not resolved (nothing in this project named the port its frontend serves; pass --frontend-url)" : `Frontend URL: ${context3.frontendUrl.url} ${describeFrontendUrlSource(context3.frontendUrl)}`;
|
|
378347
379109
|
const lines = [
|
|
@@ -378361,6 +379123,10 @@ function renderVerifyReport(result, context3, roundTrip) {
|
|
|
378361
379123
|
);
|
|
378362
379124
|
lines.push(` ${roundTrip.detail}`);
|
|
378363
379125
|
}
|
|
379126
|
+
for (const check4 of extra) {
|
|
379127
|
+
lines.push(` ${STATUS_LABELS[check4.status].padEnd(7)} ${check4.title}`);
|
|
379128
|
+
lines.push(` ${check4.detail}`);
|
|
379129
|
+
}
|
|
378364
379130
|
const rows = factRows(result.facts);
|
|
378365
379131
|
if (rows.length > 0) {
|
|
378366
379132
|
const labelWidth = Math.max(...rows.map(([label]) => label.length));
|
|
@@ -378369,10 +379135,10 @@ function renderVerifyReport(result, context3, roundTrip) {
|
|
|
378369
379135
|
lines.push(` ${label.padEnd(labelWidth)} ${value}`);
|
|
378370
379136
|
}
|
|
378371
379137
|
}
|
|
378372
|
-
lines.push("", renderSummary(result, roundTrip), "");
|
|
379138
|
+
lines.push("", renderSummary(result, roundTrip, extra), "");
|
|
378373
379139
|
return lines.join("\n");
|
|
378374
379140
|
}
|
|
378375
|
-
function renderVerifyJson(result, context3, roundTrip) {
|
|
379141
|
+
function renderVerifyJson(result, context3, roundTrip, extra = []) {
|
|
378376
379142
|
return `${JSON.stringify(
|
|
378377
379143
|
{
|
|
378378
379144
|
checks: result.checks,
|
|
@@ -378380,8 +379146,9 @@ function renderVerifyJson(result, context3, roundTrip) {
|
|
|
378380
379146
|
// `ok` answers "is this project proven", so a requested round trip that
|
|
378381
379147
|
// did not pass makes it false. Omitting the round trip from the verdict
|
|
378382
379148
|
// would let the strongest evidence in the report contradict its summary.
|
|
378383
|
-
ok: result.ok && (roundTrip === void 0 || roundTrip.status === "pass"),
|
|
379149
|
+
ok: result.ok && (roundTrip === void 0 || roundTrip.status === "pass") && extra.every((check4) => check4.status === "pass"),
|
|
378384
379150
|
...roundTrip === void 0 ? {} : { roundTrip },
|
|
379151
|
+
...extra.length === 0 ? {} : { extraChecks: extra },
|
|
378385
379152
|
// The origin a caller opens, so it never composes one. Absent rather than
|
|
378386
379153
|
// guessed when the project named no port (OSS-1126).
|
|
378387
379154
|
...context3.frontendUrl.url === void 0 ? {} : { frontendUrl: context3.frontendUrl.url },
|
|
@@ -378419,6 +379186,7 @@ function liveDependencies() {
|
|
|
378419
379186
|
return {
|
|
378420
379187
|
appApiUrl: getAppApiUrl(),
|
|
378421
379188
|
cwd: process.cwd(),
|
|
379189
|
+
hostedGatewayUrl: getHostedGatewayUrl(),
|
|
378422
379190
|
env: process.env,
|
|
378423
379191
|
fetchImpl: fetch,
|
|
378424
379192
|
newId: (prefix) => `${prefix}-${randomUUID8()}`,
|
|
@@ -378459,7 +379227,9 @@ async function runVerify(options, overrides = {}) {
|
|
|
378459
379227
|
projectEnvValues: projectEnv.values,
|
|
378460
379228
|
...options.frontendUrl === void 0 ? {} : { flagUrl: options.frontendUrl }
|
|
378461
379229
|
});
|
|
378462
|
-
const
|
|
379230
|
+
const projectApiUrl = (mergedEnv["INTELLIGENCE_API_URL"] ?? "").trim();
|
|
379231
|
+
const appApiUrl = projectApiUrl || deps.appApiUrl;
|
|
379232
|
+
const pairedGatewayUrls = (projectApiUrl === "" ? [deps.hostedGatewayUrl] : [(mergedEnv["INTELLIGENCE_GATEWAY_WS_URL"] ?? "").trim()]).filter((url4) => url4 !== "");
|
|
378463
379233
|
const corsApplies = options.frontendUrl !== void 0 && frontendUrlResolution.url !== void 0 && new URL(frontendUrlResolution.url).origin !== new URL(runtimeUrl).origin;
|
|
378464
379234
|
const [credential, runtime, frontendAssets, cors] = await Promise.all([
|
|
378465
379235
|
probeCredential(appApiUrl, apiKey?.key, deps.fetchImpl),
|
|
@@ -378503,6 +379273,11 @@ async function runVerify(options, overrides = {}) {
|
|
|
378503
379273
|
frontendAssets,
|
|
378504
379274
|
frontendUrl: frontendUrlResolution,
|
|
378505
379275
|
installedPackages,
|
|
379276
|
+
intelligenceTarget: {
|
|
379277
|
+
pairedGatewayUrls,
|
|
379278
|
+
source: projectApiUrl === "" ? "cli-default" : "project-env",
|
|
379279
|
+
verifiedUrl: appApiUrl
|
|
379280
|
+
},
|
|
378506
379281
|
projectConfig,
|
|
378507
379282
|
runtime,
|
|
378508
379283
|
runtimeUrl: runtimeUrlResolution
|
|
@@ -378511,24 +379286,89 @@ async function runVerify(options, overrides = {}) {
|
|
|
378511
379286
|
);
|
|
378512
379287
|
const roundTrip = expectedRuntime === "oss" && (options.roundTrip !== true || options.agent === void 0) ? notAttempted(
|
|
378513
379288
|
"Not attempted: --expect-runtime oss requires --round-trip --agent <id> so the named agent must answer before this command can pass."
|
|
378514
|
-
) : options.roundTrip === true ? await runLiveRoundTrip(
|
|
379289
|
+
) : options.roundTrip === true ? await runLiveRoundTrip(
|
|
379290
|
+
options,
|
|
379291
|
+
deps,
|
|
379292
|
+
runtimeUrlResolution,
|
|
379293
|
+
runtime,
|
|
379294
|
+
appApiUrl,
|
|
379295
|
+
apiKey?.key
|
|
379296
|
+
) : void 0;
|
|
378515
379297
|
const context3 = {
|
|
378516
379298
|
frontendUrl: frontendUrlResolution,
|
|
378517
379299
|
runtimeUrl,
|
|
378518
379300
|
runtimeUrlSource: runtimeUrlResolution.source,
|
|
378519
379301
|
...runtimeUrlResolution.origin === void 0 ? {} : { runtimeUrlOrigin: runtimeUrlResolution.origin }
|
|
378520
379302
|
};
|
|
379303
|
+
const learningContainer = options.expectLearningContainer === void 0 ? void 0 : await runLearningContainerCheck(
|
|
379304
|
+
options.expectLearningContainer,
|
|
379305
|
+
deps,
|
|
379306
|
+
appApiUrl,
|
|
379307
|
+
apiKey?.key,
|
|
379308
|
+
roundTrip
|
|
379309
|
+
);
|
|
379310
|
+
const extra = learningContainer === void 0 ? [] : [learningContainer];
|
|
378521
379311
|
deps.stdout(
|
|
378522
|
-
options.json ? renderVerifyJson(result, context3, roundTrip) : renderVerifyReport(result, context3, roundTrip)
|
|
379312
|
+
options.json ? renderVerifyJson(result, context3, roundTrip, extra) : renderVerifyReport(result, context3, roundTrip, extra)
|
|
378523
379313
|
);
|
|
378524
|
-
if (!result.ok || roundTrip !== void 0 && roundTrip.status !== "pass") {
|
|
379314
|
+
if (!result.ok || roundTrip !== void 0 && roundTrip.status !== "pass" || extra.some((check4) => check4.status !== "pass")) {
|
|
378525
379315
|
process.exitCode = 1;
|
|
378526
379316
|
}
|
|
378527
379317
|
}
|
|
378528
|
-
async function
|
|
378529
|
-
|
|
379318
|
+
async function runLearningContainerCheck(expected, deps, appApiUrl, apiKey, roundTrip) {
|
|
379319
|
+
const base = {
|
|
379320
|
+
id: "learning_container_assigned",
|
|
379321
|
+
title: LEARNING_TITLE
|
|
379322
|
+
};
|
|
379323
|
+
const threadId = roundTrip?.evidence?.threadId;
|
|
379324
|
+
if (threadId === void 0) {
|
|
379325
|
+
deps.recordLearningContainerCheck?.({ outcome: "undetermined" });
|
|
379326
|
+
return {
|
|
379327
|
+
...base,
|
|
379328
|
+
detail: "Not attempted: no thread was created, so there is nothing to read. The assignment is made while a run starts, so this check needs --round-trip --agent <id> to have run one.",
|
|
379329
|
+
status: "undetermined"
|
|
379330
|
+
};
|
|
379331
|
+
}
|
|
379332
|
+
const checked = await checkLearningContainer({
|
|
379333
|
+
apiKey,
|
|
379334
|
+
// The resolved host, not the build-time default. A project that names
|
|
379335
|
+
// `INTELLIGENCE_API_URL` — a self-hosted deployment, or a test standing up
|
|
379336
|
+
// a stub — is the project this check must ask about.
|
|
379337
|
+
appApiUrl,
|
|
379338
|
+
expected,
|
|
379339
|
+
fetchImpl: deps.fetchImpl,
|
|
379340
|
+
threadId
|
|
379341
|
+
});
|
|
379342
|
+
if (checked.kind === "proved") {
|
|
379343
|
+
deps.recordLearningContainerCheck?.({ outcome: "proved" });
|
|
379344
|
+
return {
|
|
379345
|
+
...base,
|
|
379346
|
+
detail: `Thread ${checked.threadId} came back from app-api carrying Learning Container "${checked.containerId}". Read from the platform, so it holds whichever way the runtime is mounted.`,
|
|
379347
|
+
status: "pass"
|
|
379348
|
+
};
|
|
379349
|
+
}
|
|
379350
|
+
if (checked.kind === "mismatch") {
|
|
379351
|
+
deps.recordLearningContainerCheck?.({
|
|
379352
|
+
outcome: checked.actual === void 0 ? "unassigned" : "other-container"
|
|
379353
|
+
});
|
|
379354
|
+
return {
|
|
379355
|
+
...base,
|
|
379356
|
+
detail: checked.actual === void 0 ? `Thread ${checked.threadId} carries no Learning Container, so nothing was assigned. The selector returned nothing for this run, or the runtime holds no getLearningContainerId at all. A plan entitlement or an /info flag saying otherwise is not evidence.` : `Thread ${checked.threadId} is assigned to "${checked.actual}", not "${checked.expected}". A thread cannot move between Containers after its first assignment, so start a new thread rather than repairing this one.`,
|
|
379357
|
+
status: "fail"
|
|
379358
|
+
};
|
|
379359
|
+
}
|
|
379360
|
+
deps.recordLearningContainerCheck?.({ outcome: "undetermined" });
|
|
379361
|
+
return {
|
|
379362
|
+
...base,
|
|
379363
|
+
detail: `Not proven: ${checked.message}`,
|
|
379364
|
+
status: "undetermined"
|
|
379365
|
+
};
|
|
379366
|
+
}
|
|
379367
|
+
async function runLiveRoundTrip(options, deps, runtimeUrl, runtime, appApiUrl, apiKey) {
|
|
379368
|
+
const singleRoute = runtime.kind === "ok" && runtime.transport === "single-route";
|
|
379369
|
+
if (singleRoute && apiKey === void 0) {
|
|
378530
379370
|
return notAttempted(
|
|
378531
|
-
|
|
379371
|
+
"Not attempted: this runtime answers a single-route envelope, so its answer has to be read from the platform, and no Intelligence API key was resolved to read it with. The checks above name the credential this project is missing."
|
|
378532
379372
|
);
|
|
378533
379373
|
}
|
|
378534
379374
|
const declared = runtime.kind === "ok" ? runtime.info.agents : [];
|
|
@@ -378553,6 +379393,10 @@ async function runLiveRoundTrip(options, deps, runtimeUrl, runtime) {
|
|
|
378553
379393
|
const probe = await probeRoundTrip({
|
|
378554
379394
|
agentId,
|
|
378555
379395
|
fetchImpl: deps.fetchImpl,
|
|
379396
|
+
...singleRoute ? {
|
|
379397
|
+
platform: { apiKey: apiKey ?? "", appApiUrl },
|
|
379398
|
+
transport: "single-route"
|
|
379399
|
+
} : {},
|
|
378556
379400
|
newId: deps.newId,
|
|
378557
379401
|
newThreadId: deps.newThreadId,
|
|
378558
379402
|
runtimeUrl: runtimeUrl.url,
|
|
@@ -378570,6 +379414,7 @@ function notAttempted(detail) {
|
|
|
378570
379414
|
title: "The agent answers a real request"
|
|
378571
379415
|
};
|
|
378572
379416
|
}
|
|
379417
|
+
var LEARNING_TITLE;
|
|
378573
379418
|
var init_verify = __esm({
|
|
378574
379419
|
"apps/cli/src/commands/verify.ts"() {
|
|
378575
379420
|
"use strict";
|
|
@@ -378579,6 +379424,7 @@ var init_verify = __esm({
|
|
|
378579
379424
|
init_project_env();
|
|
378580
379425
|
init_round_trip_checks();
|
|
378581
379426
|
init_round_trip_probe();
|
|
379427
|
+
init_learning_container_check();
|
|
378582
379428
|
init_verify_checks();
|
|
378583
379429
|
init_installed_packages();
|
|
378584
379430
|
init_verify_probes();
|
|
@@ -378586,6 +379432,7 @@ var init_verify = __esm({
|
|
|
378586
379432
|
init_runtime_url();
|
|
378587
379433
|
init_frontend_url();
|
|
378588
379434
|
init_runtime_url();
|
|
379435
|
+
LEARNING_TITLE = "The run is assigned to the Learning Container";
|
|
378589
379436
|
}
|
|
378590
379437
|
});
|
|
378591
379438
|
|
|
@@ -382980,7 +383827,7 @@ function createHostedProjectApiClient(auth2) {
|
|
|
382980
383827
|
productOrganizationId: auth2.clerkOrgId
|
|
382981
383828
|
});
|
|
382982
383829
|
}
|
|
382983
|
-
function buildInitNextSteps(templateDefinition, projectName, result, unsatisfiedKeys, installAlreadyRan = false, mockProvider = void 0) {
|
|
383830
|
+
function buildInitNextSteps(templateDefinition, projectName, result, unsatisfiedKeys, installAlreadyRan = false, mockProvider = void 0, mockAvailable = false) {
|
|
382984
383831
|
const missingPrerequisites = templateDefinition.prerequisites.filter(
|
|
382985
383832
|
(prerequisite) => result.missingPrerequisites.includes(prerequisite.command)
|
|
382986
383833
|
);
|
|
@@ -383041,6 +383888,13 @@ function buildInitNextSteps(templateDefinition, projectName, result, unsatisfied
|
|
|
383041
383888
|
code: `${requirement.key}=${requirement.example}`
|
|
383042
383889
|
});
|
|
383043
383890
|
}
|
|
383891
|
+
if (unsatisfiedKeys.length > 0 && mockProvider === void 0 && mockAvailable) {
|
|
383892
|
+
steps.push({ text: " Or run without a key:" });
|
|
383893
|
+
steps.push({
|
|
383894
|
+
text: ` Start a local mock model${SEP2}`,
|
|
383895
|
+
code: "copilotkit mock"
|
|
383896
|
+
});
|
|
383897
|
+
}
|
|
383044
383898
|
for (const note of templateDefinition.setupNotes ?? []) {
|
|
383045
383899
|
steps.push(note.code !== void 0 ? { ...note } : { text: note.text });
|
|
383046
383900
|
}
|
|
@@ -383833,7 +384687,12 @@ function ScaffoldProgress({
|
|
|
383833
384687
|
result,
|
|
383834
384688
|
unsatisfied,
|
|
383835
384689
|
installAlreadyRan,
|
|
383836
|
-
activeMockProvider
|
|
384690
|
+
activeMockProvider,
|
|
384691
|
+
// Gated on the flag as well as on the framework. `copilotkit mock` is
|
|
384692
|
+
// dark in released binaries (`cli.aimock-mock-mode`, prod: false), and a
|
|
384693
|
+
// run told to reach for a command its own CLI does not implement spends
|
|
384694
|
+
// real time discovering that -- which is itself a reported friction.
|
|
384695
|
+
scaffoldedMockProvider !== void 0 && isCliFlagEnabled("cli.aimock-mock-mode")
|
|
383837
384696
|
)
|
|
383838
384697
|
);
|
|
383839
384698
|
setScaffoldWarnings((prev) => mergeScaffoldWarnings(prev, result.warnings));
|
|
@@ -384520,6 +385379,7 @@ async function runLoginJson(dependencies = {
|
|
|
384520
385379
|
login,
|
|
384521
385380
|
recordEvent: recordTelemetryEvent,
|
|
384522
385381
|
readAuthIdentity: currentAuthIdentity,
|
|
385382
|
+
readCodingAgent: currentOnboardingCodingAgent,
|
|
384523
385383
|
readOnboardingRun: currentOnboardingRunProperties
|
|
384524
385384
|
}) {
|
|
384525
385385
|
try {
|
|
@@ -384533,8 +385393,13 @@ async function runLoginJson(dependencies = {
|
|
|
384533
385393
|
return;
|
|
384534
385394
|
}
|
|
384535
385395
|
let loginUrlWritten = false;
|
|
385396
|
+
const codingAgent = dependencies.readCodingAgent();
|
|
384536
385397
|
await dependencies.login({
|
|
384537
|
-
authHandoff: {
|
|
385398
|
+
authHandoff: {
|
|
385399
|
+
source: "cli",
|
|
385400
|
+
mode: "agent_onboarding",
|
|
385401
|
+
...codingAgent === void 0 ? {} : { agent: codingAgent }
|
|
385402
|
+
},
|
|
384538
385403
|
openBrowser: false,
|
|
384539
385404
|
onLoginUrl: (url4) => {
|
|
384540
385405
|
if (loginUrlWritten) {
|
|
@@ -384799,7 +385664,16 @@ function reviewFrictionReport(input) {
|
|
|
384799
385664
|
`--category must be one of: ${FRICTION_CATEGORIES.join(", ")}.`
|
|
384800
385665
|
);
|
|
384801
385666
|
}
|
|
384802
|
-
|
|
385667
|
+
const phase = input.phase === void 0 ? DEFAULT_FRICTION_PHASE : FRICTION_PHASES.find((candidate) => candidate === input.phase);
|
|
385668
|
+
if (phase === void 0) {
|
|
385669
|
+
return refuse(
|
|
385670
|
+
"FRICTION_PHASE_INVALID",
|
|
385671
|
+
`--phase must be one of: ${FRICTION_PHASES.join(", ")}.`
|
|
385672
|
+
);
|
|
385673
|
+
}
|
|
385674
|
+
const costOmitted = input.costSeconds === void 0;
|
|
385675
|
+
const costMalformed = !costOmitted && (!COST_SECONDS_PATTERN.test(input.costSeconds) || Number(input.costSeconds) > MAX_COST_SECONDS_ESTIMATED);
|
|
385676
|
+
if (costMalformed || costOmitted && phase !== "stop") {
|
|
384803
385677
|
return refuse(
|
|
384804
385678
|
"FRICTION_COST_INVALID",
|
|
384805
385679
|
`--cost-seconds must be a whole number of seconds from 0 to ${MAX_COST_SECONDS_ESTIMATED}.`
|
|
@@ -384851,7 +385725,10 @@ function reviewFrictionReport(input) {
|
|
|
384851
385725
|
ok: true,
|
|
384852
385726
|
report: {
|
|
384853
385727
|
category,
|
|
384854
|
-
|
|
385728
|
+
phase,
|
|
385729
|
+
// Spread so a stop report that named no cost leaves the key off rather
|
|
385730
|
+
// than reporting a zero it never estimated.
|
|
385731
|
+
...costOmitted ? {} : { costSecondsEstimated: Number(input.costSeconds) },
|
|
384855
385732
|
// Spread so an absent path leaves the key off entirely, matching how the
|
|
384856
385733
|
// telemetry properties treat every optional dimension.
|
|
384857
385734
|
...docsPath === void 0 ? {} : { docsPath },
|
|
@@ -384859,7 +385736,7 @@ function reviewFrictionReport(input) {
|
|
|
384859
385736
|
}
|
|
384860
385737
|
};
|
|
384861
385738
|
}
|
|
384862
|
-
var FRICTION_CATEGORIES, MAX_FRICTION_TEXT_CHARS, MAX_FRICTION_TEXT_NEWLINES, MAX_COST_SECONDS_ESTIMATED, MAX_FRICTION_INPUT_BYTES, FRICTION_SIZE_LIMIT, MAX_FRICTION_DOCS_PATH_CHARS, DOCS_PATH_PATTERN, COST_SECONDS_PATTERN;
|
|
385739
|
+
var FRICTION_CATEGORIES, FRICTION_PHASES, DEFAULT_FRICTION_PHASE, MAX_FRICTION_TEXT_CHARS, MAX_FRICTION_TEXT_NEWLINES, MAX_COST_SECONDS_ESTIMATED, MAX_FRICTION_INPUT_BYTES, FRICTION_SIZE_LIMIT, MAX_FRICTION_DOCS_PATH_CHARS, DOCS_PATH_PATTERN, COST_SECONDS_PATTERN;
|
|
384863
385740
|
var init_onboarding_friction = __esm({
|
|
384864
385741
|
"apps/cli/src/services/onboarding-friction.ts"() {
|
|
384865
385742
|
"use strict";
|
|
@@ -384876,6 +385753,8 @@ var init_onboarding_friction = __esm({
|
|
|
384876
385753
|
"validation-loop",
|
|
384877
385754
|
"other"
|
|
384878
385755
|
];
|
|
385756
|
+
FRICTION_PHASES = ["repair", "stop", "completion"];
|
|
385757
|
+
DEFAULT_FRICTION_PHASE = "completion";
|
|
384879
385758
|
MAX_FRICTION_TEXT_CHARS = 2e3;
|
|
384880
385759
|
MAX_FRICTION_TEXT_NEWLINES = 3;
|
|
384881
385760
|
MAX_COST_SECONDS_ESTIMATED = 86400;
|
|
@@ -384890,76 +385769,6 @@ var init_onboarding_friction = __esm({
|
|
|
384890
385769
|
}
|
|
384891
385770
|
});
|
|
384892
385771
|
|
|
384893
|
-
// apps/cli/src/services/onboarding-feedback.ts
|
|
384894
|
-
function refuse2(code, message) {
|
|
384895
|
-
return { ok: false, refusal: { code, message } };
|
|
384896
|
-
}
|
|
384897
|
-
async function readFeedbackInput(stdin) {
|
|
384898
|
-
const read = await readBoundedReportText(stdin, MAX_FEEDBACK_INPUT_BYTES);
|
|
384899
|
-
if (read.ok)
|
|
384900
|
-
return { ok: true, text: read.text };
|
|
384901
|
-
if (read.kind === "invalid-utf8") {
|
|
384902
|
-
return refuse2(
|
|
384903
|
-
"ONBOARDING_FEEDBACK_INVALID_UTF8",
|
|
384904
|
-
"Nothing was sent: the report is not valid UTF-8. Send it again as plain UTF-8 text."
|
|
384905
|
-
);
|
|
384906
|
-
}
|
|
384907
|
-
return refuse2(
|
|
384908
|
-
"ONBOARDING_FEEDBACK_TOO_LARGE",
|
|
384909
|
-
`Nothing was sent: the report is too large to read. Shorten it to at most ${MAX_FEEDBACK_TEXT_BYTES} UTF-8 bytes and send it again.`
|
|
384910
|
-
);
|
|
384911
|
-
}
|
|
384912
|
-
function reviewFeedbackReport(text2) {
|
|
384913
|
-
const violation = reviewReportText({
|
|
384914
|
-
text: text2,
|
|
384915
|
-
size: FEEDBACK_SIZE_LIMIT,
|
|
384916
|
-
maxNewlines: MAX_FEEDBACK_TEXT_NEWLINES
|
|
384917
|
-
});
|
|
384918
|
-
if (violation === void 0)
|
|
384919
|
-
return { ok: true, text: text2.trim() };
|
|
384920
|
-
switch (violation.kind) {
|
|
384921
|
-
case "empty":
|
|
384922
|
-
return refuse2(
|
|
384923
|
-
"ONBOARDING_FEEDBACK_EMPTY",
|
|
384924
|
-
"Nothing was sent: the report was empty. Name the step that failed, in one or two sentences, on standard input."
|
|
384925
|
-
);
|
|
384926
|
-
case "possible-secret":
|
|
384927
|
-
return refuse2(
|
|
384928
|
-
"ONBOARDING_FEEDBACK_POSSIBLE_SECRET",
|
|
384929
|
-
`Nothing was sent: the report looks like it contains ${violation.shape}. Describe the problem in words and send it again without the value.`
|
|
384930
|
-
);
|
|
384931
|
-
case "code-block":
|
|
384932
|
-
return refuse2(
|
|
384933
|
-
"ONBOARDING_FEEDBACK_CODE_BLOCK",
|
|
384934
|
-
"Nothing was sent: the report contains a fenced code block. Describe the problem in words, without source code, logs, or command output."
|
|
384935
|
-
);
|
|
384936
|
-
case "too-many-lines":
|
|
384937
|
-
return refuse2(
|
|
384938
|
-
"ONBOARDING_FEEDBACK_TOO_MANY_LINES",
|
|
384939
|
-
`Nothing was sent: the report has more than ${MAX_FEEDBACK_TEXT_NEWLINES + 1} lines, so it reads as pasted output. Send at most ${MAX_FEEDBACK_TEXT_NEWLINES + 1} lines of plain prose.`
|
|
384940
|
-
);
|
|
384941
|
-
case "too-long":
|
|
384942
|
-
return refuse2(
|
|
384943
|
-
"ONBOARDING_FEEDBACK_TOO_LARGE",
|
|
384944
|
-
`Nothing was sent: the report is ${violation.measured} UTF-8 bytes. Shorten it to at most ${MAX_FEEDBACK_TEXT_BYTES} and send it again.`
|
|
384945
|
-
);
|
|
384946
|
-
}
|
|
384947
|
-
}
|
|
384948
|
-
var MAX_FEEDBACK_TEXT_BYTES, MAX_FEEDBACK_TEXT_NEWLINES, MAX_FEEDBACK_INPUT_BYTES, FEEDBACK_SIZE_LIMIT;
|
|
384949
|
-
var init_onboarding_feedback = __esm({
|
|
384950
|
-
"apps/cli/src/services/onboarding-feedback.ts"() {
|
|
384951
|
-
"use strict";
|
|
384952
|
-
init_onboarding_report_text();
|
|
384953
|
-
MAX_FEEDBACK_TEXT_BYTES = 2048;
|
|
384954
|
-
MAX_FEEDBACK_TEXT_NEWLINES = 3;
|
|
384955
|
-
MAX_FEEDBACK_INPUT_BYTES = 2050;
|
|
384956
|
-
FEEDBACK_SIZE_LIMIT = {
|
|
384957
|
-
unit: "utf8-bytes",
|
|
384958
|
-
max: MAX_FEEDBACK_TEXT_BYTES
|
|
384959
|
-
};
|
|
384960
|
-
}
|
|
384961
|
-
});
|
|
384962
|
-
|
|
384963
385772
|
// apps/cli/src/services/onboarding-checkpoint.ts
|
|
384964
385773
|
function reviewCheckpoint(input) {
|
|
384965
385774
|
const phase = CHECKPOINT_PHASES.find((known) => known === input.phase);
|
|
@@ -384994,6 +385803,8 @@ var init_onboarding_checkpoint = __esm({
|
|
|
384994
385803
|
"research-returned",
|
|
384995
385804
|
"starter-cloned",
|
|
384996
385805
|
"plan-written",
|
|
385806
|
+
"container-surveyed",
|
|
385807
|
+
"container-settled",
|
|
384997
385808
|
"build-validated",
|
|
384998
385809
|
"journey-attempted",
|
|
384999
385810
|
"repair-attempted"
|
|
@@ -385005,13 +385816,70 @@ var init_onboarding_checkpoint = __esm({
|
|
|
385005
385816
|
// apps/cli/src/services/onboarding-protected-paths.ts
|
|
385006
385817
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
385007
385818
|
import { createHash as createHash7 } from "node:crypto";
|
|
385008
|
-
import { existsSync as existsSync24, readFileSync as readFileSync24, statSync as statSync4 } from "node:fs";
|
|
385819
|
+
import { existsSync as existsSync24, readFileSync as readFileSync24, readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
|
|
385009
385820
|
import { isAbsolute, join as join31, relative as relative3, resolve as resolve7, sep as sep3 } from "node:path";
|
|
385821
|
+
function deriveProjectFiles(root2) {
|
|
385822
|
+
const found = [];
|
|
385823
|
+
const pending = [root2];
|
|
385824
|
+
while (pending.length > 0) {
|
|
385825
|
+
const directory = pending.pop();
|
|
385826
|
+
if (directory === void 0)
|
|
385827
|
+
break;
|
|
385828
|
+
let entries;
|
|
385829
|
+
try {
|
|
385830
|
+
entries = readdirSync4(directory, { withFileTypes: true });
|
|
385831
|
+
} catch {
|
|
385832
|
+
continue;
|
|
385833
|
+
}
|
|
385834
|
+
for (const entry of entries) {
|
|
385835
|
+
const absolute = join31(directory, entry.name);
|
|
385836
|
+
if (entry.isDirectory()) {
|
|
385837
|
+
if (!SKIPPED_DIRECTORIES3.has(entry.name))
|
|
385838
|
+
pending.push(absolute);
|
|
385839
|
+
continue;
|
|
385840
|
+
}
|
|
385841
|
+
const relativePath = toRepositoryRelative(root2, absolute);
|
|
385842
|
+
if (relativePath !== void 0)
|
|
385843
|
+
found.push(relativePath);
|
|
385844
|
+
}
|
|
385845
|
+
}
|
|
385846
|
+
return found;
|
|
385847
|
+
}
|
|
385010
385848
|
function isGraphOwned(relativePath) {
|
|
385011
385849
|
return GRAPH_OWNED_SUFFIXES.some(
|
|
385012
385850
|
(suffix) => relativePath === suffix || relativePath.endsWith(`/${suffix}`)
|
|
385013
385851
|
);
|
|
385014
385852
|
}
|
|
385853
|
+
function isEnvPath(relativePath) {
|
|
385854
|
+
return relativePath === ".env" || relativePath.endsWith("/.env");
|
|
385855
|
+
}
|
|
385856
|
+
function envKeysOf(root2, relativePath) {
|
|
385857
|
+
const absolute = join31(root2, relativePath);
|
|
385858
|
+
try {
|
|
385859
|
+
if (!existsSync24(absolute))
|
|
385860
|
+
return [];
|
|
385861
|
+
const values = readDotEnvValues(readFileSync24(absolute, "utf8"));
|
|
385862
|
+
return Object.entries(values).map(([name, value]) => ({
|
|
385863
|
+
name,
|
|
385864
|
+
hasValue: value.trim() !== ""
|
|
385865
|
+
}));
|
|
385866
|
+
} catch {
|
|
385867
|
+
return "unreadable";
|
|
385868
|
+
}
|
|
385869
|
+
}
|
|
385870
|
+
function lostCredentials(recorded, current) {
|
|
385871
|
+
const now = new Map(current.map((key) => [key.name, key.hasValue]));
|
|
385872
|
+
return recorded.filter((key) => key.hasValue && now.get(key.name) !== true).map((key) => key.name);
|
|
385873
|
+
}
|
|
385874
|
+
function isEnvKeyList(value) {
|
|
385875
|
+
if (value === void 0)
|
|
385876
|
+
return true;
|
|
385877
|
+
if (!Array.isArray(value))
|
|
385878
|
+
return false;
|
|
385879
|
+
return value.every(
|
|
385880
|
+
(key) => typeof key === "object" && key !== null && typeof key.name === "string" && typeof key.hasValue === "boolean"
|
|
385881
|
+
);
|
|
385882
|
+
}
|
|
385015
385883
|
function isAcceptedDrift(value) {
|
|
385016
385884
|
if (value === void 0)
|
|
385017
385885
|
return true;
|
|
@@ -385026,7 +385894,7 @@ function isPathAuthorization(value) {
|
|
|
385026
385894
|
if (typeof value !== "object" || value === null)
|
|
385027
385895
|
return false;
|
|
385028
385896
|
const candidate = value;
|
|
385029
|
-
return typeof candidate.reason === "string" && typeof candidate.at === "string";
|
|
385897
|
+
return typeof candidate.reason === "string" && typeof candidate.at === "string" && (candidate.unplanned === void 0 || candidate.unplanned === true);
|
|
385030
385898
|
}
|
|
385031
385899
|
function changeBetween(captured, current) {
|
|
385032
385900
|
if (captured === void 0)
|
|
@@ -385059,13 +385927,19 @@ function readManifest(dependencies) {
|
|
|
385059
385927
|
return "malformed";
|
|
385060
385928
|
if (typeof stored.capturedAt !== "string")
|
|
385061
385929
|
return "malformed";
|
|
385930
|
+
if (stored.implementationStartedAt !== void 0 && typeof stored.implementationStartedAt !== "string") {
|
|
385931
|
+
return "malformed";
|
|
385932
|
+
}
|
|
385062
385933
|
if (!Array.isArray(stored.entries))
|
|
385063
385934
|
return "malformed";
|
|
385064
385935
|
const wellFormed = stored.entries.every(
|
|
385065
|
-
(entry) => typeof entry === "object" && entry !== null && typeof entry.path === "string" && (entry.pathClass === "protected" || entry.pathClass === "deferred") && (entry.digest === void 0 || typeof entry.digest === "string") && isAcceptedDrift(entry.acceptedDrift) && isPathAuthorization(entry.authorization)
|
|
385936
|
+
(entry) => typeof entry === "object" && entry !== null && typeof entry.path === "string" && (entry.pathClass === "protected" || entry.pathClass === "deferred") && (entry.digest === void 0 || typeof entry.digest === "string") && isAcceptedDrift(entry.acceptedDrift) && isPathAuthorization(entry.authorization) && isEnvKeyList(entry.envKeys)
|
|
385066
385937
|
);
|
|
385067
385938
|
return wellFormed ? stored : "malformed";
|
|
385068
385939
|
}
|
|
385940
|
+
function startedMark(stored) {
|
|
385941
|
+
return stored?.implementationStartedAt === void 0 ? {} : { implementationStartedAt: stored.implementationStartedAt };
|
|
385942
|
+
}
|
|
385069
385943
|
function digestOf(root2, relativePath) {
|
|
385070
385944
|
const absolute = join31(root2, relativePath);
|
|
385071
385945
|
try {
|
|
@@ -385084,8 +385958,8 @@ function byPath(entries) {
|
|
|
385084
385958
|
);
|
|
385085
385959
|
}
|
|
385086
385960
|
function deriveChangedPaths(root2) {
|
|
385087
|
-
if (
|
|
385088
|
-
return
|
|
385961
|
+
if (findRepositoryRoot(root2) === void 0)
|
|
385962
|
+
return "no-repository";
|
|
385089
385963
|
let output;
|
|
385090
385964
|
try {
|
|
385091
385965
|
output = execFileSync5(
|
|
@@ -385128,6 +386002,9 @@ function probeGraphOwned(root2, cwd2) {
|
|
|
385128
386002
|
}
|
|
385129
386003
|
return found;
|
|
385130
386004
|
}
|
|
386005
|
+
function toRequestedPath(root2, path45) {
|
|
386006
|
+
return isAbsolute(path45) ? path45 : resolve7(root2, path45);
|
|
386007
|
+
}
|
|
385131
386008
|
function toRepositoryRelative(root2, absolute) {
|
|
385132
386009
|
const relativePath = relative3(root2, absolute);
|
|
385133
386010
|
if (relativePath === "" || relativePath.startsWith(".."))
|
|
@@ -385140,10 +386017,14 @@ function captureEntry(root2, relativePath, derived) {
|
|
|
385140
386017
|
const read = digestOf(root2, relativePath);
|
|
385141
386018
|
if (read === "unreadable")
|
|
385142
386019
|
return "unreadable";
|
|
386020
|
+
const envKeys = isEnvPath(relativePath) ? envKeysOf(root2, relativePath) : void 0;
|
|
386021
|
+
if (envKeys === "unreadable")
|
|
386022
|
+
return "unreadable";
|
|
385143
386023
|
return {
|
|
385144
386024
|
path: relativePath,
|
|
385145
386025
|
pathClass: derived && isGraphOwned(relativePath) ? "deferred" : "protected",
|
|
385146
|
-
...read.digest === void 0 ? {} : { digest: read.digest }
|
|
386026
|
+
...read.digest === void 0 ? {} : { digest: read.digest },
|
|
386027
|
+
...envKeys === void 0 ? {} : { envKeys }
|
|
385147
386028
|
};
|
|
385148
386029
|
}
|
|
385149
386030
|
function captureProtectedPaths(dependencies, input) {
|
|
@@ -385154,7 +386035,7 @@ function captureProtectedPaths(dependencies, input) {
|
|
|
385154
386035
|
const existing = ownBaseline?.entries ?? [];
|
|
385155
386036
|
const requested = [];
|
|
385156
386037
|
for (const path45 of input.paths) {
|
|
385157
|
-
const absolute =
|
|
386038
|
+
const absolute = toRequestedPath(root2, path45);
|
|
385158
386039
|
const relativePath = toRepositoryRelative(root2, absolute);
|
|
385159
386040
|
if (relativePath === void 0) {
|
|
385160
386041
|
return {
|
|
@@ -385181,7 +386062,8 @@ function captureProtectedPaths(dependencies, input) {
|
|
|
385181
386062
|
if (changed === "failed") {
|
|
385182
386063
|
return { status: "blocked", reason: "git-failed", detail: root2 };
|
|
385183
386064
|
}
|
|
385184
|
-
|
|
386065
|
+
const derived = changed === "no-repository" ? deriveProjectFiles(root2) : changed;
|
|
386066
|
+
for (const path45 of derived)
|
|
385185
386067
|
candidates.add(path45);
|
|
385186
386068
|
for (const path45 of probeGraphOwned(root2, dependencies.cwd)) {
|
|
385187
386069
|
candidates.add(path45);
|
|
@@ -385204,6 +386086,7 @@ function captureProtectedPaths(dependencies, input) {
|
|
|
385204
386086
|
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
385205
386087
|
runId: input.runId,
|
|
385206
386088
|
capturedAt: ownBaseline?.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
386089
|
+
...startedMark(ownBaseline),
|
|
385207
386090
|
entries
|
|
385208
386091
|
});
|
|
385209
386092
|
return {
|
|
@@ -385289,7 +386172,7 @@ function rebaselineProtectedPaths(dependencies, input) {
|
|
|
385289
386172
|
}
|
|
385290
386173
|
const targets = [];
|
|
385291
386174
|
for (const path45 of input.paths) {
|
|
385292
|
-
const absolute =
|
|
386175
|
+
const absolute = toRequestedPath(root2, path45);
|
|
385293
386176
|
const relativePath = toRepositoryRelative(root2, absolute);
|
|
385294
386177
|
if (relativePath === void 0) {
|
|
385295
386178
|
return { status: "blocked", reason: "unknown-path", detail: path45 };
|
|
@@ -385318,10 +386201,19 @@ function rebaselineProtectedPaths(dependencies, input) {
|
|
|
385318
386201
|
detail: entry.path
|
|
385319
386202
|
};
|
|
385320
386203
|
}
|
|
386204
|
+
const promotedKeys = isEnvPath(entry.path) ? envKeysOf(root2, entry.path) : void 0;
|
|
386205
|
+
if (promotedKeys === "unreadable") {
|
|
386206
|
+
return {
|
|
386207
|
+
status: "blocked",
|
|
386208
|
+
reason: "unreadable-path",
|
|
386209
|
+
detail: entry.path
|
|
386210
|
+
};
|
|
386211
|
+
}
|
|
385321
386212
|
const next = {
|
|
385322
386213
|
path: entry.path,
|
|
385323
386214
|
pathClass: "protected",
|
|
385324
|
-
...read.digest === void 0 ? {} : { digest: read.digest }
|
|
386215
|
+
...read.digest === void 0 ? {} : { digest: read.digest },
|
|
386216
|
+
...promotedKeys === void 0 ? {} : { envKeys: promotedKeys }
|
|
385325
386217
|
};
|
|
385326
386218
|
entries.push(next);
|
|
385327
386219
|
promoted.push(next);
|
|
@@ -385329,6 +386221,7 @@ function rebaselineProtectedPaths(dependencies, input) {
|
|
|
385329
386221
|
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
385330
386222
|
runId: stored.runId,
|
|
385331
386223
|
capturedAt: stored.capturedAt,
|
|
386224
|
+
...startedMark(stored),
|
|
385332
386225
|
entries: byPath(entries)
|
|
385333
386226
|
});
|
|
385334
386227
|
return { status: "passed", runId: stored.runId, promoted: byPath(promoted) };
|
|
@@ -385369,7 +386262,7 @@ function acceptProtectedPathDrift(dependencies, input) {
|
|
|
385369
386262
|
const drift = /* @__PURE__ */ new Map();
|
|
385370
386263
|
const accepted = [];
|
|
385371
386264
|
for (const path45 of input.paths) {
|
|
385372
|
-
const absolute =
|
|
386265
|
+
const absolute = toRequestedPath(root2, path45);
|
|
385373
386266
|
const relativePath = toRepositoryRelative(root2, absolute);
|
|
385374
386267
|
if (relativePath === void 0) {
|
|
385375
386268
|
return { status: "blocked", reason: "unknown-path", detail: path45 };
|
|
@@ -385436,16 +386329,166 @@ function acceptProtectedPathDrift(dependencies, input) {
|
|
|
385436
386329
|
path: entry.path,
|
|
385437
386330
|
pathClass: entry.pathClass,
|
|
385438
386331
|
...digest === void 0 ? {} : { digest },
|
|
386332
|
+
// Carried rather than rebuilt. No env path reaches here today, because
|
|
386333
|
+
// every one of them is graph-owned and refused above. That is a guard one
|
|
386334
|
+
// edit away from changing, and dropping the record would leave the
|
|
386335
|
+
// credential route refusing `unrecorded-keys` on a path it should answer.
|
|
386336
|
+
...entry.envKeys === void 0 ? {} : { envKeys: entry.envKeys },
|
|
385439
386337
|
acceptedDrift
|
|
385440
386338
|
});
|
|
385441
386339
|
}
|
|
385442
386340
|
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
385443
386341
|
runId: stored.runId,
|
|
385444
386342
|
capturedAt: stored.capturedAt,
|
|
386343
|
+
...startedMark(stored),
|
|
385445
386344
|
entries: byPath(entries)
|
|
385446
386345
|
});
|
|
385447
386346
|
return { status: "passed", runId: stored.runId, accepted: byPath(accepted) };
|
|
385448
386347
|
}
|
|
386348
|
+
function acceptCredentialPlacement(dependencies, input) {
|
|
386349
|
+
const root2 = resolveAnchoredRoot(dependencies);
|
|
386350
|
+
const stored = readManifest(dependencies);
|
|
386351
|
+
if (stored === void 0) {
|
|
386352
|
+
return { status: "blocked", reason: "no-baseline", detail: input.runId };
|
|
386353
|
+
}
|
|
386354
|
+
if (stored === "malformed") {
|
|
386355
|
+
return {
|
|
386356
|
+
status: "blocked",
|
|
386357
|
+
reason: "unreadable-baseline",
|
|
386358
|
+
detail: input.runId
|
|
386359
|
+
};
|
|
386360
|
+
}
|
|
386361
|
+
if (stored.runId !== input.runId) {
|
|
386362
|
+
return { status: "blocked", reason: "run-mismatch", detail: stored.runId };
|
|
386363
|
+
}
|
|
386364
|
+
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
386365
|
+
const placed = /* @__PURE__ */ new Map();
|
|
386366
|
+
const accepted = [];
|
|
386367
|
+
for (const path45 of input.paths) {
|
|
386368
|
+
const absolute = toRequestedPath(root2, path45);
|
|
386369
|
+
const relativePath = toRepositoryRelative(root2, absolute);
|
|
386370
|
+
if (relativePath === void 0) {
|
|
386371
|
+
return { status: "blocked", reason: "unknown-path", detail: path45 };
|
|
386372
|
+
}
|
|
386373
|
+
if (placed.has(relativePath))
|
|
386374
|
+
continue;
|
|
386375
|
+
if (!isEnvPath(relativePath)) {
|
|
386376
|
+
return { status: "blocked", reason: "not-env-path", detail: relativePath };
|
|
386377
|
+
}
|
|
386378
|
+
const entry = stored.entries.find((held) => held.path === relativePath);
|
|
386379
|
+
if (entry === void 0) {
|
|
386380
|
+
return { status: "blocked", reason: "unknown-path", detail: relativePath };
|
|
386381
|
+
}
|
|
386382
|
+
if (entry.pathClass === "deferred") {
|
|
386383
|
+
return {
|
|
386384
|
+
status: "blocked",
|
|
386385
|
+
reason: "deferred-path",
|
|
386386
|
+
detail: relativePath
|
|
386387
|
+
};
|
|
386388
|
+
}
|
|
386389
|
+
const read = digestOf(root2, relativePath);
|
|
386390
|
+
if (read === "unreadable") {
|
|
386391
|
+
return {
|
|
386392
|
+
status: "blocked",
|
|
386393
|
+
reason: "unreadable-path",
|
|
386394
|
+
detail: relativePath
|
|
386395
|
+
};
|
|
386396
|
+
}
|
|
386397
|
+
if (read.digest === entry.digest) {
|
|
386398
|
+
return {
|
|
386399
|
+
status: "blocked",
|
|
386400
|
+
reason: "unchanged-path",
|
|
386401
|
+
detail: relativePath
|
|
386402
|
+
};
|
|
386403
|
+
}
|
|
386404
|
+
const current = envKeysOf(root2, relativePath);
|
|
386405
|
+
if (current === "unreadable") {
|
|
386406
|
+
return {
|
|
386407
|
+
status: "blocked",
|
|
386408
|
+
reason: "unreadable-path",
|
|
386409
|
+
detail: relativePath
|
|
386410
|
+
};
|
|
386411
|
+
}
|
|
386412
|
+
if (entry.envKeys === void 0) {
|
|
386413
|
+
return {
|
|
386414
|
+
status: "blocked",
|
|
386415
|
+
reason: "unrecorded-keys",
|
|
386416
|
+
detail: relativePath
|
|
386417
|
+
};
|
|
386418
|
+
}
|
|
386419
|
+
const lost = lostCredentials(entry.envKeys, current);
|
|
386420
|
+
if (lost.length > 0) {
|
|
386421
|
+
return {
|
|
386422
|
+
status: "blocked",
|
|
386423
|
+
reason: "credential-lost",
|
|
386424
|
+
detail: `${relativePath}: ${lost.join(", ")}`
|
|
386425
|
+
};
|
|
386426
|
+
}
|
|
386427
|
+
const change = changeBetween(entry.digest, read.digest);
|
|
386428
|
+
placed.set(relativePath, {
|
|
386429
|
+
change,
|
|
386430
|
+
at,
|
|
386431
|
+
envKeys: current,
|
|
386432
|
+
...read.digest === void 0 ? {} : { digest: read.digest }
|
|
386433
|
+
});
|
|
386434
|
+
accepted.push({ path: relativePath, change, at });
|
|
386435
|
+
}
|
|
386436
|
+
const entries = [];
|
|
386437
|
+
for (const entry of stored.entries) {
|
|
386438
|
+
const moved = placed.get(entry.path);
|
|
386439
|
+
if (moved === void 0) {
|
|
386440
|
+
entries.push(entry);
|
|
386441
|
+
continue;
|
|
386442
|
+
}
|
|
386443
|
+
const { digest, envKeys, ...acceptedDrift } = moved;
|
|
386444
|
+
entries.push({
|
|
386445
|
+
path: entry.path,
|
|
386446
|
+
pathClass: entry.pathClass,
|
|
386447
|
+
...digest === void 0 ? {} : { digest },
|
|
386448
|
+
...entry.authorization === void 0 ? {} : { authorization: entry.authorization },
|
|
386449
|
+
acceptedDrift,
|
|
386450
|
+
envKeys
|
|
386451
|
+
});
|
|
386452
|
+
}
|
|
386453
|
+
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
386454
|
+
runId: stored.runId,
|
|
386455
|
+
capturedAt: stored.capturedAt,
|
|
386456
|
+
...startedMark(stored),
|
|
386457
|
+
entries: byPath(entries)
|
|
386458
|
+
});
|
|
386459
|
+
return { status: "passed", runId: stored.runId, accepted: byPath(accepted) };
|
|
386460
|
+
}
|
|
386461
|
+
function markImplementationStarted(dependencies, input) {
|
|
386462
|
+
const stored = readManifest(dependencies);
|
|
386463
|
+
if (stored === void 0) {
|
|
386464
|
+
return { status: "blocked", reason: "no-baseline", detail: input.runId };
|
|
386465
|
+
}
|
|
386466
|
+
if (stored === "malformed") {
|
|
386467
|
+
return {
|
|
386468
|
+
status: "blocked",
|
|
386469
|
+
reason: "unreadable-baseline",
|
|
386470
|
+
detail: input.runId
|
|
386471
|
+
};
|
|
386472
|
+
}
|
|
386473
|
+
if (stored.runId !== input.runId) {
|
|
386474
|
+
return { status: "blocked", reason: "run-mismatch", detail: stored.runId };
|
|
386475
|
+
}
|
|
386476
|
+
if (stored.implementationStartedAt !== void 0) {
|
|
386477
|
+
return {
|
|
386478
|
+
status: "passed",
|
|
386479
|
+
runId: stored.runId,
|
|
386480
|
+
startedAt: stored.implementationStartedAt
|
|
386481
|
+
};
|
|
386482
|
+
}
|
|
386483
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
386484
|
+
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
386485
|
+
runId: stored.runId,
|
|
386486
|
+
capturedAt: stored.capturedAt,
|
|
386487
|
+
implementationStartedAt: startedAt,
|
|
386488
|
+
entries: stored.entries
|
|
386489
|
+
});
|
|
386490
|
+
return { status: "passed", runId: stored.runId, startedAt };
|
|
386491
|
+
}
|
|
385449
386492
|
function authorizeProtectedPathChange(dependencies, input) {
|
|
385450
386493
|
const root2 = resolveAnchoredRoot(dependencies);
|
|
385451
386494
|
const stored = readManifest(dependencies);
|
|
@@ -385468,9 +386511,10 @@ function authorizeProtectedPathChange(dependencies, input) {
|
|
|
385468
386511
|
}
|
|
385469
386512
|
const at = (/* @__PURE__ */ new Date()).toISOString();
|
|
385470
386513
|
const granted = /* @__PURE__ */ new Map();
|
|
386514
|
+
const priorDrift = /* @__PURE__ */ new Map();
|
|
385471
386515
|
const authorized = [];
|
|
385472
386516
|
for (const path45 of input.paths) {
|
|
385473
|
-
const absolute =
|
|
386517
|
+
const absolute = toRequestedPath(root2, path45);
|
|
385474
386518
|
const relativePath = toRepositoryRelative(root2, absolute);
|
|
385475
386519
|
if (relativePath === void 0) {
|
|
385476
386520
|
return { status: "blocked", reason: "unknown-path", detail: path45 };
|
|
@@ -385495,6 +386539,24 @@ function authorizeProtectedPathChange(dependencies, input) {
|
|
|
385495
386539
|
detail: relativePath
|
|
385496
386540
|
};
|
|
385497
386541
|
}
|
|
386542
|
+
const started = stored.implementationStartedAt !== void 0;
|
|
386543
|
+
if (started && input.unplanned !== true) {
|
|
386544
|
+
return {
|
|
386545
|
+
status: "blocked",
|
|
386546
|
+
reason: "unplanned-path",
|
|
386547
|
+
detail: relativePath
|
|
386548
|
+
};
|
|
386549
|
+
}
|
|
386550
|
+
if (!started && input.unplanned === true) {
|
|
386551
|
+
return { status: "blocked", reason: "planned-path", detail: relativePath };
|
|
386552
|
+
}
|
|
386553
|
+
if (started && input.acceptPriorChange === true) {
|
|
386554
|
+
return {
|
|
386555
|
+
status: "blocked",
|
|
386556
|
+
reason: "prior-change-after-start",
|
|
386557
|
+
detail: relativePath
|
|
386558
|
+
};
|
|
386559
|
+
}
|
|
385498
386560
|
const read = digestOf(root2, relativePath);
|
|
385499
386561
|
if (read === "unreadable") {
|
|
385500
386562
|
return {
|
|
@@ -385504,18 +386566,45 @@ function authorizeProtectedPathChange(dependencies, input) {
|
|
|
385504
386566
|
};
|
|
385505
386567
|
}
|
|
385506
386568
|
if (read.digest !== entry.digest) {
|
|
385507
|
-
|
|
386569
|
+
if (input.acceptPriorChange !== true) {
|
|
386570
|
+
return {
|
|
386571
|
+
status: "blocked",
|
|
386572
|
+
reason: "changed-path",
|
|
386573
|
+
detail: relativePath
|
|
386574
|
+
};
|
|
386575
|
+
}
|
|
386576
|
+
priorDrift.set(relativePath, {
|
|
386577
|
+
change: changeBetween(entry.digest, read.digest),
|
|
386578
|
+
at,
|
|
386579
|
+
...read.digest === void 0 ? {} : { digest: read.digest }
|
|
386580
|
+
});
|
|
385508
386581
|
}
|
|
385509
|
-
|
|
385510
|
-
|
|
386582
|
+
const authorization = input.unplanned === true ? { reason, at, unplanned: true } : { reason, at };
|
|
386583
|
+
granted.set(relativePath, authorization);
|
|
386584
|
+
authorized.push({ path: relativePath, ...authorization });
|
|
385511
386585
|
}
|
|
385512
386586
|
const entries = stored.entries.map((entry) => {
|
|
385513
386587
|
const authorization = granted.get(entry.path);
|
|
385514
|
-
|
|
386588
|
+
if (authorization === void 0)
|
|
386589
|
+
return entry;
|
|
386590
|
+
const moved = priorDrift.get(entry.path);
|
|
386591
|
+
if (moved === void 0)
|
|
386592
|
+
return { ...entry, authorization };
|
|
386593
|
+
const { digest, ...acceptedDrift } = moved;
|
|
386594
|
+
return {
|
|
386595
|
+
path: entry.path,
|
|
386596
|
+
pathClass: entry.pathClass,
|
|
386597
|
+
...digest === void 0 ? {} : { digest },
|
|
386598
|
+
// Carried for the same reason as in the acceptance route above.
|
|
386599
|
+
...entry.envKeys === void 0 ? {} : { envKeys: entry.envKeys },
|
|
386600
|
+
acceptedDrift,
|
|
386601
|
+
authorization
|
|
386602
|
+
};
|
|
385515
386603
|
});
|
|
385516
386604
|
dependencies.store.set(protectedBaselineKey(dependencies), {
|
|
385517
386605
|
runId: stored.runId,
|
|
385518
386606
|
capturedAt: stored.capturedAt,
|
|
386607
|
+
...startedMark(stored),
|
|
385519
386608
|
entries: byPath(entries)
|
|
385520
386609
|
});
|
|
385521
386610
|
return {
|
|
@@ -385524,26 +386613,60 @@ function authorizeProtectedPathChange(dependencies, input) {
|
|
|
385524
386613
|
authorized: byPath(authorized)
|
|
385525
386614
|
};
|
|
385526
386615
|
}
|
|
385527
|
-
var GRAPH_OWNED_SUFFIXES;
|
|
386616
|
+
var SKIPPED_DIRECTORIES3, GRAPH_OWNED_SUFFIXES;
|
|
385528
386617
|
var init_onboarding_protected_paths = __esm({
|
|
385529
386618
|
"apps/cli/src/services/onboarding-protected-paths.ts"() {
|
|
385530
386619
|
"use strict";
|
|
386620
|
+
init_dotenv_read();
|
|
386621
|
+
init_repository_root();
|
|
385531
386622
|
init_onboarding_state();
|
|
386623
|
+
SKIPPED_DIRECTORIES3 = /* @__PURE__ */ new Set([
|
|
386624
|
+
"node_modules",
|
|
386625
|
+
"dist",
|
|
386626
|
+
"build",
|
|
386627
|
+
"out",
|
|
386628
|
+
"coverage",
|
|
386629
|
+
".next",
|
|
386630
|
+
"venv",
|
|
386631
|
+
"__pycache__"
|
|
386632
|
+
]);
|
|
385532
386633
|
GRAPH_OWNED_SUFFIXES = [".env", ".copilotkit/project.json"];
|
|
385533
386634
|
}
|
|
385534
386635
|
});
|
|
385535
386636
|
|
|
385536
386637
|
// apps/cli/src/services/onboarding-classification.ts
|
|
385537
|
-
function
|
|
385538
|
-
if (
|
|
385539
|
-
return void 0;
|
|
385540
|
-
if (route.length === 0)
|
|
386638
|
+
function resolveAgentFrameworkAlias(value) {
|
|
386639
|
+
if (value === void 0)
|
|
385541
386640
|
return void 0;
|
|
385542
|
-
|
|
386641
|
+
return ONBOARDING_AGENT_FRAMEWORK_ALIASES[value] ?? value;
|
|
386642
|
+
}
|
|
386643
|
+
function unprovenBaselineRefusal(startingState, route, proof) {
|
|
386644
|
+
if (startingState !== "both-oss" && startingState !== "both-copilotkit-unproved") {
|
|
385543
386645
|
return void 0;
|
|
385544
|
-
|
|
386646
|
+
}
|
|
386647
|
+
if (route.length > 0 && !route.includes(OSS_BASELINE_NODE)) {
|
|
386648
|
+
return `--starting-state ${startingState} records a project whose CopilotKit integration was reached, and this run never served ${OSS_BASELINE_NODE}.
|
|
385545
386649
|
Its route is: ${route.join(",")}.
|
|
385546
386650
|
Read ${OSS_BASELINE_NODE} and record the state its proof returns.`;
|
|
386651
|
+
}
|
|
386652
|
+
if (proof === void 0)
|
|
386653
|
+
return void 0;
|
|
386654
|
+
if (startingState === "both-oss") {
|
|
386655
|
+
return proof.outcome === "passed" ? void 0 : `--starting-state both-oss records a proved OSS baseline, and this run recorded that baseline as ${proof.outcome}.
|
|
386656
|
+
Record --starting-state both-copilotkit-unproved instead: the CopilotKit integration is present and its round trip did not prove.`;
|
|
386657
|
+
}
|
|
386658
|
+
return proof.outcome === "passed" ? `--starting-state both-copilotkit-unproved records a round trip that did not prove, and this run recorded its baseline as passed.
|
|
386659
|
+
Record --starting-state both-oss instead, and keep the proof evidence with the plan.` : void 0;
|
|
386660
|
+
}
|
|
386661
|
+
function contradictedIntegrationRefusal(startingState, route) {
|
|
386662
|
+
if (!ABSENCE_STATES.some((state) => state === startingState)) {
|
|
386663
|
+
return void 0;
|
|
386664
|
+
}
|
|
386665
|
+
if (!route.includes(OSS_BASELINE_NODE))
|
|
386666
|
+
return void 0;
|
|
386667
|
+
return `--starting-state ${startingState} records a project without a CopilotKit integration, and this run was served ${OSS_BASELINE_NODE}, which is reached only when an agent, a frontend and a CopilotKit integration are all proved present.
|
|
386668
|
+
Its route is: ${route.join(",")}.
|
|
386669
|
+
Record --starting-state both-oss for a baseline that proved, or --starting-state both-copilotkit-unproved for one that did not.`;
|
|
385547
386670
|
}
|
|
385548
386671
|
function unresearchedBaselineWarning(promptName, route) {
|
|
385549
386672
|
if (promptName !== OSS_BASELINE_NODE)
|
|
@@ -385563,7 +386686,7 @@ function requireOnboardingChoice(flag, value, choices) {
|
|
|
385563
386686
|
}
|
|
385564
386687
|
return selected;
|
|
385565
386688
|
}
|
|
385566
|
-
var ONBOARDING_STARTING_STATES, ONBOARDING_AGENT_FRAMEWORKS, ONBOARDING_FRONTENDS, OSS_BASELINE_NODE, TERMINAL_NODES, REPOSITORY_RESEARCH_NODE;
|
|
386689
|
+
var ONBOARDING_STARTING_STATES, ONBOARDING_AGENT_FRAMEWORKS, ONBOARDING_AGENT_FRAMEWORK_ALIASES, ONBOARDING_FRONTENDS, ONBOARDING_PROOF_STEPS, ONBOARDING_PROOF_OUTCOMES, ABSENCE_STATES, OSS_BASELINE_NODE, TERMINAL_NODES, REPOSITORY_RESEARCH_NODE;
|
|
385567
386690
|
var init_onboarding_classification = __esm({
|
|
385568
386691
|
"apps/cli/src/services/onboarding-classification.ts"() {
|
|
385569
386692
|
"use strict";
|
|
@@ -385572,6 +386695,7 @@ var init_onboarding_classification = __esm({
|
|
|
385572
386695
|
"agent-only",
|
|
385573
386696
|
"frontend-only",
|
|
385574
386697
|
"both",
|
|
386698
|
+
"both-copilotkit-unproved",
|
|
385575
386699
|
"both-oss"
|
|
385576
386700
|
];
|
|
385577
386701
|
ONBOARDING_AGENT_FRAMEWORKS = [
|
|
@@ -385595,6 +386719,9 @@ var init_onboarding_classification = __esm({
|
|
|
385595
386719
|
"strands-python",
|
|
385596
386720
|
"strands-typescript"
|
|
385597
386721
|
];
|
|
386722
|
+
ONBOARDING_AGENT_FRAMEWORK_ALIASES = {
|
|
386723
|
+
langgraph: "langgraph-python"
|
|
386724
|
+
};
|
|
385598
386725
|
ONBOARDING_FRONTENDS = [
|
|
385599
386726
|
"react-spa",
|
|
385600
386727
|
"nextjs",
|
|
@@ -385602,6 +386729,18 @@ var init_onboarding_classification = __esm({
|
|
|
385602
386729
|
"vue",
|
|
385603
386730
|
"react-native"
|
|
385604
386731
|
];
|
|
386732
|
+
ONBOARDING_PROOF_STEPS = ["oss-baseline", "round-trip"];
|
|
386733
|
+
ONBOARDING_PROOF_OUTCOMES = [
|
|
386734
|
+
"passed",
|
|
386735
|
+
"failed",
|
|
386736
|
+
"skipped"
|
|
386737
|
+
];
|
|
386738
|
+
ABSENCE_STATES = [
|
|
386739
|
+
"empty",
|
|
386740
|
+
"agent-only",
|
|
386741
|
+
"frontend-only",
|
|
386742
|
+
"both"
|
|
386743
|
+
];
|
|
385605
386744
|
OSS_BASELINE_NODE = "proof/oss-baseline";
|
|
385606
386745
|
TERMINAL_NODES = {
|
|
385607
386746
|
"fallback/best-effort": "best-effort",
|
|
@@ -385611,6 +386750,12 @@ var init_onboarding_classification = __esm({
|
|
|
385611
386750
|
// feature run must not enter, because a stop reported from inside a route the
|
|
385612
386751
|
// run never took is a stop that never happened.
|
|
385613
386752
|
"feature/stop": "feature-blocked",
|
|
386753
|
+
// A run that broke gets its own ending. 52 outside runs ended at
|
|
386754
|
+
// `unsupported/no-validated-path` in the three weeks to 2026-09-13, and 10 of
|
|
386755
|
+
// them had classified as `built-in` with `nextjs` -- a stack this graph serves.
|
|
386756
|
+
// While one terminal absorbs both, "we do not support this" and "this run
|
|
386757
|
+
// broke" are the same row, and neither can be counted.
|
|
386758
|
+
"stopped/run-failed": "run-failed",
|
|
385614
386759
|
"unsupported/no-validated-path": "unsupported"
|
|
385615
386760
|
};
|
|
385616
386761
|
REPOSITORY_RESEARCH_NODE = "subagent/inspect-repository";
|
|
@@ -385780,7 +386925,7 @@ async function runOnboard(argv, dependencies) {
|
|
|
385780
386925
|
deps,
|
|
385781
386926
|
() => deps.loadStartPrompt(parsed.values.intent)
|
|
385782
386927
|
);
|
|
385783
|
-
const
|
|
386928
|
+
const binding = startOnboardingRun(
|
|
385784
386929
|
{
|
|
385785
386930
|
cwd: deps.cwd,
|
|
385786
386931
|
store: deps.store,
|
|
@@ -385791,14 +386936,40 @@ async function runOnboard(argv, dependencies) {
|
|
|
385791
386936
|
);
|
|
385792
386937
|
recordStarted(
|
|
385793
386938
|
deps,
|
|
385794
|
-
|
|
386939
|
+
binding.runId,
|
|
385795
386940
|
"start",
|
|
385796
|
-
|
|
386941
|
+
binding.idOrigin,
|
|
385797
386942
|
parsed.values["coding-agent"]
|
|
385798
386943
|
);
|
|
385799
|
-
|
|
386944
|
+
if (parsed.values["coding-agent"] !== void 0) {
|
|
386945
|
+
recordCodingAgentBestEffort(
|
|
386946
|
+
deps,
|
|
386947
|
+
binding.runId,
|
|
386948
|
+
parsed.values["coding-agent"]
|
|
386949
|
+
);
|
|
386950
|
+
}
|
|
386951
|
+
recordAbandonedRunWhenFound(deps, binding.runId);
|
|
386952
|
+
printRunId(deps, binding.runId);
|
|
385800
386953
|
await printGraphTree(deps);
|
|
385801
|
-
writePrompt(deps,
|
|
386954
|
+
writePrompt(deps, binding.runId, startPrompt);
|
|
386955
|
+
return;
|
|
386956
|
+
}
|
|
386957
|
+
if (subcommand === "identify") {
|
|
386958
|
+
const parsed = parseIdentify(argv.slice(1));
|
|
386959
|
+
const runId2 = requireBoundRun(deps, IDENTIFY_RUN_NOT_BOUND);
|
|
386960
|
+
recordCodingAgentBestEffort(deps, runId2, parsed.codingAgent);
|
|
386961
|
+
recordBestEffort(deps, {
|
|
386962
|
+
event: "cli.onboarding.identified",
|
|
386963
|
+
properties: {
|
|
386964
|
+
command: "onboard",
|
|
386965
|
+
...onboardingIntentProperties(deps),
|
|
386966
|
+
onboarding_run_id: runId2,
|
|
386967
|
+
cli_version: deps.cliVersion,
|
|
386968
|
+
coding_agent: normalizeCodingAgent(parsed.codingAgent)
|
|
386969
|
+
}
|
|
386970
|
+
});
|
|
386971
|
+
deps.stdout.write(`Coding agent recorded for run ${runId2}.
|
|
386972
|
+
`);
|
|
385802
386973
|
return;
|
|
385803
386974
|
}
|
|
385804
386975
|
if (subcommand === "route") {
|
|
@@ -385812,23 +386983,21 @@ async function runOnboard(argv, dependencies) {
|
|
|
385812
386983
|
if (argv.length !== 2 || promptName === void 0) {
|
|
385813
386984
|
throw new Error("Usage: copilotkit onboard read <prompt-name>");
|
|
385814
386985
|
}
|
|
385815
|
-
await printPrompt(
|
|
386986
|
+
await printPrompt(
|
|
386987
|
+
deps,
|
|
386988
|
+
requireBoundRun(deps, READ_RUN_NOT_BOUND),
|
|
386989
|
+
promptName
|
|
386990
|
+
);
|
|
385816
386991
|
return;
|
|
385817
386992
|
}
|
|
385818
|
-
|
|
385819
|
-
|
|
385820
|
-
|
|
385821
|
-
randomRunId: deps.randomRunId
|
|
385822
|
-
});
|
|
385823
|
-
if (binding.started) {
|
|
385824
|
-
recordStarted(
|
|
385825
|
-
deps,
|
|
385826
|
-
binding.runId,
|
|
385827
|
-
"another-step",
|
|
385828
|
-
binding.idOrigin,
|
|
385829
|
-
void 0
|
|
386993
|
+
if (subcommand === void 0 || !ONBOARD_SUBCOMMANDS.includes(subcommand)) {
|
|
386994
|
+
throw new Error(
|
|
386995
|
+
`Usage: copilotkit onboard <${ONBOARD_SUBCOMMANDS.join("|")}>`
|
|
385830
386996
|
);
|
|
385831
386997
|
}
|
|
386998
|
+
const runId = readOnboardingRunId({ cwd: deps.cwd, store: deps.store });
|
|
386999
|
+
if (runId === void 0)
|
|
387000
|
+
throw new Error(STEP_RUN_NOT_BOUND);
|
|
385832
387001
|
if (subcommand === "complete") {
|
|
385833
387002
|
const opened = parseFrontendUrl(argv.slice(1));
|
|
385834
387003
|
if (opened === void 0)
|
|
@@ -385839,14 +387008,15 @@ async function runOnboard(argv, dependencies) {
|
|
|
385839
387008
|
const check4 = parseSurfaceCheck(blocked2.rest);
|
|
385840
387009
|
if (check4 === void 0)
|
|
385841
387010
|
throw new Error(SURFACE_CHECK_USAGE);
|
|
385842
|
-
const accepted = readAcceptedDriftBestEffort(deps,
|
|
385843
|
-
const authorized = readAuthorizationsBestEffort(deps,
|
|
387011
|
+
const accepted = readAcceptedDriftBestEffort(deps, runId);
|
|
387012
|
+
const authorized = readAuthorizationsBestEffort(deps, runId);
|
|
387013
|
+
markRunEndedBestEffort(deps, runId);
|
|
385844
387014
|
recordBestEffort(deps, {
|
|
385845
387015
|
event: "cli.onboarding.completed",
|
|
385846
387016
|
properties: {
|
|
385847
387017
|
command: "onboard",
|
|
385848
387018
|
...onboardingIntentProperties(deps),
|
|
385849
|
-
onboarding_run_id:
|
|
387019
|
+
onboarding_run_id: runId,
|
|
385850
387020
|
cli_version: deps.cliVersion,
|
|
385851
387021
|
accepted_count: accepted.length,
|
|
385852
387022
|
authorized_count: authorized.length,
|
|
@@ -385882,7 +387052,7 @@ async function runOnboard(argv, dependencies) {
|
|
|
385882
387052
|
const requestedFramework = parsed.values["agent-framework"];
|
|
385883
387053
|
const startingState = reportingRefusal(
|
|
385884
387054
|
deps,
|
|
385885
|
-
|
|
387055
|
+
runId,
|
|
385886
387056
|
"starting-state-invalid",
|
|
385887
387057
|
{},
|
|
385888
387058
|
() => requireOnboardingChoice(
|
|
@@ -385893,18 +387063,18 @@ async function runOnboard(argv, dependencies) {
|
|
|
385893
387063
|
);
|
|
385894
387064
|
const agentFramework = reportingRefusal(
|
|
385895
387065
|
deps,
|
|
385896
|
-
|
|
387066
|
+
runId,
|
|
385897
387067
|
"agent-framework-invalid",
|
|
385898
387068
|
{ requested_agent_framework: reportableSlug(requestedFramework) },
|
|
385899
387069
|
() => requireOnboardingChoice(
|
|
385900
387070
|
"--agent-framework",
|
|
385901
|
-
requestedFramework,
|
|
387071
|
+
resolveAgentFrameworkAlias(requestedFramework),
|
|
385902
387072
|
ONBOARDING_AGENT_FRAMEWORKS
|
|
385903
387073
|
)
|
|
385904
387074
|
);
|
|
385905
387075
|
const frontend = reportingRefusal(
|
|
385906
387076
|
deps,
|
|
385907
|
-
|
|
387077
|
+
runId,
|
|
385908
387078
|
"frontend-invalid",
|
|
385909
387079
|
{},
|
|
385910
387080
|
() => requireOnboardingChoice(
|
|
@@ -385913,12 +387083,19 @@ async function runOnboard(argv, dependencies) {
|
|
|
385913
387083
|
ONBOARDING_FRONTENDS
|
|
385914
387084
|
)
|
|
385915
387085
|
);
|
|
387086
|
+
const route = readOnboardingRoute({ cwd: deps.cwd, store: deps.store });
|
|
387087
|
+
const contradiction = contradictedIntegrationRefusal(startingState, route);
|
|
387088
|
+
if (contradiction !== void 0) {
|
|
387089
|
+
recordClassifyRefusal(deps, runId, "integration-contradicted", {});
|
|
387090
|
+
throw new Error(contradiction);
|
|
387091
|
+
}
|
|
385916
387092
|
const refusal = unprovenBaselineRefusal(
|
|
385917
387093
|
startingState,
|
|
385918
|
-
|
|
387094
|
+
route,
|
|
387095
|
+
readBaselineProofBestEffort(deps)
|
|
385919
387096
|
);
|
|
385920
387097
|
if (refusal !== void 0) {
|
|
385921
|
-
recordClassifyRefusal(deps,
|
|
387098
|
+
recordClassifyRefusal(deps, runId, "baseline-unproven", {});
|
|
385922
387099
|
throw new Error(refusal);
|
|
385923
387100
|
}
|
|
385924
387101
|
recordBestEffort(deps, {
|
|
@@ -385926,7 +387103,7 @@ async function runOnboard(argv, dependencies) {
|
|
|
385926
387103
|
properties: {
|
|
385927
387104
|
command: "onboard",
|
|
385928
387105
|
...onboardingIntentProperties(deps),
|
|
385929
|
-
onboarding_run_id:
|
|
387106
|
+
onboarding_run_id: runId,
|
|
385930
387107
|
cli_version: deps.cliVersion,
|
|
385931
387108
|
starting_state: startingState,
|
|
385932
387109
|
// Mapped at the emit boundary, never at the flag: the graph's own
|
|
@@ -385939,15 +387116,8 @@ async function runOnboard(argv, dependencies) {
|
|
|
385939
387116
|
deps.stdout.write("Onboarding path included in telemetry when enabled.\n");
|
|
385940
387117
|
return;
|
|
385941
387118
|
}
|
|
385942
|
-
if (subcommand === "feedback") {
|
|
385943
|
-
if (argv.length !== 1) {
|
|
385944
|
-
throw new Error("Usage: copilotkit onboard feedback");
|
|
385945
|
-
}
|
|
385946
|
-
await reportFeedback(deps, binding.runId);
|
|
385947
|
-
return;
|
|
385948
|
-
}
|
|
385949
387119
|
if (subcommand === "friction") {
|
|
385950
|
-
await reportFriction(deps,
|
|
387120
|
+
await reportFriction(deps, runId, argv.slice(1));
|
|
385951
387121
|
return;
|
|
385952
387122
|
}
|
|
385953
387123
|
if (subcommand === "protect") {
|
|
@@ -385955,11 +387125,14 @@ async function runOnboard(argv, dependencies) {
|
|
|
385955
387125
|
args: [...argv.slice(1)],
|
|
385956
387126
|
allowPositionals: false,
|
|
385957
387127
|
options: {
|
|
387128
|
+
"accept-credential": { type: "boolean" },
|
|
385958
387129
|
"accept-external": { type: "boolean" },
|
|
385959
387130
|
authorize: { type: "boolean" },
|
|
385960
387131
|
path: { type: "string", multiple: true },
|
|
385961
387132
|
reason: { type: "string" },
|
|
385962
|
-
rebaseline: { type: "boolean" }
|
|
387133
|
+
rebaseline: { type: "boolean" },
|
|
387134
|
+
unplanned: { type: "boolean" },
|
|
387135
|
+
"with-prior-change": { type: "boolean" }
|
|
385963
387136
|
},
|
|
385964
387137
|
strict: true
|
|
385965
387138
|
});
|
|
@@ -385967,21 +387140,52 @@ async function runOnboard(argv, dependencies) {
|
|
|
385967
387140
|
const target = { cwd: deps.cwd, store: deps.store };
|
|
385968
387141
|
const rebaseline = parsed.values.rebaseline === true;
|
|
385969
387142
|
const acceptExternal = parsed.values["accept-external"] === true;
|
|
387143
|
+
const acceptCredential = parsed.values["accept-credential"] === true;
|
|
385970
387144
|
const authorize = parsed.values.authorize === true;
|
|
385971
|
-
|
|
387145
|
+
const withPriorChange = parsed.values["with-prior-change"] === true;
|
|
387146
|
+
const unplanned = parsed.values.unplanned === true;
|
|
387147
|
+
if ([rebaseline, acceptExternal, acceptCredential, authorize].filter(Boolean).length > 1) {
|
|
385972
387148
|
throw new Error(EXCLUSIVE_MODE_USAGE);
|
|
385973
387149
|
}
|
|
387150
|
+
if (withPriorChange && !authorize) {
|
|
387151
|
+
throw new Error(PRIOR_CHANGE_USAGE);
|
|
387152
|
+
}
|
|
387153
|
+
if (unplanned && !authorize) {
|
|
387154
|
+
throw new Error(UNPLANNED_USAGE);
|
|
387155
|
+
}
|
|
387156
|
+
if (acceptCredential) {
|
|
387157
|
+
if (paths.length === 0)
|
|
387158
|
+
throw new Error(ACCEPT_CREDENTIAL_USAGE);
|
|
387159
|
+
const placed = acceptCredentialPlacement(target, {
|
|
387160
|
+
runId,
|
|
387161
|
+
paths
|
|
387162
|
+
});
|
|
387163
|
+
recordProtect(
|
|
387164
|
+
deps,
|
|
387165
|
+
runId,
|
|
387166
|
+
"accept-credential",
|
|
387167
|
+
placed,
|
|
387168
|
+
(result) => ({
|
|
387169
|
+
path_count: result.accepted.length,
|
|
387170
|
+
drift_kinds: joinChanges(result.accepted.map((one) => one.change))
|
|
387171
|
+
})
|
|
387172
|
+
);
|
|
387173
|
+
deps.stdout.write(credentialReport(placed));
|
|
387174
|
+
return;
|
|
387175
|
+
}
|
|
385974
387176
|
if (authorize) {
|
|
385975
387177
|
const reason = parsed.values.reason ?? "";
|
|
385976
387178
|
if (paths.length === 0 || reason.trim() === "") {
|
|
385977
387179
|
throw new Error(AUTHORIZE_USAGE);
|
|
385978
387180
|
}
|
|
385979
387181
|
const authorized = authorizeProtectedPathChange(target, {
|
|
385980
|
-
runId
|
|
387182
|
+
runId,
|
|
385981
387183
|
paths,
|
|
385982
|
-
reason
|
|
387184
|
+
reason,
|
|
387185
|
+
acceptPriorChange: withPriorChange,
|
|
387186
|
+
unplanned
|
|
385983
387187
|
});
|
|
385984
|
-
recordProtect(deps,
|
|
387188
|
+
recordProtect(deps, runId, "authorize", authorized, (result) => ({
|
|
385985
387189
|
path_count: result.authorized.length
|
|
385986
387190
|
}));
|
|
385987
387191
|
deps.stdout.write(authorizationReport(authorized));
|
|
@@ -385991,10 +387195,10 @@ async function runOnboard(argv, dependencies) {
|
|
|
385991
387195
|
if (paths.length === 0)
|
|
385992
387196
|
throw new Error(ACCEPT_USAGE);
|
|
385993
387197
|
const accepted = acceptProtectedPathDrift(target, {
|
|
385994
|
-
runId
|
|
387198
|
+
runId,
|
|
385995
387199
|
paths
|
|
385996
387200
|
});
|
|
385997
|
-
recordProtect(deps,
|
|
387201
|
+
recordProtect(deps, runId, "accept", accepted, (result) => ({
|
|
385998
387202
|
path_count: result.accepted.length,
|
|
385999
387203
|
drift_kinds: joinChanges(result.accepted.map((one) => one.change))
|
|
386000
387204
|
}));
|
|
@@ -386005,20 +387209,20 @@ async function runOnboard(argv, dependencies) {
|
|
|
386005
387209
|
if (paths.length === 0)
|
|
386006
387210
|
throw new Error(REBASELINE_USAGE);
|
|
386007
387211
|
const promoted = rebaselineProtectedPaths(target, {
|
|
386008
|
-
runId
|
|
387212
|
+
runId,
|
|
386009
387213
|
paths
|
|
386010
387214
|
});
|
|
386011
|
-
recordProtect(deps,
|
|
387215
|
+
recordProtect(deps, runId, "rebaseline", promoted, (result) => ({
|
|
386012
387216
|
path_count: result.promoted.length
|
|
386013
387217
|
}));
|
|
386014
387218
|
deps.stdout.write(rebaselineReport(promoted));
|
|
386015
387219
|
return;
|
|
386016
387220
|
}
|
|
386017
387221
|
const captured = captureProtectedPaths(target, {
|
|
386018
|
-
runId
|
|
387222
|
+
runId,
|
|
386019
387223
|
paths
|
|
386020
387224
|
});
|
|
386021
|
-
recordProtect(deps,
|
|
387225
|
+
recordProtect(deps, runId, "capture", captured, (result) => ({
|
|
386022
387226
|
path_count: result.added.length,
|
|
386023
387227
|
protect_derived: result.derived
|
|
386024
387228
|
}));
|
|
@@ -386026,17 +387230,21 @@ async function runOnboard(argv, dependencies) {
|
|
|
386026
387230
|
return;
|
|
386027
387231
|
}
|
|
386028
387232
|
if (subcommand === "checkpoint") {
|
|
386029
|
-
reportCheckpoint(deps,
|
|
387233
|
+
reportCheckpoint(deps, runId, argv.slice(1));
|
|
386030
387234
|
return;
|
|
386031
387235
|
}
|
|
386032
387236
|
if (subcommand === "proof") {
|
|
386033
387237
|
const proof = parseProof(argv.slice(1));
|
|
387238
|
+
recordProofBestEffort(deps, runId, proof.step, {
|
|
387239
|
+
outcome: proof.outcome,
|
|
387240
|
+
...proof.predicate === void 0 ? {} : { predicate: proof.predicate }
|
|
387241
|
+
});
|
|
386034
387242
|
recordBestEffort(deps, {
|
|
386035
387243
|
event: "cli.onboarding.proof_recorded",
|
|
386036
387244
|
properties: {
|
|
386037
387245
|
command: "onboard",
|
|
386038
387246
|
...onboardingIntentProperties(deps),
|
|
386039
|
-
onboarding_run_id:
|
|
387247
|
+
onboarding_run_id: runId,
|
|
386040
387248
|
cli_version: deps.cliVersion,
|
|
386041
387249
|
proof_step: proof.step,
|
|
386042
387250
|
proof_outcome: proof.outcome,
|
|
@@ -386053,14 +387261,14 @@ async function runOnboard(argv, dependencies) {
|
|
|
386053
387261
|
throw new Error("Usage: copilotkit onboard audit");
|
|
386054
387262
|
const audit = auditProtectedPaths(
|
|
386055
387263
|
{ cwd: deps.cwd, store: deps.store },
|
|
386056
|
-
{ runId
|
|
387264
|
+
{ runId }
|
|
386057
387265
|
);
|
|
386058
387266
|
recordBestEffort(deps, {
|
|
386059
387267
|
event: "cli.onboarding.audit_completed",
|
|
386060
387268
|
properties: {
|
|
386061
387269
|
command: "onboard",
|
|
386062
387270
|
...onboardingIntentProperties(deps),
|
|
386063
|
-
onboarding_run_id:
|
|
387271
|
+
onboarding_run_id: runId,
|
|
386064
387272
|
cli_version: deps.cliVersion,
|
|
386065
387273
|
...describeAudit(audit)
|
|
386066
387274
|
}
|
|
@@ -386068,17 +387276,17 @@ async function runOnboard(argv, dependencies) {
|
|
|
386068
387276
|
deps.stdout.write(auditReport(audit));
|
|
386069
387277
|
return;
|
|
386070
387278
|
}
|
|
386071
|
-
throw new Error(
|
|
386072
|
-
`Usage: copilotkit onboard <${ONBOARD_SUBCOMMANDS.join("|")}>`
|
|
386073
|
-
);
|
|
386074
387279
|
}
|
|
386075
|
-
function
|
|
387280
|
+
function runNotBound(reason) {
|
|
387281
|
+
return "No onboarding run is bound to this directory.\n\n" + reason + "\n\nIf this session has not started, run `copilotkit onboard start` here.\nIf it has, run `copilotkit onboard start --run <id>` here with the id the\nfirst start printed, or run this command from the directory you started in.\n\nThis is a missing start, not a failed step: nothing has been proved\nunsupported.";
|
|
387282
|
+
}
|
|
387283
|
+
function requireBoundRun(dependencies, refusal) {
|
|
386076
387284
|
const runId = readOnboardingRunId({
|
|
386077
387285
|
cwd: dependencies.cwd,
|
|
386078
387286
|
store: dependencies.store
|
|
386079
387287
|
});
|
|
386080
387288
|
if (runId === void 0)
|
|
386081
|
-
throw new Error(
|
|
387289
|
+
throw new Error(refusal);
|
|
386082
387290
|
return runId;
|
|
386083
387291
|
}
|
|
386084
387292
|
function plural(count, noun) {
|
|
@@ -386164,6 +387372,59 @@ ${detail}`;
|
|
|
386164
387372
|
""
|
|
386165
387373
|
].join("\n");
|
|
386166
387374
|
}
|
|
387375
|
+
function credentialReport(result) {
|
|
387376
|
+
if (result.status === "blocked") {
|
|
387377
|
+
const detail = {
|
|
387378
|
+
"no-baseline": `No protected-path baseline was captured for run ${result.detail}.
|
|
387379
|
+
Run \`copilotkit onboard protect\` first.
|
|
387380
|
+
`,
|
|
387381
|
+
"run-mismatch": `The captured baseline belongs to run ${result.detail}, not to this run.
|
|
387382
|
+
A credential can only be accepted against the baseline of the run that
|
|
387383
|
+
asked for it.
|
|
387384
|
+
`,
|
|
387385
|
+
"unreadable-baseline": `The captured baseline for run ${result.detail} could not be read.
|
|
387386
|
+
Capture it again before accepting anything against it.
|
|
387387
|
+
`,
|
|
387388
|
+
"unreadable-path": `The protected path \`${result.detail}\` could not be read, so the credential
|
|
387389
|
+
it now holds could not be checked.
|
|
387390
|
+
`,
|
|
387391
|
+
"unknown-path": `The path \`${result.detail}\` is not in this run\u2019s baseline.
|
|
387392
|
+
Only a captured path can be accepted.
|
|
387393
|
+
`,
|
|
387394
|
+
"deferred-path": `The path \`${result.detail}\` is deferred, not protected.
|
|
387395
|
+
This graph has not finished writing it, so promote it first with
|
|
387396
|
+
\`onboard protect --rebaseline --path <path>\`.
|
|
387397
|
+
`,
|
|
387398
|
+
"not-env-path": `The path \`${result.detail}\` is not an env file.
|
|
387399
|
+
This route reads variable names to prove no credential was lost, which only
|
|
387400
|
+
means something for a file of \`KEY=value\` lines.
|
|
387401
|
+
`,
|
|
387402
|
+
"unchanged-path": `The path \`${result.detail}\` matches the digest captured for it.
|
|
387403
|
+
Nothing was placed in it, so there is no credential to accept.
|
|
387404
|
+
`,
|
|
387405
|
+
"unrecorded-keys": `The baseline holds no variable names for \`${result.detail}\`.
|
|
387406
|
+
This route proves no credential was lost by comparing them, so with none
|
|
387407
|
+
recorded it can prove nothing. Capture the path again with
|
|
387408
|
+
\`onboard protect --path <path>\` before the developer writes to it.
|
|
387409
|
+
`,
|
|
387410
|
+
"credential-lost": `A credential recorded for \`${result.detail}\` is gone.
|
|
387411
|
+
This route accepts a credential the developer added. It refuses a change
|
|
387412
|
+
that drops one, which is the failure the baseline exists to catch. Do not
|
|
387413
|
+
repair or rewrite the file. Report the missing variable and route out.
|
|
387414
|
+
`
|
|
387415
|
+
}[result.reason];
|
|
387416
|
+
return `Status: blocked
|
|
387417
|
+
${detail}${NOTHING_ACCEPTED}`;
|
|
387418
|
+
}
|
|
387419
|
+
return [
|
|
387420
|
+
"Status: passed",
|
|
387421
|
+
`Accepted the placed credential in ${plural(result.accepted.length, "env file")} for run ${result.runId}.`,
|
|
387422
|
+
...result.accepted.map(changeLine),
|
|
387423
|
+
"Every credential the baseline recorded is still there.",
|
|
387424
|
+
"Report each accepted path in the summary.",
|
|
387425
|
+
""
|
|
387426
|
+
].join("\n");
|
|
387427
|
+
}
|
|
386167
387428
|
function acceptanceReport(result) {
|
|
386168
387429
|
if (result.status === "blocked") {
|
|
386169
387430
|
const detail = {
|
|
@@ -386217,7 +387478,8 @@ ${detail}${NOTHING_ACCEPTED}`;
|
|
|
386217
387478
|
].join("\n");
|
|
386218
387479
|
}
|
|
386219
387480
|
function authorizationLine(granted) {
|
|
386220
|
-
|
|
387481
|
+
const source = granted.unplanned === true ? " (outside the approved plan)" : "";
|
|
387482
|
+
return ` ${granted.path} \u2014 ${granted.reason}${source}`;
|
|
386221
387483
|
}
|
|
386222
387484
|
function authorizedLines(authorized) {
|
|
386223
387485
|
return authorized.length === 0 ? [] : ["Authorized to change:", ...authorized.map(authorizationLine)];
|
|
@@ -386249,11 +387511,31 @@ Nothing outside the run writes it, so consent here would only license the
|
|
|
386249
387511
|
run against its own credential output.
|
|
386250
387512
|
`,
|
|
386251
387513
|
"missing-reason": "No reason was given.\nConsent is recorded so the closing report can tell the developer what their\nfile was changed for. A blank reason records permission and no answer.\n",
|
|
387514
|
+
"unplanned-path": `The path \`${result.detail}\` is not one the approved plan asked for.
|
|
387515
|
+
This run has already reported its plan, so the developer has approved every
|
|
387516
|
+
path they are going to approve. They did not approve this one. Ask them
|
|
387517
|
+
to allow the change, and record the answer they give with
|
|
387518
|
+
\`onboard protect --authorize --unplanned --path <path> --reason "<their
|
|
387519
|
+
answer>"\`. If you cannot ask, route out. Do not repair the path.
|
|
387520
|
+
`,
|
|
387521
|
+
"prior-change-after-start": `The path \`${result.detail}\` cannot carry a prior-change claim any more.
|
|
387522
|
+
That claim says the developer changed the file before this run implemented
|
|
387523
|
+
anything, and this run has already reported its plan. A protected path that
|
|
387524
|
+
changed after that is this run\u2019s own work. Route out rather than record
|
|
387525
|
+
consent over it.
|
|
387526
|
+
`,
|
|
387527
|
+
"planned-path": `The path \`${result.detail}\` can still be authorized by the plan itself.
|
|
387528
|
+
This run has not reported its plan yet, so --unplanned describes nothing:
|
|
387529
|
+
consent here is the developer approving the plan. Record it without the
|
|
387530
|
+
flag, or add the path to the plan and have the developer approve that.
|
|
387531
|
+
`,
|
|
386252
387532
|
"changed-path": `The path \`${result.detail}\` has already changed since it was captured.
|
|
386253
387533
|
Consent has to be recorded before the change, or it cannot be told apart from
|
|
386254
387534
|
a run clearing a failure it caused. Run \`onboard audit\`: if a Files changed
|
|
386255
|
-
section from this run names the path, route out
|
|
386256
|
-
\`onboard protect --accept-external
|
|
387535
|
+
section from this run names the path, route out. If none does, the developer
|
|
387536
|
+
changed it, and either accept it with \`onboard protect --accept-external
|
|
387537
|
+
--path <path>\` or, when this run must change the same file, record consent
|
|
387538
|
+
over their change by adding --with-prior-change.
|
|
386257
387539
|
`
|
|
386258
387540
|
}[result.reason];
|
|
386259
387541
|
return `Status: blocked
|
|
@@ -386385,6 +387667,24 @@ function parseProof(args) {
|
|
|
386385
387667
|
}
|
|
386386
387668
|
return { step, outcome, predicate };
|
|
386387
387669
|
}
|
|
387670
|
+
function parseIdentify(args) {
|
|
387671
|
+
let parsed;
|
|
387672
|
+
try {
|
|
387673
|
+
parsed = parseArgs2({
|
|
387674
|
+
args: [...args],
|
|
387675
|
+
allowPositionals: false,
|
|
387676
|
+
options: { "coding-agent": { type: "string" } },
|
|
387677
|
+
strict: true
|
|
387678
|
+
});
|
|
387679
|
+
} catch {
|
|
387680
|
+
throw new Error(IDENTIFY_USAGE);
|
|
387681
|
+
}
|
|
387682
|
+
const codingAgent = parsed.values["coding-agent"];
|
|
387683
|
+
if (codingAgent === void 0 || codingAgent.trim().length === 0) {
|
|
387684
|
+
throw new Error(IDENTIFY_USAGE);
|
|
387685
|
+
}
|
|
387686
|
+
return { codingAgent };
|
|
387687
|
+
}
|
|
386388
387688
|
function reportCheckpoint(dependencies, runId, args) {
|
|
386389
387689
|
let parsed;
|
|
386390
387690
|
try {
|
|
@@ -386410,6 +387710,12 @@ function reportCheckpoint(dependencies, runId, args) {
|
|
|
386410
387710
|
if (!reviewed.ok) {
|
|
386411
387711
|
return printCheckpointRefusal(dependencies, runId, reviewed.refusal);
|
|
386412
387712
|
}
|
|
387713
|
+
if (reviewed.checkpoint.phase === "plan-written") {
|
|
387714
|
+
markImplementationStarted(
|
|
387715
|
+
{ cwd: dependencies.cwd, store: dependencies.store },
|
|
387716
|
+
{ runId }
|
|
387717
|
+
);
|
|
387718
|
+
}
|
|
386413
387719
|
recordBestEffort(dependencies, {
|
|
386414
387720
|
event: "cli.onboarding.checkpoint",
|
|
386415
387721
|
properties: {
|
|
@@ -386477,6 +387783,7 @@ function recordTerminalWhenReached(dependencies, runId, promptName) {
|
|
|
386477
387783
|
const terminal = TERMINAL_NODES[promptName];
|
|
386478
387784
|
if (terminal === void 0)
|
|
386479
387785
|
return;
|
|
387786
|
+
markRunEndedBestEffort(dependencies, runId);
|
|
386480
387787
|
recordBestEffort(dependencies, {
|
|
386481
387788
|
event: "cli.onboarding.terminal_reached",
|
|
386482
387789
|
properties: {
|
|
@@ -386488,6 +387795,40 @@ function recordTerminalWhenReached(dependencies, runId, promptName) {
|
|
|
386488
387795
|
}
|
|
386489
387796
|
});
|
|
386490
387797
|
}
|
|
387798
|
+
function recordAbandonedRunWhenFound(dependencies, currentRunId) {
|
|
387799
|
+
let abandoned;
|
|
387800
|
+
try {
|
|
387801
|
+
abandoned = readAbandonedRun(
|
|
387802
|
+
{ cwd: dependencies.cwd, store: dependencies.store },
|
|
387803
|
+
currentRunId
|
|
387804
|
+
);
|
|
387805
|
+
} catch {
|
|
387806
|
+
return;
|
|
387807
|
+
}
|
|
387808
|
+
if (abandoned === void 0)
|
|
387809
|
+
return;
|
|
387810
|
+
recordBestEffort(dependencies, {
|
|
387811
|
+
event: "cli.onboarding.run_abandoned",
|
|
387812
|
+
properties: {
|
|
387813
|
+
command: "onboard",
|
|
387814
|
+
...onboardingIntentProperties(dependencies),
|
|
387815
|
+
// The run that is reporting, the way every other event binds. The run
|
|
387816
|
+
// being reported cannot emit anything: it is over, and reporting it is
|
|
387817
|
+
// the whole point. It rides as its own property instead.
|
|
387818
|
+
onboarding_run_id: currentRunId,
|
|
387819
|
+
cli_version: dependencies.cliVersion,
|
|
387820
|
+
abandoned_run_id: abandoned.runId,
|
|
387821
|
+
abandoned_at_prompt: abandoned.lastPrompt,
|
|
387822
|
+
abandoned_after_steps: abandoned.steps
|
|
387823
|
+
}
|
|
387824
|
+
});
|
|
387825
|
+
}
|
|
387826
|
+
function markRunEndedBestEffort(dependencies, runId) {
|
|
387827
|
+
try {
|
|
387828
|
+
markRunEnded({ cwd: dependencies.cwd, store: dependencies.store }, runId);
|
|
387829
|
+
} catch {
|
|
387830
|
+
}
|
|
387831
|
+
}
|
|
386491
387832
|
function joinChanges(changes) {
|
|
386492
387833
|
return [...new Set(changes)].sort().join(",");
|
|
386493
387834
|
}
|
|
@@ -386615,42 +387956,15 @@ function completionReport(input) {
|
|
|
386615
387956
|
}
|
|
386616
387957
|
return input.blocker === void 0 ? "CopilotKit onboarding marked complete.\n" : blockedAfterProof(input.blocker);
|
|
386617
387958
|
}
|
|
386618
|
-
|
|
386619
|
-
|
|
386620
|
-
|
|
386621
|
-
|
|
386622
|
-
|
|
386623
|
-
|
|
386624
|
-
|
|
386625
|
-
|
|
386626
|
-
let sent = false;
|
|
386627
|
-
try {
|
|
386628
|
-
sent = await dependencies.submitFeedbackEvent({
|
|
386629
|
-
event: "cli.onboarding.feedback_submitted",
|
|
386630
|
-
properties: {
|
|
386631
|
-
command: "onboard",
|
|
386632
|
-
...onboardingIntentProperties(dependencies),
|
|
386633
|
-
onboarding_run_id: runId,
|
|
386634
|
-
cli_version: dependencies.cliVersion,
|
|
386635
|
-
feedback_text: feedbackText
|
|
386636
|
-
}
|
|
386637
|
-
});
|
|
386638
|
-
} catch {
|
|
386639
|
-
sent = false;
|
|
387959
|
+
function describeSubmission(subject, submission) {
|
|
387960
|
+
switch (submission.status) {
|
|
387961
|
+
case "sent":
|
|
387962
|
+
return "Friction reported.";
|
|
387963
|
+
case "declined":
|
|
387964
|
+
return `${subject} was not sent because telemetry is off.`;
|
|
387965
|
+
default:
|
|
387966
|
+
return `${subject} was not sent because the telemetry send failed: ${submission.detail}`;
|
|
386640
387967
|
}
|
|
386641
|
-
dependencies.stdout.write(
|
|
386642
|
-
`${sent ? "Feedback sent." : "Feedback was not sent because telemetry is disabled or unavailable."}
|
|
386643
|
-
report: ${feedbackText}
|
|
386644
|
-
`
|
|
386645
|
-
);
|
|
386646
|
-
}
|
|
386647
|
-
function printFeedbackRefusal(dependencies, runId, refusal) {
|
|
386648
|
-
recordReportRefused(dependencies, runId, "feedback", refusal.code);
|
|
386649
|
-
dependencies.stdout.write(
|
|
386650
|
-
`Feedback refused, and nothing was sent.
|
|
386651
|
-
${refusal.code}: ${refusal.message}
|
|
386652
|
-
`
|
|
386653
|
-
);
|
|
386654
387968
|
}
|
|
386655
387969
|
async function reportFriction(dependencies, runId, args) {
|
|
386656
387970
|
const parsed = parseFrictionArguments(args);
|
|
@@ -386663,14 +387977,15 @@ async function reportFriction(dependencies, runId, args) {
|
|
|
386663
387977
|
category: parsed.category,
|
|
386664
387978
|
costSeconds: parsed.costSeconds,
|
|
386665
387979
|
docsPath: parsed.docsPath,
|
|
387980
|
+
phase: parsed.phase,
|
|
386666
387981
|
text: input.text
|
|
386667
387982
|
});
|
|
386668
387983
|
if (!reviewed.ok)
|
|
386669
387984
|
return printFrictionRefusal(dependencies, runId, reviewed.refusal);
|
|
386670
387985
|
const report = reviewed.report;
|
|
386671
|
-
let
|
|
387986
|
+
let submission;
|
|
386672
387987
|
try {
|
|
386673
|
-
|
|
387988
|
+
submission = await dependencies.submitFeedbackEvent({
|
|
386674
387989
|
event: "cli.onboarding.friction_reported",
|
|
386675
387990
|
properties: {
|
|
386676
387991
|
command: "onboard",
|
|
@@ -386678,17 +387993,20 @@ async function reportFriction(dependencies, runId, args) {
|
|
|
386678
387993
|
onboarding_run_id: runId,
|
|
386679
387994
|
cli_version: dependencies.cliVersion,
|
|
386680
387995
|
friction_category: report.category,
|
|
386681
|
-
|
|
387996
|
+
friction_phase: report.phase,
|
|
387997
|
+
// Spread so a stop report that named no cost leaves the key off rather
|
|
387998
|
+
// than sending an undefined the sink stores as a value.
|
|
387999
|
+
...report.costSecondsEstimated === void 0 ? {} : { cost_seconds_estimated: report.costSecondsEstimated },
|
|
386682
388000
|
// Spread so a report about no particular page leaves the key off
|
|
386683
388001
|
// rather than joining to an empty one.
|
|
386684
388002
|
...report.docsPath === void 0 ? {} : { friction_docs_path: report.docsPath },
|
|
386685
388003
|
friction_text: report.text
|
|
386686
388004
|
}
|
|
386687
388005
|
});
|
|
386688
|
-
} catch {
|
|
386689
|
-
|
|
388006
|
+
} catch (error98) {
|
|
388007
|
+
submission = { status: "failed", detail: describeSubmissionError(error98) };
|
|
386690
388008
|
}
|
|
386691
|
-
printFrictionReport(dependencies, report,
|
|
388009
|
+
printFrictionReport(dependencies, report, submission);
|
|
386692
388010
|
}
|
|
386693
388011
|
function parseFrictionArguments(args) {
|
|
386694
388012
|
try {
|
|
@@ -386698,7 +388016,8 @@ function parseFrictionArguments(args) {
|
|
|
386698
388016
|
options: {
|
|
386699
388017
|
category: { type: "string" },
|
|
386700
388018
|
"cost-seconds": { type: "string" },
|
|
386701
|
-
"docs-path": { type: "string" }
|
|
388019
|
+
"docs-path": { type: "string" },
|
|
388020
|
+
phase: { type: "string" }
|
|
386702
388021
|
},
|
|
386703
388022
|
strict: true
|
|
386704
388023
|
});
|
|
@@ -386706,14 +388025,15 @@ function parseFrictionArguments(args) {
|
|
|
386706
388025
|
ok: true,
|
|
386707
388026
|
category: parsed.values.category,
|
|
386708
388027
|
costSeconds: parsed.values["cost-seconds"],
|
|
386709
|
-
docsPath: parsed.values["docs-path"]
|
|
388028
|
+
docsPath: parsed.values["docs-path"],
|
|
388029
|
+
phase: parsed.values.phase
|
|
386710
388030
|
};
|
|
386711
388031
|
} catch {
|
|
386712
388032
|
return {
|
|
386713
388033
|
ok: false,
|
|
386714
388034
|
refusal: {
|
|
386715
388035
|
code: "FRICTION_ARGUMENTS_INVALID",
|
|
386716
|
-
message: `Usage: copilotkit onboard friction --category <${FRICTION_CATEGORIES.join("|")}> --cost-seconds <seconds> [--docs-path <page path or URL>]`
|
|
388036
|
+
message: `Usage: copilotkit onboard friction --category <${FRICTION_CATEGORIES.join("|")}> --cost-seconds <seconds> [--phase <${FRICTION_PHASES.join("|")}>] [--docs-path <page path or URL>]`
|
|
386717
388037
|
}
|
|
386718
388038
|
};
|
|
386719
388039
|
}
|
|
@@ -386726,12 +388046,13 @@ ${refusal.code}: ${refusal.message}
|
|
|
386726
388046
|
`
|
|
386727
388047
|
);
|
|
386728
388048
|
}
|
|
386729
|
-
function printFrictionReport(dependencies, report,
|
|
388049
|
+
function printFrictionReport(dependencies, report, submission) {
|
|
386730
388050
|
dependencies.stdout.write(
|
|
386731
|
-
`${
|
|
388051
|
+
`${describeSubmission("Friction", submission)}
|
|
386732
388052
|
category: ${report.category}
|
|
386733
|
-
|
|
386734
|
-
` + (report.
|
|
388053
|
+
phase: ${report.phase}
|
|
388054
|
+
` + (report.costSecondsEstimated === void 0 ? "" : `cost_seconds_estimated: ${report.costSecondsEstimated}
|
|
388055
|
+
`) + (report.docsPath === void 0 ? "" : `docs_path: ${report.docsPath}
|
|
386735
388056
|
`) + `report: ${report.text}
|
|
386736
388057
|
`
|
|
386737
388058
|
);
|
|
@@ -386896,6 +388217,37 @@ function readRouteBestEffort(dependencies) {
|
|
|
386896
388217
|
return [];
|
|
386897
388218
|
}
|
|
386898
388219
|
}
|
|
388220
|
+
function recordProofBestEffort(dependencies, runId, step, proof) {
|
|
388221
|
+
try {
|
|
388222
|
+
recordProofOutcome(
|
|
388223
|
+
{ cwd: dependencies.cwd, store: dependencies.store },
|
|
388224
|
+
runId,
|
|
388225
|
+
step,
|
|
388226
|
+
proof
|
|
388227
|
+
);
|
|
388228
|
+
} catch {
|
|
388229
|
+
}
|
|
388230
|
+
}
|
|
388231
|
+
function recordCodingAgentBestEffort(dependencies, runId, codingAgent) {
|
|
388232
|
+
try {
|
|
388233
|
+
recordCodingAgent(
|
|
388234
|
+
{ cwd: dependencies.cwd, store: dependencies.store },
|
|
388235
|
+
runId,
|
|
388236
|
+
codingAgent
|
|
388237
|
+
);
|
|
388238
|
+
} catch {
|
|
388239
|
+
}
|
|
388240
|
+
}
|
|
388241
|
+
function readBaselineProofBestEffort(dependencies) {
|
|
388242
|
+
try {
|
|
388243
|
+
return readProofOutcome(
|
|
388244
|
+
{ cwd: dependencies.cwd, store: dependencies.store },
|
|
388245
|
+
"oss-baseline"
|
|
388246
|
+
);
|
|
388247
|
+
} catch {
|
|
388248
|
+
return void 0;
|
|
388249
|
+
}
|
|
388250
|
+
}
|
|
386899
388251
|
function recordRouteBestEffort(dependencies, runId, promptName) {
|
|
386900
388252
|
try {
|
|
386901
388253
|
recordServedPrompt(
|
|
@@ -386919,7 +388271,7 @@ function recordBestEffort(dependencies, event) {
|
|
|
386919
388271
|
} catch {
|
|
386920
388272
|
}
|
|
386921
388273
|
}
|
|
386922
|
-
var ONBOARD_SUBCOMMANDS,
|
|
388274
|
+
var ONBOARD_SUBCOMMANDS, READ_RUN_NOT_BOUND, IDENTIFY_RUN_NOT_BOUND, STEP_RUN_NOT_BOUND, REBASELINE_USAGE, ACCEPT_USAGE, AUTHORIZE_USAGE, ACCEPT_CREDENTIAL_USAGE, PRIOR_CHANGE_USAGE, UNPLANNED_USAGE, EXCLUSIVE_MODE_USAGE, NOTHING_PROVED, NOTHING_AUTHORIZED, NOTHING_ACCEPTED, VISUAL_CHECK_OUTCOMES, DEVICE_CHECK_OUTCOMES, BLOCKER_CAUSES, BLOCKER_USAGE, SURFACE_CHECK_USAGE, FRONTEND_URL_USAGE, PROOF_STEPS, PROOF_OUTCOMES, BASELINE_PREDICATE_COUNT, PROOF_USAGE, IDENTIFY_USAGE, BLOCKER_REPORTS;
|
|
386923
388275
|
var init_onboard = __esm({
|
|
386924
388276
|
async "apps/cli/src/commands/onboard.ts"() {
|
|
386925
388277
|
"use strict";
|
|
@@ -386927,7 +388279,6 @@ var init_onboard = __esm({
|
|
|
386927
388279
|
init_config_service();
|
|
386928
388280
|
init_onboarding_graph();
|
|
386929
388281
|
init_onboarding_friction();
|
|
386930
|
-
init_onboarding_feedback();
|
|
386931
388282
|
init_onboarding_checkpoint();
|
|
386932
388283
|
init_onboarding_state();
|
|
386933
388284
|
init_onboarding_protected_paths();
|
|
@@ -386940,6 +388291,7 @@ var init_onboard = __esm({
|
|
|
386940
388291
|
init_resolved_dependencies();
|
|
386941
388292
|
ONBOARD_SUBCOMMANDS = [
|
|
386942
388293
|
"start",
|
|
388294
|
+
"identify",
|
|
386943
388295
|
"read",
|
|
386944
388296
|
"route",
|
|
386945
388297
|
"classify",
|
|
@@ -386948,14 +388300,24 @@ var init_onboard = __esm({
|
|
|
386948
388300
|
"checkpoint",
|
|
386949
388301
|
"proof",
|
|
386950
388302
|
"complete",
|
|
386951
|
-
"feedback",
|
|
386952
388303
|
"friction"
|
|
386953
388304
|
];
|
|
386954
|
-
|
|
388305
|
+
READ_RUN_NOT_BOUND = runNotBound(
|
|
388306
|
+
"`onboard read` reports every node it serves against the run `onboard start`\ndeclared. Minting one here would record this directory as a second run of a\nsession that already has one, and leave the first looking like a stall."
|
|
388307
|
+
);
|
|
388308
|
+
IDENTIFY_RUN_NOT_BOUND = runNotBound(
|
|
388309
|
+
"`onboard identify` records the coding agent against the run `onboard start`\ndeclared. Minting one here would file this identify, and the login that\nfollows it, under a run no other step in the session ever reports against."
|
|
388310
|
+
);
|
|
388311
|
+
STEP_RUN_NOT_BOUND = runNotBound(
|
|
388312
|
+
"This step reports against the run `onboard start` declared. Minting one here\nwould bind a second run to this directory alone, and take the route, the\nprotected baseline and the proof record with it."
|
|
388313
|
+
);
|
|
386955
388314
|
REBASELINE_USAGE = "Usage: copilotkit onboard protect --rebaseline --path <path> [--path <path>]\nName the paths to re-capture. A re-baseline with no path would be a request to\nre-read the whole baseline, which is the one thing this command must never do.";
|
|
386956
388315
|
ACCEPT_USAGE = "Usage: copilotkit onboard protect --accept-external --path <path> [--path <path>]\nName the paths to accept. An acceptance with no path would accept every change\nthis run has not seen, which is the one thing this command must never do.";
|
|
386957
388316
|
AUTHORIZE_USAGE = "Usage: copilotkit onboard protect --authorize --path <path> [--path <path>]\n --reason <why this run must change it>\nName the paths and say why. Consent with no path would license every file the\ndeveloper owns, and consent with no reason leaves the closing report unable to\ntell them what their file was changed for.";
|
|
386958
|
-
|
|
388317
|
+
ACCEPT_CREDENTIAL_USAGE = "Usage: copilotkit onboard protect --accept-credential --path <path> [--path <path>]\nName the env files whose new credential you accept. This route checks that no\ncredential the baseline recorded was lost, so it needs the paths to check.";
|
|
388318
|
+
PRIOR_CHANGE_USAGE = "--with-prior-change belongs to --authorize and to nothing else.\nIt widens one authorization to cover a change the developer already made to\nthe path. No other mode records consent, so nothing there can carry it.";
|
|
388319
|
+
UNPLANNED_USAGE = "--unplanned belongs to --authorize and to nothing else.\nIt records that the developer gave this consent mid-run, after the approved\nplan was settled. No other mode records consent, so nothing there can carry it.";
|
|
388320
|
+
EXCLUSIVE_MODE_USAGE = "Use one of --rebaseline, --accept-external, --accept-credential or --authorize,\nnot more than one. --rebaseline records a file this run wrote.\n--accept-external records a change that came from outside the run.\n--accept-credential records a credential the developer placed in an env file\nbecause the run asked. --authorize records the developer allowing this run to\nchange a file of theirs. One path cannot be more than one of them.";
|
|
386959
388321
|
NOTHING_PROVED = "This is a missing baseline, not a preservation failure: no protected path has\nbeen proved changed, and none has been proved unchanged either.\n";
|
|
386960
388322
|
NOTHING_AUTHORIZED = "Nothing was recorded. No path in this call was authorized, including any path\nnamed before the one above.\n";
|
|
386961
388323
|
NOTHING_ACCEPTED = "Nothing was recorded. No path in this call was accepted, including any path\nnamed before the one above.\n";
|
|
@@ -386982,8 +388344,8 @@ blocked reads the unsupported terminal instead, and reports a path that works
|
|
|
386982
388344
|
as one this release does not carry.`;
|
|
386983
388345
|
SURFACE_CHECK_USAGE = "Usage: copilotkit onboard complete --visual-check <performed|skipped-no-browser-tool|failed>\n or: copilotkit onboard complete --device-check <performed|skipped-no-device|failed>\nPass exactly one. A web journey is proven in a browser and a mobile one on a device;\nwhich flag you pass is how this run states which surface it proved.";
|
|
386984
388346
|
FRONTEND_URL_USAGE = "Usage: copilotkit onboard complete <surface-check> --frontend-url <absolute url>\nPass the URL a browser actually opened, for example http://localhost:3000.\nOnly the kind of host is recorded -- loopback hostname, loopback IP literal,\nother IP literal, other name -- never the host itself.";
|
|
386985
|
-
PROOF_STEPS =
|
|
386986
|
-
PROOF_OUTCOMES =
|
|
388347
|
+
PROOF_STEPS = ONBOARDING_PROOF_STEPS;
|
|
388348
|
+
PROOF_OUTCOMES = ONBOARDING_PROOF_OUTCOMES;
|
|
386987
388349
|
BASELINE_PREDICATE_COUNT = 6;
|
|
386988
388350
|
PROOF_USAGE = `Usage: copilotkit onboard proof --step <${PROOF_STEPS.join("|")}> --outcome <${PROOF_OUTCOMES.join("|")}>
|
|
386989
388351
|
[--predicate <1-${BASELINE_PREDICATE_COUNT}>]
|
|
@@ -386994,6 +388356,7 @@ trip.
|
|
|
386994
388356
|
Pass --predicate with a failed or skipped oss-baseline to name which of the
|
|
386995
388357
|
six predicates it was. A passed gate has no predicate to name, and the
|
|
386996
388358
|
round trip has no numbered predicates at all.`;
|
|
388359
|
+
IDENTIFY_USAGE = "Usage: copilotkit onboard identify --coding-agent <slug>";
|
|
386997
388360
|
BLOCKER_REPORTS = {
|
|
386998
388361
|
inspector: {
|
|
386999
388362
|
cause: "the debugging surface for this frontend did not open.",
|
|
@@ -389970,6 +391333,7 @@ init_feature_flags();
|
|
|
389970
391333
|
init_exit_code();
|
|
389971
391334
|
init_unknown_input();
|
|
389972
391335
|
await init_telemetry();
|
|
391336
|
+
init_event_properties();
|
|
389973
391337
|
import { parseArgs as parseArgs4 } from "node:util";
|
|
389974
391338
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
389975
391339
|
import path44 from "node:path";
|
|
@@ -390204,8 +391568,8 @@ General:
|
|
|
390204
391568
|
--verbose Mirror CLI diagnostics to stderr
|
|
390205
391569
|
|
|
390206
391570
|
Privacy:
|
|
390207
|
-
CopilotKit collects CLI usage data to improve the product.
|
|
390208
|
-
|
|
391571
|
+
CopilotKit collects CLI usage data to improve the product. An onboarding
|
|
391572
|
+
friction report sends up to 2,048 UTF-8 bytes through this telemetry path. To opt out, set
|
|
390209
391573
|
DO_NOT_TRACK=1 or COPILOTKIT_TELEMETRY_DISABLED=1 in your environment.
|
|
390210
391574
|
`,
|
|
390211
391575
|
login: `Usage: copilotkit login [--json]
|
|
@@ -390217,19 +391581,22 @@ Options:
|
|
|
390217
391581
|
-h, --help Show help for login
|
|
390218
391582
|
`,
|
|
390219
391583
|
onboard: `Usage: copilotkit onboard start [--intent <slug>] [--run <id>] [--coding-agent <slug>]
|
|
391584
|
+
copilotkit onboard identify --coding-agent <slug>
|
|
390220
391585
|
copilotkit onboard read <prompt-name>
|
|
390221
391586
|
copilotkit onboard route
|
|
390222
391587
|
copilotkit onboard classify --starting-state <state> --agent-framework <framework> --frontend <frontend>
|
|
390223
391588
|
copilotkit onboard protect [--path <path>] [--rebaseline --path <path>]
|
|
390224
391589
|
[--accept-external --path <path>]
|
|
390225
|
-
[--
|
|
391590
|
+
[--accept-credential --path <path>]
|
|
391591
|
+
[--authorize --path <path> --reason <why>
|
|
391592
|
+
[--with-prior-change] [--unplanned]]
|
|
390226
391593
|
copilotkit onboard audit
|
|
390227
391594
|
copilotkit onboard checkpoint --phase <slug> [--attempt <n>]
|
|
390228
391595
|
copilotkit onboard proof --step <oss-baseline|round-trip> --outcome <passed|failed|skipped>
|
|
390229
391596
|
[--predicate <1-6>]
|
|
390230
391597
|
copilotkit onboard complete
|
|
390231
|
-
copilotkit onboard
|
|
390232
|
-
|
|
391598
|
+
copilotkit onboard friction --category <slug> [--cost-seconds <seconds>]
|
|
391599
|
+
[--phase <repair|stop|completion>]
|
|
390233
391600
|
|
|
390234
391601
|
Guide a coding agent through the Markdown graph bundled with this exact CLI.
|
|
390235
391602
|
|
|
@@ -390244,12 +391611,12 @@ Subcommands:
|
|
|
390244
391611
|
checkpoint Report how far a long step has got
|
|
390245
391612
|
proof Record what one proof gate returned
|
|
390246
391613
|
complete Mark a proven onboarding run complete
|
|
390247
|
-
feedback Read one non-empty message from standard input
|
|
390248
391614
|
friction Report one papercut that slowed a run down
|
|
390249
391615
|
|
|
390250
|
-
|
|
390251
|
-
source code, logs, or command output. The global telemetry setting
|
|
390252
|
-
When telemetry is
|
|
391616
|
+
A friction report must be no larger than 2,048 UTF-8 bytes. Do not include
|
|
391617
|
+
secrets, source code, logs, or command output. The global telemetry setting
|
|
391618
|
+
applies. When telemetry is off, or the send fails, the command exits zero and
|
|
391619
|
+
says which.
|
|
390253
391620
|
|
|
390254
391621
|
Protect captures the paths this run must not change -- the developer's work in
|
|
390255
391622
|
progress -- as path and digest, derived from the working tree rather than taken
|
|
@@ -390269,6 +391636,13 @@ report. Accept a path only when the run can show it did not write that path
|
|
|
390269
391636
|
itself, and never one of the two files above: those exist to be rewritten by the
|
|
390270
391637
|
run, so accepting one would record the run's own damage as the baseline.
|
|
390271
391638
|
|
|
391639
|
+
An env file is the exception, because the run asks the developer to write their
|
|
391640
|
+
model credential into it. Accept that with protect --accept-credential --path
|
|
391641
|
+
<path>. It takes nobody's word: it compares the variable names the baseline
|
|
391642
|
+
recorded with the names the file holds now, and refuses when a recorded
|
|
391643
|
+
credential is gone or empty. So the developer's own paste passes, and a step
|
|
391644
|
+
that rewrites .env and drops the project key still fails.
|
|
391645
|
+
|
|
390272
391646
|
Adding a feature to an app the developer already built needs the opposite
|
|
390273
391647
|
record. The option lives in a file they wrote, so the run has to change it. The
|
|
390274
391648
|
plan asks for that path, approving the plan grants it, and the grant is recorded
|
|
@@ -390276,12 +391650,23 @@ with protect --authorize --path <path> --reason <why> before any edit. The audit
|
|
|
390276
391650
|
then reports the path instead of failing on it, and every later audit and the
|
|
390277
391651
|
closing report name it with its reason. An authorization is refused once the
|
|
390278
391652
|
path has moved, because consent taken afterwards cannot be told apart from a run
|
|
390279
|
-
clearing a failure it caused.
|
|
391653
|
+
clearing a failure it caused. Add --with-prior-change for the one case that rule
|
|
391654
|
+
had no answer for: the developer changed the file after the capture, and the run
|
|
391655
|
+
must change the same file. The earlier change is recorded as drift beside the
|
|
391656
|
+
consent, so both authors stay visible in the closing report.
|
|
391657
|
+
|
|
391658
|
+
Consent belongs to the plan the developer approved. Once the run reports that
|
|
391659
|
+
plan with checkpoint --phase plan-written, --authorize is refused for every path
|
|
391660
|
+
the plan did not name: the developer approved the plan, not whatever the run
|
|
391661
|
+
reaches later. Where the run must change such a path, it asks the developer and
|
|
391662
|
+
records their answer with --unplanned, which marks the consent as taken outside
|
|
391663
|
+
the plan wherever it is printed. The flag is refused before the plan is
|
|
391664
|
+
reported, so it can never stand in for the plan's own approval.
|
|
390280
391665
|
|
|
390281
391666
|
Checkpoint reports progress from inside a step, where the graph would
|
|
390282
391667
|
otherwise say nothing between one prompt and the next. --phase takes one of:
|
|
390283
|
-
research-returned, starter-cloned, plan-written,
|
|
390284
|
-
journey-attempted, repair-attempted. Pass --attempt <1-9>
|
|
391668
|
+
research-returned, starter-cloned, plan-written, container-surveyed,
|
|
391669
|
+
container-settled, build-validated, journey-attempted, repair-attempted. Pass --attempt <1-9>
|
|
390285
391670
|
where the step loops, so a repair cycle can be counted.
|
|
390286
391671
|
A refused checkpoint exits zero and prints the closed set. It is called from
|
|
390287
391672
|
the middle of the longest step of a run, and a non-zero exit there reads as a
|
|
@@ -390310,6 +391695,10 @@ report from standard input, at most 2,000 characters and four lines of prose.
|
|
|
390310
391695
|
--category takes one of: docs-missing, docs-wrong, docs-sequential, cli-gap,
|
|
390311
391696
|
sdk-gap, environment, port-collision, credential, validation-loop, other.
|
|
390312
391697
|
--cost-seconds takes the reporting agent's own estimate of the seconds lost.
|
|
391698
|
+
--phase takes one of: repair, stop, completion, and defaults to completion. A
|
|
391699
|
+
repair report is filed once a repair cycle has resolved. A stop report is the
|
|
391700
|
+
one that can leave --cost-seconds off, because a run that stopped cannot
|
|
391701
|
+
separate one papercut's cost from the cost of the whole run.
|
|
390313
391702
|
|
|
390314
391703
|
A report containing a secret shape, a fenced code block, or pasted output is
|
|
390315
391704
|
refused before anything is sent, and the reason is printed. Both commands print
|
|
@@ -390317,19 +391706,28 @@ what they sent. Every refusal exits zero and leaves onboarding unaffected.
|
|
|
390317
391706
|
`,
|
|
390318
391707
|
verify: `Usage: copilotkit verify [--json] [--runtime-url <url>] [--round-trip]
|
|
390319
391708
|
[--expect-runtime <mode>] [--frontend-url <url>]
|
|
391709
|
+
[--expect-learning-container <id>]
|
|
390320
391710
|
|
|
390321
391711
|
Check that this project's CopilotKit wiring works, and report what it found.
|
|
390322
391712
|
|
|
390323
391713
|
Checks that a hosted project is selected, that a project API key is present and
|
|
390324
391714
|
authenticates against Intelligence, that the CopilotKit runtime responds, that
|
|
390325
|
-
it declares at least one agent, that it
|
|
390326
|
-
|
|
390327
|
-
|
|
390328
|
-
|
|
391715
|
+
it declares at least one agent, that it holds an Intelligence client and calls
|
|
391716
|
+
the same deployment the key was proven against, that it accepts the origin a
|
|
391717
|
+
browser opens, and that the installed CopilotKit packages match the version it
|
|
391718
|
+
reports. Reports the runtime version, the agent framework in use, whether
|
|
391719
|
+
transcription is wired, the realtime gateway wiring, and the license state.
|
|
390329
391720
|
|
|
390330
391721
|
Every check reports PASS, FAIL, or UNKNOWN. UNKNOWN means the check could not
|
|
390331
391722
|
run \u2014 it never means the check passed. Exits non-zero unless every check passed.
|
|
390332
391723
|
|
|
391724
|
+
The runtime's /info route reports that an Intelligence client was constructed.
|
|
391725
|
+
It does not report that the client reached anything, so no check here reads it
|
|
391726
|
+
as a successful call. Set INTELLIGENCE_API_URL in the env file the app loads:
|
|
391727
|
+
without it the runtime falls back to its own built-in host while this command
|
|
391728
|
+
proves the key against the host baked into this binary, and a valid key then
|
|
391729
|
+
gets 401 on every request.
|
|
391730
|
+
|
|
390333
391731
|
The report names the runtime URL it probed and where that URL came from. Nothing
|
|
390334
391732
|
answering at a URL the project named is a FAIL; nothing answering at the assumed
|
|
390335
391733
|
default is UNKNOWN, because an app running on a port this command never learned
|
|
@@ -390340,6 +391738,13 @@ the answer back from the thread, which is the only check here that proves the
|
|
|
390340
391738
|
agent runs rather than that it is configured. That costs a model call and
|
|
390341
391739
|
records a thread, so it is opt-in.
|
|
390342
391740
|
|
|
391741
|
+
A runtime mounted mode: "single-route" runs the request through its agent/run
|
|
391742
|
+
envelope, and the answer is read from the platform because that mount carries
|
|
391743
|
+
its thread routes inside the envelope rather than as REST paths this command
|
|
391744
|
+
can call. The report names which read answered: through the app, the answer
|
|
391745
|
+
belongs to the caller the app identified; from the platform, the run and its
|
|
391746
|
+
answer are proved and the end user they belonged to is not.
|
|
391747
|
+
|
|
390343
391748
|
With --expect-runtime oss, hosted project and credential checks do not apply.
|
|
390344
391749
|
The command exits zero only when valid /info data declares the named agent,
|
|
390345
391750
|
reports no Intelligence entitlement, and --round-trip --agent <id> passes.
|
|
@@ -390358,6 +391763,12 @@ Options:
|
|
|
390358
391763
|
to send a real CORS preflight when that origin differs
|
|
390359
391764
|
from the runtime's
|
|
390360
391765
|
--expect-runtime <mode> Require intelligence (default) or oss runtime mode
|
|
391766
|
+
--expect-learning-container <id>
|
|
391767
|
+
Require the round trip's thread to carry this
|
|
391768
|
+
Learning Container. Needs --round-trip --agent <id>.
|
|
391769
|
+
Read from the platform, so it answers for a runtime
|
|
391770
|
+
mounted mode: "single-route" too. A plan entitlement
|
|
391771
|
+
or an /info flag is not evidence.
|
|
390361
391772
|
--round-trip Also run the agent and read its answer back
|
|
390362
391773
|
--agent <id> Which declared agent to run, when there are several
|
|
390363
391774
|
--timeout <seconds> How long to wait for the answer (default: 90)
|
|
@@ -390653,6 +392064,7 @@ Actions:
|
|
|
390653
392064
|
learning containers list List Learning Containers (alias: ls)
|
|
390654
392065
|
learning containers get <id> Show one Learning Container (alias: show)
|
|
390655
392066
|
learning containers create Create a Learning Container
|
|
392067
|
+
learning containers select Pick one, or create one, in a terminal
|
|
390656
392068
|
learning containers update <id> Change a name or prompt context
|
|
390657
392069
|
learning containers delete <id> Delete an unused Learning Container
|
|
390658
392070
|
|
|
@@ -391245,7 +392657,7 @@ async function applyGlobalArgs(parsed) {
|
|
|
391245
392657
|
setCliLogsVerbose2(true);
|
|
391246
392658
|
}
|
|
391247
392659
|
}
|
|
391248
|
-
async function runWhoami() {
|
|
392660
|
+
async function runWhoami(ctx) {
|
|
391249
392661
|
const {
|
|
391250
392662
|
clearAuthOnTerminalSessionInvalidation: clearAuthOnTerminalSessionInvalidation2,
|
|
391251
392663
|
TERMINAL_SESSION_INVALID_MESSAGE: TERMINAL_SESSION_INVALID_MESSAGE2,
|
|
@@ -391265,17 +392677,20 @@ async function runWhoami() {
|
|
|
391265
392677
|
if (clearAuthOnTerminalSessionInvalidation2(error98)) {
|
|
391266
392678
|
process.stdout.write(`${TERMINAL_SESSION_INVALID_MESSAGE2}
|
|
391267
392679
|
`);
|
|
392680
|
+
ctx.reportFailure({ errorCode: "auth" });
|
|
391268
392681
|
return;
|
|
391269
392682
|
}
|
|
391270
392683
|
if (error98 instanceof ApiClientError2 && error98.status > 0) {
|
|
391271
392684
|
process.stdout.write(`${error98.message}
|
|
391272
392685
|
`);
|
|
392686
|
+
ctx.reportFailure({ errorCode: classifyError(error98) });
|
|
391273
392687
|
return;
|
|
391274
392688
|
}
|
|
391275
392689
|
throw error98;
|
|
391276
392690
|
}
|
|
391277
392691
|
if (!session) {
|
|
391278
392692
|
process.stdout.write("Session expired. Please run: copilotkit login\n");
|
|
392693
|
+
ctx.reportFailure({ errorCode: "auth" });
|
|
391279
392694
|
return;
|
|
391280
392695
|
}
|
|
391281
392696
|
process.stdout.write(`Email: ${session.user.email}
|
|
@@ -391736,6 +393151,15 @@ function parseLearningContainersCommandArgs(argv) {
|
|
|
391736
393151
|
...parsed.values.cursor === void 0 ? {} : { cursor: parsed.values.cursor }
|
|
391737
393152
|
};
|
|
391738
393153
|
}
|
|
393154
|
+
if (subcommand === "select") {
|
|
393155
|
+
const parsed = parseArgs4({
|
|
393156
|
+
args,
|
|
393157
|
+
options: { json: { type: "boolean" } },
|
|
393158
|
+
strict: true,
|
|
393159
|
+
allowPositionals: false
|
|
393160
|
+
});
|
|
393161
|
+
return { action: "select", json: parsed.values.json === true };
|
|
393162
|
+
}
|
|
391739
393163
|
if (subcommand === "get") {
|
|
391740
393164
|
const parsed = parseArgs4({
|
|
391741
393165
|
args,
|
|
@@ -391974,7 +393398,7 @@ function learningParseFailureSubcommand(argv) {
|
|
|
391974
393398
|
const resource = argv[0];
|
|
391975
393399
|
const action = argv[1];
|
|
391976
393400
|
if (resource === "containers") {
|
|
391977
|
-
return action === "list" || action === "get" || action === "show" || action === "create" || action === "update" || action === "delete" ? `containers.${action === "show" ? "get" : action}` : "containers.invalid";
|
|
393401
|
+
return action === "list" || action === "get" || action === "show" || action === "create" || action === "select" || action === "update" || action === "delete" ? `containers.${action === "show" ? "get" : action}` : "containers.invalid";
|
|
391978
393402
|
}
|
|
391979
393403
|
if (resource === "insights" || resource === "skills") {
|
|
391980
393404
|
return action === "list" || action === "ls" ? `${resource}.list` : `${resource}.invalid`;
|
|
@@ -392078,10 +393502,10 @@ ${helpTextForTopic("learning")}`
|
|
|
392078
393502
|
createLearningContainersCommandDependencies: createLearningContainersCommandDependencies2,
|
|
392079
393503
|
runLearningContainersCommand: runLearningContainersCommand2
|
|
392080
393504
|
} = await init_learning_containers().then(() => learning_containers_exports);
|
|
392081
|
-
await runLearningContainersCommand2(
|
|
392082
|
-
|
|
392083
|
-
|
|
392084
|
-
);
|
|
393505
|
+
await runLearningContainersCommand2(command2, {
|
|
393506
|
+
...createLearningContainersCommandDependencies2(),
|
|
393507
|
+
telemetry: { setProperties: telemetryContext.setProperties }
|
|
393508
|
+
});
|
|
392085
393509
|
}
|
|
392086
393510
|
);
|
|
392087
393511
|
}
|
|
@@ -392173,6 +393597,7 @@ async function runVerifyCommand(argv) {
|
|
|
392173
393597
|
options: {
|
|
392174
393598
|
agent: { type: "string" },
|
|
392175
393599
|
"expect-runtime": { type: "string" },
|
|
393600
|
+
"expect-learning-container": { type: "string" },
|
|
392176
393601
|
"frontend-url": { type: "string" },
|
|
392177
393602
|
header: { multiple: true, type: "string" },
|
|
392178
393603
|
json: { type: "boolean" },
|
|
@@ -392226,17 +393651,44 @@ async function runVerifyCommand(argv) {
|
|
|
392226
393651
|
await exitWithFlush(1);
|
|
392227
393652
|
}
|
|
392228
393653
|
const agent = parsed.values["agent"];
|
|
393654
|
+
const expectLearningContainer = parsed.values["expect-learning-container"];
|
|
393655
|
+
if (expectLearningContainer !== void 0 && !/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(expectLearningContainer)) {
|
|
393656
|
+
process.stderr.write(
|
|
393657
|
+
"Error: --expect-learning-container expects 1-64 lowercase letters, numbers, and single hyphens.\n"
|
|
393658
|
+
);
|
|
393659
|
+
await exitWithFlush(1);
|
|
393660
|
+
}
|
|
392229
393661
|
const { runVerify: runVerify2 } = await Promise.resolve().then(() => (init_verify(), verify_exports));
|
|
392230
|
-
await runVerify2(
|
|
392231
|
-
|
|
392232
|
-
|
|
392233
|
-
|
|
392234
|
-
|
|
392235
|
-
|
|
392236
|
-
|
|
392237
|
-
|
|
392238
|
-
|
|
392239
|
-
|
|
393662
|
+
await runVerify2(
|
|
393663
|
+
{
|
|
393664
|
+
json: parsed.values["json"] === true,
|
|
393665
|
+
...agent === void 0 ? {} : { agent },
|
|
393666
|
+
...expectLearningContainer === void 0 ? {} : { expectLearningContainer },
|
|
393667
|
+
...expectedRuntime === void 0 ? {} : { expectRuntime: expectedRuntime },
|
|
393668
|
+
...headers === void 0 || Object.keys(headers).length === 0 ? {} : { headers },
|
|
393669
|
+
...frontendUrl === void 0 ? {} : { frontendUrl },
|
|
393670
|
+
...parsed.values["round-trip"] === true ? { roundTrip: true } : {},
|
|
393671
|
+
...runtimeUrl === void 0 ? {} : { runtimeUrl },
|
|
393672
|
+
...timeoutSeconds === void 0 ? {} : { timeoutMs: Number(timeoutSeconds) * 1e3 }
|
|
393673
|
+
},
|
|
393674
|
+
{
|
|
393675
|
+
// A point event rather than a property on the command's own lifecycle
|
|
393676
|
+
// event. `verify` is dispatched as `auto`, which owns the bookend and does
|
|
393677
|
+
// not hand the runner its telemetry context, and the outcome is worth its
|
|
393678
|
+
// own row: the lifecycle event answers "did the command run", this answers
|
|
393679
|
+
// "did Learning prove out for this project".
|
|
393680
|
+
recordLearningContainerCheck: ({ outcome }) => {
|
|
393681
|
+
recordTelemetryEvent({
|
|
393682
|
+
event: "cli.verify.learning_container_checked",
|
|
393683
|
+
properties: {
|
|
393684
|
+
command: "verify",
|
|
393685
|
+
learning_check_outcome: outcome,
|
|
393686
|
+
...currentOnboardingRunProperties()
|
|
393687
|
+
}
|
|
393688
|
+
});
|
|
393689
|
+
}
|
|
393690
|
+
}
|
|
393691
|
+
);
|
|
392240
393692
|
}
|
|
392241
393693
|
async function runTypegenCommand(argv) {
|
|
392242
393694
|
const parsed = parseArgs4({
|
|
@@ -392498,13 +393950,17 @@ async function runInitCommand(invokedAs, argv) {
|
|
|
392498
393950
|
await runInit2(flags, callbacks);
|
|
392499
393951
|
});
|
|
392500
393952
|
}
|
|
393953
|
+
var UNWRAPPED_TELEMETRY_CONTEXT = {
|
|
393954
|
+
setProperties: () => void 0,
|
|
393955
|
+
reportFailure: () => void 0
|
|
393956
|
+
};
|
|
392501
393957
|
var ONBOARD_SUBCOMMANDS2 = [
|
|
392502
393958
|
"audit",
|
|
392503
393959
|
"checkpoint",
|
|
392504
393960
|
"classify",
|
|
392505
393961
|
"complete",
|
|
392506
|
-
"feedback",
|
|
392507
393962
|
"friction",
|
|
393963
|
+
"identify",
|
|
392508
393964
|
"proof",
|
|
392509
393965
|
"protect",
|
|
392510
393966
|
"read",
|
|
@@ -392567,8 +394023,8 @@ var COMMAND_TABLE = {
|
|
|
392567
394023
|
whoami: {
|
|
392568
394024
|
kind: "auto",
|
|
392569
394025
|
command: "whoami",
|
|
392570
|
-
run: async () => {
|
|
392571
|
-
await runWhoami();
|
|
394026
|
+
run: async (_argv, _token, ctx) => {
|
|
394027
|
+
await runWhoami(ctx);
|
|
392572
394028
|
}
|
|
392573
394029
|
},
|
|
392574
394030
|
docs: {
|
|
@@ -392731,13 +394187,13 @@ async function main(rawArgv = process.argv.slice(2)) {
|
|
|
392731
394187
|
command: entry.command,
|
|
392732
394188
|
...subcommand === void 0 ? {} : { subcommand }
|
|
392733
394189
|
},
|
|
392734
|
-
async () => {
|
|
392735
|
-
await entry.run(commandArgv, command2);
|
|
394190
|
+
async (ctx) => {
|
|
394191
|
+
await entry.run(commandArgv, command2, ctx);
|
|
392736
394192
|
}
|
|
392737
394193
|
);
|
|
392738
394194
|
return;
|
|
392739
394195
|
}
|
|
392740
|
-
await entry.run(commandArgv, command2);
|
|
394196
|
+
await entry.run(commandArgv, command2, UNWRAPPED_TELEMETRY_CONTEXT);
|
|
392741
394197
|
}
|
|
392742
394198
|
function resolveRealPath(candidatePath) {
|
|
392743
394199
|
const absolutePath = path44.resolve(candidatePath);
|