apex-code 0.0.1-alpha.5 → 0.0.1-alpha.7

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 (69) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +10 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +17 -0
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +46 -3
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/package-manager.d.ts.map +1 -1
  10. package/dist/core/package-manager.js +15 -0
  11. package/dist/core/package-manager.js.map +1 -1
  12. package/dist/core/permissions/gate.d.ts +7 -0
  13. package/dist/core/permissions/gate.d.ts.map +1 -1
  14. package/dist/core/permissions/gate.js.map +1 -1
  15. package/dist/core/permissions/startup.d.ts +12 -0
  16. package/dist/core/permissions/startup.d.ts.map +1 -1
  17. package/dist/core/permissions/startup.js +12 -4
  18. package/dist/core/permissions/startup.js.map +1 -1
  19. package/dist/core/sandbox/cli-launch.d.ts +43 -0
  20. package/dist/core/sandbox/cli-launch.d.ts.map +1 -1
  21. package/dist/core/sandbox/cli-launch.js +70 -3
  22. package/dist/core/sandbox/cli-launch.js.map +1 -1
  23. package/dist/core/sandbox/cli-supervisor.d.ts +2 -0
  24. package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -1
  25. package/dist/core/sandbox/cli-supervisor.js +1 -0
  26. package/dist/core/sandbox/cli-supervisor.js.map +1 -1
  27. package/dist/core/skills.d.ts +19 -7
  28. package/dist/core/skills.d.ts.map +1 -1
  29. package/dist/core/skills.js +77 -19
  30. package/dist/core/skills.js.map +1 -1
  31. package/dist/core/slash-commands.d.ts.map +1 -1
  32. package/dist/core/slash-commands.js +1 -1
  33. package/dist/core/slash-commands.js.map +1 -1
  34. package/dist/core/system-prompt.d.ts.map +1 -1
  35. package/dist/core/system-prompt.js +3 -3
  36. package/dist/core/system-prompt.js.map +1 -1
  37. package/dist/core/tools/index.d.ts +5 -1
  38. package/dist/core/tools/index.d.ts.map +1 -1
  39. package/dist/core/tools/index.js +12 -0
  40. package/dist/core/tools/index.js.map +1 -1
  41. package/dist/core/tools/skill-search.d.ts +32 -0
  42. package/dist/core/tools/skill-search.d.ts.map +1 -0
  43. package/dist/core/tools/skill-search.js +56 -0
  44. package/dist/core/tools/skill-search.js.map +1 -0
  45. package/dist/main.d.ts.map +1 -1
  46. package/dist/main.js +1 -0
  47. package/dist/main.js.map +1 -1
  48. package/dist/modes/interactive/components/footer.d.ts +3 -0
  49. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  50. package/dist/modes/interactive/components/footer.js +13 -0
  51. package/dist/modes/interactive/components/footer.js.map +1 -1
  52. package/dist/modes/interactive/components/model-selector.d.ts +19 -6
  53. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/model-selector.js +172 -89
  55. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  56. package/dist/modes/interactive/components/settings-selector.d.ts +13 -0
  57. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/settings-selector.js +96 -0
  59. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  60. package/dist/modes/interactive/interactive-mode.d.ts +11 -0
  61. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  62. package/dist/modes/interactive/interactive-mode.js +64 -4
  63. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  64. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  65. package/dist/modes/rpc/rpc-mode.js +2 -1
  66. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  67. package/docs/skills.md +54 -4
  68. package/npm-shrinkwrap.json +5 -5
  69. package/package.json +2 -2
@@ -26,6 +26,7 @@ import { DefaultPackageManager } from "../../core/package-manager.js";
26
26
  import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
27
27
  import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
28
28
  import { formatShareUnavailableMessage, publishSessionShare } from "../../core/session-share.js";
29
+ import { slugifySkillCommandName } from "../../core/skills.js";
29
30
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
30
31
  import { hasTrustRequiringProjectResources, ProjectTrustStore } from "../../core/trust-manager.js";
31
32
  import { getUsageCostBreakdown } from "../../core/usage-totals.js";
@@ -61,7 +62,7 @@ import { ModelSelectorComponent } from "./components/model-selector.js";
61
62
  import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
62
63
  import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
63
64
  import { SessionSelectorComponent } from "./components/session-selector.js";
64
- import { SettingsSelectorComponent } from "./components/settings-selector.js";
65
+ import { PERMISSION_MODE_OVERRIDE_HINTS, SettingsSelectorComponent } from "./components/settings-selector.js";
65
66
  import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
66
67
  import { ApexSplashHeader } from "./components/splash-header.js";
67
68
  import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
@@ -211,6 +212,8 @@ export function createInteractiveTuiReference(getTui) {
211
212
  }
212
213
  export class InteractiveMode {
213
214
  runtimeHost;
215
+ /** Settled once the most recent /settings permission-mode write has hit disk. */
216
+ pendingPermissionModeWrite;
214
217
  renderer;
215
218
  ui;
216
219
  mainScreenRenderState;
@@ -484,7 +487,7 @@ export class InteractiveMode {
484
487
  const skillCommandList = [];
485
488
  if (this.settingsManager.getEnableSkillCommands()) {
486
489
  for (const skill of this.session.resourceLoader.getSkills().skills) {
487
- const commandName = `skill:${skill.name}`;
490
+ const commandName = `skill:${slugifySkillCommandName(skill.name)}`;
488
491
  this.skillCommands.set(commandName, skill.filePath);
489
492
  skillCommandList.push({
490
493
  name: commandName,
@@ -1443,6 +1446,7 @@ export class InteractiveMode {
1443
1446
  this.applyFullscreenScrollbarSetting();
1444
1447
  this.footer.setSession(this.session);
1445
1448
  this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
1449
+ this.refreshFooterPermissionMode();
1446
1450
  this.footerDataProvider.setCwd(this.sessionManager.getCwd());
1447
1451
  this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
1448
1452
  this.outputPad = this.settingsManager.getOutputPad();
@@ -2282,10 +2286,17 @@ export class InteractiveMode {
2282
2286
  text = text.trim();
2283
2287
  if (!text)
2284
2288
  return;
2289
+ // A mode chosen in /settings is written asynchronously. Awaiting it here
2290
+ // keeps the store authoritative before any tool call can read it, so a
2291
+ // switch *out* of bypassPermissions can never be raced by the next turn.
2292
+ if (this.pendingPermissionModeWrite) {
2293
+ await this.pendingPermissionModeWrite;
2294
+ this.pendingPermissionModeWrite = undefined;
2295
+ }
2285
2296
  // Handle commands
2286
2297
  if (text === "/settings") {
2287
- this.showSettingsSelector();
2288
2298
  this.editor.setText("");
2299
+ await this.showSettingsSelector();
2289
2300
  return;
2290
2301
  }
2291
2302
  if (text === "/scoped-models") {
@@ -3592,7 +3603,52 @@ export class InteractiveMode {
3592
3603
  this.ui.setFocus(created.focus);
3593
3604
  this.ui.requestRender();
3594
3605
  }
3595
- showSettingsSelector() {
3606
+ /**
3607
+ * Resyncs the footer from the store. Called on every session swap, not just at
3608
+ * startup: `applyRuntimeSettings` also repoints the cwd, and cwd selects which
3609
+ * project-scope permission file applies, so the mode genuinely can differ
3610
+ * between two sessions in one process. A footer left showing the old value
3611
+ * would under-report bypassPermissions, which is the one direction that matters.
3612
+ */
3613
+ refreshFooterPermissionMode() {
3614
+ void this.session.getPermissionMode().then((resolution) => {
3615
+ this.footer.setPermissionMode(resolution?.mode ?? "default");
3616
+ this.ui.requestRender();
3617
+ });
3618
+ }
3619
+ /**
3620
+ * Writes the mode to user scope, then reports what is actually in force. The
3621
+ * write can be outranked by `--permission-mode` or a project file, and a
3622
+ * settings row that silently does nothing is worse than no row at all.
3623
+ */
3624
+ async applyPermissionMode(mode) {
3625
+ let resolution;
3626
+ try {
3627
+ const write = this.session.setPermissionMode(mode);
3628
+ this.pendingPermissionModeWrite = write.then(() => { }, () => { });
3629
+ resolution = await write;
3630
+ }
3631
+ catch (error) {
3632
+ // Never swallow this. A permission mode the user believes they set, and
3633
+ // did not, is the one outcome worse than the prompt they were escaping.
3634
+ const detail = error instanceof Error ? error.message : String(error);
3635
+ this.chatContainer.addChild(new Text(theme.fg("error", `Permission mode could not be saved: ${detail}`), 1, 0));
3636
+ this.ui.requestRender();
3637
+ return;
3638
+ }
3639
+ if (!resolution)
3640
+ return;
3641
+ const outranked = resolution.mode !== mode;
3642
+ const source = PERMISSION_MODE_OVERRIDE_HINTS[resolution.origin] ?? resolution.origin;
3643
+ const line = outranked
3644
+ ? `Permission mode saved as ${mode}, but ${source} sets ${resolution.mode} for this session.`
3645
+ : `Permission mode set to ${mode}.`;
3646
+ this.chatContainer.addChild(new Text(theme.fg(outranked ? "warning" : "muted", line), 1, 0));
3647
+ this.footer.setPermissionMode(resolution.mode);
3648
+ this.ui.requestRender();
3649
+ }
3650
+ async showSettingsSelector() {
3651
+ const permissionMode = await this.session.getPermissionMode();
3596
3652
  this.showSelector((done) => {
3597
3653
  let selector;
3598
3654
  selector = new SettingsSelectorComponent({
@@ -3620,6 +3676,7 @@ export class InteractiveMode {
3620
3676
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
3621
3677
  showCacheMissNotices: this.settingsManager.getShowCacheMissNotices(),
3622
3678
  defaultProjectTrust: this.settingsManager.getDefaultProjectTrust(),
3679
+ permissionMode,
3623
3680
  editorPaddingX: this.settingsManager.getEditorPaddingX(),
3624
3681
  outputPad: this.settingsManager.getOutputPad(),
3625
3682
  autocompleteMaxVisible: this.settingsManager.getAutocompleteMaxVisible(),
@@ -3717,6 +3774,9 @@ export class InteractiveMode {
3717
3774
  onDefaultProjectTrustChange: (defaultProjectTrust) => {
3718
3775
  this.settingsManager.setDefaultProjectTrust(defaultProjectTrust);
3719
3776
  },
3777
+ onPermissionModeChange: (mode) => {
3778
+ void this.applyPermissionMode(mode);
3779
+ },
3720
3780
  onDoubleEscapeActionChange: (action) => {
3721
3781
  this.settingsManager.setDoubleEscapeAction(action);
3722
3782
  },