@sayknow-cli/coding-agent 0.3.8 → 0.3.9

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 (57) hide show
  1. package/dist/types/config/settings-schema.d.ts +14 -0
  2. package/dist/types/modes/components/thinking-selector.d.ts +2 -2
  3. package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
  4. package/dist/types/modes/interactive-mode.d.ts +2 -0
  5. package/dist/types/modes/rpc/rpc-mode.d.ts +1 -3
  6. package/dist/types/modes/rpc/rpc-socket-security.d.ts +3 -0
  7. package/dist/types/modes/types.d.ts +2 -0
  8. package/dist/types/modes/utils/injected-user-submission.d.ts +52 -0
  9. package/dist/types/notifications/config-commands.d.ts +9 -0
  10. package/dist/types/notifications/config.d.ts +16 -0
  11. package/dist/types/notifications/index.d.ts +2 -0
  12. package/dist/types/notifications/lifecycle-commands.d.ts +1 -0
  13. package/dist/types/notifications/lifecycle-control-runtime.d.ts +2 -1
  14. package/dist/types/notifications/reply-sent-store.d.ts +53 -0
  15. package/dist/types/notifications/rich-draft.d.ts +68 -0
  16. package/dist/types/notifications/rich-render.d.ts +90 -0
  17. package/dist/types/notifications/telegram-daemon.d.ts +22 -0
  18. package/dist/types/notifications/telegram-reference.d.ts +7 -0
  19. package/dist/types/notifications/threaded-render.d.ts +8 -0
  20. package/dist/types/skc-runtime/tmux-common.d.ts +1 -0
  21. package/dist/types/utils/pasted-image-path.d.ts +30 -0
  22. package/package.json +7 -7
  23. package/src/cli/notify-cli.ts +11 -9
  24. package/src/cli/update-cli.ts +63 -24
  25. package/src/config/keybindings.ts +1 -1
  26. package/src/config/settings-schema.ts +8 -0
  27. package/src/internal-urls/docs-index.generated.ts +5 -5
  28. package/src/lsp/client.ts +1 -0
  29. package/src/modes/components/footer.ts +7 -2
  30. package/src/modes/components/thinking-selector.ts +10 -8
  31. package/src/modes/controllers/event-controller.ts +11 -2
  32. package/src/modes/controllers/extension-ui-controller.ts +8 -1
  33. package/src/modes/controllers/input-controller.ts +12 -17
  34. package/src/modes/controllers/selector-controller.ts +41 -0
  35. package/src/modes/interactive-mode.ts +5 -0
  36. package/src/modes/rpc/rpc-mode.ts +3 -9
  37. package/src/modes/rpc/rpc-socket-security.ts +13 -1
  38. package/src/modes/types.ts +2 -0
  39. package/src/modes/utils/injected-user-submission.ts +94 -0
  40. package/src/notifications/config-commands.ts +20 -0
  41. package/src/notifications/config.ts +27 -0
  42. package/src/notifications/index.ts +28 -5
  43. package/src/notifications/lifecycle-commands.ts +37 -16
  44. package/src/notifications/lifecycle-control-runtime.ts +8 -3
  45. package/src/notifications/reply-sent-store.ts +134 -0
  46. package/src/notifications/rich-draft.ts +107 -0
  47. package/src/notifications/rich-render.ts +142 -0
  48. package/src/notifications/telegram-daemon.ts +346 -89
  49. package/src/notifications/telegram-reference.ts +17 -0
  50. package/src/notifications/threaded-render.ts +28 -1
  51. package/src/prompts/tools/search-tool-bm25.md +5 -0
  52. package/src/sdk.ts +36 -8
  53. package/src/session/agent-session.ts +6 -4
  54. package/src/skc-runtime/tmux-common.ts +1 -0
  55. package/src/skc-runtime/ultragoal-runtime.ts +10 -1
  56. package/src/slash-commands/builtin-registry.ts +78 -1
  57. package/src/utils/pasted-image-path.ts +170 -0
@@ -14,9 +14,10 @@ import { installDefaultSkcDefinitions } from "../defaults/skc-defaults";
14
14
  import { theme } from "../modes/theme/theme";
15
15
 
16
16
  const RELEASE_REPO = "jaybeyond/Sayknow_CLI";
17
- const PACKAGE = "@sayknow-cli/coding-agent";
18
- const NPM_WRAPPER_PACKAGE = "sayknow-cli";
19
- const NPM_MANAGED_PACKAGES = [NPM_WRAPPER_PACKAGE, PACKAGE] as const;
17
+ const RELEASE_TAG_PREFIX = "sayknow-v";
18
+ const PACKAGE = "sayknow-cli";
19
+ const SCOPED_CLI_PACKAGE = "@sayknow-cli/coding-agent";
20
+ const NPM_MANAGED_PACKAGES = [PACKAGE, SCOPED_CLI_PACKAGE] as const;
20
21
 
21
22
  interface ReleaseInfo {
22
23
  tag: string;
@@ -136,35 +137,79 @@ function defaultPackageExists(_packageName: string, packageRoot: string): boolea
136
137
  return fs.existsSync(path.join(packageRoot, "package.json"));
137
138
  }
138
139
 
139
- function npmPackageRootForBinPath(binPath: string, packageName: string, platform: PathPlatform): string {
140
+ function npmPackageRootForWindowsShim(binPath: string, packageName: string, platform: PathPlatform): string {
140
141
  const pathApi = pathApiForPlatform(platform);
141
142
  const segments = packageName.split("/");
142
143
  return pathApi.join(pathApi.dirname(binPath), "node_modules", ...segments);
143
144
  }
144
145
 
146
+ function packageRootFromNodeModulesPath(
147
+ binPath: string,
148
+ packageName: string,
149
+ platform: PathPlatform,
150
+ ): string | undefined {
151
+ const pathApi = pathApiForPlatform(platform);
152
+ const packageSegments = packageName.split("/");
153
+ const parts = pathApi.normalize(binPath).split(pathApi.sep).filter(Boolean);
154
+ for (let index = 0; index < parts.length; index++) {
155
+ if (parts[index] !== "node_modules") continue;
156
+ const packageStart = index + 1;
157
+ const matched = packageSegments.every((segment, offset) => parts[packageStart + offset] === segment);
158
+ if (!matched) continue;
159
+ const prefix = binPath.startsWith(pathApi.sep) ? pathApi.sep : "";
160
+ return pathApi.join(prefix, ...parts.slice(0, packageStart + packageSegments.length));
161
+ }
162
+ return undefined;
163
+ }
164
+
165
+ function npmPackageRootsForPosixShim(binPath: string, packageName: string): string[] {
166
+ const pathApi = path.posix;
167
+ const binDir = pathApi.dirname(binPath);
168
+ const packageSegments = packageName.split("/");
169
+ return [
170
+ pathApi.join(pathApi.dirname(binDir), "lib", "node_modules", ...packageSegments),
171
+ pathApi.join(binDir, "node_modules", ...packageSegments),
172
+ ];
173
+ }
174
+
145
175
  function resolveNpmManagedTarget(
146
176
  ompPath: string,
147
177
  platform: PathPlatform = process.platform,
148
178
  packageExists: PackageExists = defaultPackageExists,
149
179
  ): PackageManagerTarget | undefined {
150
- if (platform !== "win32") return undefined;
151
180
  const pathApi = pathApiForPlatform(platform);
152
- const extension = pathApi.extname(ompPath).toLowerCase();
153
- if (extension !== ".cmd" && extension !== ".ps1") return undefined;
154
- const basename = pathApi.basename(ompPath, extension).toLowerCase();
155
- if (basename !== APP_NAME.toLowerCase()) return undefined;
181
+ const basename = pathApi.basename(ompPath, pathApi.extname(ompPath)).toLowerCase();
182
+ const resolvedPath = tryRealpath(ompPath);
183
+ const candidatePaths = resolvedPath ? [resolvedPath, ompPath] : [ompPath];
156
184
 
185
+ if (platform === "win32") {
186
+ const extension = pathApi.extname(ompPath).toLowerCase();
187
+ if (extension !== ".cmd" && extension !== ".ps1") return undefined;
188
+ if (basename !== APP_NAME.toLowerCase()) return undefined;
189
+ for (const packageName of NPM_MANAGED_PACKAGES) {
190
+ const packageRoot = npmPackageRootForWindowsShim(ompPath, packageName, platform);
191
+ if (packageExists(packageName, packageRoot)) return { manager: "npm", packageName };
192
+ }
193
+ return undefined;
194
+ }
195
+
196
+ if (basename !== APP_NAME.toLowerCase()) return undefined;
157
197
  for (const packageName of NPM_MANAGED_PACKAGES) {
158
- const packageRoot = npmPackageRootForBinPath(ompPath, packageName, platform);
159
- if (packageExists(packageName, packageRoot)) return { manager: "npm", packageName };
198
+ for (const candidatePath of candidatePaths) {
199
+ const packageRoot = packageRootFromNodeModulesPath(candidatePath, packageName, platform);
200
+ if (packageRoot && packageExists(packageName, packageRoot)) return { manager: "npm", packageName };
201
+ }
202
+ for (const packageRoot of npmPackageRootsForPosixShim(ompPath, packageName)) {
203
+ if (packageExists(packageName, packageRoot)) return { manager: "npm", packageName };
204
+ }
160
205
  }
161
206
  return undefined;
162
207
  }
163
208
 
164
209
  function resolveUpdateMethod(ompPath: string, bunBinDir: string | undefined): "bun" | "npm" | "binary" {
210
+ if (bunBinDir && isPathInDirectory(ompPath, bunBinDir)) return "bun";
165
211
  if (resolveNpmManagedTarget(ompPath)) return "npm";
166
- if (!bunBinDir) return "binary";
167
- return isPathInDirectory(ompPath, bunBinDir) ? "bun" : "binary";
212
+ return "binary";
168
213
  }
169
214
 
170
215
  export function resolveUpdateMethodForTest(ompPath: string, bunBinDir: string | undefined): "bun" | "npm" | "binary" {
@@ -183,16 +228,10 @@ async function resolveUpdateTarget(): Promise<UpdateTarget> {
183
228
  const ompPath = resolveSkcPath();
184
229
 
185
230
  if (ompPath) {
231
+ if (bunBinDir && isPathInDirectory(ompPath, bunBinDir)) return { method: "bun" };
186
232
  const npmTarget = resolveNpmManagedTarget(ompPath);
187
233
  if (npmTarget) return { method: "npm", packageName: npmTarget.packageName };
188
- const method = resolveUpdateMethod(ompPath, bunBinDir);
189
- if (method === "bun") return { method };
190
- if (method === "npm") {
191
- throw new Error(
192
- formatUnsupportedTargetMessage(`Could not resolve npm package root for ${APP_NAME} shim ${ompPath}`),
193
- );
194
- }
195
- return { method, path: ompPath };
234
+ return { method: "binary", path: ompPath };
196
235
  }
197
236
 
198
237
  if (bunBinDir) return { method: "bun" };
@@ -212,7 +251,7 @@ async function getLatestRelease(): Promise<ReleaseInfo> {
212
251
 
213
252
  const data = (await response.json()) as { version: string };
214
253
  const version = data.version;
215
- const tag = `v${version}`;
254
+ const tag = `${RELEASE_TAG_PREFIX}${version}`;
216
255
 
217
256
  return {
218
257
  tag,
@@ -350,7 +389,7 @@ function formatBinaryInstallInstruction(platform: NodeJS.Platform = process.plat
350
389
  function formatManualUpdateInstructions(platform: NodeJS.Platform = process.platform): string {
351
390
  return [
352
391
  `If ${APP_NAME} was installed with Bun, run: bun install -g ${PACKAGE}@latest`,
353
- `If ${APP_NAME} was installed with npm, pnpm, or another package manager, update it with that same manager.`,
392
+ `If ${APP_NAME} was installed with npm, pnpm, or another package manager, run: npm install -g ${PACKAGE}@latest`,
354
393
  formatBinaryInstallInstruction(platform),
355
394
  ].join("\n");
356
395
  }
@@ -365,7 +404,7 @@ function buildReleaseBinaryUrl(
365
404
  arch: string = process.arch,
366
405
  ): string {
367
406
  const binaryName = getBinaryName(platform, arch);
368
- const tag = `v${version}`;
407
+ const tag = `${RELEASE_TAG_PREFIX}${version}`;
369
408
  return `https://github.com/${RELEASE_REPO}/releases/download/${tag}/${binaryName}`;
370
409
  }
371
410
 
@@ -61,7 +61,7 @@ declare module "@sayknow-cli/tui" {
61
61
  }
62
62
 
63
63
  export function defaultMessageQueueKeysForPlatform(platform: NodeJS.Platform = process.platform): KeyId {
64
- return platform === "win32" ? "alt+q" : "alt+enter";
64
+ return platform === "win32" || platform === "darwin" ? "alt+q" : "alt+enter";
65
65
  }
66
66
 
67
67
  /**
@@ -262,6 +262,8 @@ export const SETTINGS_SCHEMA = {
262
262
  "notifications.enabled": { type: "boolean", default: false },
263
263
  "notifications.telegram.botToken": { type: "string", default: undefined },
264
264
  "notifications.telegram.chatId": { type: "string", default: undefined },
265
+ "notifications.telegram.rich.enabled": { type: "boolean", default: true },
266
+ "notifications.telegram.richDraft.enabled": { type: "boolean", default: false },
265
267
  "notifications.discord.botToken": { type: "string", default: undefined },
266
268
  "notifications.discord.channelId": { type: "string", default: undefined },
267
269
  "notifications.slack.botToken": { type: "string", default: undefined },
@@ -3610,6 +3612,12 @@ export interface NotificationsSettings {
3610
3612
  telegram: {
3611
3613
  botToken: string | undefined;
3612
3614
  chatId: string | undefined;
3615
+ rich: {
3616
+ enabled: boolean;
3617
+ };
3618
+ richDraft: {
3619
+ enabled: boolean;
3620
+ };
3613
3621
  };
3614
3622
  discord: {
3615
3623
  botToken: string | undefined;