copilotkit 4.10.0 → 4.11.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 (76) hide show
  1. package/README.md +14 -4
  2. package/cli-build-info.json +8 -8
  3. package/index.js +150 -43
  4. package/onboarding/index.json +26 -1
  5. package/onboarding/prompts/authenticate/start.md +27 -13
  6. package/onboarding/prompts/conversion/plan.md +3 -3
  7. package/onboarding/prompts/credentials/finalize-plan.md +30 -21
  8. package/onboarding/prompts/credentials/plan.md +20 -20
  9. package/onboarding/prompts/credentials/settle-credentials.md +9 -9
  10. package/onboarding/prompts/credentials/write-plan.md +7 -7
  11. package/onboarding/prompts/fallback/best-effort.md +9 -8
  12. package/onboarding/prompts/feature/a2ui/implement.md +6 -6
  13. package/onboarding/prompts/feature/a2ui/proof.md +6 -6
  14. package/onboarding/prompts/feature/a2ui/start.md +7 -7
  15. package/onboarding/prompts/feature/channels/implement.md +70 -0
  16. package/onboarding/prompts/feature/channels/proof.md +60 -0
  17. package/onboarding/prompts/feature/channels/start.md +90 -0
  18. package/onboarding/prompts/feature/chat-suggestions/implement.md +6 -6
  19. package/onboarding/prompts/feature/chat-suggestions/proof.md +6 -6
  20. package/onboarding/prompts/feature/chat-suggestions/start.md +7 -7
  21. package/onboarding/prompts/feature/complete.md +1 -1
  22. package/onboarding/prompts/feature/learning/implement.md +12 -12
  23. package/onboarding/prompts/feature/learning/proof.md +7 -7
  24. package/onboarding/prompts/feature/learning/start.md +6 -6
  25. package/onboarding/prompts/feature/open-generative-ui/implement.md +6 -6
  26. package/onboarding/prompts/feature/open-generative-ui/proof.md +6 -6
  27. package/onboarding/prompts/feature/open-generative-ui/start.md +7 -7
  28. package/onboarding/prompts/feature/realtime-sync/implement.md +7 -7
  29. package/onboarding/prompts/feature/realtime-sync/proof.md +6 -6
  30. package/onboarding/prompts/feature/realtime-sync/start.md +6 -6
  31. package/onboarding/prompts/feature/rich-threads/implement.md +8 -8
  32. package/onboarding/prompts/feature/rich-threads/proof.md +6 -6
  33. package/onboarding/prompts/feature/rich-threads/start.md +6 -6
  34. package/onboarding/prompts/feature/stop.md +12 -6
  35. package/onboarding/prompts/feature/voice/implement.md +6 -6
  36. package/onboarding/prompts/feature/voice/proof.md +6 -6
  37. package/onboarding/prompts/feature/voice/start.md +7 -7
  38. package/onboarding/prompts/framework/ag2.md +2 -2
  39. package/onboarding/prompts/framework/agno.md +2 -2
  40. package/onboarding/prompts/framework/built-in.md +2 -2
  41. package/onboarding/prompts/framework/claude-sdk-python.md +2 -2
  42. package/onboarding/prompts/framework/claude-sdk-typescript.md +2 -2
  43. package/onboarding/prompts/framework/crewai-flows.md +2 -2
  44. package/onboarding/prompts/framework/deep-agents.md +2 -2
  45. package/onboarding/prompts/framework/google-adk.md +2 -2
  46. package/onboarding/prompts/framework/langgraph-fastapi.md +2 -2
  47. package/onboarding/prompts/framework/langgraph-python.md +2 -2
  48. package/onboarding/prompts/framework/langgraph-typescript.md +2 -2
  49. package/onboarding/prompts/framework/llamaindex.md +2 -2
  50. package/onboarding/prompts/framework/mastra.md +2 -2
  51. package/onboarding/prompts/framework/ms-agent-dotnet.md +2 -2
  52. package/onboarding/prompts/framework/ms-agent-harness-dotnet.md +2 -2
  53. package/onboarding/prompts/framework/ms-agent-python.md +2 -2
  54. package/onboarding/prompts/framework/pydantic-ai.md +2 -2
  55. package/onboarding/prompts/framework/strands-python.md +2 -2
  56. package/onboarding/prompts/framework/strands-typescript.md +2 -2
  57. package/onboarding/prompts/frontend/angular.md +3 -3
  58. package/onboarding/prompts/frontend/nextjs.md +3 -3
  59. package/onboarding/prompts/frontend/plan.md +17 -12
  60. package/onboarding/prompts/frontend/react-native.md +2 -2
  61. package/onboarding/prompts/frontend/react-spa.md +2 -2
  62. package/onboarding/prompts/frontend/vue.md +2 -2
  63. package/onboarding/prompts/implementation/build-and-validate.md +29 -17
  64. package/onboarding/prompts/proof/complete.md +22 -14
  65. package/onboarding/prompts/proof/oss-baseline.md +5 -5
  66. package/onboarding/prompts/proof/round-trip.md +16 -15
  67. package/onboarding/prompts/research/gather.md +18 -4
  68. package/onboarding/prompts/research/route.md +9 -10
  69. package/onboarding/prompts/starter/clone.md +6 -6
  70. package/onboarding/prompts/stopped/run-failed.md +3 -3
  71. package/onboarding/prompts/subagent/create-plan.md +1 -1
  72. package/onboarding/prompts/subagent/prove-oss-baseline.md +1 -1
  73. package/onboarding/prompts/subagent/prove-round-trip.md +32 -15
  74. package/onboarding/prompts/unsupported/no-validated-path.md +4 -4
  75. package/package.json +1 -1
  76. package/release/release-tool.js +1 -1
package/README.md CHANGED
@@ -230,6 +230,17 @@ npx --yes copilotkit@latest onboard start \
230
230
  | `add-voice` | Add documented voice transcription to the existing composer |
231
231
  | `add-realtime-sync` | Prove managed thread changes sync between active clients |
232
232
 
233
+ Run `copilotkit channels setup` to copy the same small `onboard start --run <id>`
234
+ prompt as the website CTA. There is no `--intent add-channels`. The copied
235
+ prompt has no Channel sentence. When the project has no frontend, the root graph
236
+ asks which frontend they want and offers Slack and Microsoft Teams there. If the
237
+ copied prompt came from a Slack or Teams docs page, that page is the named
238
+ frontend.
239
+ Its first prompt records the coding agent with `onboard identify`, including when
240
+ the entry command omitted `--coding-agent`. Channel setup stage events include
241
+ the existing `onboarding_run_id` when the command runs inside an onboarding run;
242
+ standalone commands omit it. These events use the CLI's existing telemetry consent gate.
243
+
233
244
  The intent describes the developer's requested outcome, not a claim about the
234
245
  current project state. Each path inspects the app first: it preserves a proven
235
246
  existing configuration, stops rather than inventing credentials or identities,
@@ -362,14 +373,13 @@ copilotkit channels setup
362
373
  copilotkit channels setup --no-clipboard
363
374
  ```
364
375
 
365
- It installs the `channels-setup` skill, then prints a one-line prompt to paste
376
+ The command copies the small `onboard start --run <id>` prompt.
377
+ It installs the `channels-setup` skill, then prints that prompt to paste
366
378
  into your coding agent and copies it to your clipboard. The prompt is always
367
379
  printed, so you can read it before handing it over. Pass `--no-clipboard` in a
368
380
  headless or remote shell.
369
381
 
370
- Everything the run needs is in the skill, so the prompt only names the skill and
371
- the goal. It does not name a provider: Slack or Microsoft Teams is the skill's
372
- own first question.
382
+ The copied command does not name a provider. The graph asks Slack or Teams.
373
383
 
374
384
  Only the prompt goes to stdout. The line introducing it and the clipboard result
375
385
  go to stderr, so `copilotkit channels setup > prompt.txt` gives you the payload
@@ -2,20 +2,20 @@
2
2
  "schemaVersion": 1,
3
3
  "package": {
4
4
  "name": "copilotkit",
5
- "version": "4.10.0"
5
+ "version": "4.11.0"
6
6
  },
7
7
  "intelligence": {
8
- "commit": "c8e38c8634104047e47545c1ed45a21c259a8658"
8
+ "commit": "362d341410722307c1067c71ac14710245300cff"
9
9
  },
10
10
  "copilotKit": {
11
- "submittedInput": "ce490419d0",
12
- "commit": "ce490419d046abe697438b070a99ad5d674365cc"
11
+ "submittedInput": "dc1238c0bd473e259c992b85026cb30fe6b3b726",
12
+ "commit": "dc1238c0bd473e259c992b85026cb30fe6b3b726"
13
13
  },
14
14
  "channel": "production",
15
- "triggeringActor": "BenTaylorDev",
15
+ "triggeringActor": "tylerslaton",
16
16
  "workflow": {
17
- "runId": "35011911410",
18
- "runUrl": "https://github.com/CopilotKit/Intelligence/actions/runs/35011911410"
17
+ "runId": "35162202498",
18
+ "runUrl": "https://github.com/CopilotKit/Intelligence/actions/runs/35162202498"
19
19
  },
20
20
  "validationResult": "passed",
21
21
  "ag2": {
@@ -24,5 +24,5 @@
24
24
  "revision": "main",
25
25
  "pinned": false
26
26
  },
27
- "builtAt": "2026-09-15T19:10:59Z"
27
+ "builtAt": "2026-09-16T23:26:51Z"
28
28
  }
package/index.js CHANGED
@@ -96,14 +96,14 @@ function getTelemetryEndpointUrl() {
96
96
  }
97
97
  function getBuildInfo() {
98
98
  return {
99
- version: true ? "4.10.0" : "dev",
100
- buildNumber: true ? "35011911410" : "dev",
101
- commitSha: true ? "c8e38c8634104047e47545c1ed45a21c259a8658" : "dev",
99
+ version: true ? "4.11.0" : "dev",
100
+ buildNumber: true ? "35162202498" : "dev",
101
+ commitSha: true ? "362d341410722307c1067c71ac14710245300cff" : "dev",
102
102
  copilotKitCommit: getTemplateRef()
103
103
  };
104
104
  }
105
105
  function getTemplateRef() {
106
- return true ? "ce490419d046abe697438b070a99ad5d674365cc" : "main";
106
+ return true ? "dc1238c0bd473e259c992b85026cb30fe6b3b726" : "main";
107
107
  }
108
108
  function getC15tBackendUrl() {
109
109
  return true ? "https://calm-hazelnut-joy-copilotkit.inth.app" : "";
@@ -28668,18 +28668,22 @@ var init_repository_root = __esm({
28668
28668
  import * as fs7 from "node:fs";
28669
28669
  import * as os2 from "node:os";
28670
28670
  import * as path9 from "node:path";
28671
- function prepareProjectConfig(selection, previous, generateBindingId) {
28671
+ function prepareProjectConfig(selection, previous, generateBindingId, statedRuntimeUrl) {
28672
28672
  const telemetryBindingId = previous?.projectId === selection.projectId && previous.clerkOrgId === selection.clerkOrgId && previous.telemetryBindingId !== void 0 ? previous.telemetryBindingId : generateBindingId();
28673
28673
  return projectConfigSchema.extend({ telemetryBindingId: external_exports.string().trim().min(1) }).parse({
28674
28674
  ...selection,
28675
28675
  telemetryBindingId,
28676
- // Carried through unconditionally, including across a change of project.
28677
- // Nothing in the CLI writes it, so its only possible author is a person,
28678
- // and it describes where this directory's app serves rather than which
28676
+ // A stated URL wins. Otherwise the recorded one is carried through
28677
+ // unconditionally, including across a change of project, because it
28678
+ // describes where this directory's app serves rather than which
28679
28679
  // Intelligence project the app reports to (OSS-1090).
28680
- ...previous?.runtimeUrl === void 0 ? {} : { runtimeUrl: previous.runtimeUrl }
28680
+ ...runtimeUrlFields(statedRuntimeUrl, previous?.runtimeUrl)
28681
28681
  });
28682
28682
  }
28683
+ function runtimeUrlFields(stated, recorded) {
28684
+ const chosen = stated?.trim() === "" ? void 0 : stated ?? recorded;
28685
+ return chosen === void 0 ? {} : { runtimeUrl: chosen };
28686
+ }
28683
28687
  function projectConfigPath(dir) {
28684
28688
  return path9.join(dir, ".copilotkit", "project.json");
28685
28689
  }
@@ -28776,15 +28780,19 @@ var init_project_config = __esm({
28776
28780
  telemetryBindingId: external_exports.string().trim().min(1).optional(),
28777
28781
  /**
28778
28782
  * Absolute URL of this project's CopilotKit runtime, when the project pins
28779
- * one by hand.
28783
+ * one.
28784
+ *
28785
+ * Stated, never guessed. `copilotkit verify` works out the port from the
28786
+ * app's own dev configuration, and this is where a project whose runtime is
28787
+ * somewhere that cannot be worked out — a different mount path, a
28788
+ * container, a port that only ever appears on a command line — says so once
28789
+ * instead of passing `--runtime-url` on every invocation (OSS-1090).
28780
28790
  *
28781
- * Written by a person, not by the CLI. `copilotkit verify` works out the
28782
- * port from the app's own dev configuration, and this is where a project
28783
- * whose runtime is somewhere that cannot be worked out — a different mount
28784
- * path, a container, a port that only ever appears on a command line —
28785
- * states it once instead of passing `--runtime-url` on every invocation
28786
- * (OSS-1090). The schema is strict, so it has to be declared here for such
28787
- * a file to parse at all.
28791
+ * A person writes it, and so does `project select --runtime-url`. An
28792
+ * onboarding run settles a free port and then has nowhere to put it, so
28793
+ * `verify` falls back to its assumed default and reports on whatever holds
28794
+ * that port — in one run, an unrelated checkout (PE-58). The flag is still
28795
+ * a statement rather than a guess: the caller has to name the URL.
28788
28796
  */
28789
28797
  runtimeUrl: external_exports.string().trim().min(1).optional()
28790
28798
  }).strict();
@@ -66837,7 +66845,7 @@ var require_websocket = __commonJS({
66837
66845
  var http4 = __require("http");
66838
66846
  var net = __require("net");
66839
66847
  var tls = __require("tls");
66840
- var { randomBytes: randomBytes3, createHash: createHash8 } = __require("crypto");
66848
+ var { randomBytes: randomBytes4, createHash: createHash8 } = __require("crypto");
66841
66849
  var { Duplex, Readable: Readable5 } = __require("stream");
66842
66850
  var { URL: URL7 } = __require("url");
66843
66851
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -67384,7 +67392,7 @@ var require_websocket = __commonJS({
67384
67392
  }
67385
67393
  }
67386
67394
  const defaultPort = isSecure ? 443 : 80;
67387
- const key = randomBytes3(16).toString("base64");
67395
+ const key = randomBytes4(16).toString("base64");
67388
67396
  const request = isSecure ? https2.request : http4.request;
67389
67397
  const protocolSet = /* @__PURE__ */ new Set();
67390
67398
  let perMessageDeflate;
@@ -92313,7 +92321,8 @@ function recordChannelsStage(input) {
92313
92321
  // the builder writes every key explicitly from its input so customer
92314
92322
  // content cannot leak in by construction, and reading ambient process
92315
92323
  // state inside it would break that guarantee. Both values are booleans.
92316
- ...currentCliStateProperties(input.command ?? "channels")
92324
+ ...currentCliStateProperties(input.command ?? "channels"),
92325
+ ...currentOnboardingRunProperties()
92317
92326
  }
92318
92327
  });
92319
92328
  }
@@ -96144,6 +96153,13 @@ function validateProjectName(raw2, existing) {
96144
96153
  message: `Intelligence project name must be ${MAX_PROJECT_NAME_LENGTH} characters or fewer.`
96145
96154
  };
96146
96155
  }
96156
+ if (name.length < MIN_PROJECT_NAME_LENGTH || GENERIC_PROJECT_NAMES.has(name.toLowerCase()) || THROWAWAY_PROJECT_NAME.test(name.toLowerCase())) {
96157
+ return {
96158
+ ok: false,
96159
+ reason: "generic",
96160
+ message: `"${name}" names a directory rather than a project. Give a name that says what this project does, so it can be told apart in the dashboard later.`
96161
+ };
96162
+ }
96147
96163
  const duplicate = existing.find(
96148
96164
  (project) => project.name.toLowerCase() === name.toLowerCase()
96149
96165
  );
@@ -96158,11 +96174,33 @@ function validateProjectName(raw2, existing) {
96158
96174
  }
96159
96175
  return { ok: true, name };
96160
96176
  }
96161
- var MAX_PROJECT_NAME_LENGTH, NUMERIC_SUFFIX, SUGGESTION_ATTEMPTS;
96177
+ var MAX_PROJECT_NAME_LENGTH, MIN_PROJECT_NAME_LENGTH, GENERIC_PROJECT_NAMES, THROWAWAY_PROJECT_NAME, NUMERIC_SUFFIX, SUGGESTION_ATTEMPTS;
96162
96178
  var init_hosted_project_name = __esm({
96163
96179
  "apps/cli/src/services/hosted-project-name.ts"() {
96164
96180
  "use strict";
96165
96181
  MAX_PROJECT_NAME_LENGTH = 100;
96182
+ MIN_PROJECT_NAME_LENGTH = 3;
96183
+ GENERIC_PROJECT_NAMES = /* @__PURE__ */ new Set([
96184
+ "api",
96185
+ "app",
96186
+ "apps",
96187
+ "backend",
96188
+ "client",
96189
+ "frontend",
96190
+ "lib",
96191
+ "libs",
96192
+ "package",
96193
+ "packages",
96194
+ "project",
96195
+ "repo",
96196
+ "server",
96197
+ "service",
96198
+ "site",
96199
+ "src",
96200
+ "web",
96201
+ "website"
96202
+ ]);
96203
+ THROWAWAY_PROJECT_NAME = /^(?:bar|baz|demo|example|foo|hello|placeholder|qux|run|sample|scratch|temp|test|tmp|trial|try)(?:[-_]?(?:\d+|[a-z]))?$/u;
96166
96204
  NUMERIC_SUFFIX = /-\d+$/;
96167
96205
  SUGGESTION_ATTEMPTS = 1e3;
96168
96206
  }
@@ -96191,6 +96229,13 @@ function defer() {
96191
96229
  });
96192
96230
  return { promise: promise3, resolve: resolve9 };
96193
96231
  }
96232
+ function hostedProjectPickerWindowStart(selectedIndex, itemCount) {
96233
+ const lastStart = Math.max(0, itemCount - MAX_HOSTED_PROJECT_PICKER_VISIBLE);
96234
+ return Math.min(
96235
+ Math.max(0, selectedIndex - MAX_HOSTED_PROJECT_PICKER_VISIBLE + 1),
96236
+ lastStart
96237
+ );
96238
+ }
96194
96239
  function ProjectExplainer({ dim = false }) {
96195
96240
  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." });
96196
96241
  }
@@ -96385,12 +96430,21 @@ function HostedProjectSelect({
96385
96430
  })),
96386
96431
  { label: "Create a new project", value: "__create__" }
96387
96432
  ];
96433
+ const windowStart = hostedProjectPickerWindowStart(
96434
+ pickerIndex,
96435
+ items.length
96436
+ );
96437
+ const visibleItems = items.slice(
96438
+ windowStart,
96439
+ windowStart + MAX_HOSTED_PROJECT_PICKER_VISIBLE
96440
+ );
96388
96441
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", children: [
96389
96442
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Connect this app to one of your existing projects, or create a new one." }),
96390
96443
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProjectExplainer, { dim: true }),
96391
96444
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: " " }),
96392
96445
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: "Select a project (\u2191/\u2193 to move, Enter to choose, Esc to cancel):" }),
96393
- items.map((item, index2) => {
96446
+ visibleItems.map((item, visibleIndex) => {
96447
+ const index2 = windowStart + visibleIndex;
96394
96448
  const selected = index2 === pickerIndex;
96395
96449
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
96396
96450
  Text,
@@ -96441,7 +96495,7 @@ function HostedProjectSelect({
96441
96495
  }
96442
96496
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: view.message });
96443
96497
  }
96444
- var import_react37, import_jsx_runtime7;
96498
+ var import_react37, import_jsx_runtime7, MAX_HOSTED_PROJECT_PICKER_VISIBLE;
96445
96499
  var init_hosted_project_select = __esm({
96446
96500
  async "apps/cli/src/ui/hosted-project-select.tsx"() {
96447
96501
  "use strict";
@@ -96451,6 +96505,7 @@ var init_hosted_project_select = __esm({
96451
96505
  init_hosted_project_name();
96452
96506
  init_theme();
96453
96507
  import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
96508
+ MAX_HOSTED_PROJECT_PICKER_VISIBLE = 6;
96454
96509
  }
96455
96510
  });
96456
96511
 
@@ -96812,7 +96867,7 @@ var init_telemetry_identity_events = __esm({
96812
96867
  // apps/cli/src/commands/project-select-effects.ts
96813
96868
  import { randomUUID as randomUUID3 } from "node:crypto";
96814
96869
  import * as path18 from "node:path";
96815
- function persistSelection(dir, selection) {
96870
+ function persistSelection(dir, selection, statedRuntimeUrl) {
96816
96871
  try {
96817
96872
  const previous = readProjectConfig(dir) ?? null;
96818
96873
  const config3 = prepareProjectConfig(
@@ -96822,7 +96877,8 @@ function persistSelection(dir, selection) {
96822
96877
  clerkOrgId: selection.organizationId
96823
96878
  },
96824
96879
  previous,
96825
- randomUUID3
96880
+ randomUUID3,
96881
+ statedRuntimeUrl
96826
96882
  );
96827
96883
  writeProjectConfig(dir, config3);
96828
96884
  return {
@@ -97013,9 +97069,9 @@ function toRequest(options) {
97013
97069
  }
97014
97070
  return null;
97015
97071
  }
97016
- async function completeSelection(apiClient, selection) {
97072
+ async function completeSelection(apiClient, selection, statedRuntimeUrl) {
97017
97073
  const recordDir = resolveProjectConfigWriteDir(process.cwd());
97018
- const persisted = persistSelection(recordDir, selection);
97074
+ const persisted = persistSelection(recordDir, selection, statedRuntimeUrl);
97019
97075
  if (persisted.bindingId === null) {
97020
97076
  return withoutSelection(persisted.outcome);
97021
97077
  }
@@ -97066,7 +97122,7 @@ The recorded selection is kept, so finish it with \`${projectSelectRetryCommand(
97066
97122
  configPath
97067
97123
  };
97068
97124
  }
97069
- async function driveFlagSelect(apiClient, request) {
97125
+ async function driveFlagSelect(apiClient, request, statedRuntimeUrl) {
97070
97126
  const { prompts, refusal } = createFlagPrompts(request);
97071
97127
  let result;
97072
97128
  try {
@@ -97096,7 +97152,7 @@ async function driveFlagSelect(apiClient, request) {
97096
97152
  ...recorded.suggestedName === void 0 ? {} : { suggestedName: recorded.suggestedName }
97097
97153
  });
97098
97154
  }
97099
- return await completeSelection(apiClient, result);
97155
+ return await completeSelection(apiClient, result, statedRuntimeUrl);
97100
97156
  }
97101
97157
  async function drivePicker(apiClient, options) {
97102
97158
  let outcome = { kind: "canceled" };
@@ -97135,7 +97191,7 @@ async function drivePicker(apiClient, options) {
97135
97191
  if (selection === null) {
97136
97192
  return withoutSelection(outcome);
97137
97193
  }
97138
- return await completeSelection(apiClient, selection);
97194
+ return await completeSelection(apiClient, selection, options.runtimeUrl);
97139
97195
  }
97140
97196
  async function driveProjectSelect(options, render2 = { renderToStderr: false }) {
97141
97197
  const auth2 = authStore.get();
@@ -97154,7 +97210,10 @@ async function driveProjectSelect(options, render2 = { renderToStderr: false })
97154
97210
  productOrganizationId: auth2.clerkOrgId
97155
97211
  });
97156
97212
  const request = toRequest(options);
97157
- return request === null ? await drivePicker(apiClient, render2) : await driveFlagSelect(apiClient, request);
97213
+ return request === null ? await drivePicker(apiClient, {
97214
+ ...render2,
97215
+ ...options.runtimeUrl === void 0 ? {} : { runtimeUrl: options.runtimeUrl }
97216
+ }) : await driveFlagSelect(apiClient, request, options.runtimeUrl);
97158
97217
  }
97159
97218
  async function runProjectSelect(options = {}) {
97160
97219
  const { outcome } = await driveProjectSelect(options);
@@ -97856,13 +97915,17 @@ var init_clipboard = __esm({
97856
97915
  });
97857
97916
 
97858
97917
  // apps/cli/src/services/agent-prompt.ts
97918
+ import { randomBytes as randomBytes2 } from "node:crypto";
97859
97919
  function buildSkillsOnboardPrompt() {
97860
97920
  return SKILLS_ONBOARD_AGENT_PROMPT;
97861
97921
  }
97862
97922
  function buildChannelsSetupPrompt() {
97863
- return CHANNELS_SETUP_PROMPT;
97923
+ const runId = randomBytes2(9).toString("base64url");
97924
+ return `Help me get started with CopilotKit. Run this command and follow the instructions:
97925
+
97926
+ npx --yes copilotkit@latest onboard start --run=${runId}`;
97864
97927
  }
97865
- var SKILLS_ONBOARD_AGENT_PROMPT, CHANNELS_SETUP_SKILL, CHANNELS_SETUP_PROMPT;
97928
+ var SKILLS_ONBOARD_AGENT_PROMPT, CHANNELS_SETUP_SKILL;
97866
97929
  var init_agent_prompt = __esm({
97867
97930
  "apps/cli/src/services/agent-prompt.ts"() {
97868
97931
  "use strict";
@@ -97876,7 +97939,6 @@ Use the copilotkit-setup skill to:
97876
97939
 
97877
97940
  Start by inspecting my repo, then walk me through the setup.`;
97878
97941
  CHANNELS_SETUP_SKILL = "channels-setup";
97879
- CHANNELS_SETUP_PROMPT = `Use the \`${CHANNELS_SETUP_SKILL}\` skill to set up a Channel for this project.`;
97880
97942
  }
97881
97943
  });
97882
97944
 
@@ -141620,7 +141682,7 @@ var require_websocket2 = __commonJS({
141620
141682
  var http4 = __require("http");
141621
141683
  var net = __require("net");
141622
141684
  var tls = __require("tls");
141623
- var { randomBytes: randomBytes3, createHash: createHash8 } = __require("crypto");
141685
+ var { randomBytes: randomBytes4, createHash: createHash8 } = __require("crypto");
141624
141686
  var { Duplex, Readable: Readable5 } = __require("stream");
141625
141687
  var { URL: URL7 } = __require("url");
141626
141688
  var PerMessageDeflate2 = require_permessage_deflate2();
@@ -142175,7 +142237,7 @@ var require_websocket2 = __commonJS({
142175
142237
  }
142176
142238
  }
142177
142239
  const defaultPort = isSecure ? 443 : 80;
142178
- const key = randomBytes3(16).toString("base64");
142240
+ const key = randomBytes4(16).toString("base64");
142179
142241
  const request = isSecure ? https2.request : http4.request;
142180
142242
  const protocolSet = /* @__PURE__ */ new Set();
142181
142243
  let perMessageDeflate;
@@ -386886,7 +386948,7 @@ __export(onboard_exports, {
386886
386948
  ONBOARD_SUBCOMMANDS: () => ONBOARD_SUBCOMMANDS,
386887
386949
  runOnboard: () => runOnboard
386888
386950
  });
386889
- import { randomBytes as randomBytes2 } from "node:crypto";
386951
+ import { randomBytes as randomBytes3 } from "node:crypto";
386890
386952
  import { parseArgs as parseArgs2 } from "node:util";
386891
386953
  async function runOnboard(argv, dependencies) {
386892
386954
  const deps = dependencies ?? {
@@ -386896,7 +386958,7 @@ async function runOnboard(argv, dependencies) {
386896
386958
  stderr: process.stderr,
386897
386959
  store: configStore,
386898
386960
  cliVersion: getBuildInfo().version,
386899
- randomRunId: () => randomBytes2(9).toString("base64url"),
386961
+ randomRunId: () => randomBytes3(9).toString("base64url"),
386900
386962
  loadPrompt: loadOnboardingPrompt,
386901
386963
  loadGraphTree: loadOnboardingGraphTree,
386902
386964
  loadStartPrompt: loadOnboardingStartPrompt,
@@ -387599,6 +387661,9 @@ ${detail}${NOTHING_PROVED}`;
387599
387661
  ""
387600
387662
  ].join("\n");
387601
387663
  }
387664
+ function leavesSurfaceUnproven(check4) {
387665
+ return check4.outcome !== "performed" && check4.outcome !== DECLINED_SURFACE_CHECK;
387666
+ }
387602
387667
  function parseFrontendUrl(rest) {
387603
387668
  const flagIndex = rest.indexOf("--frontend-url");
387604
387669
  if (flagIndex === -1)
@@ -387925,6 +387990,18 @@ function blockedWithoutSurfaceProof(check4) {
387925
387990
  ""
387926
387991
  ].join("\n");
387927
387992
  }
387993
+ function declinedSurfaceNote(check4) {
387994
+ const surface = check4.kind === "visual" ? "browser" : "device";
387995
+ return [
387996
+ "CopilotKit onboarding marked complete.",
387997
+ "",
387998
+ ` This run cloned a starter, so it drove no ${surface} of its own.`,
387999
+ " That code is what the starter smoke jobs drive on every change, and",
388000
+ " `copilotkit verify --round-trip` proved the agent round trip here.",
388001
+ ` To see it yourself, open the app and drive it once by hand.`,
388002
+ ""
388003
+ ].join("\n");
388004
+ }
387928
388005
  function blockedAfterProof(blocker) {
387929
388006
  const report = BLOCKER_REPORTS[blocker];
387930
388007
  return [
@@ -387948,13 +388025,15 @@ function blockedAfterProof(blocker) {
387948
388025
  ].join("\n");
387949
388026
  }
387950
388027
  function completionReport(input) {
387951
- if (input.check.outcome !== "performed") {
388028
+ if (leavesSurfaceUnproven(input.check)) {
387952
388029
  const surface = blockedWithoutSurfaceProof(input.check);
387953
388030
  if (input.blocker === void 0)
387954
388031
  return surface;
387955
388032
  return `${surface}${blockedAfterProof(input.blocker)}`;
387956
388033
  }
387957
- return input.blocker === void 0 ? "CopilotKit onboarding marked complete.\n" : blockedAfterProof(input.blocker);
388034
+ if (input.blocker !== void 0)
388035
+ return blockedAfterProof(input.blocker);
388036
+ return input.check.outcome === DECLINED_SURFACE_CHECK ? declinedSurfaceNote(input.check) : "CopilotKit onboarding marked complete.\n";
387958
388037
  }
387959
388038
  function describeSubmission(subject, submission) {
387960
388039
  switch (submission.status) {
@@ -388271,7 +388350,7 @@ function recordBestEffort(dependencies, event) {
388271
388350
  } catch {
388272
388351
  }
388273
388352
  }
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;
388353
+ 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, DECLINED_SURFACE_CHECK, 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;
388275
388354
  var init_onboard = __esm({
388276
388355
  async "apps/cli/src/commands/onboard.ts"() {
388277
388356
  "use strict";
@@ -388321,14 +388400,17 @@ var init_onboard = __esm({
388321
388400
  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";
388322
388401
  NOTHING_AUTHORIZED = "Nothing was recorded. No path in this call was authorized, including any path\nnamed before the one above.\n";
388323
388402
  NOTHING_ACCEPTED = "Nothing was recorded. No path in this call was accepted, including any path\nnamed before the one above.\n";
388403
+ DECLINED_SURFACE_CHECK = "skipped-cloned-starter";
388324
388404
  VISUAL_CHECK_OUTCOMES = [
388325
388405
  "performed",
388326
388406
  "skipped-no-browser-tool",
388407
+ DECLINED_SURFACE_CHECK,
388327
388408
  "failed"
388328
388409
  ];
388329
388410
  DEVICE_CHECK_OUTCOMES = [
388330
388411
  "performed",
388331
388412
  "skipped-no-device",
388413
+ DECLINED_SURFACE_CHECK,
388332
388414
  "failed"
388333
388415
  ];
388334
388416
  BLOCKER_CAUSES = [
@@ -388342,7 +388424,7 @@ surface this run proved and what blocked it afterwards are separate facts.
388342
388424
  Use \`other\` rather than leaving the flag off. A run with no way to say it was
388343
388425
  blocked reads the unsupported terminal instead, and reports a path that works
388344
388426
  as one this release does not carry.`;
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.";
388427
+ SURFACE_CHECK_USAGE = "Usage: copilotkit onboard complete --visual-check <performed|skipped-no-browser-tool|skipped-cloned-starter|failed>\n or: copilotkit onboard complete --device-check <performed|skipped-no-device|skipped-cloned-starter|failed>\n`skipped-cloned-starter` is for a run that cloned a starter and was told to open no\nbrowser. It does not block. Every other skip says the surface is unproven and does.\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.";
388346
388428
  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.";
388347
388429
  PROOF_STEPS = ONBOARDING_PROOF_STEPS;
388348
388430
  PROOF_OUTCOMES = ONBOARDING_PROOF_OUTCOMES;
@@ -392020,6 +392102,7 @@ name the answer up front, so they run in a non-interactive shell.
392020
392102
  Options:
392021
392103
  --project <ref> Select an existing project by slug or id, no prompt
392022
392104
  --create <name> Create a project with this name and select it
392105
+ --runtime-url <url> Record where this project's runtime serves
392023
392106
  --json Emit a machine-readable result on stdout
392024
392107
  -h, --help Show help for project select
392025
392108
 
@@ -392028,6 +392111,11 @@ organization's real projects, so a typo fails with the available slugs rather
392028
392111
  than recording a selection that points at nothing. Run
392029
392112
  \`copilotkit project list --json\` first to see them.
392030
392113
 
392114
+ --runtime-url records "runtimeUrl" in the project record, so \`copilotkit verify\`
392115
+ probes the URL this project states instead of assuming port 3000. Pass it when
392116
+ the app serves somewhere that cannot be worked out from its dev configuration: a
392117
+ non-default port, a different mount path, or a container.
392118
+
392031
392119
  --json reports selected_project_slug, project_file_written,
392032
392120
  api_key_provisioned, and environment_file_written. The payload never contains
392033
392121
  the API key.
@@ -392883,6 +392971,7 @@ ${formatStaleBuildNote()}
392883
392971
  options: {
392884
392972
  project: { type: "string" },
392885
392973
  create: { type: "string" },
392974
+ "runtime-url": { type: "string" },
392886
392975
  json: { type: "boolean" }
392887
392976
  },
392888
392977
  strict: true,
@@ -392890,7 +392979,24 @@ ${formatStaleBuildNote()}
392890
392979
  });
392891
392980
  const project = parsed.values["project"];
392892
392981
  const create3 = parsed.values["create"];
392982
+ const runtimeUrl = parsed.values["runtime-url"];
392893
392983
  const json4 = parsed.values["json"] === true;
392984
+ if (runtimeUrl !== void 0 && !URL.canParse(runtimeUrl)) {
392985
+ recordTelemetryEvent({
392986
+ properties: {
392987
+ command: "project",
392988
+ subcommand: "select",
392989
+ outcome: "failed",
392990
+ error_code: "validation"
392991
+ }
392992
+ });
392993
+ process.stderr.write(
392994
+ `Error: --runtime-url must be an absolute URL (received "${runtimeUrl}").
392995
+ `
392996
+ );
392997
+ await exitWithFlush(1);
392998
+ return;
392999
+ }
392894
393000
  if (project !== void 0 && create3 !== void 0) {
392895
393001
  recordTelemetryEvent({
392896
393002
  properties: {
@@ -392927,7 +393033,8 @@ ${formatStaleBuildNote()}
392927
393033
  }
392928
393034
  const options = {
392929
393035
  ...project === void 0 ? {} : { project },
392930
- ...create3 === void 0 ? {} : { create: create3 }
393036
+ ...create3 === void 0 ? {} : { create: create3 },
393037
+ ...runtimeUrl === void 0 ? {} : { runtimeUrl }
392931
393038
  };
392932
393039
  await withTelemetry(
392933
393040
  { command: "project", subcommand: "select" },
@@ -1,5 +1,5 @@
1
1
  {
2
- "graphTree": "d0d29f5f2ed37dd76f08bb7655e28da124813c2f",
2
+ "graphTree": "31372aea9d38d802779516dc556c136faf611b32",
3
3
  "intentRoots": {
4
4
  "add-a2ui": "feature/a2ui/start",
5
5
  "add-chat-suggestions": "feature/chat-suggestions/start",
@@ -106,6 +106,30 @@
106
106
  "milestone": "feature",
107
107
  "name": "feature/a2ui/start"
108
108
  },
109
+ {
110
+ "edges": [
111
+ "feature/stop",
112
+ "feature/channels/proof"
113
+ ],
114
+ "milestone": "feature",
115
+ "name": "feature/channels/implement"
116
+ },
117
+ {
118
+ "edges": [
119
+ "feature/stop",
120
+ "feature/complete"
121
+ ],
122
+ "milestone": "feature",
123
+ "name": "feature/channels/proof"
124
+ },
125
+ {
126
+ "edges": [
127
+ "feature/stop",
128
+ "feature/channels/implement"
129
+ ],
130
+ "milestone": "feature",
131
+ "name": "feature/channels/start"
132
+ },
109
133
  {
110
134
  "edges": [
111
135
  "feature/stop",
@@ -437,6 +461,7 @@
437
461
  "frontend/angular",
438
462
  "frontend/vue",
439
463
  "frontend/react-native",
464
+ "feature/channels/start",
440
465
  "unsupported/no-validated-path"
441
466
  ],
442
467
  "milestone": "frontend",