winter-super-cli 2026.6.26 → 2026.6.27

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 (122) hide show
  1. package/CHANGELOG.md +28 -5
  2. package/README.md +66 -0
  3. package/package.json +5 -1
  4. package/resources/local/gsap-skills/.claude-plugin/marketplace.json +20 -0
  5. package/resources/local/gsap-skills/.claude-plugin/plugin.json +6 -0
  6. package/resources/local/gsap-skills/.cursor-plugin/marketplace.json +13 -0
  7. package/resources/local/gsap-skills/.cursor-plugin/plugin.json +22 -0
  8. package/resources/local/gsap-skills/.github/copilot-instructions.md +17 -0
  9. package/resources/local/gsap-skills/.github/instructions/react.instructions.md +15 -0
  10. package/resources/local/gsap-skills/.github/instructions/scrolltrigger.instructions.md +18 -0
  11. package/resources/local/gsap-skills/AGENTS.md +27 -0
  12. package/resources/local/gsap-skills/CLAUDE.md +1 -0
  13. package/resources/local/gsap-skills/GEMINI.md +1 -0
  14. package/resources/local/gsap-skills/LICENSE +21 -0
  15. package/resources/local/gsap-skills/README.md +163 -0
  16. package/resources/local/gsap-skills/assets/gsap-green.svg +7 -0
  17. package/resources/local/gsap-skills/assets/gsap-icon-inverted.svg +15 -0
  18. package/resources/local/gsap-skills/assets/gsap-icon-square.svg +1 -0
  19. package/resources/local/gsap-skills/assets/gsap-white.svg +7 -0
  20. package/resources/local/gsap-skills/examples/README.md +29 -0
  21. package/resources/local/gsap-skills/examples/nuxt/app/app.vue +3 -0
  22. package/resources/local/gsap-skills/examples/nuxt/app/composables/useGSAP.ts +91 -0
  23. package/resources/local/gsap-skills/examples/nuxt/app/pages/index.vue +55 -0
  24. package/resources/local/gsap-skills/examples/nuxt/nuxt.config.ts +4 -0
  25. package/resources/local/gsap-skills/examples/nuxt/package.json +18 -0
  26. package/resources/local/gsap-skills/examples/react/App.jsx +46 -0
  27. package/resources/local/gsap-skills/examples/react/index.html +12 -0
  28. package/resources/local/gsap-skills/examples/react/main.jsx +9 -0
  29. package/resources/local/gsap-skills/examples/react/package.json +21 -0
  30. package/resources/local/gsap-skills/examples/react/vite.config.js +7 -0
  31. package/resources/local/gsap-skills/examples/vanilla/index.html +33 -0
  32. package/resources/local/gsap-skills/examples/vanilla/main.js +36 -0
  33. package/resources/local/gsap-skills/examples/vue/app.vue +47 -0
  34. package/resources/local/gsap-skills/examples/vue/index.html +15 -0
  35. package/resources/local/gsap-skills/examples/vue/main.js +9 -0
  36. package/resources/local/gsap-skills/examples/vue/package.json +19 -0
  37. package/resources/local/gsap-skills/examples/vue/vite.config.js +7 -0
  38. package/resources/local/gsap-skills/skills/gsap-core/SKILL.md +254 -0
  39. package/resources/local/gsap-skills/skills/gsap-frameworks/SKILL.md +266 -0
  40. package/resources/local/gsap-skills/skills/gsap-performance/SKILL.md +79 -0
  41. package/resources/local/gsap-skills/skills/gsap-plugins/SKILL.md +433 -0
  42. package/resources/local/gsap-skills/skills/gsap-react/SKILL.md +136 -0
  43. package/resources/local/gsap-skills/skills/gsap-scrolltrigger/SKILL.md +296 -0
  44. package/resources/local/gsap-skills/skills/gsap-timeline/SKILL.md +107 -0
  45. package/resources/local/gsap-skills/skills/gsap-utils/SKILL.md +284 -0
  46. package/resources/local/gsap-skills/skills/llms.txt +39 -0
  47. package/resources/local/hermes-agent-core/AGENTS.md +1132 -0
  48. package/resources/local/hermes-agent-core/LICENSE +21 -0
  49. package/resources/local/hermes-agent-core/README.md +215 -0
  50. package/resources/local/hermes-agent-core/docs/2026-05-07-s6-overlay-dynamic-subagent-gateways.md +434 -0
  51. package/resources/local/hermes-agent-core/hermes-already-has-routines.md +160 -0
  52. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
  53. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
  54. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
  55. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1021 -0
  56. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +277 -0
  57. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +57 -0
  58. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
  59. package/resources/local/hermes-agent-core/skills/github/DESCRIPTION.md +3 -0
  60. package/resources/local/hermes-agent-core/skills/github/codebase-inspection/SKILL.md +116 -0
  61. package/resources/local/hermes-agent-core/skills/github/github-auth/SKILL.md +247 -0
  62. package/resources/local/hermes-agent-core/skills/github/github-auth/scripts/gh-env.sh +66 -0
  63. package/resources/local/hermes-agent-core/skills/github/github-code-review/SKILL.md +481 -0
  64. package/resources/local/hermes-agent-core/skills/github/github-code-review/references/review-output-template.md +74 -0
  65. package/resources/local/hermes-agent-core/skills/github/github-issues/SKILL.md +370 -0
  66. package/resources/local/hermes-agent-core/skills/github/github-issues/templates/bug-report.md +35 -0
  67. package/resources/local/hermes-agent-core/skills/github/github-issues/templates/feature-request.md +31 -0
  68. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/SKILL.md +367 -0
  69. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
  70. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
  71. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
  72. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
  73. package/resources/local/hermes-agent-core/skills/github/github-repo-management/SKILL.md +516 -0
  74. package/resources/local/hermes-agent-core/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
  75. package/resources/local/hermes-agent-core/skills/mcp/DESCRIPTION.md +3 -0
  76. package/resources/local/hermes-agent-core/skills/mcp/native-mcp/SKILL.md +357 -0
  77. package/resources/local/hermes-agent-core/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
  78. package/resources/local/hermes-agent-core/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
  79. package/resources/local/hermes-agent-core/skills/software-development/hermes-s6-container-supervision/SKILL.md +176 -0
  80. package/resources/local/hermes-agent-core/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
  81. package/resources/local/hermes-agent-core/skills/software-development/plan/SKILL.md +58 -0
  82. package/resources/local/hermes-agent-core/skills/software-development/python-debugpy/SKILL.md +375 -0
  83. package/resources/local/hermes-agent-core/skills/software-development/requesting-code-review/SKILL.md +280 -0
  84. package/resources/local/hermes-agent-core/skills/software-development/spike/SKILL.md +197 -0
  85. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/SKILL.md +352 -0
  86. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
  87. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
  88. package/resources/local/hermes-agent-core/skills/software-development/systematic-debugging/SKILL.md +367 -0
  89. package/resources/local/hermes-agent-core/skills/software-development/test-driven-development/SKILL.md +343 -0
  90. package/resources/local/hermes-agent-core/skills/software-development/writing-plans/SKILL.md +297 -0
  91. package/resources/local/manifest.json +12 -0
  92. package/rule.md +2 -0
  93. package/scripts/audit-pack.js +5 -0
  94. package/scripts/smoke-browser.js +53 -0
  95. package/scripts/smoke-package.js +38 -4
  96. package/skill.md +36 -4
  97. package/skills/gsap.md +26 -0
  98. package/skills/hermes-agent.md +17 -0
  99. package/src/agent/agent-definitions.js +4 -4
  100. package/src/agent/runtime.js +179 -5
  101. package/src/agent/subagent-child.js +44 -0
  102. package/src/ai/capability-scorecard.js +193 -14
  103. package/src/ai/hermes-core.js +77 -0
  104. package/src/ai/model-capabilities.js +42 -2
  105. package/src/ai/prompts/system-prompt.js +16 -2
  106. package/src/ai/small-model-amplifier.js +35 -7
  107. package/src/ai/workflow-selector.js +22 -1
  108. package/src/cli/commands.js +21 -1
  109. package/src/cli/config.js +42 -4
  110. package/src/cli/context-loader.js +253 -9
  111. package/src/cli/conversation-format.js +5 -0
  112. package/src/cli/input-controller.js +79 -10
  113. package/src/cli/prompt-builder.js +45 -8
  114. package/src/cli/repl-commands.js +115 -0
  115. package/src/cli/repl.js +147 -86
  116. package/src/cli/slash-commands.js +3 -1
  117. package/src/cli/tui.js +133 -37
  118. package/src/mcp/client.js +46 -5
  119. package/src/tools/agent.js +316 -25
  120. package/src/tools/executor.js +310 -9
  121. package/src/tools/permission.js +20 -17
  122. package/winter.d.ts +112 -10
package/src/cli/config.js CHANGED
@@ -7,7 +7,7 @@ import { promises as fs } from 'fs';
7
7
  import path from 'path';
8
8
  import { homedir } from 'os';
9
9
  import { loadEnvFile, stripInlineSecrets } from './secret-env.js';
10
- import { CHROME_DEVTOOLS_MCP_NAME, createChromeDevtoolsMcpServer } from '../mcp/presets.js';
10
+ import { CHROME_DEVTOOLS_MCP_NAME, createChromeDevtoolsMcpServer, ensureMcpConfigShape } from '../mcp/presets.js';
11
11
 
12
12
  export class ConfigLoader {
13
13
  constructor() {
@@ -22,14 +22,29 @@ export class ConfigLoader {
22
22
  await loadEnvFile(this.envFile);
23
23
  const data = await fs.readFile(this.configFile, 'utf8');
24
24
  const config = JSON.parse(data.replace(/^\uFEFF/, ''));
25
- return this.applyEnv(config);
25
+ return this.applyEnv(this.ensureBundledDefaults(config));
26
26
  } catch {
27
27
  // Return defaults
28
28
  await loadEnvFile(this.envFile);
29
- return this.applyEnv(this.getDefaults());
29
+ return this.applyEnv(this.ensureBundledDefaults(this.getDefaults()));
30
30
  }
31
31
  }
32
32
 
33
+ ensureBundledDefaults(config = {}) {
34
+ const next = structuredClone(config || {});
35
+ ensureMcpConfigShape(next);
36
+ if (!next.mcp.servers.some(server => server?.name === CHROME_DEVTOOLS_MCP_NAME)) {
37
+ next.mcp.servers.push(createChromeDevtoolsMcpServer(['--isolated']));
38
+ }
39
+ next.permissions.allowlist.tools = [
40
+ ...new Set([...(next.permissions.allowlist.tools || []), 'MCP']),
41
+ ];
42
+ next.permissions.allowlist.mcpServers = [
43
+ ...new Set([...(next.permissions.allowlist.mcpServers || []), CHROME_DEVTOOLS_MCP_NAME]),
44
+ ];
45
+ return next;
46
+ }
47
+
33
48
  applyEnv(config) {
34
49
  const next = structuredClone(config || this.getDefaults());
35
50
  for (const [provider, section] of Object.entries(next)) {
@@ -105,7 +120,13 @@ export class ConfigLoader {
105
120
  sandbox: {
106
121
  enabled: true,
107
122
  restrictToWorkspace: true,
108
- allowedCommands: ['git', 'npm', 'node', 'python'],
123
+ allowedCommands: [
124
+ 'git', 'npm', 'npx', 'node', 'python',
125
+ 'ping', 'test-connection', 'curl', 'wget', 'iwr', 'irm',
126
+ 'invoke-webrequest', 'invoke-restmethod', 'nslookup', 'resolve-dnsname',
127
+ 'tracert', 'traceroute', 'pathping', 'dig', 'ipconfig', 'ifconfig',
128
+ 'ip', 'netstat', 'speedtest', 'speedtest-cli', 'measure-command',
129
+ ],
109
130
  },
110
131
  session: {
111
132
  autoSave: true,
@@ -240,6 +261,23 @@ export class ConfigLoader {
240
261
  await this.save(config);
241
262
  }
242
263
 
264
+ async setFullAccess(enabled = true) {
265
+ const config = await this.load();
266
+ const defaults = this.getDefaults();
267
+ const fullAccess = Boolean(enabled);
268
+ config.sandbox = {
269
+ ...(config.sandbox || {}),
270
+ enabled: !fullAccess,
271
+ restrictToWorkspace: !fullAccess,
272
+ allowedCommands: config.sandbox?.allowedCommands || defaults.sandbox.allowedCommands,
273
+ };
274
+ config.permissions = config.permissions || { allowlist: {} };
275
+ config.permissions.allowlist = config.permissions.allowlist || { tools: [], commands: [], mcpServers: [] };
276
+ config.permissions.promptByDefault = !fullAccess;
277
+ await this.save(config);
278
+ return config;
279
+ }
280
+
243
281
  async setMcpServers(servers = []) {
244
282
  const config = await this.load();
245
283
  config.mcp = config.mcp || {};
@@ -83,6 +83,11 @@ export class ContextLoader {
83
83
  pageAgent: path.join(localRoot, 'page-agent'),
84
84
  ecc: path.join(localRoot, 'ecc'),
85
85
  eccReadme: path.join(localRoot, 'ecc', 'README.md'),
86
+ gsapSkills: path.join(localRoot, 'gsap-skills'),
87
+ gsapSkillsIndex: path.join(localRoot, 'gsap-skills', 'skills', 'llms.txt'),
88
+ hermesAgentCore: path.join(localRoot, 'hermes-agent-core'),
89
+ hermesAgentCoreAgents: path.join(localRoot, 'hermes-agent-core', 'AGENTS.md'),
90
+ hermesAgentCoreSkills: path.join(localRoot, 'hermes-agent-core', 'skills'),
86
91
  designs: path.join(localRoot, 'awesome-design-md', 'design-md'),
87
92
  agents: path.join(localRoot, 'agents.md'),
88
93
  manifest: path.join(localRoot, 'manifest.json'),
@@ -101,6 +106,17 @@ export class ContextLoader {
101
106
  }
102
107
  }
103
108
 
109
+ async readFirstExisting(basePath, candidates = [], maxChars = 1800) {
110
+ for (const candidate of candidates) {
111
+ const filePath = path.join(basePath, candidate);
112
+ const content = await this.readTextIfExists(filePath, maxChars);
113
+ if (content) {
114
+ return { filePath, content };
115
+ }
116
+ }
117
+ return { filePath: '', content: '' };
118
+ }
119
+
104
120
  getUserResourcePaths() {
105
121
  const home = homedir();
106
122
  return {
@@ -175,7 +191,7 @@ export class ContextLoader {
175
191
  }
176
192
 
177
193
  lines.push('- Use Read/Grep/Glob to inspect any local resource when it matters for the task.');
178
- lines.push('- Local resource families: winter skills, winter memories, agents.md, awesome-design-md, claude, codex, karpathy-tools, page-agent, ecc.');
194
+ lines.push('- Local resource families: winter skills, winter memories, agents.md, awesome-design-md, claude, codex, karpathy-tools, page-agent, ecc, gsap-skills, hermes-agent-core.');
179
195
  lines.push(`- User resource roots: ${userPaths.codexRoot}, ${userPaths.claudeRoot}`);
180
196
 
181
197
  if (winterSkills.length > 0) {
@@ -229,6 +245,11 @@ export class ContextLoader {
229
245
  const pageAgentReadmePath = path.join(paths.pageAgent, 'README.md');
230
246
  const pageAgentAgentsPath = path.join(paths.pageAgent, 'AGENTS.md');
231
247
  const pageAgentWinterPath = path.join(paths.pageAgent, 'WINTER.md');
248
+ const gsapReadmePath = path.join(paths.gsapSkills, 'README.md');
249
+ const gsapIndexPath = paths.gsapSkillsIndex;
250
+ const hermesReadmePath = path.join(paths.hermesAgentCore, 'README.md');
251
+ const hermesAgentsPath = paths.hermesAgentCoreAgents;
252
+ const hermesRoutinesPath = path.join(paths.hermesAgentCore, 'hermes-already-has-routines.md');
232
253
  const winterCodingSkillPath = path.join(paths.winter.skills, 'coding.md');
233
254
  const winterDebugSkillPath = path.join(paths.winter.skills, 'debug.md');
234
255
  const winterTestSkillPath = path.join(paths.winter.skills, 'test.md');
@@ -241,6 +262,12 @@ export class ContextLoader {
241
262
  designBrands,
242
263
  pageAgentWinter,
243
264
  pageAgentAgents,
265
+ gsapReadme,
266
+ gsapIndex,
267
+ hermesReadme,
268
+ hermesAgents,
269
+ hermesRoutines,
270
+ hermesSkillFamilies,
244
271
  winterCodingSkill,
245
272
  winterDebugSkill,
246
273
  winterTestSkill,
@@ -252,6 +279,12 @@ export class ContextLoader {
252
279
  this.listPathEntries(paths.designs, 40),
253
280
  this.readTextIfExists(pageAgentWinterPath, 1600),
254
281
  this.readTextIfExists(pageAgentAgentsPath, 2200),
282
+ this.readTextIfExists(gsapReadmePath, 1600),
283
+ this.readTextIfExists(gsapIndexPath, 1800),
284
+ this.readTextIfExists(hermesReadmePath, 1800),
285
+ this.readTextIfExists(hermesAgentsPath, 2200),
286
+ this.readTextIfExists(hermesRoutinesPath, 1400),
287
+ this.listPathEntries(paths.hermesAgentCoreSkills, 40),
255
288
  this.readTextIfExists(winterCodingSkillPath, 1200),
256
289
  this.readTextIfExists(winterDebugSkillPath, 1000),
257
290
  this.readTextIfExists(winterTestSkillPath, 1000),
@@ -265,6 +298,12 @@ export class ContextLoader {
265
298
  designBrands.length > 0 ||
266
299
  pageAgentWinter ||
267
300
  pageAgentAgents ||
301
+ gsapReadme ||
302
+ gsapIndex ||
303
+ hermesReadme ||
304
+ hermesAgents ||
305
+ hermesRoutines ||
306
+ hermesSkillFamilies.length > 0 ||
268
307
  winterCodingSkill ||
269
308
  winterDebugSkill ||
270
309
  winterTestSkill ||
@@ -282,6 +321,10 @@ export class ContextLoader {
282
321
  lines.push(`- Page Agent (Alibaba GUI Agent): ${path.relative(this.projectPath, pageAgentReadmePath)}`);
283
322
  lines.push(' Apply: for browser automation, smart form filling, SaaS AI copilot, accessibility, and multi-page agent tasks. PageAgent is an in-page JavaScript library that uses text-based DOM manipulation to control web interfaces with natural language. No browser extension or headless browser required.');
284
323
  lines.push(` Internal architecture at: ${path.relative(this.projectPath, pageAgentAgentsPath)}`);
324
+ lines.push(`- GSAP skills: ${path.relative(this.projectPath, gsapIndexPath)}`);
325
+ lines.push(' Apply: for JavaScript animation, React/Vue/Svelte animation, timelines, ScrollTrigger, Flip, Draggable, SVG/motion-path work, and animation performance. Read the matching GSAP SKILL.md before implementing non-trivial animation.');
326
+ lines.push(`- Hermes Agent core: ${path.relative(this.projectPath, hermesAgentsPath)}`);
327
+ lines.push(' Apply directly in Winter core for self-improving skills, session search/compression, subagent delegation, tool gateway discipline, TUI/gateway separation, scheduled automation, and central command registry patterns.');
285
328
  lines.push(`- Design system corpus: ${path.relative(this.projectPath, designReadmePath)} and ${path.relative(this.projectPath, paths.designs)}`);
286
329
  lines.push(' Apply: for UI/brand/design tasks, search the design-md corpus first and follow the closest existing brand/design guidance instead of inventing style from scratch.');
287
330
  lines.push(`- Winter packaged skills: ${path.relative(this.projectPath, paths.winter.skills)}`);
@@ -297,6 +340,13 @@ export class ContextLoader {
297
340
  if (brandNames.length > 0) {
298
341
  lines.push(`- Available design-md examples include: ${brandNames.join(', ')}${designBrands.length > brandNames.length ? ', ...' : ''}`);
299
342
  }
343
+ const hermesFamilies = hermesSkillFamilies
344
+ .filter(item => item.isDirectory)
345
+ .map(item => item.name)
346
+ .slice(0, 12);
347
+ if (hermesFamilies.length > 0) {
348
+ lines.push(`- Hermes core skill families include: ${hermesFamilies.join(', ')}${hermesSkillFamilies.length > hermesFamilies.length ? ', ...' : ''}`);
349
+ }
300
350
 
301
351
  const evidence = [];
302
352
  if (/Think Before Coding|Simplicity First|Surgical Changes|Goal-Driven Execution/i.test(karpathy)) {
@@ -314,6 +364,12 @@ export class ContextLoader {
314
364
  if (/Monorepo|PageAgentCore|PageController|DOM Pipeline|FlatDomTree/i.test(pageAgentAgents)) {
315
365
  evidence.push('page-agent AGENTS.md confirms monorepo structure, DOM pipeline, and tool architecture.');
316
366
  }
367
+ if (/gsap-core|gsap-scrolltrigger|gsap-react|ScrollTrigger|timeline/i.test(`${gsapReadme}\n${gsapIndex}`)) {
368
+ evidence.push('gsap-skills confirms core GSAP, timelines, ScrollTrigger, framework, plugin, and performance guidance.');
369
+ }
370
+ if (/self-improving|learning loop|subagents|TUI|gateway|Skill|MCP|cron|scheduled/i.test(`${hermesReadme}\n${hermesAgents}\n${hermesRoutines}`)) {
371
+ evidence.push('hermes-agent-core confirms self-improving agent loops, skills, memory/search, subagents, tool gateways, TUI separation, and automation routines.');
372
+ }
317
373
  if (/Read code to understand|Read relevant project files|Verify|automatic tool usage/i.test(winterCodingSkill)) {
318
374
  evidence.push('packaged coding skill confirms inspect-before-edit and verify-after-change behavior.');
319
375
  }
@@ -333,26 +389,192 @@ export class ContextLoader {
333
389
  return lines.join('\n');
334
390
  }
335
391
 
392
+ async getResourceApplicationProfile({ projectInstructionFiles = [] } = {}) {
393
+ const paths = this.getResourcePaths();
394
+ const userPaths = this.getUserResourcePaths();
395
+ const [
396
+ karpathy,
397
+ agents,
398
+ pageAgent,
399
+ pageAgentAgents,
400
+ hermesAgents,
401
+ hermesReadme,
402
+ hermesRoutines,
403
+ gsapIndex,
404
+ gsapReadme,
405
+ eccReadme,
406
+ codexGuide,
407
+ claudeGuide,
408
+ codexRules,
409
+ codexSkills,
410
+ claudeSkills,
411
+ designBrands,
412
+ winterSkills,
413
+ winterMemories,
414
+ userCodexSkills,
415
+ userCodexRules,
416
+ userCodexMemories,
417
+ userClaudeSkills,
418
+ ] = await Promise.all([
419
+ this.readTextIfExists(path.join(paths.karpathy, 'CLAUDE.md'), 1400),
420
+ this.readTextIfExists(path.join(paths.agents, 'AGENTS.md'), 1400),
421
+ this.readFirstExisting(paths.pageAgent, ['WINTER.md', 'README.md'], 1400),
422
+ this.readTextIfExists(path.join(paths.pageAgent, 'AGENTS.md'), 1400),
423
+ this.readTextIfExists(paths.hermesAgentCoreAgents, 1600),
424
+ this.readTextIfExists(path.join(paths.hermesAgentCore, 'README.md'), 1400),
425
+ this.readTextIfExists(path.join(paths.hermesAgentCore, 'hermes-already-has-routines.md'), 1200),
426
+ this.readTextIfExists(paths.gsapSkillsIndex, 1600),
427
+ this.readTextIfExists(path.join(paths.gsapSkills, 'README.md'), 1200),
428
+ this.readTextIfExists(paths.eccReadme, 1200),
429
+ this.readFirstExisting(paths.codex.root, ['AGENTS.md', 'README.md', 'CLAUDE.md'], 1400),
430
+ this.readFirstExisting(paths.claude.root, ['AGENTS.md', 'README.md', 'CLAUDE.md'], 1400),
431
+ this.listPathEntries(paths.codex.rules, 40),
432
+ this.listPathEntries(paths.codex.skills, 40),
433
+ this.listPathEntries(paths.claude.skills, 40),
434
+ this.listPathEntries(paths.designs, 40),
435
+ this.listPathEntries(paths.winter.skills, 40),
436
+ this.listPathEntries(paths.winter.memories, 40),
437
+ this.listPathEntries(userPaths.codexSkills, 40),
438
+ this.listPathEntries(userPaths.codexRules, 40),
439
+ this.listPathEntries(userPaths.codexMemories, 40),
440
+ this.listPathEntries(userPaths.claudeSkills, 40),
441
+ ]);
442
+
443
+ const lines = [];
444
+ lines.push('[Auto-loaded Resource Application Profile]');
445
+ lines.push('- Winter must apply this profile automatically before task work. It is not optional and does not require a slash command.');
446
+ lines.push('- Default agent loop: read project rules + relevant resource profile -> inspect project state -> use tools -> verify -> final.');
447
+ lines.push('- If a task touches any listed domain, inspect the matching resource file in depth with Read/Grep before implementation.');
448
+
449
+ const projectRules = (projectInstructionFiles || [])
450
+ .map(file => `${file.relativePath}: ${this.compactText(String(file.content || '').replace(/\s+/g, ' ').trim(), 360, file.relativePath)}`)
451
+ .filter(Boolean);
452
+ if (projectRules.length > 0) {
453
+ lines.push('Project rules loaded:');
454
+ projectRules.slice(0, 8).forEach(rule => lines.push(`- ${rule}`));
455
+ }
456
+
457
+ const addSection = (name, apply, evidence, sourcePath = '') => {
458
+ lines.push(`${name}:`);
459
+ lines.push(`- Apply: ${apply}`);
460
+ if (sourcePath) lines.push(`- Source: ${sourcePath}`);
461
+ if (evidence) lines.push(`- Loaded evidence: ${this.compactText(evidence.replace(/\s+/g, ' ').trim(), 520, name)}`);
462
+ };
463
+
464
+ addSection(
465
+ 'karpathy-tools',
466
+ 'coding discipline, simplicity, surgical edits, verification criteria, and anti-overengineering.',
467
+ karpathy,
468
+ path.join(paths.karpathy, 'CLAUDE.md')
469
+ );
470
+ addSection(
471
+ 'agents.md',
472
+ 'agentic development workflow, dependency hygiene, project conventions, and repo-specific agent rules.',
473
+ agents,
474
+ path.join(paths.agents, 'AGENTS.md')
475
+ );
476
+ addSection(
477
+ 'page-agent',
478
+ 'visible/browser-like GUI automation, DOM reasoning, form workflows, multi-page interaction, and web agent tasks.',
479
+ `${pageAgent.content}\n${pageAgentAgents}`,
480
+ pageAgent.filePath || path.join(paths.pageAgent, 'README.md')
481
+ );
482
+ addSection(
483
+ 'hermes-agent-core',
484
+ 'self-improving loops, skill lifecycle, memory/search compression, subagents, TUI separation, tool gateways, and automation routines.',
485
+ `${hermesAgents}\n${hermesReadme}\n${hermesRoutines}`,
486
+ paths.hermesAgentCore
487
+ );
488
+ addSection(
489
+ 'gsap-skills',
490
+ 'GSAP animation, timelines, ScrollTrigger, framework bindings, SVG/motion-path work, and animation performance.',
491
+ `${gsapIndex}\n${gsapReadme}`,
492
+ paths.gsapSkills
493
+ );
494
+ addSection(
495
+ 'ecc',
496
+ 'ECC knowledge/resource browsing and bundled ecosystem context when a task references ECC or encoded/corpus resources.',
497
+ eccReadme,
498
+ paths.ecc
499
+ );
500
+ addSection(
501
+ 'codex',
502
+ 'Codex-style skills, plugins, rules, memories, provider/tool reliability, and coding-agent behavior.',
503
+ codexGuide.content,
504
+ paths.codex.root
505
+ );
506
+ addSection(
507
+ 'claude',
508
+ 'Claude-style skills, plugins, project rules, subagent conventions, hooks, and MCP workflows.',
509
+ claudeGuide.content,
510
+ paths.claude.root
511
+ );
512
+ addSection(
513
+ 'awesome-design-md',
514
+ 'brand/design/UI work. Search design-md before inventing visual direction; use the closest matching design guide.',
515
+ designBrands.length ? `Design libraries available: ${designBrands.filter(item => item.isDirectory).slice(0, 24).map(item => item.name).join(', ')}` : '',
516
+ paths.designs
517
+ );
518
+ addSection(
519
+ 'winter packaged skills and memories',
520
+ 'baseline coding/debug/test/memory behavior that survives global installs and external project roots.',
521
+ [
522
+ winterSkills.length ? `Skills: ${winterSkills.slice(0, 24).map(item => item.name).join(', ')}` : '',
523
+ winterMemories.length ? `Memories: ${winterMemories.slice(0, 16).map(item => item.name).join(', ')}` : '',
524
+ ].filter(Boolean).join(' '),
525
+ paths.winter.root
526
+ );
527
+
528
+ const catalogLines = [];
529
+ if (codexRules.length > 0) catalogLines.push(`Codex rules: ${codexRules.slice(0, 16).map(item => item.name).join(', ')}`);
530
+ if (codexSkills.length > 0) catalogLines.push(`Codex skills: ${codexSkills.slice(0, 16).map(item => item.name).join(', ')}`);
531
+ if (claudeSkills.length > 0) catalogLines.push(`Claude skills: ${claudeSkills.slice(0, 16).map(item => item.name).join(', ')}`);
532
+ if (userCodexSkills.length > 0) catalogLines.push(`Home Codex skills: ${userCodexSkills.slice(0, 16).map(item => item.name).join(', ')}`);
533
+ if (userCodexRules.length > 0) catalogLines.push(`Home Codex rules: ${userCodexRules.slice(0, 16).map(item => item.name).join(', ')}`);
534
+ if (userCodexMemories.length > 0) catalogLines.push(`Home Codex memories: ${userCodexMemories.slice(0, 16).map(item => item.name).join(', ')}`);
535
+ if (userClaudeSkills.length > 0) catalogLines.push(`Home Claude skills: ${userClaudeSkills.slice(0, 16).map(item => item.name).join(', ')}`);
536
+ if (catalogLines.length > 0) {
537
+ lines.push('Discovered rule/skill/memory catalogs:');
538
+ catalogLines.forEach(item => lines.push(`- ${item}`));
539
+ }
540
+
541
+ return lines.join('\n');
542
+ }
543
+
336
544
  async getProjectSignals() {
337
545
  const signals = [];
546
+ const addSignal = (value) => {
547
+ const raw = String(value || '').toLowerCase();
548
+ if (!raw) return;
549
+ signals.push(raw);
550
+ for (const part of raw.split(/[^a-z0-9.+#-]+/i).filter(Boolean)) {
551
+ signals.push(part);
552
+ }
553
+ for (const part of raw.split(/[^a-z0-9]+/i).filter(Boolean)) {
554
+ signals.push(part);
555
+ }
556
+ };
338
557
 
339
558
  try {
340
559
  const packageJsonPath = path.join(this.projectPath, 'package.json');
341
560
  const raw = await fs.readFile(packageJsonPath, 'utf8');
342
561
  const pkg = JSON.parse(raw);
343
562
 
344
- signals.push(String(pkg.name || '').toLowerCase());
345
- signals.push(String(pkg.description || '').toLowerCase());
563
+ addSignal(pkg.name);
564
+ addSignal(pkg.description);
565
+ for (const keyword of pkg.keywords || []) {
566
+ addSignal(keyword);
567
+ }
346
568
 
347
569
  for (const key of ['dependencies', 'devDependencies', 'peerDependencies']) {
348
570
  const deps = pkg[key] || {};
349
571
  for (const depName of Object.keys(deps)) {
350
- signals.push(depName.toLowerCase());
572
+ addSignal(depName);
351
573
  }
352
574
  }
353
575
 
354
576
  for (const script of Object.values(pkg.scripts || {})) {
355
- signals.push(String(script).toLowerCase());
577
+ addSignal(script);
356
578
  }
357
579
  } catch {
358
580
  // Ignore package.json parsing issues.
@@ -362,8 +584,8 @@ export class ContextLoader {
362
584
  const entries = await fs.readdir(this.projectPath, { withFileTypes: true });
363
585
  for (const entry of entries) {
364
586
  if (!entry.isFile()) continue;
365
- signals.push(path.extname(entry.name).toLowerCase().slice(1));
366
- signals.push(entry.name.toLowerCase());
587
+ addSignal(path.extname(entry.name).toLowerCase().slice(1));
588
+ addSignal(entry.name);
367
589
  }
368
590
  } catch {
369
591
  // Ignore directory scan issues.
@@ -376,12 +598,23 @@ export class ContextLoader {
376
598
  const catalog = new Set(['coding', 'design', 'debug', 'refactor', 'test', 'security', 'performance']);
377
599
  const resourcePaths = this.getResourcePaths();
378
600
  const userPaths = this.getUserResourcePaths();
379
- const folders = [resourcePaths.winter.skills, resourcePaths.claude.skills, resourcePaths.codex.skills, userPaths.claudeSkills, userPaths.codexSkills];
601
+ const folders = [
602
+ resourcePaths.winter.skills,
603
+ resourcePaths.claude.skills,
604
+ resourcePaths.codex.skills,
605
+ path.join(resourcePaths.gsapSkills, 'skills'),
606
+ path.join(resourcePaths.hermesAgentCoreSkills, 'software-development'),
607
+ path.join(resourcePaths.hermesAgentCoreSkills, 'autonomous-ai-agents'),
608
+ path.join(resourcePaths.hermesAgentCoreSkills, 'mcp'),
609
+ path.join(resourcePaths.hermesAgentCoreSkills, 'github'),
610
+ userPaths.claudeSkills,
611
+ userPaths.codexSkills,
612
+ ];
380
613
 
381
614
  for (const folder of folders) {
382
615
  const entries = await this.listPathEntries(folder, 200);
383
616
  for (const entry of entries) {
384
- catalog.add(entry.name);
617
+ catalog.add(entry.name.replace(/\.md$/i, ''));
385
618
  }
386
619
  }
387
620
 
@@ -406,6 +639,11 @@ export class ContextLoader {
406
639
 
407
640
  if (hasAny('claude', 'agent', 'mcp', 'plugin', 'skill', 'automation', 'workflow')) {
408
641
  ['skill-creator', 'claude-automation-recommender', 'claude-md-improver', 'agent-development', 'hook-development', 'command-development', 'plugin-dev'].forEach(skill => activeSkills.add(skill));
642
+ ['hermes-agent', 'subagent-driven-development', 'native-mcp', 'hermes-agent-skill-authoring'].forEach(skill => activeSkills.add(skill));
643
+ }
644
+
645
+ if (hasAny('tui', 'terminal', 'gateway', 'cron', 'schedule', 'webhook', 'memory', 'session', 'subagent')) {
646
+ ['hermes-agent', 'subagent-driven-development', 'systematic-debugging', 'test-driven-development'].forEach(skill => activeSkills.add(skill));
409
647
  }
410
648
 
411
649
  if (hasAny('docs', 'markdown', 'md', 'readme', 'documentation')) {
@@ -416,6 +654,12 @@ export class ContextLoader {
416
654
  ['vibefigma', 'web-design-guidelines'].forEach(skill => activeSkills.add(skill));
417
655
  }
418
656
 
657
+ if (hasAny('gsap', 'animation', 'animate', 'motion', 'scrolltrigger', 'scroll-trigger', 'greensock')) {
658
+ ['gsap', 'gsap-core', 'gsap-timeline', 'gsap-scrolltrigger', 'gsap-performance'].forEach(skill => activeSkills.add(skill));
659
+ if (hasAny('react', 'next', 'nextjs', 'tsx', 'jsx')) activeSkills.add('gsap-react');
660
+ if (hasAny('vue', 'svelte', 'nuxt', 'sveltekit')) activeSkills.add('gsap-frameworks');
661
+ }
662
+
419
663
  const filtered = [...activeSkills].filter(skill => catalog.has(skill));
420
664
  return {
421
665
  availableSkills: [...catalog],
@@ -93,6 +93,11 @@ export function formatToolResultForConsole(toolName, result) {
93
93
  return `Fetched ${result.url} (${result.length} chars)`;
94
94
  case 'WebSearch':
95
95
  return `Found ${result.count} result(s)`;
96
+ case 'Agent':
97
+ case 'DelegateTask':
98
+ return `${result.status || 'completed'} ${result.agentId || ''}: ${result.summary || result.finalContent || ''}`.trim();
99
+ case 'ParallelAgent':
100
+ return `${result.status || 'completed'} ${result.count || 0} agent(s): ${result.summary || ''}`.trim();
96
101
  default:
97
102
  return result.message || '';
98
103
  }
@@ -141,8 +141,16 @@ export class WinterInputController {
141
141
  if (repl._handlingDirectClipboardPaste || repl.readlineClosed || !repl.running) return false;
142
142
  repl._handlingDirectClipboardPaste = true;
143
143
  try {
144
- const image = await repl.getClipboardImage();
145
- if (!image) return false;
144
+ const payload = typeof repl.getClipboardPayload === 'function'
145
+ ? await repl.getClipboardPayload()
146
+ : { type: 'image', image: await repl.getClipboardImage() };
147
+ if (!payload) return false;
148
+
149
+ if (payload.type === 'text') {
150
+ return await this.handleClipboardText(payload.text);
151
+ }
152
+
153
+ if (!payload.image) return false;
146
154
 
147
155
  const prompt = (repl.rl?.line || '').trim() || 'Analyze this pasted clipboard image.';
148
156
  this.closeSlashMenu();
@@ -153,7 +161,7 @@ export class WinterInputController {
153
161
  repl.inputQueue = repl.inputQueue
154
162
  .then(async () => {
155
163
  repl.closeInputBox?.();
156
- await this.processPastedImageTask(prompt, image);
164
+ await this.processPastedImageTask(prompt, payload.image);
157
165
  })
158
166
  .catch((error) => {
159
167
  repl.closeInputBox?.();
@@ -166,6 +174,52 @@ export class WinterInputController {
166
174
  }
167
175
  }
168
176
 
177
+ async handleClipboardText(text = '') {
178
+ const repl = this.repl;
179
+ const normalized = repl.normalizePastedText ? repl.normalizePastedText(text) : String(text || '');
180
+ if (!normalized.trim()) return false;
181
+
182
+ const currentLine = String(repl.rl?.line || '');
183
+ const isLargeOrMultiline = /\r|\n/.test(normalized) || repl.shouldPersistPastedText?.(normalized);
184
+
185
+ if (!isLargeOrMultiline) {
186
+ repl.rl?.write?.(normalized);
187
+ return true;
188
+ }
189
+
190
+ this.closeSlashMenu();
191
+ repl.rl?.write?.(null, { ctrl: true, name: 'u' });
192
+
193
+ const combined = [currentLine, normalized].filter(value => String(value || '').trim()).join('\n').trim();
194
+ repl.inputQueue = repl.inputQueue
195
+ .then(async () => {
196
+ repl.closeInputBox?.();
197
+ await this.processPastedTextTask(combined);
198
+ })
199
+ .catch((error) => {
200
+ repl.closeInputBox?.();
201
+ console.log(`\n${colors.red}✖ Paste text error: ${error.message}${colors.reset}\n`);
202
+ if (repl.running && !repl.readlineClosed) repl.showInputPrompt?.();
203
+ });
204
+ return true;
205
+ }
206
+
207
+ async processPastedTextTask(text = '') {
208
+ const repl = this.repl;
209
+ const content = repl.normalizePastedText ? repl.normalizePastedText(text).trim() : String(text || '').trim();
210
+ if (!content) return;
211
+
212
+ if (repl.shouldPersistPastedText?.(content)) {
213
+ const paste = await repl.persistPastedText(content);
214
+ const reference = repl.formatPastedTextReference(paste);
215
+ console.log(`${colors.cyan}│ ${colors.dim}${reference}${colors.reset}`);
216
+ await repl.handleInput(reference);
217
+ return;
218
+ }
219
+
220
+ await repl.handleInput(content);
221
+ }
222
+
169
223
  async processPastedImageTask(prompt, image) {
170
224
  const repl = this.repl;
171
225
  repl.isProcessing = true;
@@ -195,14 +249,14 @@ export class WinterInputController {
195
249
  }
196
250
  if (repl.slashMenu.open && repl.slashMenu.line === line) return;
197
251
 
198
- repl.slashMenu = { open: true, line, items: matches, selected: 0, printedLines: repl.slashMenu?.printedLines || 0 };
252
+ repl.slashMenu = { open: true, line, items: matches, selected: 0, offset: 0, printedLines: repl.slashMenu?.printedLines || 0 };
199
253
  this.renderSlashMenu();
200
254
  }
201
255
 
202
256
  closeSlashMenu() {
203
257
  const repl = this.repl;
204
258
  this.clearSlashMenuRender();
205
- repl.slashMenu = { open: false, line: '', items: [], selected: 0, printedLines: 0 };
259
+ repl.slashMenu = { open: false, line: '', items: [], selected: 0, offset: 0, printedLines: 0 };
206
260
  }
207
261
 
208
262
  clearSlashMenuRender() {
@@ -242,9 +296,21 @@ export class WinterInputController {
242
296
  if (!repl.slashMenu.items.length) return;
243
297
  const count = repl.slashMenu.items.length;
244
298
  repl.slashMenu.selected = (repl.slashMenu.selected + delta + count) % count;
299
+ this.ensureSlashSelectionVisible();
245
300
  this.renderSlashMenu();
246
301
  }
247
302
 
303
+ ensureSlashSelectionVisible(maxDisplay = 7) {
304
+ const menu = this.repl.slashMenu;
305
+ if (!menu?.items?.length) return;
306
+ const selected = Math.max(0, Math.min(menu.selected || 0, menu.items.length - 1));
307
+ let offset = Math.max(0, Number(menu.offset || 0));
308
+ if (selected < offset) offset = selected;
309
+ if (selected >= offset + maxDisplay) offset = selected - maxDisplay + 1;
310
+ const maxOffset = Math.max(0, menu.items.length - maxDisplay);
311
+ menu.offset = Math.max(0, Math.min(offset, maxOffset));
312
+ }
313
+
248
314
  acceptSlashSelection() {
249
315
  const repl = this.repl;
250
316
  const item = repl.slashMenu.items[repl.slashMenu.selected];
@@ -268,20 +334,23 @@ export class WinterInputController {
268
334
  const matches = repl.slashMenu.items;
269
335
  if (!matches.length) return;
270
336
 
271
- const maxDisplay = 5;
272
- const displayedMatches = matches.slice(0, maxDisplay);
337
+ const maxDisplay = 7;
338
+ this.ensureSlashSelectionVisible(maxDisplay);
339
+ const offset = Math.max(0, Number(repl.slashMenu.offset || 0));
340
+ const displayedMatches = matches.slice(offset, offset + maxDisplay);
273
341
  const body = [
274
- `${colors.dim}Tab selects. Esc closes. Enter sends the current line.${colors.reset}`,
342
+ `${colors.dim}Tab selects. Esc closes. Enter sends the current line. Up/Down scroll.${colors.reset}`,
275
343
  '',
276
344
  ...displayedMatches.map((item, index) => {
277
345
  const usage = item.usage ? ` ${colors.dim}${item.usage}${colors.reset}` : '';
278
- const pointer = index === repl.slashMenu.selected ? `${colors.green}>${colors.reset}` : ' ';
346
+ const absoluteIndex = offset + index;
347
+ const pointer = absoluteIndex === repl.slashMenu.selected ? `${colors.green}>${colors.reset}` : ' ';
279
348
  return `${pointer} ${colors.cyan}${padVisible(item.cmd, 16)}${colors.reset} ${colors.dim}${item.desc}${colors.reset}${usage}`;
280
349
  }),
281
350
  ];
282
351
 
283
352
  if (matches.length > maxDisplay) {
284
- body.push(` ${colors.dim}... ${matches.length - maxDisplay} more. Keep typing to filter.${colors.reset}`);
353
+ body.push(` ${colors.dim}${offset + 1}-${Math.min(offset + maxDisplay, matches.length)} / ${matches.length}${colors.reset}`);
285
354
  }
286
355
 
287
356
  this.clearSlashMenuRender();