copilotkit 4.9.60 → 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.
Files changed (73) hide show
  1. package/cli-build-info.json +7 -7
  2. package/index.js +324 -162
  3. package/onboarding/index.json +81 -18
  4. package/onboarding/prompts/authenticate/start.md +41 -202
  5. package/onboarding/prompts/conversion/plan.md +3 -3
  6. package/onboarding/prompts/credentials/finalize-plan.md +15 -129
  7. package/onboarding/prompts/credentials/plan.md +20 -20
  8. package/onboarding/prompts/credentials/settle-credentials.md +153 -0
  9. package/onboarding/prompts/credentials/write-plan.md +93 -0
  10. package/onboarding/prompts/fallback/best-effort.md +12 -9
  11. package/onboarding/prompts/feature/a2ui/implement.md +35 -6
  12. package/onboarding/prompts/feature/a2ui/proof.md +30 -6
  13. package/onboarding/prompts/feature/a2ui/start.md +29 -6
  14. package/onboarding/prompts/feature/chat-suggestions/implement.md +36 -6
  15. package/onboarding/prompts/feature/chat-suggestions/proof.md +30 -5
  16. package/onboarding/prompts/feature/chat-suggestions/start.md +29 -6
  17. package/onboarding/prompts/feature/complete.md +11 -0
  18. package/onboarding/prompts/feature/learning/implement.md +41 -12
  19. package/onboarding/prompts/feature/learning/proof.md +32 -6
  20. package/onboarding/prompts/feature/learning/start.md +28 -5
  21. package/onboarding/prompts/feature/open-generative-ui/implement.md +37 -6
  22. package/onboarding/prompts/feature/open-generative-ui/proof.md +30 -5
  23. package/onboarding/prompts/feature/open-generative-ui/start.md +29 -6
  24. package/onboarding/prompts/feature/realtime-sync/implement.md +36 -7
  25. package/onboarding/prompts/feature/realtime-sync/proof.md +29 -5
  26. package/onboarding/prompts/feature/realtime-sync/start.md +28 -5
  27. package/onboarding/prompts/feature/rich-threads/implement.md +37 -8
  28. package/onboarding/prompts/feature/rich-threads/proof.md +31 -5
  29. package/onboarding/prompts/feature/rich-threads/start.md +28 -5
  30. package/onboarding/prompts/feature/stop.md +9 -6
  31. package/onboarding/prompts/feature/voice/implement.md +35 -6
  32. package/onboarding/prompts/feature/voice/proof.md +30 -5
  33. package/onboarding/prompts/feature/voice/start.md +29 -6
  34. package/onboarding/prompts/framework/ag2.md +2 -2
  35. package/onboarding/prompts/framework/agno.md +2 -2
  36. package/onboarding/prompts/framework/built-in.md +2 -2
  37. package/onboarding/prompts/framework/claude-sdk-python.md +2 -2
  38. package/onboarding/prompts/framework/claude-sdk-typescript.md +2 -2
  39. package/onboarding/prompts/framework/crewai-flows.md +2 -2
  40. package/onboarding/prompts/framework/deep-agents.md +2 -2
  41. package/onboarding/prompts/framework/google-adk.md +2 -2
  42. package/onboarding/prompts/framework/langgraph-fastapi.md +2 -2
  43. package/onboarding/prompts/framework/langgraph-python.md +2 -2
  44. package/onboarding/prompts/framework/langgraph-typescript.md +2 -2
  45. package/onboarding/prompts/framework/llamaindex.md +2 -2
  46. package/onboarding/prompts/framework/mastra.md +2 -2
  47. package/onboarding/prompts/framework/ms-agent-dotnet.md +2 -2
  48. package/onboarding/prompts/framework/ms-agent-harness-dotnet.md +2 -2
  49. package/onboarding/prompts/framework/ms-agent-python.md +2 -2
  50. package/onboarding/prompts/framework/pydantic-ai.md +2 -2
  51. package/onboarding/prompts/framework/strands-python.md +2 -2
  52. package/onboarding/prompts/framework/strands-typescript.md +2 -2
  53. package/onboarding/prompts/frontend/angular.md +3 -3
  54. package/onboarding/prompts/frontend/nextjs.md +3 -3
  55. package/onboarding/prompts/frontend/plan.md +6 -6
  56. package/onboarding/prompts/frontend/react-native.md +2 -2
  57. package/onboarding/prompts/frontend/react-spa.md +2 -2
  58. package/onboarding/prompts/frontend/vue.md +2 -2
  59. package/onboarding/prompts/implementation/build-and-validate.md +75 -15
  60. package/onboarding/prompts/proof/complete.md +21 -8
  61. package/onboarding/prompts/proof/oss-baseline.md +6 -5
  62. package/onboarding/prompts/proof/round-trip.md +27 -14
  63. package/onboarding/prompts/research/gather.md +121 -0
  64. package/onboarding/prompts/research/route.md +81 -0
  65. package/onboarding/prompts/starter/clone.md +18 -9
  66. package/onboarding/prompts/stopped/run-failed.md +44 -0
  67. package/onboarding/prompts/subagent/create-plan.md +32 -1
  68. package/onboarding/prompts/subagent/implement-and-validate.md +9 -1
  69. package/onboarding/prompts/subagent/prove-oss-baseline.md +1 -1
  70. package/onboarding/prompts/subagent/prove-round-trip.md +52 -8
  71. package/onboarding/prompts/unsupported/no-validated-path.md +9 -6
  72. package/package.json +1 -1
  73. 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.9.60" : "dev",
100
- buildNumber: true ? "34616405214" : "dev",
101
- commitSha: true ? "5f0f9a7cf15492544f1341f562fa5cd55387099c" : "dev",
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 ? "d1584b840f904674b470be5d2b16c4ccca99c4f4" : "main";
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 === "LEARNING_CONTAINER_NOT_FOUND" || 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") {
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));
@@ -91701,7 +91730,7 @@ function formatTelemetryNotice(privacyPolicyUrl) {
91701
91730
  return [
91702
91731
  "The CopilotKit CLI collects usage data to help improve the product.",
91703
91732
  "While you are signed in, that data is linked to your CopilotKit account.",
91704
- "The onboarding feedback command may send up to 2,048 UTF-8 bytes of text.",
91733
+ "The onboarding friction command sends up to 2,048 UTF-8 bytes of text.",
91705
91734
  "",
91706
91735
  " Disable anytime: copilotkit telemetry disable (or set DO_NOT_TRACK=1)",
91707
91736
  ` Privacy policy: ${privacyPolicyUrl}`,
@@ -91748,6 +91777,15 @@ function createTelemetryService(deps) {
91748
91777
  return typeof deps.installationId === "function" ? deps.installationId() : deps.installationId;
91749
91778
  }
91750
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
+ }
91751
91789
  const controller = new AbortController();
91752
91790
  const timer = setTimeout(() => controller.abort(), perRequestTimeoutMs);
91753
91791
  timer.unref?.();
@@ -91763,33 +91801,38 @@ function createTelemetryService(deps) {
91763
91801
  signal: controller.signal
91764
91802
  });
91765
91803
  if (!res.ok) {
91804
+ const latencyMs = Date.now() - started;
91766
91805
  deps.logger.warn({
91767
91806
  msg: "telemetry.sink.failed",
91807
+ event: prepared.body.event,
91768
91808
  status: res.status,
91769
- latency_ms: Date.now() - started,
91809
+ latency_ms: latencyMs,
91770
91810
  outcome: prepared.outcome,
91771
91811
  command: prepared.command
91772
91812
  });
91773
- return false;
91813
+ return { status: "http_error", httpStatus: res.status, latencyMs };
91774
91814
  }
91775
91815
  deps.logger.debug({
91776
91816
  msg: "telemetry.sink.succeeded",
91817
+ event: prepared.body.event,
91777
91818
  status: res.status,
91778
91819
  latency_ms: Date.now() - started,
91779
91820
  outcome: prepared.outcome,
91780
91821
  command: prepared.command
91781
91822
  });
91782
- return true;
91823
+ return { status: "sent" };
91783
91824
  } catch (err2) {
91784
91825
  const isAbort = err2 instanceof Error && err2.name === "AbortError";
91826
+ const latencyMs = Date.now() - started;
91785
91827
  deps.logger.warn({
91786
91828
  msg: "telemetry.sink.failed",
91787
- latency_ms: Date.now() - started,
91829
+ event: prepared.body.event,
91830
+ latency_ms: latencyMs,
91788
91831
  outcome: prepared.outcome,
91789
91832
  command: prepared.command,
91790
91833
  error_code: isAbort ? "timeout" : "network"
91791
91834
  });
91792
- return false;
91835
+ return isAbort ? { status: "timeout", timeoutMs: perRequestTimeoutMs, latencyMs } : { status: "network", latencyMs };
91793
91836
  } finally {
91794
91837
  clearTimeout(timer);
91795
91838
  }
@@ -91816,6 +91859,7 @@ function createTelemetryService(deps) {
91816
91859
  if (inFlight.size >= maxInFlight) {
91817
91860
  deps.logger.error({
91818
91861
  msg: "telemetry.dropped.queue_full",
91862
+ event: event.event ?? CLI_TELEMETRY_EVENT_NAME,
91819
91863
  outcome: event.properties.outcome,
91820
91864
  command: event.properties.command
91821
91865
  });
@@ -91831,8 +91875,17 @@ function createTelemetryService(deps) {
91831
91875
  });
91832
91876
  }
91833
91877
  async function submitEvent(event) {
91834
- if (!deps.enabled || inFlight.size >= maxInFlight)
91835
- return false;
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
+ }
91836
91889
  const promise3 = (async () => {
91837
91890
  await new Promise((resolve9) => setImmediate(resolve9));
91838
91891
  return await sendOne(prepareEvent(event));
@@ -92017,14 +92070,47 @@ async function submitTelemetryEvent(event) {
92017
92070
  if (!gate.send)
92018
92071
  return { status: "declined" };
92019
92072
  try {
92020
- const accepted = await getTelemetry().submitEvent(
92073
+ const delivery = await getTelemetry().submitEvent(
92021
92074
  withProjectIdentity(event)
92022
92075
  );
92023
- return accepted ? { status: "sent" } : { status: "failed", detail: "the transport did not accept the event" };
92076
+ return describeDelivery(delivery);
92024
92077
  } catch (error98) {
92025
92078
  return { status: "failed", detail: describeSubmissionError(error98) };
92026
92079
  }
92027
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
+ }
92028
92114
  function describeSubmissionError(error98) {
92029
92115
  if (error98 instanceof Error && error98.message !== "")
92030
92116
  return error98.message;
@@ -94899,13 +94985,25 @@ import * as fs18 from "node:fs";
94899
94985
  import * as path14 from "node:path";
94900
94986
  import * as os7 from "node:os";
94901
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
+ }
94902
95000
  function isProjectDirOccupied(projectDir) {
94903
- return fs18.existsSync(projectDir) && fs18.readdirSync(projectDir).length > 0;
95001
+ return fs18.existsSync(projectDir) && fs18.readdirSync(projectDir).some(entryHoldsProject);
94904
95002
  }
94905
95003
  function assertProjectDirAvailable(projectDir) {
94906
95004
  if (isProjectDirOccupied(projectDir)) {
94907
95005
  throw tagError(
94908
- new Error(`${projectDir} already exists and is not empty`),
95006
+ new Error(`${projectDir} already holds a project`),
94909
95007
  TELEMETRY_ERROR_CODES.PREREQUISITE_MISSING
94910
95008
  );
94911
95009
  }
@@ -95155,12 +95253,36 @@ async function initializeProjectGit(projectDir) {
95155
95253
  }
95156
95254
  return { kind: "initialized" };
95157
95255
  }
95158
- 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;
95159
95257
  var init_project_scaffold = __esm({
95160
95258
  "apps/cli/src/services/project-scaffold.ts"() {
95161
95259
  "use strict";
95162
95260
  init_repository_root();
95163
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"];
95164
95286
  TEST_HARNESS_ARTIFACTS = [
95165
95287
  "docker",
95166
95288
  ".dockerignore",
@@ -100013,6 +100135,70 @@ var init_learning = __esm({
100013
100135
  }
100014
100136
  });
100015
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
+
100016
100202
  // libs/app-api-contracts/src/threads.ts
100017
100203
  var threadIdSchema, appUserAliasSchema, collapseAppUserAliases, refuseInternalAppUserForms, threadAppUserSchema, threadReadQuerySchema;
100018
100204
  var init_threads = __esm({
@@ -100124,6 +100310,8 @@ var init_src6 = __esm({
100124
100310
  init_inspector_metadata();
100125
100311
  init_inspector_learning();
100126
100312
  init_learning();
100313
+ init_learning_schedule();
100314
+ init_learning_automation();
100127
100315
  init_threads();
100128
100316
  init_usage();
100129
100317
  }
@@ -383639,7 +383827,7 @@ function createHostedProjectApiClient(auth2) {
383639
383827
  productOrganizationId: auth2.clerkOrgId
383640
383828
  });
383641
383829
  }
383642
- 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) {
383643
383831
  const missingPrerequisites = templateDefinition.prerequisites.filter(
383644
383832
  (prerequisite) => result.missingPrerequisites.includes(prerequisite.command)
383645
383833
  );
@@ -383700,6 +383888,13 @@ function buildInitNextSteps(templateDefinition, projectName, result, unsatisfied
383700
383888
  code: `${requirement.key}=${requirement.example}`
383701
383889
  });
383702
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
+ }
383703
383898
  for (const note of templateDefinition.setupNotes ?? []) {
383704
383899
  steps.push(note.code !== void 0 ? { ...note } : { text: note.text });
383705
383900
  }
@@ -384492,7 +384687,12 @@ function ScaffoldProgress({
384492
384687
  result,
384493
384688
  unsatisfied,
384494
384689
  installAlreadyRan,
384495
- 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")
384496
384696
  )
384497
384697
  );
384498
384698
  setScaffoldWarnings((prev) => mergeScaffoldWarnings(prev, result.warnings));
@@ -385464,7 +385664,16 @@ function reviewFrictionReport(input) {
385464
385664
  `--category must be one of: ${FRICTION_CATEGORIES.join(", ")}.`
385465
385665
  );
385466
385666
  }
385467
- if (input.costSeconds === void 0 || !COST_SECONDS_PATTERN.test(input.costSeconds) || Number(input.costSeconds) > MAX_COST_SECONDS_ESTIMATED) {
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") {
385468
385677
  return refuse(
385469
385678
  "FRICTION_COST_INVALID",
385470
385679
  `--cost-seconds must be a whole number of seconds from 0 to ${MAX_COST_SECONDS_ESTIMATED}.`
@@ -385516,7 +385725,10 @@ function reviewFrictionReport(input) {
385516
385725
  ok: true,
385517
385726
  report: {
385518
385727
  category,
385519
- costSecondsEstimated: Number(input.costSeconds),
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) },
385520
385732
  // Spread so an absent path leaves the key off entirely, matching how the
385521
385733
  // telemetry properties treat every optional dimension.
385522
385734
  ...docsPath === void 0 ? {} : { docsPath },
@@ -385524,7 +385736,7 @@ function reviewFrictionReport(input) {
385524
385736
  }
385525
385737
  };
385526
385738
  }
385527
- 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;
385528
385740
  var init_onboarding_friction = __esm({
385529
385741
  "apps/cli/src/services/onboarding-friction.ts"() {
385530
385742
  "use strict";
@@ -385541,6 +385753,8 @@ var init_onboarding_friction = __esm({
385541
385753
  "validation-loop",
385542
385754
  "other"
385543
385755
  ];
385756
+ FRICTION_PHASES = ["repair", "stop", "completion"];
385757
+ DEFAULT_FRICTION_PHASE = "completion";
385544
385758
  MAX_FRICTION_TEXT_CHARS = 2e3;
385545
385759
  MAX_FRICTION_TEXT_NEWLINES = 3;
385546
385760
  MAX_COST_SECONDS_ESTIMATED = 86400;
@@ -385555,76 +385769,6 @@ var init_onboarding_friction = __esm({
385555
385769
  }
385556
385770
  });
385557
385771
 
385558
- // apps/cli/src/services/onboarding-feedback.ts
385559
- function refuse2(code, message) {
385560
- return { ok: false, refusal: { code, message } };
385561
- }
385562
- async function readFeedbackInput(stdin) {
385563
- const read = await readBoundedReportText(stdin, MAX_FEEDBACK_INPUT_BYTES);
385564
- if (read.ok)
385565
- return { ok: true, text: read.text };
385566
- if (read.kind === "invalid-utf8") {
385567
- return refuse2(
385568
- "ONBOARDING_FEEDBACK_INVALID_UTF8",
385569
- "Nothing was sent: the report is not valid UTF-8. Send it again as plain UTF-8 text."
385570
- );
385571
- }
385572
- return refuse2(
385573
- "ONBOARDING_FEEDBACK_TOO_LARGE",
385574
- `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.`
385575
- );
385576
- }
385577
- function reviewFeedbackReport(text2) {
385578
- const violation = reviewReportText({
385579
- text: text2,
385580
- size: FEEDBACK_SIZE_LIMIT,
385581
- maxNewlines: MAX_FEEDBACK_TEXT_NEWLINES
385582
- });
385583
- if (violation === void 0)
385584
- return { ok: true, text: text2.trim() };
385585
- switch (violation.kind) {
385586
- case "empty":
385587
- return refuse2(
385588
- "ONBOARDING_FEEDBACK_EMPTY",
385589
- "Nothing was sent: the report was empty. Name the step that failed, in one or two sentences, on standard input."
385590
- );
385591
- case "possible-secret":
385592
- return refuse2(
385593
- "ONBOARDING_FEEDBACK_POSSIBLE_SECRET",
385594
- `Nothing was sent: the report looks like it contains ${violation.shape}. Describe the problem in words and send it again without the value.`
385595
- );
385596
- case "code-block":
385597
- return refuse2(
385598
- "ONBOARDING_FEEDBACK_CODE_BLOCK",
385599
- "Nothing was sent: the report contains a fenced code block. Describe the problem in words, without source code, logs, or command output."
385600
- );
385601
- case "too-many-lines":
385602
- return refuse2(
385603
- "ONBOARDING_FEEDBACK_TOO_MANY_LINES",
385604
- `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.`
385605
- );
385606
- case "too-long":
385607
- return refuse2(
385608
- "ONBOARDING_FEEDBACK_TOO_LARGE",
385609
- `Nothing was sent: the report is ${violation.measured} UTF-8 bytes. Shorten it to at most ${MAX_FEEDBACK_TEXT_BYTES} and send it again.`
385610
- );
385611
- }
385612
- }
385613
- var MAX_FEEDBACK_TEXT_BYTES, MAX_FEEDBACK_TEXT_NEWLINES, MAX_FEEDBACK_INPUT_BYTES, FEEDBACK_SIZE_LIMIT;
385614
- var init_onboarding_feedback = __esm({
385615
- "apps/cli/src/services/onboarding-feedback.ts"() {
385616
- "use strict";
385617
- init_onboarding_report_text();
385618
- MAX_FEEDBACK_TEXT_BYTES = 2048;
385619
- MAX_FEEDBACK_TEXT_NEWLINES = 3;
385620
- MAX_FEEDBACK_INPUT_BYTES = 2050;
385621
- FEEDBACK_SIZE_LIMIT = {
385622
- unit: "utf8-bytes",
385623
- max: MAX_FEEDBACK_TEXT_BYTES
385624
- };
385625
- }
385626
- });
385627
-
385628
385772
  // apps/cli/src/services/onboarding-checkpoint.ts
385629
385773
  function reviewCheckpoint(input) {
385630
385774
  const phase = CHECKPOINT_PHASES.find((known) => known === input.phase);
@@ -385858,6 +386002,9 @@ function probeGraphOwned(root2, cwd2) {
385858
386002
  }
385859
386003
  return found;
385860
386004
  }
386005
+ function toRequestedPath(root2, path45) {
386006
+ return isAbsolute(path45) ? path45 : resolve7(root2, path45);
386007
+ }
385861
386008
  function toRepositoryRelative(root2, absolute) {
385862
386009
  const relativePath = relative3(root2, absolute);
385863
386010
  if (relativePath === "" || relativePath.startsWith(".."))
@@ -385888,7 +386035,7 @@ function captureProtectedPaths(dependencies, input) {
385888
386035
  const existing = ownBaseline?.entries ?? [];
385889
386036
  const requested = [];
385890
386037
  for (const path45 of input.paths) {
385891
- const absolute = isAbsolute(path45) ? path45 : resolve7(dependencies.cwd, path45);
386038
+ const absolute = toRequestedPath(root2, path45);
385892
386039
  const relativePath = toRepositoryRelative(root2, absolute);
385893
386040
  if (relativePath === void 0) {
385894
386041
  return {
@@ -386025,7 +386172,7 @@ function rebaselineProtectedPaths(dependencies, input) {
386025
386172
  }
386026
386173
  const targets = [];
386027
386174
  for (const path45 of input.paths) {
386028
- const absolute = isAbsolute(path45) ? path45 : resolve7(dependencies.cwd, path45);
386175
+ const absolute = toRequestedPath(root2, path45);
386029
386176
  const relativePath = toRepositoryRelative(root2, absolute);
386030
386177
  if (relativePath === void 0) {
386031
386178
  return { status: "blocked", reason: "unknown-path", detail: path45 };
@@ -386115,7 +386262,7 @@ function acceptProtectedPathDrift(dependencies, input) {
386115
386262
  const drift = /* @__PURE__ */ new Map();
386116
386263
  const accepted = [];
386117
386264
  for (const path45 of input.paths) {
386118
- const absolute = isAbsolute(path45) ? path45 : resolve7(dependencies.cwd, path45);
386265
+ const absolute = toRequestedPath(root2, path45);
386119
386266
  const relativePath = toRepositoryRelative(root2, absolute);
386120
386267
  if (relativePath === void 0) {
386121
386268
  return { status: "blocked", reason: "unknown-path", detail: path45 };
@@ -386218,7 +386365,7 @@ function acceptCredentialPlacement(dependencies, input) {
386218
386365
  const placed = /* @__PURE__ */ new Map();
386219
386366
  const accepted = [];
386220
386367
  for (const path45 of input.paths) {
386221
- const absolute = isAbsolute(path45) ? path45 : resolve7(dependencies.cwd, path45);
386368
+ const absolute = toRequestedPath(root2, path45);
386222
386369
  const relativePath = toRepositoryRelative(root2, absolute);
386223
386370
  if (relativePath === void 0) {
386224
386371
  return { status: "blocked", reason: "unknown-path", detail: path45 };
@@ -386367,7 +386514,7 @@ function authorizeProtectedPathChange(dependencies, input) {
386367
386514
  const priorDrift = /* @__PURE__ */ new Map();
386368
386515
  const authorized = [];
386369
386516
  for (const path45 of input.paths) {
386370
- const absolute = isAbsolute(path45) ? path45 : resolve7(dependencies.cwd, path45);
386517
+ const absolute = toRequestedPath(root2, path45);
386371
386518
  const relativePath = toRepositoryRelative(root2, absolute);
386372
386519
  if (relativePath === void 0) {
386373
386520
  return { status: "blocked", reason: "unknown-path", detail: path45 };
@@ -386488,6 +386635,11 @@ var init_onboarding_protected_paths = __esm({
386488
386635
  });
386489
386636
 
386490
386637
  // apps/cli/src/services/onboarding-classification.ts
386638
+ function resolveAgentFrameworkAlias(value) {
386639
+ if (value === void 0)
386640
+ return void 0;
386641
+ return ONBOARDING_AGENT_FRAMEWORK_ALIASES[value] ?? value;
386642
+ }
386491
386643
  function unprovenBaselineRefusal(startingState, route, proof) {
386492
386644
  if (startingState !== "both-oss" && startingState !== "both-copilotkit-unproved") {
386493
386645
  return void 0;
@@ -386534,7 +386686,7 @@ function requireOnboardingChoice(flag, value, choices) {
386534
386686
  }
386535
386687
  return selected;
386536
386688
  }
386537
- var ONBOARDING_STARTING_STATES, ONBOARDING_AGENT_FRAMEWORKS, ONBOARDING_FRONTENDS, ONBOARDING_PROOF_STEPS, ONBOARDING_PROOF_OUTCOMES, ABSENCE_STATES, 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;
386538
386690
  var init_onboarding_classification = __esm({
386539
386691
  "apps/cli/src/services/onboarding-classification.ts"() {
386540
386692
  "use strict";
@@ -386567,6 +386719,9 @@ var init_onboarding_classification = __esm({
386567
386719
  "strands-python",
386568
386720
  "strands-typescript"
386569
386721
  ];
386722
+ ONBOARDING_AGENT_FRAMEWORK_ALIASES = {
386723
+ langgraph: "langgraph-python"
386724
+ };
386570
386725
  ONBOARDING_FRONTENDS = [
386571
386726
  "react-spa",
386572
386727
  "nextjs",
@@ -386595,6 +386750,12 @@ var init_onboarding_classification = __esm({
386595
386750
  // feature run must not enter, because a stop reported from inside a route the
386596
386751
  // run never took is a stop that never happened.
386597
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",
386598
386759
  "unsupported/no-validated-path": "unsupported"
386599
386760
  };
386600
386761
  REPOSITORY_RESEARCH_NODE = "subagent/inspect-repository";
@@ -386787,6 +386948,7 @@ async function runOnboard(argv, dependencies) {
386787
386948
  parsed.values["coding-agent"]
386788
386949
  );
386789
386950
  }
386951
+ recordAbandonedRunWhenFound(deps, binding.runId);
386790
386952
  printRunId(deps, binding.runId);
386791
386953
  await printGraphTree(deps);
386792
386954
  writePrompt(deps, binding.runId, startPrompt);
@@ -386848,6 +387010,7 @@ async function runOnboard(argv, dependencies) {
386848
387010
  throw new Error(SURFACE_CHECK_USAGE);
386849
387011
  const accepted = readAcceptedDriftBestEffort(deps, runId);
386850
387012
  const authorized = readAuthorizationsBestEffort(deps, runId);
387013
+ markRunEndedBestEffort(deps, runId);
386851
387014
  recordBestEffort(deps, {
386852
387015
  event: "cli.onboarding.completed",
386853
387016
  properties: {
@@ -386905,7 +387068,7 @@ async function runOnboard(argv, dependencies) {
386905
387068
  { requested_agent_framework: reportableSlug(requestedFramework) },
386906
387069
  () => requireOnboardingChoice(
386907
387070
  "--agent-framework",
386908
- requestedFramework,
387071
+ resolveAgentFrameworkAlias(requestedFramework),
386909
387072
  ONBOARDING_AGENT_FRAMEWORKS
386910
387073
  )
386911
387074
  );
@@ -386953,13 +387116,6 @@ async function runOnboard(argv, dependencies) {
386953
387116
  deps.stdout.write("Onboarding path included in telemetry when enabled.\n");
386954
387117
  return;
386955
387118
  }
386956
- if (subcommand === "feedback") {
386957
- if (argv.length !== 1) {
386958
- throw new Error("Usage: copilotkit onboard feedback");
386959
- }
386960
- await reportFeedback(deps, runId);
386961
- return;
386962
- }
386963
387119
  if (subcommand === "friction") {
386964
387120
  await reportFriction(deps, runId, argv.slice(1));
386965
387121
  return;
@@ -387627,6 +387783,7 @@ function recordTerminalWhenReached(dependencies, runId, promptName) {
387627
387783
  const terminal = TERMINAL_NODES[promptName];
387628
387784
  if (terminal === void 0)
387629
387785
  return;
387786
+ markRunEndedBestEffort(dependencies, runId);
387630
387787
  recordBestEffort(dependencies, {
387631
387788
  event: "cli.onboarding.terminal_reached",
387632
387789
  properties: {
@@ -387638,6 +387795,40 @@ function recordTerminalWhenReached(dependencies, runId, promptName) {
387638
387795
  }
387639
387796
  });
387640
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
+ }
387641
387832
  function joinChanges(changes) {
387642
387833
  return [...new Set(changes)].sort().join(",");
387643
387834
  }
@@ -387765,53 +387956,16 @@ function completionReport(input) {
387765
387956
  }
387766
387957
  return input.blocker === void 0 ? "CopilotKit onboarding marked complete.\n" : blockedAfterProof(input.blocker);
387767
387958
  }
387768
- async function reportFeedback(dependencies, runId) {
387769
- const input = await readFeedbackInput(dependencies.stdin);
387770
- if (!input.ok)
387771
- return printFeedbackRefusal(dependencies, runId, input.refusal);
387772
- const reviewed = reviewFeedbackReport(input.text);
387773
- if (!reviewed.ok)
387774
- return printFeedbackRefusal(dependencies, runId, reviewed.refusal);
387775
- const feedbackText = reviewed.text;
387776
- let submission;
387777
- try {
387778
- submission = await dependencies.submitFeedbackEvent({
387779
- event: "cli.onboarding.feedback_submitted",
387780
- properties: {
387781
- command: "onboard",
387782
- ...onboardingIntentProperties(dependencies),
387783
- onboarding_run_id: runId,
387784
- cli_version: dependencies.cliVersion,
387785
- feedback_text: feedbackText
387786
- }
387787
- });
387788
- } catch (error98) {
387789
- submission = { status: "failed", detail: describeSubmissionError(error98) };
387790
- }
387791
- dependencies.stdout.write(
387792
- `${describeSubmission("Feedback", submission)}
387793
- report: ${feedbackText}
387794
- `
387795
- );
387796
- }
387797
387959
  function describeSubmission(subject, submission) {
387798
387960
  switch (submission.status) {
387799
387961
  case "sent":
387800
- return subject === "Feedback" ? "Feedback sent." : "Friction reported.";
387962
+ return "Friction reported.";
387801
387963
  case "declined":
387802
387964
  return `${subject} was not sent because telemetry is off.`;
387803
387965
  default:
387804
387966
  return `${subject} was not sent because the telemetry send failed: ${submission.detail}`;
387805
387967
  }
387806
387968
  }
387807
- function printFeedbackRefusal(dependencies, runId, refusal) {
387808
- recordReportRefused(dependencies, runId, "feedback", refusal.code);
387809
- dependencies.stdout.write(
387810
- `Feedback refused, and nothing was sent.
387811
- ${refusal.code}: ${refusal.message}
387812
- `
387813
- );
387814
- }
387815
387969
  async function reportFriction(dependencies, runId, args) {
387816
387970
  const parsed = parseFrictionArguments(args);
387817
387971
  if (!parsed.ok)
@@ -387823,6 +387977,7 @@ async function reportFriction(dependencies, runId, args) {
387823
387977
  category: parsed.category,
387824
387978
  costSeconds: parsed.costSeconds,
387825
387979
  docsPath: parsed.docsPath,
387980
+ phase: parsed.phase,
387826
387981
  text: input.text
387827
387982
  });
387828
387983
  if (!reviewed.ok)
@@ -387838,7 +387993,10 @@ async function reportFriction(dependencies, runId, args) {
387838
387993
  onboarding_run_id: runId,
387839
387994
  cli_version: dependencies.cliVersion,
387840
387995
  friction_category: report.category,
387841
- cost_seconds_estimated: report.costSecondsEstimated,
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 },
387842
388000
  // Spread so a report about no particular page leaves the key off
387843
388001
  // rather than joining to an empty one.
387844
388002
  ...report.docsPath === void 0 ? {} : { friction_docs_path: report.docsPath },
@@ -387858,7 +388016,8 @@ function parseFrictionArguments(args) {
387858
388016
  options: {
387859
388017
  category: { type: "string" },
387860
388018
  "cost-seconds": { type: "string" },
387861
- "docs-path": { type: "string" }
388019
+ "docs-path": { type: "string" },
388020
+ phase: { type: "string" }
387862
388021
  },
387863
388022
  strict: true
387864
388023
  });
@@ -387866,14 +388025,15 @@ function parseFrictionArguments(args) {
387866
388025
  ok: true,
387867
388026
  category: parsed.values.category,
387868
388027
  costSeconds: parsed.values["cost-seconds"],
387869
- docsPath: parsed.values["docs-path"]
388028
+ docsPath: parsed.values["docs-path"],
388029
+ phase: parsed.values.phase
387870
388030
  };
387871
388031
  } catch {
387872
388032
  return {
387873
388033
  ok: false,
387874
388034
  refusal: {
387875
388035
  code: "FRICTION_ARGUMENTS_INVALID",
387876
- 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>]`
387877
388037
  }
387878
388038
  };
387879
388039
  }
@@ -387890,8 +388050,9 @@ function printFrictionReport(dependencies, report, submission) {
387890
388050
  dependencies.stdout.write(
387891
388051
  `${describeSubmission("Friction", submission)}
387892
388052
  category: ${report.category}
387893
- cost_seconds_estimated: ${report.costSecondsEstimated}
387894
- ` + (report.docsPath === void 0 ? "" : `docs_path: ${report.docsPath}
388053
+ phase: ${report.phase}
388054
+ ` + (report.costSecondsEstimated === void 0 ? "" : `cost_seconds_estimated: ${report.costSecondsEstimated}
388055
+ `) + (report.docsPath === void 0 ? "" : `docs_path: ${report.docsPath}
387895
388056
  `) + `report: ${report.text}
387896
388057
  `
387897
388058
  );
@@ -388118,7 +388279,6 @@ var init_onboard = __esm({
388118
388279
  init_config_service();
388119
388280
  init_onboarding_graph();
388120
388281
  init_onboarding_friction();
388121
- init_onboarding_feedback();
388122
388282
  init_onboarding_checkpoint();
388123
388283
  init_onboarding_state();
388124
388284
  init_onboarding_protected_paths();
@@ -388140,7 +388300,6 @@ var init_onboard = __esm({
388140
388300
  "checkpoint",
388141
388301
  "proof",
388142
388302
  "complete",
388143
- "feedback",
388144
388303
  "friction"
388145
388304
  ];
388146
388305
  READ_RUN_NOT_BOUND = runNotBound(
@@ -391409,8 +391568,8 @@ General:
391409
391568
  --verbose Mirror CLI diagnostics to stderr
391410
391569
 
391411
391570
  Privacy:
391412
- CopilotKit collects CLI usage data to improve the product. Onboarding feedback
391413
- may send up to 2,048 UTF-8 bytes through this telemetry path. To opt out, set
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
391414
391573
  DO_NOT_TRACK=1 or COPILOTKIT_TELEMETRY_DISABLED=1 in your environment.
391415
391574
  `,
391416
391575
  login: `Usage: copilotkit login [--json]
@@ -391436,8 +391595,8 @@ Options:
391436
391595
  copilotkit onboard proof --step <oss-baseline|round-trip> --outcome <passed|failed|skipped>
391437
391596
  [--predicate <1-6>]
391438
391597
  copilotkit onboard complete
391439
- copilotkit onboard feedback
391440
- copilotkit onboard friction --category <slug> --cost-seconds <seconds>
391598
+ copilotkit onboard friction --category <slug> [--cost-seconds <seconds>]
391599
+ [--phase <repair|stop|completion>]
391441
391600
 
391442
391601
  Guide a coding agent through the Markdown graph bundled with this exact CLI.
391443
391602
 
@@ -391452,12 +391611,12 @@ Subcommands:
391452
391611
  checkpoint Report how far a long step has got
391453
391612
  proof Record what one proof gate returned
391454
391613
  complete Mark a proven onboarding run complete
391455
- feedback Read one non-empty message from standard input
391456
391614
  friction Report one papercut that slowed a run down
391457
391615
 
391458
- Feedback must be no larger than 2,048 UTF-8 bytes. Do not include secrets,
391459
- source code, logs, or command output. The global telemetry setting applies.
391460
- When telemetry is off, or the send fails, feedback exits zero and says which.
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.
391461
391620
 
391462
391621
  Protect captures the paths this run must not change -- the developer's work in
391463
391622
  progress -- as path and digest, derived from the working tree rather than taken
@@ -391536,6 +391695,10 @@ report from standard input, at most 2,000 characters and four lines of prose.
391536
391695
  --category takes one of: docs-missing, docs-wrong, docs-sequential, cli-gap,
391537
391696
  sdk-gap, environment, port-collision, credential, validation-loop, other.
391538
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.
391539
391702
 
391540
391703
  A report containing a secret shape, a fenced code block, or pasted output is
391541
391704
  refused before anything is sent, and the reason is printed. Both commands print
@@ -393796,7 +393959,6 @@ var ONBOARD_SUBCOMMANDS2 = [
393796
393959
  "checkpoint",
393797
393960
  "classify",
393798
393961
  "complete",
393799
- "feedback",
393800
393962
  "friction",
393801
393963
  "identify",
393802
393964
  "proof",