@selesai/code 0.10.1 → 0.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 (128) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/config.d.ts +5 -3
  3. package/dist/config.js +6 -4
  4. package/dist/core/skills.d.ts +2 -0
  5. package/dist/core/skills.js +1 -0
  6. package/dist/defaults/settings.json +0 -3
  7. package/dist/extensions/auto-session-name.test.ts +157 -0
  8. package/dist/extensions/auto-session-name.ts +96 -0
  9. package/dist/extensions/cost-reconcile.test.ts +76 -0
  10. package/dist/extensions/cost-reconcile.ts +278 -0
  11. package/dist/extensions/enable-readonly-tools.test.ts +11 -0
  12. package/dist/extensions/enable-readonly-tools.ts +7 -3
  13. package/dist/extensions/package.json +3 -0
  14. package/dist/extensions/pi-tool-display/CHANGELOG.md +329 -0
  15. package/dist/extensions/pi-tool-display/LICENSE +21 -0
  16. package/dist/extensions/pi-tool-display/README.md +417 -0
  17. package/dist/extensions/pi-tool-display/config/config.example.json +40 -0
  18. package/dist/extensions/pi-tool-display/index.ts +3 -0
  19. package/dist/extensions/pi-tool-display/package-lock.json +2555 -0
  20. package/dist/extensions/pi-tool-display/package.json +86 -0
  21. package/dist/extensions/pi-tool-display/src/agent-dir.ts +35 -0
  22. package/dist/extensions/pi-tool-display/src/ansi-utils.ts +116 -0
  23. package/dist/extensions/pi-tool-display/src/bash-display.ts +213 -0
  24. package/dist/extensions/pi-tool-display/src/capabilities.ts +88 -0
  25. package/dist/extensions/pi-tool-display/src/config-modal.ts +541 -0
  26. package/dist/extensions/pi-tool-display/src/config-store.ts +304 -0
  27. package/dist/extensions/pi-tool-display/src/debug-logger.ts +150 -0
  28. package/dist/extensions/pi-tool-display/src/diff-presentation.ts +72 -0
  29. package/dist/extensions/pi-tool-display/src/diff-renderer.ts +2517 -0
  30. package/dist/extensions/pi-tool-display/src/disposable.ts +34 -0
  31. package/dist/extensions/pi-tool-display/src/extension-lifecycle.ts +14 -0
  32. package/dist/extensions/pi-tool-display/src/index.ts +109 -0
  33. package/dist/extensions/pi-tool-display/src/line-width-safety.ts +93 -0
  34. package/dist/extensions/pi-tool-display/src/modal-icons.ts +57 -0
  35. package/dist/extensions/pi-tool-display/src/pending-diff-preview.ts +370 -0
  36. package/dist/extensions/pi-tool-display/src/presets.ts +117 -0
  37. package/dist/extensions/pi-tool-display/src/render-utils.ts +186 -0
  38. package/dist/extensions/pi-tool-display/src/settings-inspector-modal.ts +475 -0
  39. package/dist/extensions/pi-tool-display/src/thinking-label.ts +343 -0
  40. package/dist/extensions/pi-tool-display/src/tool-call-box.ts +181 -0
  41. package/dist/extensions/pi-tool-display/src/tool-metadata.ts +139 -0
  42. package/dist/extensions/pi-tool-display/src/tool-overrides.ts +2168 -0
  43. package/dist/extensions/pi-tool-display/src/types.ts +109 -0
  44. package/dist/extensions/pi-tool-display/src/user-message-box-markdown.ts +64 -0
  45. package/dist/extensions/pi-tool-display/src/user-message-box-native.ts +66 -0
  46. package/dist/extensions/pi-tool-display/src/user-message-box-patch.ts +72 -0
  47. package/dist/extensions/pi-tool-display/src/user-message-box-renderer.ts +419 -0
  48. package/dist/extensions/pi-tool-display/src/user-message-box-utils.ts +106 -0
  49. package/dist/extensions/pi-tool-display/src/write-display-utils.ts +31 -0
  50. package/dist/extensions/pi-tool-display/src/zellij-modal.ts +1027 -0
  51. package/dist/extensions/pi-tool-display/tests/active-backlog-red.test.ts +65 -0
  52. package/dist/extensions/pi-tool-display/tests/ansi-utils.test.ts +345 -0
  53. package/dist/extensions/pi-tool-display/tests/bash-display.test.ts +442 -0
  54. package/dist/extensions/pi-tool-display/tests/capabilities-edge.test.ts +360 -0
  55. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +54 -0
  56. package/dist/extensions/pi-tool-display/tests/config-modal.test.ts +360 -0
  57. package/dist/extensions/pi-tool-display/tests/config-store.test.ts +87 -0
  58. package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +415 -0
  59. package/dist/extensions/pi-tool-display/tests/debug-logger-edge.test.ts +630 -0
  60. package/dist/extensions/pi-tool-display/tests/debug-logger.test.ts +62 -0
  61. package/dist/extensions/pi-tool-display/tests/diff-renderer-ansi.test.ts +55 -0
  62. package/dist/extensions/pi-tool-display/tests/diff-renderer-edge.test.ts +886 -0
  63. package/dist/extensions/pi-tool-display/tests/diff-renderer-numbering.test.ts +135 -0
  64. package/dist/extensions/pi-tool-display/tests/diff-renderer-width.test.ts +454 -0
  65. package/dist/extensions/pi-tool-display/tests/diff-renderer-wrap.test.ts +169 -0
  66. package/dist/extensions/pi-tool-display/tests/index-integration.test.ts +354 -0
  67. package/dist/extensions/pi-tool-display/tests/pending-diff-preview.test.ts +79 -0
  68. package/dist/extensions/pi-tool-display/tests/presets-edge.test.ts +229 -0
  69. package/dist/extensions/pi-tool-display/tests/presets.test.ts +26 -0
  70. package/dist/extensions/pi-tool-display/tests/reload-behavior.test.ts +1241 -0
  71. package/dist/extensions/pi-tool-display/tests/render-utils.test.ts +710 -0
  72. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +450 -0
  73. package/dist/extensions/pi-tool-display/tests/thinking-label-edge.test.ts +904 -0
  74. package/dist/extensions/pi-tool-display/tests/thinking-label.test.ts +72 -0
  75. package/dist/extensions/pi-tool-display/tests/tool-call-box.test.ts +105 -0
  76. package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +613 -0
  77. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +499 -0
  78. package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +315 -0
  79. package/dist/extensions/pi-tool-display/tests/tool-overrides-write-meta.test.ts +68 -0
  80. package/dist/extensions/pi-tool-display/tests/tool-ui-utils.test.ts +413 -0
  81. package/dist/extensions/pi-tool-display/tests/user-message-box-performance-red.test.ts +176 -0
  82. package/dist/extensions/pi-tool-display/tests/user-message-box.test.ts +908 -0
  83. package/dist/extensions/pi-tool-display/tests/zellij-modal.test.ts +848 -0
  84. package/dist/extensions/pi-tool-display/tool-display-api-consumer.d.ts +30 -0
  85. package/dist/extensions/pi-tool-display/tool-display-api-consumer.js +40 -0
  86. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +46 -1
  87. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +10 -0
  88. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
  89. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +3 -3
  90. package/dist/extensions/pi-zentui/test/format.test.ts +50 -2
  91. package/dist/modes/interactive/components/startup-box.d.ts +38 -0
  92. package/dist/modes/interactive/components/startup-box.js +90 -0
  93. package/dist/modes/interactive/interactive-mode.d.ts +3 -0
  94. package/dist/modes/interactive/interactive-mode.js +85 -122
  95. package/dist/skills/agent-browser/SKILL.md +1 -0
  96. package/dist/skills/batch-grill-me/SKILL.md +1 -0
  97. package/dist/skills/brandkit/SKILL.md +1 -0
  98. package/dist/skills/design-references/SKILL.md +1 -0
  99. package/dist/skills/design-taste-frontend/SKILL.md +1 -0
  100. package/dist/skills/design-taste-frontend-v1/SKILL.md +1 -0
  101. package/dist/skills/full-output-enforcement/SKILL.md +1 -0
  102. package/dist/skills/gpt-taste/SKILL.md +1 -0
  103. package/dist/skills/grill-me/SKILL.md +1 -0
  104. package/dist/skills/handoff/SKILL.md +1 -0
  105. package/dist/skills/handoff-text/SKILL.md +1 -0
  106. package/dist/skills/high-end-visual-design/SKILL.md +1 -0
  107. package/dist/skills/image-to-code/SKILL.md +1 -0
  108. package/dist/skills/imagegen-frontend-mobile/SKILL.md +1 -0
  109. package/dist/skills/imagegen-frontend-web/SKILL.md +1 -0
  110. package/dist/skills/implanger/SKILL.md +1 -0
  111. package/dist/skills/improve-codebase/SKILL.md +1 -0
  112. package/dist/skills/industrial-brutalist-ui/SKILL.md +1 -0
  113. package/dist/skills/minimalist-ui/SKILL.md +1 -0
  114. package/dist/skills/pi-subagents/SKILL.md +1 -0
  115. package/dist/skills/planger/SKILL.md +1 -0
  116. package/dist/skills/ponytail/SKILL.md +1 -0
  117. package/dist/skills/ponytail-audit/SKILL.md +1 -0
  118. package/dist/skills/ponytail-debt/SKILL.md +1 -0
  119. package/dist/skills/ponytail-gain/SKILL.md +1 -0
  120. package/dist/skills/ponytail-help/SKILL.md +1 -0
  121. package/dist/skills/ponytail-review/SKILL.md +1 -0
  122. package/dist/skills/redesign-existing-projects/SKILL.md +1 -0
  123. package/dist/skills/selesai-handoff/SKILL.md +1 -0
  124. package/dist/skills/stitch-design-taste/SKILL.md +1 -0
  125. package/dist/skills/unlazy/SKILL.md +1 -0
  126. package/dist/skills/web-design-guidelines/SKILL.md +1 -0
  127. package/dist/skills/workflow/SKILL.md +1 -0
  128. package/package.json +3 -3
@@ -48,6 +48,7 @@ import { CustomEntryComponent } from "./components/custom-entry.js";
48
48
  import { CustomMessageComponent } from "./components/custom-message.js";
49
49
  import { DaxnutsComponent } from "./components/daxnuts.js";
50
50
  import { DynamicBorder } from "./components/dynamic-border.js";
51
+ import { StartupBox } from "./components/startup-box.js";
51
52
  import { EarendilAnnouncementComponent } from "./components/earendil-announcement.js";
52
53
  import { ExtensionEditorComponent } from "./components/extension-editor.js";
53
54
  import { ExtensionInputComponent } from "./components/extension-input.js";
@@ -99,6 +100,29 @@ function isDeadTerminalError(error) {
99
100
  return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
100
101
  }
101
102
  const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";
103
+ const SELESAI_LOGO = [
104
+ " ____ ____ __ ____ ____ ______ ______",
105
+ "/\\ _`\\ /\\ _`\\ /\\ \\ /\\ _`\\ /\\ _`\\ /\\ _ \\/\\__ _\\",
106
+ "\\ \\,\\L\\_\\ \\ \\L\\_\\ \\ \\ \\ \\ \\L\\_\\ \\,\\L\\_\\ \\ \\L\\ \\/_/\\ \\/",
107
+ " \\/_\\__ \\\\ \\ _\\L\\ \\ \\ __\\ \\ _\\L\\/_\\__ \\\\ \\ __ \\ \\ \\ \\",
108
+ " /\\ \\L\\ \\ \\ \\L\\ \\ \\ \\L\\ \\\\ \\ \\L\\ \\/\\ \\L\\ \\ \\ \\/\\ \\ \\_\\ \\__",
109
+ " \\ `\\____\\ \\____/\\ \\____/ \\ \\____/\\ `\\____\\ \\_\\ \\_\\/\\_____\\",
110
+ " \\/_____/\\/___/ \\/___/ \\/___/ \\/_____/\\/_\\/\\/_\\/\\/_____\\",
111
+ ];
112
+ // Vertical gradient across logo lines: top #ff6b2c → bottom #fb923c.
113
+ function gradientLogo(lines, from, to) {
114
+ const a = [0xff, 0x6b, 0x2c];
115
+ const b = [0xfb, 0x92, 0x3c];
116
+ return lines
117
+ .map((line, i) => {
118
+ const t = lines.length === 1 ? 0 : i / (lines.length - 1);
119
+ const r = Math.round(a[0] + (b[0] - a[0]) * t);
120
+ const g = Math.round(a[1] + (b[1] - a[1]) * t);
121
+ const bl = Math.round(a[2] + (b[2] - a[2]) * t);
122
+ return chalk.hex(`#${((r << 16) | (g << 8) | bl).toString(16).padStart(6, "0")}`).bold(line);
123
+ })
124
+ .join("\n");
125
+ }
102
126
  function isAnthropicSubscriptionAuthKey(apiKey) {
103
127
  return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
104
128
  }
@@ -310,6 +334,8 @@ export class InteractiveMode {
310
334
  headerContainer;
311
335
  // Built-in header (logo + keybinding hints + changelog)
312
336
  builtInHeader = undefined;
337
+ // Startup banner (logo + loaded resources) dismisses on first user message
338
+ startupBannerDismissed = false;
313
339
  // Custom header from extension (undefined = use built-in header)
314
340
  customHeader = undefined;
315
341
  options;
@@ -665,52 +691,36 @@ export class InteractiveMode {
665
691
  this.ui.start();
666
692
  this.isInitialized = true;
667
693
  await this.themeController.applyFromSettings();
668
- // Add header with keybindings from config (unless silenced)
669
- if (this.options.verbose || !this.settingsManager.getQuietStartup()) {
670
- const logo = theme.bold(theme.fg("accent", APP_NAME)) + theme.fg("dim", ` v${this.version}`);
671
- // Build startup instructions using keybinding hint helpers
672
- const hint = (keybinding, description) => keyHint(keybinding, description);
673
- const expandedInstructions = [
674
- hint("app.interrupt", "to interrupt"),
675
- hint("app.clear", "to clear"),
676
- rawKeyHint(`${keyText("app.clear")} twice`, "to exit"),
677
- hint("app.exit", "to exit (empty)"),
678
- hint("app.suspend", "to suspend"),
679
- keyHint("tui.editor.deleteToLineEnd", "to delete to end"),
680
- hint("app.thinking.cycle", "to cycle thinking level"),
681
- rawKeyHint(`${keyText("app.model.cycleForward")}/${keyText("app.model.cycleBackward")}`, "to cycle models"),
682
- hint("app.model.select", "to select model"),
683
- hint("app.tools.expand", "to expand tools"),
684
- hint("app.thinking.toggle", "to expand thinking"),
685
- hint("app.editor.external", "for external editor"),
686
- rawKeyHint("/", "for commands"),
687
- rawKeyHint("!", "to run bash"),
688
- rawKeyHint("!!", "to run bash (no context)"),
689
- hint("app.message.followUp", "to queue follow-up"),
690
- hint("app.message.dequeue", "to edit all queued messages"),
691
- hint("app.clipboard.pasteImage", "to paste image (with text fallback)"),
692
- rawKeyHint("drop files", "to attach"),
693
- ].join("\n");
694
- const compactInstructions = [
695
- hint("app.interrupt", "interrupt"),
696
- rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`, "clear/exit"),
697
- rawKeyHint("/", "commands"),
698
- rawKeyHint("!", "bash"),
699
- hint("app.tools.expand", "more"),
700
- ].join(theme.fg("muted", " · "));
701
- const compactOnboarding = theme.fg("dim", `Press ${keyText("app.tools.expand")} to show full startup help and loaded resources.`);
702
- const onboarding = theme.fg("dim", `Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.`);
703
- this.builtInHeader = new ExpandableText(() => `${logo}\n${compactInstructions}\n${compactOnboarding}\n\n${onboarding}`, () => `${logo}\n${expandedInstructions}\n\n${onboarding}`, this.getStartupExpansionState(), 1, 0);
704
- // Setup UI layout
705
- this.headerContainer.addChild(new Spacer(1));
706
- this.headerContainer.addChild(this.builtInHeader);
707
- this.headerContainer.addChild(new Spacer(1));
708
- }
709
- else {
710
- // Minimal header when silenced
711
- this.builtInHeader = new Text("", 0, 0);
712
- this.headerContainer.addChild(this.builtInHeader);
713
- }
694
+ // Brand banner always appears; quiet startup only hides keybinding help.
695
+ const logo = `${gradientLogo(SELESAI_LOGO, "#ff6b2c", "#fb923c")}\n${theme.fg("dim", ` ${APP_NAME} v${this.version} · /help for commands`)}`;
696
+ // Build startup instructions using keybinding hint helpers
697
+ const hint = (keybinding, description) => keyHint(keybinding, description);
698
+ const expandedInstructions = [
699
+ hint("app.interrupt", "to interrupt"),
700
+ hint("app.clear", "to clear"),
701
+ rawKeyHint(`${keyText("app.clear")} twice`, "to exit"),
702
+ hint("app.exit", "to exit (empty)"),
703
+ hint("app.suspend", "to suspend"),
704
+ keyHint("tui.editor.deleteToLineEnd", "to delete to end"),
705
+ hint("app.thinking.cycle", "to cycle thinking level"),
706
+ rawKeyHint(`${keyText("app.model.cycleForward")}/${keyText("app.model.cycleBackward")}`, "to cycle models"),
707
+ hint("app.model.select", "to select model"),
708
+ hint("app.tools.expand", "to expand tools"),
709
+ hint("app.thinking.toggle", "to expand thinking"),
710
+ hint("app.editor.external", "for external editor"),
711
+ rawKeyHint("/", "for commands"),
712
+ rawKeyHint("!", "to run bash"),
713
+ rawKeyHint("!!", "to run bash (no context)"),
714
+ hint("app.message.followUp", "to queue follow-up"),
715
+ hint("app.message.dequeue", "to edit all queued messages"),
716
+ hint("app.clipboard.pasteImage", "to paste image (with text fallback)"),
717
+ rawKeyHint("drop files", "to attach"),
718
+ ].join("\n");
719
+ this.builtInHeader = new ExpandableText(() => logo, () => `${logo}\n\n${expandedInstructions}`, this.getStartupExpansionState(), 1, 0);
720
+ // Setup UI layout
721
+ this.headerContainer.addChild(new Spacer(1));
722
+ this.headerContainer.addChild(this.builtInHeader);
723
+ this.headerContainer.addChild(new Spacer(1));
714
724
  this.ui.requestRender();
715
725
  // Ensure fd and rg are available after mounting the TUI (downloads if missing, adds to PATH via getBinDir)
716
726
  // so slow downloads do not make startup appear frozen.
@@ -1235,25 +1245,14 @@ export class InteractiveMode {
1235
1245
  }
1236
1246
  showLoadedResources(options) {
1237
1247
  // Resource rendering is idempotent; chat clears no longer clear this separate container.
1248
+ if (this.startupBannerDismissed)
1249
+ return;
1238
1250
  this.loadedResourcesContainer.clear();
1239
- const showListing = options?.force || this.options.verbose || !this.settingsManager.getQuietStartup();
1251
+ const showListing = options?.force || !this.startupBannerDismissed || this.options.verbose || !this.settingsManager.getQuietStartup();
1240
1252
  const showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;
1241
1253
  if (!showListing && !showDiagnostics) {
1242
1254
  return;
1243
1255
  }
1244
- const sectionHeader = (name, color = "mdHeading") => theme.fg(color, `[${name}]`);
1245
- const formatCompactList = (items, options) => {
1246
- const labels = items.map((item) => item.trim()).filter((item) => item.length > 0);
1247
- if (options?.sort !== false) {
1248
- labels.sort((a, b) => a.localeCompare(b));
1249
- }
1250
- return theme.fg("dim", ` ${labels.join(", ")}`);
1251
- };
1252
- const addLoadedSection = (name, collapsedBody, expandedBody = collapsedBody, color = "mdHeading") => {
1253
- const section = new ExpandableText(() => `${sectionHeader(name, color)}\n${collapsedBody}`, () => `${sectionHeader(name, color)}\n${expandedBody}`, this.getStartupExpansionState(), 0, 0);
1254
- this.loadedResourcesContainer.addChild(section);
1255
- this.loadedResourcesContainer.addChild(new Spacer(1));
1256
- };
1257
1256
  const skillsResult = this.session.resourceLoader.getSkills();
1258
1257
  const promptsResult = this.session.resourceLoader.getPrompts();
1259
1258
  const themesResult = this.session.resourceLoader.getThemes();
@@ -1287,70 +1286,16 @@ export class InteractiveMode {
1287
1286
  }
1288
1287
  }
1289
1288
  if (showListing) {
1290
- const systemPromptSource = this.session.resourceLoader.getSystemPromptSource();
1291
- const contextFiles = [
1292
- ...(systemPromptSource ? [systemPromptSource] : []),
1293
- ...this.session.resourceLoader.getAppendSystemPromptSources(),
1294
- ...this.session.resourceLoader.getAgentsFiles().agentsFiles,
1295
- ];
1296
- if (contextFiles.length > 0) {
1297
- this.loadedResourcesContainer.addChild(new Spacer(1));
1298
- const contextList = contextFiles
1299
- .map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
1300
- .join("\n");
1301
- const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
1302
- addLoadedSection("Context", contextCompactList, contextList);
1303
- }
1304
1289
  const skills = skillsResult.skills;
1305
1290
  if (skills.length > 0) {
1306
- const groups = this.buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
1307
- const skillList = this.formatScopeGroups(groups, {
1308
- formatPath: (item) => this.formatDisplayPath(item.path),
1309
- formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
1310
- });
1311
- const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
1312
- addLoadedSection("Skills", skillCompactList, skillList);
1313
- }
1314
- const templates = this.session.promptTemplates;
1315
- if (templates.length > 0) {
1316
- const groups = this.buildScopeGroups(templates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })));
1317
- const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
1318
- const templateList = this.formatScopeGroups(groups, {
1319
- formatPath: (item) => {
1320
- const template = templateByPath.get(item.path);
1321
- return template ? `/${template.name}` : this.formatDisplayPath(item.path);
1322
- },
1323
- formatPackagePath: (item) => {
1324
- const template = templateByPath.get(item.path);
1325
- return template ? `/${template.name}` : this.formatDisplayPath(item.path);
1326
- },
1327
- });
1328
- const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
1329
- addLoadedSection("Prompts", promptCompactList, templateList);
1330
- }
1331
- if (extensions.length > 0) {
1332
- const groups = this.buildScopeGroups(extensions);
1333
- const extList = this.formatScopeGroups(groups, {
1334
- formatPath: (item) => this.formatExtensionDisplayPath(item.path),
1335
- formatPackagePath: (item) => this.formatExtensionDisplayPath(this.getShortPath(item.path, item.sourceInfo)),
1336
- });
1337
- const extensionCompactList = formatCompactList(this.getCompactExtensionLabels(extensions));
1338
- addLoadedSection("Extensions", extensionCompactList, extList, "mdHeading");
1339
- }
1340
- // Show loaded themes (excluding built-in)
1341
- const loadedThemes = themesResult.themes;
1342
- const customThemes = loadedThemes.filter((t) => t.sourcePath);
1343
- if (customThemes.length > 0) {
1344
- const groups = this.buildScopeGroups(customThemes.map((loadedTheme) => ({
1345
- path: loadedTheme.sourcePath,
1346
- sourceInfo: loadedTheme.sourceInfo,
1347
- })));
1348
- const themeList = this.formatScopeGroups(groups, {
1349
- formatPath: (item) => this.formatDisplayPath(item.path),
1350
- formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
1351
- });
1352
- const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ?? this.getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
1353
- addLoadedSection("Themes", themeCompactList, themeList);
1291
+ const skillLabels = skills.map((skill) => skill.category ? `[${skill.category}] ${skill.name}` : skill.name);
1292
+ this.loadedResourcesContainer.addChild(new StartupBox("Skills", skillLabels));
1293
+ this.loadedResourcesContainer.addChild(new Spacer(1));
1294
+ }
1295
+ const tools = this.session.getActiveToolNames();
1296
+ if (tools.length > 0) {
1297
+ this.loadedResourcesContainer.addChild(new StartupBox("Tools", tools));
1298
+ this.loadedResourcesContainer.addChild(new Spacer(1));
1354
1299
  }
1355
1300
  }
1356
1301
  if (showDiagnostics) {
@@ -1391,6 +1336,15 @@ export class InteractiveMode {
1391
1336
  }
1392
1337
  }
1393
1338
  }
1339
+ /** Dismiss the startup banner (logo + loaded resources) on first user message. */
1340
+ dismissStartupBanner() {
1341
+ if (this.startupBannerDismissed)
1342
+ return;
1343
+ this.startupBannerDismissed = true;
1344
+ this.headerContainer.clear();
1345
+ this.loadedResourcesContainer.clear();
1346
+ this.ui.requestRender();
1347
+ }
1394
1348
  /**
1395
1349
  * Initialize the extension system with TUI-based UI context.
1396
1350
  */
@@ -2496,6 +2450,7 @@ export class InteractiveMode {
2496
2450
  this.editor.setText(text);
2497
2451
  return;
2498
2452
  }
2453
+ this.dismissStartupBanner();
2499
2454
  this.editor.addToHistory?.(text);
2500
2455
  await this.handleBashCommand(command, isExcluded);
2501
2456
  this.isBashMode = false;
@@ -2506,11 +2461,13 @@ export class InteractiveMode {
2506
2461
  // Queue input during compaction (extension commands execute immediately)
2507
2462
  if (this.session.isCompacting) {
2508
2463
  if (this.isExtensionCommand(text)) {
2464
+ this.dismissStartupBanner();
2509
2465
  this.editor.addToHistory?.(text);
2510
2466
  this.editor.setText("");
2511
2467
  await this.session.prompt(text, { images });
2512
2468
  }
2513
2469
  else {
2470
+ this.dismissStartupBanner();
2514
2471
  this.queueCompactionMessage(text, "steer", images);
2515
2472
  }
2516
2473
  return;
@@ -2518,6 +2475,7 @@ export class InteractiveMode {
2518
2475
  // If streaming, use prompt() with steer behavior
2519
2476
  // This handles extension commands (execute immediately), prompt template expansion, and queueing
2520
2477
  if (this.session.isStreaming) {
2478
+ this.dismissStartupBanner();
2521
2479
  this.editor.addToHistory?.(text);
2522
2480
  this.editor.setText("");
2523
2481
  await this.session.prompt(text, { streamingBehavior: "steer", images });
@@ -2528,6 +2486,7 @@ export class InteractiveMode {
2528
2486
  // Normal message submission
2529
2487
  // First, move any pending bash components to chat
2530
2488
  this.flushPendingBashComponents();
2489
+ this.dismissStartupBanner();
2531
2490
  const input = { text, images };
2532
2491
  if (this.onInputCallback) {
2533
2492
  this.onInputCallback(input);
@@ -3103,6 +3062,10 @@ export class InteractiveMode {
3103
3062
  const times = compactionCount === 1 ? "1 time" : `${compactionCount} times`;
3104
3063
  this.showStatus(`Session compacted ${times}`);
3105
3064
  }
3065
+ // Resume: jump to the end of the transcript
3066
+ if (entries.length > 0) {
3067
+ this.transcriptScrollView?.scrollToEnd();
3068
+ }
3106
3069
  }
3107
3070
  renderProjectTrustWarningIfNeeded() {
3108
3071
  if (this.settingsManager.isProjectTrusted() || !hasTrustRequiringProjectResources(this.sessionManager.getCwd())) {
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: agent-browser
3
+ category: automation
3
4
  description: Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
4
5
  allowed-tools: Bash(agent-browser:*), Bash(npx agent-browser:*)
5
6
  hidden: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: batch-grill-me
3
+ category: interview
3
4
  description: A relentless interview that asks every frontier question at once, round by round.
4
5
  disable-model-invocation: true
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: brandkit
3
+ category: design
3
4
  description: Premium brand-kit image generation skill for creating high-end brand-guidelines boards, logo systems, identity decks, and visual-world presentations. Trained for minimalist, cinematic, editorial, dark-tech, luxury, cultural, security, gaming, developer-tool, and consumer-app brand systems. Optimized for intentional logo concepting, refined composition, sparse typography, strong symbolic meaning, premium mockups, art-directed imagery, and flexible grid layouts.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: design-references
3
+ category: design
3
4
  description: Design-reference lookup from VoltAgent's Awesome DESIGN.md collection. Use when the user asks for design references or inspiration, or wants a page/product to feel like a known site or brand (Linear, Stripe, Apple, etc.).
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: design-taste-frontend
3
+ category: design
3
4
  description: Anti-slop frontend skill for landing pages, portfolios, and redesigns. The agent reads the brief, infers the right design direction, and ships interfaces that do not look templated. Real design systems when applicable, audit-first on redesigns, strict pre-flight check.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: design-taste-frontend-v1
3
+ category: design
3
4
  description: The original v1 taste-skill, preserved for projects depending on its exact behavior. The current default is `design-taste-frontend` (v2 experimental), which is a substantial rewrite. Use this v1 install name only if you need exact backward compatibility.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: full-output-enforcement
3
+ category: discipline
3
4
  description: Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: gpt-taste
3
+ category: design
3
4
  description: Elite UX/UI & Advanced GSAP Motion Engineer. Enforces Python-driven true randomization for layout variance, strict AIDA page structure, wide editorial typography (bans 6-line wraps), gapless bento grids, strict GSAP ScrollTriggers (pinning, stacking, scrubbing), inline micro-images, and massive section spacing.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: grill-me
3
+ category: interview
3
4
  description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: handoff
3
+ category: handoff
3
4
  description: Compact the current conversation into a handoff document for another agent to pick up.
4
5
  argument-hint: "What will the next session be used for?"
5
6
  disable-model-invocation: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: handoff-text
3
+ category: handoff
3
4
  description: Compact the current conversation into a handoff document for another agent to pick up.
4
5
  argument-hint: "What will the next session be used for?"
5
6
  disable-model-invocation: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: high-end-visual-design
3
+ category: design
3
4
  description: Teaches the AI to design like a high-end agency. Defines the exact fonts, spacing, shadows, card structures, and animations that make a website feel expensive. Blocks all the common defaults that make AI designs look cheap or generic.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: image-to-code
3
+ category: imagegen
3
4
  description: Elite website image-to-code skill for Codex. For visually important web tasks, it must first generate the design image(s) itself, deeply analyze them, then implement the website to match them as closely as possible. In Codex, it must prefer large, readable, section-specific images instead of tiny compressed boards, generate fresh standalone images for sections or detail views instead of cropping old ones, avoid lazy under-generation, avoid cards-inside-cards-inside-cards UI, and keep the hero clean, spacious, readable, and visible on a small laptop.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: imagegen-frontend-mobile
3
+ category: imagegen
3
4
  description: Elite mobile app image-generation skill for creating premium, app-native screen concepts and flows. Designed for iOS, Android, and cross-platform mobile products. Prioritizes clean hierarchy, comfortably readable text, strong multi-screen consistency, controlled color palettes, non-generic creative direction, textured surfaces, image-led composition, tasteful custom iconography, and clean phone mockup framing. By default, screens should be shown inside a subtle premium iPhone or similar phone mockup with a visible frame, while the main focus stays on the app content itself. This skill generates images only. It does not write code.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: imagegen-frontend-web
3
+ category: imagegen
3
4
  description: Elite frontend image-direction skill for generating premium, conversion-aware website design references. CRITICAL OUTPUT RULE — generate ONE separate horizontal image FOR EVERY section. A landing page with 8 sections produces 8 images. Never compress multiple sections into one image. Enforces composition variety (not always left-text / right-image), background-image freedom, varied CTAs, varied hero scales (giant / mid / mini minimalist), narrative concept spine, second-read moments, and a single consistent palette across all images. Optimized for landing pages, marketing sites, and product comps that developers or coding models can accurately recreate.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: implanger
3
+ category: planning
3
4
  description: Execute the Planger's style planning
4
5
  argument-hint: "For Subagent to be able to understand Planger and can execute it perfectly"
5
6
  disable-model-invocation: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: improve-codebase
3
+ category: planning
3
4
  description: improve codebase quality
4
5
  disable-model-invocation: true
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: industrial-brutalist-ui
3
+ category: design
3
4
  description: Raw mechanical interfaces fusing Swiss typographic print with military terminal aesthetics. Rigid grids, extreme type scale contrast, utilitarian color, analog degradation effects. For data-heavy dashboards, portfolios, or editorial sites that need to feel like declassified blueprints.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: minimalist-ui
3
+ category: design
3
4
  description: Clean editorial-style interfaces. Warm monochrome palette, typographic contrast, flat bento grids, muted pastels. No gradients, no heavy shadows.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: pi-subagents
3
+ category: orchestration
3
4
  description: |
4
5
  Delegate work to builtin or custom subagents with single-agent, parallel,
5
6
  scripted-chaining, async, forked-context, and coordinated workflows. Use
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: planger
3
+ category: planning
3
4
  description: Create decomposed planning for sub agent
4
5
  argument-hint: "How i provide a good plan for subagent"
5
6
  disable-model-invocation: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail
3
+ category: simplicity
3
4
  description: >
4
5
  Forces the laziest solution that actually works, simplest, shortest, most
5
6
  minimal. Channels a senior dev who has seen everything: question whether the
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail-audit
3
+ category: simplicity
3
4
  description: >
4
5
  Whole-repo audit for over-engineering. Like ponytail-review, but scans the
5
6
  entire codebase instead of a diff: a ranked list of what to delete, simplify,
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail-debt
3
+ category: simplicity
3
4
  description: >
4
5
  Harvest every `ponytail:` comment in the codebase into a debt ledger, so the
5
6
  deliberate shortcuts and deferrals ponytail leaves behind get tracked instead
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail-gain
3
+ category: simplicity
3
4
  description: >
4
5
  Show ponytail's measured impact as a compact scoreboard: less code, less
5
6
  cost, more speed, from the benchmark medians. One-shot display, not a
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail-help
3
+ category: simplicity
3
4
  description: >
4
5
  Quick-reference card for all ponytail modes, skills, and commands.
5
6
  One-shot display, not a persistent mode. Trigger: /ponytail-help,
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ponytail-review
3
+ category: simplicity
3
4
  description: >
4
5
  Code review focused exclusively on over-engineering. Finds what to delete:
5
6
  reinvented standard library, unneeded dependencies, speculative abstractions,
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: redesign-existing-projects
3
+ category: design
3
4
  description: Upgrades existing websites and apps to premium quality. Audits current design, identifies generic AI patterns, and applies high-end design standards without breaking functionality. Works with any CSS framework or vanilla CSS.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: selesai-handoff
3
+ category: handoff
3
4
  description: Hand the current conversation off to a fresh background agent that picks up the work immediately.
4
5
  argument-hint: "What will the next session be used for?"
5
6
  disable-model-invocation: true
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: stitch-design-taste
3
+ category: design
3
4
  description: Semantic Design System Skill for Google Stitch. Generates agent-friendly DESIGN.md files that enforce premium, anti-generic UI standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion, and hardware-accelerated performance.
4
5
  license: MIT
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: unlazy
3
+ category: discipline
3
4
  description: Enforces completion discipline for substantial autonomous work by writing acceptance gates before execution, decomposing work with the Depth Tree, running approved checks, and re-verifying evidence before reporting. Use when Codex faces a long or multi-part task, work that has returned half-done, an exhaustive audit or build, parallel leaves or pipelines, or explicit triggers such as /unlazy, $unlazy, "tree N", "gates", and "do not stop until it is done".
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: web-design-guidelines
3
+ category: design
3
4
  description: Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".
4
5
  license: MIT
5
6
  metadata:
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: workflow
3
+ category: orchestration
3
4
  description: Adaptively orchestrate non-trivial implementation work with Selesai subagents. Use when the user asks to use a workflow, orchestrate a task, run an implementation/review/fix loop, or coordinate architecture, workers, and reviewers. Choose only the necessary stages; do not use static slash-command flows.
4
5
  ---
5
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selesai/code",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Maintained, extension-first Pi coding agent with built-in workflows, subagents, web research, questions, skills, and an enhanced terminal UI.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -52,8 +52,8 @@
52
52
  "clean": "shx rm -rf dist",
53
53
  "dev": "tsx src/cli.ts",
54
54
  "dev:print": "tsx src/cli.ts --print",
55
- "test": "vitest run src/extensions/undo.test.ts src/extensions/tps.test.ts src/extensions/agent-browser.test.ts src/extensions/context-compaction-reminder.test.ts src/extensions/copy-turn.test.ts src/extensions/grep-app/index.test.ts src/extensions/inline-skills.test.ts src/extensions/rtk.test.ts src/extensions/model-prompt-injector/index.test.ts src/extensions/web-agent-onboarding.test.ts src/extensions/handoff-new.test.ts src/extensions/question/tests src/extensions/ponytail/test src/__tests__/tokenin-onboarding.test.ts src/__tests__/model-registry-defaults.test.ts src/cli/args.test.ts",
56
- "test:coverage": "vitest run --coverage src/extensions/undo.test.ts src/extensions/tps.test.ts src/extensions/agent-browser.test.ts src/extensions/context-compaction-reminder.test.ts src/extensions/copy-turn.test.ts src/extensions/grep-app/index.test.ts src/extensions/inline-skills.test.ts src/extensions/rtk.test.ts src/extensions/model-prompt-injector/index.test.ts src/extensions/web-agent-onboarding.test.ts src/extensions/handoff-new.test.ts src/extensions/question/tests src/extensions/ponytail/test src/__tests__/tokenin-onboarding.test.ts src/__tests__/model-registry-defaults.test.ts src/cli/args.test.ts",
55
+ "test": "vitest run src/extensions/undo.test.ts src/extensions/tps.test.ts src/extensions/agent-browser.test.ts src/extensions/auto-session-name.test.ts src/extensions/context-compaction-reminder.test.ts src/extensions/copy-turn.test.ts src/extensions/grep-app/index.test.ts src/extensions/inline-skills.test.ts src/extensions/rtk.test.ts src/extensions/model-prompt-injector/index.test.ts src/extensions/web-agent-onboarding.test.ts src/extensions/handoff-new.test.ts src/extensions/question/tests src/extensions/ponytail/test src/__tests__/tokenin-onboarding.test.ts src/__tests__/model-registry-defaults.test.ts src/cli/args.test.ts",
56
+ "test:coverage": "vitest run --coverage src/extensions/undo.test.ts src/extensions/tps.test.ts src/extensions/agent-browser.test.ts src/extensions/auto-session-name.test.ts src/extensions/context-compaction-reminder.test.ts src/extensions/copy-turn.test.ts src/extensions/grep-app/index.test.ts src/extensions/inline-skills.test.ts src/extensions/rtk.test.ts src/extensions/model-prompt-injector/index.test.ts src/extensions/web-agent-onboarding.test.ts src/extensions/handoff-new.test.ts src/extensions/question/tests src/extensions/ponytail/test src/__tests__/tokenin-onboarding.test.ts src/__tests__/model-registry-defaults.test.ts src/cli/args.test.ts",
57
57
  "prepare": "npm run build",
58
58
  "build": "npm run clean && tsgo -p tsconfig.build.json && shx chmod +x dist/cli.js dist/rpc-entry.js && npm run copy-assets",
59
59
  "copy-assets": "shx mkdir -p dist/modes/interactive/theme && shx cp src/modes/interactive/theme/*.json dist/modes/interactive/theme/ && shx mkdir -p dist/modes/interactive/assets && shx cp src/modes/interactive/assets/*.png dist/modes/interactive/assets/ && shx mkdir -p dist/core/export-html/vendor && shx cp src/core/export-html/template.html src/core/export-html/template.css src/core/export-html/template.js dist/core/export-html/ && shx cp src/core/export-html/vendor/*.js dist/core/export-html/vendor/ && shx mkdir -p dist/defaults && shx cp src/defaults/* dist/defaults/ && shx mkdir -p dist/extensions && node scripts/copy-extensions.mjs && shx mkdir -p dist/themes && shx cp -r src/themes/. dist/themes/ && shx mkdir -p dist/skills && shx cp -r src/skills/. dist/skills/"