@easynet/agent-runtime 1.0.2 → 1.0.4

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 (205) hide show
  1. package/.github/workflows/ci.yml +9 -24
  2. package/.github/workflows/release.yml +38 -26
  3. package/agent-runtime/.github/workflows/ci.yml +69 -0
  4. package/agent-runtime/.github/workflows/release.yml +118 -0
  5. package/agent-runtime/.releaserc.cjs +26 -0
  6. package/agent-runtime/config/agent.deep.yaml +25 -0
  7. package/agent-runtime/config/agent.react.yaml +24 -0
  8. package/agent-runtime/example/basic-usage.ts +49 -0
  9. package/agent-runtime/package-lock.json +7740 -0
  10. package/agent-runtime/package.json +49 -0
  11. package/agent-runtime/pnpm-lock.yaml +3712 -0
  12. package/agent-runtime/scripts/resolve-deps.js +54 -0
  13. package/agent-runtime/src/agents/deep-agent.ts +165 -0
  14. package/agent-runtime/src/agents/react-agent.helpers.ts +227 -0
  15. package/agent-runtime/src/agents/react-agent.ts +584 -0
  16. package/{src → agent-runtime/src/agents}/sub-agent.ts +2 -2
  17. package/agent-runtime/src/cli/args.ts +15 -0
  18. package/agent-runtime/src/cli/event-listener.ts +162 -0
  19. package/agent-runtime/src/cli/interactive.ts +144 -0
  20. package/agent-runtime/src/cli/runtime.ts +31 -0
  21. package/agent-runtime/src/cli/spinner.ts +23 -0
  22. package/agent-runtime/src/cli/terminal-render.ts +322 -0
  23. package/agent-runtime/src/cli/types.ts +33 -0
  24. package/agent-runtime/src/cli.ts +134 -0
  25. package/agent-runtime/src/config/helpers.ts +179 -0
  26. package/agent-runtime/src/config/index.ts +245 -0
  27. package/agent-runtime/src/config/types.ts +62 -0
  28. package/agent-runtime/src/core/context.ts +266 -0
  29. package/agent-runtime/src/index.ts +55 -0
  30. package/agent-runtime/tsconfig.json +18 -0
  31. package/apps/imessagebot/README.md +38 -0
  32. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/README.md +33 -0
  33. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/package-lock.json +15257 -0
  34. package/apps/imessagebot/config/.agent/cache/easynet/agent-tool-buildin/0.0.45/package.json +55 -0
  35. package/apps/imessagebot/config/agents/deep/agent.yaml +31 -0
  36. package/apps/imessagebot/config/agents/react/agent.yaml +58 -0
  37. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/README.md +33 -0
  38. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/package-lock.json +15457 -0
  39. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.43/package.json +55 -0
  40. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/README.md +33 -0
  41. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/package-lock.json +15257 -0
  42. package/apps/imessagebot/config/agents/shared/.agent/cache/easynet/agent-tool-buildin/0.0.46/package.json +62 -0
  43. package/apps/imessagebot/config/agents/shared/memory.yaml +31 -0
  44. package/apps/imessagebot/config/agents/shared/model.yaml +23 -0
  45. package/apps/imessagebot/config/agents/shared/tool.yaml +13 -0
  46. package/apps/imessagebot/config/app.yaml +14 -0
  47. package/apps/imessagebot/package-lock.json +53695 -0
  48. package/apps/imessagebot/package.json +41 -0
  49. package/apps/imessagebot/pnpm-lock.yaml +1589 -0
  50. package/apps/imessagebot/scripts/resolve-deps.js +41 -0
  51. package/apps/imessagebot/scripts/test-llm.mjs +27 -0
  52. package/apps/imessagebot/scripts/validate-tools-config.mjs +174 -0
  53. package/apps/imessagebot/src/config.ts +76 -0
  54. package/apps/imessagebot/src/context.ts +35 -0
  55. package/apps/imessagebot/src/index.ts +17 -0
  56. package/apps/imessagebot/tsconfig.json +18 -0
  57. package/apps/itermbot/.github/workflows/ci.yml +61 -0
  58. package/apps/itermbot/.github/workflows/release.yml +80 -0
  59. package/apps/itermbot/.releaserc.cjs +26 -0
  60. package/apps/itermbot/README.md +82 -0
  61. package/apps/itermbot/config/app.yaml +29 -0
  62. package/apps/itermbot/config/tsconfig.json +18 -0
  63. package/apps/itermbot/macos_disk_usage_agent_plan.md +244 -0
  64. package/apps/itermbot/package-lock.json +53697 -0
  65. package/apps/itermbot/package.json +57 -0
  66. package/apps/itermbot/pnpm-lock.yaml +3966 -0
  67. package/apps/itermbot/scripts/patch-buildin-cache.sh +25 -0
  68. package/apps/itermbot/scripts/resolve-deps.js +41 -0
  69. package/apps/itermbot/scripts/test-llm.mjs +32 -0
  70. package/apps/itermbot/skills/command-explain-and-guard/SKILL.md +39 -0
  71. package/apps/itermbot/skills/command-explain-and-guard/handler.js +86 -0
  72. package/apps/itermbot/skills/disk-usage-investigate/SKILL.md +44 -0
  73. package/apps/itermbot/skills/disk-usage-investigate/handler.js +12 -0
  74. package/apps/itermbot/skills/gpu-ssh-monitor/SKILL.md +64 -0
  75. package/apps/itermbot/skills/repo-triage/SKILL.md +40 -0
  76. package/apps/itermbot/skills/repo-triage/handler.js +56 -0
  77. package/apps/itermbot/skills/test-failure-diagnose/SKILL.md +43 -0
  78. package/apps/itermbot/skills/test-failure-diagnose/handler.js +107 -0
  79. package/apps/itermbot/src/config.ts +95 -0
  80. package/apps/itermbot/src/context.ts +35 -0
  81. package/apps/itermbot/src/index.ts +223 -0
  82. package/apps/itermbot/src/iterm/session-hint.ts +40 -0
  83. package/apps/itermbot/src/iterm/target-routing.ts +419 -0
  84. package/apps/itermbot/src/startup/colors.ts +317 -0
  85. package/apps/itermbot/src/startup/diagnostics.ts +97 -0
  86. package/apps/itermbot/src/startup/ui.ts +141 -0
  87. package/config/agent.deep.yaml +25 -0
  88. package/config/agent.react.yaml +24 -0
  89. package/dist/agents/deep-agent.d.ts +37 -0
  90. package/dist/agents/deep-agent.d.ts.map +1 -0
  91. package/dist/agents/deep-agent.js +115 -0
  92. package/dist/agents/deep-agent.js.map +1 -0
  93. package/dist/agents/react-agent.d.ts +40 -0
  94. package/dist/agents/react-agent.d.ts.map +1 -0
  95. package/dist/agents/react-agent.helpers.d.ts +40 -0
  96. package/dist/agents/react-agent.helpers.d.ts.map +1 -0
  97. package/dist/agents/react-agent.helpers.js +196 -0
  98. package/dist/agents/react-agent.helpers.js.map +1 -0
  99. package/dist/agents/react-agent.js +400 -0
  100. package/dist/agents/react-agent.js.map +1 -0
  101. package/dist/agents/sub-agent.d.ts +34 -0
  102. package/dist/agents/sub-agent.d.ts.map +1 -0
  103. package/dist/agents/sub-agent.js +53 -0
  104. package/dist/agents/sub-agent.js.map +1 -0
  105. package/dist/cli/args.d.ts +8 -0
  106. package/dist/cli/args.d.ts.map +1 -0
  107. package/dist/cli/args.js +9 -0
  108. package/dist/cli/args.js.map +1 -0
  109. package/dist/cli/event-listener.d.ts +3 -0
  110. package/dist/cli/event-listener.d.ts.map +1 -0
  111. package/dist/cli/event-listener.js +131 -0
  112. package/dist/cli/event-listener.js.map +1 -0
  113. package/dist/cli/interactive.d.ts +4 -0
  114. package/dist/cli/interactive.d.ts.map +1 -0
  115. package/dist/cli/interactive.js +118 -0
  116. package/dist/cli/interactive.js.map +1 -0
  117. package/dist/cli/runtime.d.ts +8 -0
  118. package/dist/cli/runtime.d.ts.map +1 -0
  119. package/dist/cli/runtime.js +27 -0
  120. package/dist/cli/runtime.js.map +1 -0
  121. package/dist/cli/spinner.d.ts +2 -0
  122. package/dist/cli/spinner.d.ts.map +1 -0
  123. package/dist/cli/spinner.js +22 -0
  124. package/dist/cli/spinner.js.map +1 -0
  125. package/dist/cli/terminal-render.d.ts +7 -0
  126. package/dist/cli/terminal-render.d.ts.map +1 -0
  127. package/dist/cli/terminal-render.js +282 -0
  128. package/dist/cli/terminal-render.js.map +1 -0
  129. package/dist/cli/types.d.ts +29 -0
  130. package/dist/cli/types.d.ts.map +1 -0
  131. package/dist/cli/types.js +3 -0
  132. package/dist/cli/types.js.map +1 -0
  133. package/dist/cli.d.ts +4 -41
  134. package/dist/cli.d.ts.map +1 -1
  135. package/dist/cli.js +84 -588
  136. package/dist/cli.js.map +1 -1
  137. package/dist/config/helpers.d.ts +6 -0
  138. package/dist/config/helpers.d.ts.map +1 -0
  139. package/dist/config/helpers.js +164 -0
  140. package/dist/config/helpers.js.map +1 -0
  141. package/dist/config/index.d.ts +15 -0
  142. package/dist/config/index.d.ts.map +1 -0
  143. package/dist/config/index.js +160 -0
  144. package/dist/config/index.js.map +1 -0
  145. package/dist/config/types.d.ts +57 -0
  146. package/dist/config/types.d.ts.map +1 -0
  147. package/dist/config/types.js +2 -0
  148. package/dist/config/types.js.map +1 -0
  149. package/dist/context.d.ts +8 -69
  150. package/dist/context.d.ts.map +1 -1
  151. package/dist/context.js +44 -24
  152. package/dist/context.js.map +1 -1
  153. package/dist/core/context.d.ts +66 -0
  154. package/dist/core/context.d.ts.map +1 -0
  155. package/dist/core/context.js +149 -0
  156. package/dist/core/context.js.map +1 -0
  157. package/dist/deep-agent.d.ts +5 -2
  158. package/dist/deep-agent.d.ts.map +1 -1
  159. package/dist/deep-agent.js +44 -11
  160. package/dist/deep-agent.js.map +1 -1
  161. package/dist/index.d.ts +6 -6
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +6 -6
  164. package/dist/index.js.map +1 -1
  165. package/dist/middleware/malformed-tool-call-middleware.d.ts +8 -0
  166. package/dist/middleware/malformed-tool-call-middleware.d.ts.map +1 -0
  167. package/dist/middleware/malformed-tool-call-middleware.js +191 -0
  168. package/dist/middleware/malformed-tool-call-middleware.js.map +1 -0
  169. package/dist/react-agent.d.ts +2 -2
  170. package/dist/react-agent.d.ts.map +1 -1
  171. package/dist/react-agent.js +28 -9
  172. package/dist/react-agent.js.map +1 -1
  173. package/package.json +1 -1
  174. package/scripts/resolve-deps.js +54 -0
  175. package/src/agents/deep-agent.ts +165 -0
  176. package/src/agents/react-agent.helpers.ts +227 -0
  177. package/src/agents/react-agent.ts +584 -0
  178. package/src/agents/sub-agent.ts +82 -0
  179. package/src/cli/args.ts +15 -0
  180. package/src/cli/event-listener.ts +162 -0
  181. package/src/cli/interactive.ts +144 -0
  182. package/src/cli/runtime.ts +31 -0
  183. package/src/cli/spinner.ts +23 -0
  184. package/src/cli/terminal-render.ts +322 -0
  185. package/src/cli/types.ts +33 -0
  186. package/src/cli.ts +91 -702
  187. package/src/config/helpers.ts +179 -0
  188. package/src/config/index.ts +245 -0
  189. package/src/config/types.ts +62 -0
  190. package/src/core/context.ts +266 -0
  191. package/src/index.ts +13 -11
  192. package/src/middleware/malformed-tool-call-middleware.ts +239 -0
  193. package/src/types/markdown-it-terminal.d.ts +4 -0
  194. package/src/types/marked-terminal.d.ts +16 -0
  195. package/dist/config.d.ts +0 -86
  196. package/dist/config.d.ts.map +0 -1
  197. package/dist/config.js +0 -84
  198. package/dist/config.js.map +0 -1
  199. package/src/config.ts +0 -177
  200. package/src/context.ts +0 -247
  201. package/src/deep-agent.ts +0 -104
  202. package/src/react-agent.ts +0 -576
  203. /package/{src → agent-runtime/src/middleware}/malformed-tool-call-middleware.ts +0 -0
  204. /package/{src → agent-runtime/src/types}/markdown-it-terminal.d.ts +0 -0
  205. /package/{src → agent-runtime/src/types}/marked-terminal.d.ts +0 -0
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+ # Patch the runtime cache with the local agent-tool-buildin build.
3
+ # Run after `npm run build` in agent-tool-buildin to pick up local changes.
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ LOCAL_DIR="$SCRIPT_DIR/../../../agent-tool-buildin"
8
+ CACHE_BASE="$SCRIPT_DIR/../config/.agent/cache/easynet/agent-tool-buildin"
9
+
10
+ VERSION=$(node -e "console.log(require('$LOCAL_DIR/package.json').version)")
11
+ CACHE_DIR="$CACHE_BASE/$VERSION"
12
+
13
+ if [ ! -d "$CACHE_DIR/dist" ]; then
14
+ echo "Cache dir not found: $CACHE_DIR/dist"
15
+ echo "Run itermbot once first to populate the cache, then re-run this script."
16
+ exit 1
17
+ fi
18
+
19
+ cp "$LOCAL_DIR/dist/src/iterm/itermRunCommandInSession.js" "$CACHE_DIR/dist/src/iterm/"
20
+ cp "$LOCAL_DIR/dist/src/iterm/itermRunCommandInSession.d.ts" "$CACHE_DIR/dist/src/iterm/" 2>/dev/null || true
21
+ cp "$LOCAL_DIR/dist/src/iterm/common.js" "$CACHE_DIR/dist/src/iterm/"
22
+ cp "$LOCAL_DIR/dist/src/iterm/common.d.ts" "$CACHE_DIR/dist/src/iterm/" 2>/dev/null || true
23
+ cp "$LOCAL_DIR/dist/core-tools-manifest.json" "$CACHE_DIR/dist/"
24
+
25
+ echo "Patched cache at $CACHE_DIR with local build v$VERSION"
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * resolve-deps.js
4
+ *
5
+ * Run automatically via `preinstall` npm hook.
6
+ * In CI (CI=true), rewrites file: references in package.json to npm versions
7
+ * so that `npm install` can resolve them without local sibling directories.
8
+ *
9
+ * Local development: no-op (CI env var is not set).
10
+ */
11
+
12
+ import { readFileSync, writeFileSync } from 'fs';
13
+ import { resolve, dirname } from 'path';
14
+ import { fileURLToPath } from 'url';
15
+
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const pkgPath = resolve(__dirname, '..', 'package.json');
18
+
19
+ if (!process.env.CI) {
20
+ process.exit(0);
21
+ }
22
+
23
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
24
+ let changed = false;
25
+
26
+ for (const section of ['dependencies', 'devDependencies']) {
27
+ const deps = pkg[section];
28
+ if (!deps) continue;
29
+ for (const [name, version] of Object.entries(deps)) {
30
+ if (name.startsWith('@easynet/') && typeof version === 'string' && version.startsWith('file:')) {
31
+ deps[name] = 'latest';
32
+ changed = true;
33
+ console.log(`[resolve-deps] ${name}: file: → latest`);
34
+ }
35
+ }
36
+ }
37
+
38
+ if (changed) {
39
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
40
+ console.log('[resolve-deps] package.json updated for CI.');
41
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Quick LLM config test. Run from app root: npm run test:llm
3
+ */
4
+ import { createAgentLlm } from "@easynet/agent-model";
5
+ import { loadAppConfig, getModelsConfigPath } from "../dist/config.js";
6
+
7
+ async function main() {
8
+ try {
9
+ const appConfig = await loadAppConfig("config/app.yaml");
10
+ const agentNames = Object.keys(appConfig?.app?.agent ?? {});
11
+ const agentName = appConfig?.app?.defaultAgent ?? agentNames[0];
12
+ const modelPath = getModelsConfigPath(appConfig, agentName);
13
+ console.log(`[test-llm] Loading LLM from ${modelPath} ...`);
14
+ const llm = await createAgentLlm({
15
+ configPath: modelPath,
16
+ checkConnectivity: false,
17
+ });
18
+
19
+ console.log("[test-llm] Invoking LLM ...");
20
+ const res = await llm.invoke(
21
+ "In one sentence, introduce yourself and say you are being used to test iTermBot's LLM config."
22
+ );
23
+
24
+ console.log("[test-llm] Raw response:");
25
+ console.log(JSON.stringify(res, null, 2));
26
+ } catch (err) {
27
+ console.error("[test-llm] Error:", err);
28
+ process.exit(1);
29
+ }
30
+ }
31
+
32
+ main();
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: command-explain-and-guard
3
+ description: Explain shell command intent, assess risk, and suggest safer alternatives.
4
+ allowed-tools: exec.runCommand
5
+ metadata:
6
+ owner: itermbot
7
+ domain: safety
8
+ ---
9
+
10
+ # Command Explain And Guard
11
+
12
+ Use this skill before executing potentially risky shell commands.
13
+
14
+ ## Output
15
+
16
+ - command intent
17
+ - risk level (`low|medium|high|critical`)
18
+ - key risk reasons
19
+ - safe alternative command
20
+
21
+ ## Risk policy
22
+
23
+ - destructive delete (`rm -rf`, `find ... -delete`) => critical
24
+ - force push/history rewrite => high
25
+ - broad recursive changes => high
26
+ - read-only inspection commands => low
27
+
28
+ ## Input contract
29
+
30
+ - `command`: shell command string.
31
+
32
+ ## Output contract
33
+
34
+ Return:
35
+
36
+ - `intent`
37
+ - `riskLevel`
38
+ - `reasons[]`
39
+ - `safeAlternative`
@@ -0,0 +1,86 @@
1
+ function normalize(command) {
2
+ return String(command || "").trim();
3
+ }
4
+
5
+ function assessRisk(command) {
6
+ const c = command.toLowerCase();
7
+
8
+ if (!c) {
9
+ return {
10
+ intent: "No command provided.",
11
+ riskLevel: "medium",
12
+ reasons: ["Empty command cannot be assessed reliably."],
13
+ safeAlternative: "echo \"No command to execute\"",
14
+ };
15
+ }
16
+
17
+ if (/\brm\s+-rf\b|\bfind\b.*\b-delete\b|\bdd\s+if=/.test(c)) {
18
+ return {
19
+ intent: "Destructive filesystem operation.",
20
+ riskLevel: "critical",
21
+ reasons: [
22
+ "Can irreversibly delete files or overwrite data.",
23
+ "Scope may be broader than intended.",
24
+ ],
25
+ safeAlternative: "ls -la <target> && rm -ri <target>",
26
+ };
27
+ }
28
+
29
+ if (/\bgit\s+push\b.*\s--force\b|\bgit\s+reset\s+--hard\b|\bgit\s+clean\s+-fd\b/.test(c)) {
30
+ return {
31
+ intent: "History rewrite or aggressive workspace cleanup.",
32
+ riskLevel: "high",
33
+ reasons: [
34
+ "Can discard local commits or untracked work.",
35
+ "Hard to recover without backups/reflog.",
36
+ ],
37
+ safeAlternative: "git status && git stash push -u && git branch backup/<name>",
38
+ };
39
+ }
40
+
41
+ if (/\b(chmod|chown)\b.*\s-r\b|\bsed\s+-i\b|\bperl\s+-pi\b/.test(c)) {
42
+ return {
43
+ intent: "Recursive or in-place bulk modification.",
44
+ riskLevel: "high",
45
+ reasons: [
46
+ "May modify many files unintentionally.",
47
+ "Rollback is difficult without VCS checkpoints.",
48
+ ],
49
+ safeAlternative: "Preview targets first, then apply on a small subset.",
50
+ };
51
+ }
52
+
53
+ if (/\b(cat|ls|pwd|echo|head|tail|grep|rg|git\s+status|git\s+log)\b/.test(c)) {
54
+ return {
55
+ intent: "Read-only inspection command.",
56
+ riskLevel: "low",
57
+ reasons: ["Does not directly modify files or history."],
58
+ safeAlternative: command,
59
+ };
60
+ }
61
+
62
+ return {
63
+ intent: "General command execution.",
64
+ riskLevel: "medium",
65
+ reasons: [
66
+ "Side effects are unclear from command alone.",
67
+ "Validate scope and target before execution.",
68
+ ],
69
+ safeAlternative: "echo \"Dry-run first\" && <command>",
70
+ };
71
+ }
72
+
73
+ export default async function handler(args) {
74
+ const command = normalize(args?.command);
75
+ const assessed = assessRisk(command);
76
+
77
+ return {
78
+ result: {
79
+ command,
80
+ intent: assessed.intent,
81
+ riskLevel: assessed.riskLevel,
82
+ reasons: assessed.reasons,
83
+ safeAlternative: assessed.safeAlternative,
84
+ },
85
+ };
86
+ }
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: disk-usage-investigate
3
+ description: Investigate macOS disk space usage — find the largest directories and suggest cleanup.
4
+ metadata:
5
+ owner: itermbot
6
+ domain: diagnostics
7
+ ---
8
+
9
+ # Disk Usage Investigation (macOS)
10
+
11
+ Call this skill when the user asks about disk space, storage usage, or which directories are using the most space.
12
+
13
+ ## Strategy
14
+
15
+ ### 1. Global overview
16
+ - Run `df -h` to see which mount points are most full.
17
+ - Optionally run `diskutil list` / `diskutil apfs list` for APFS diagnostics.
18
+
19
+ ### 2. Top-level breakdown
20
+ - Run `du -xhd 1 /System/Volumes/Data 2>/dev/null | sort -h` for top-level directories.
21
+ - Drill one level deeper into the largest results (e.g. `Users`, `Library`).
22
+
23
+ ### 3. User home
24
+ - Use `du -hd 1 ~` to list child directories; focus only on the largest few (>20 GB).
25
+ - Stop drilling when the largest child is < ~5 GB.
26
+
27
+ ### 4. Common heavy hitters
28
+ Check these with `du`:
29
+ - `~/Downloads`, `~/Desktop`
30
+ - `~/Library/Application Support/MobileSync/Backup` (iOS backups)
31
+ - `~/Library/Mail`, `~/Library/Messages`, `~/Pictures`
32
+ - `~/Library/Caches`, `~/Library/Containers`
33
+ - `~/Library/Developer/Xcode`, `~/Library/Developer/CoreSimulator`, `~/Library/Developer/Xcode/DerivedData`
34
+ - `~/Library/Containers/com.docker.docker`
35
+ - `/opt/homebrew/Cellar`, `/opt/homebrew/Caskroom`, `~/Library/Caches/Homebrew`
36
+
37
+ ### 5. Time Machine snapshots
38
+ - `tmutil listlocalsnapshots /` for diagnostics only.
39
+ - Never run destructive cleanup automatically — summarize options and wait for user approval.
40
+
41
+ ### 6. Reporting
42
+ - Produce a structured summary: overall usage, top contributors by path/size, cleanup candidates with risk level.
43
+ - Focus on biggest contributors; avoid broad or deep recursive scans.
44
+ - Use `output` from each command to decide next steps — don't fire commands blindly.
@@ -0,0 +1,12 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { fileURLToPath } from "node:url";
3
+ import { dirname, join } from "node:path";
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+
7
+ export default async function handler() {
8
+ const md = await readFile(join(__dirname, "SKILL.md"), "utf-8");
9
+ // Strip YAML frontmatter, return only instructions body
10
+ const body = md.replace(/^---[\s\S]*?---\s*/, "").trim();
11
+ return { result: { instructions: body } };
12
+ }
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: gpu-ssh-monitor
3
+ description: Login to boqiang@ssh.easynet.world and monitor NVIDIA GPU status using nvidia-smi (watch mode preferred).
4
+ allowed-tools: itermRunCommandInSession
5
+ metadata:
6
+ owner: itermbot
7
+ domain: ops
8
+ ---
9
+
10
+ # GPU SSH Monitor
11
+
12
+ Use this skill when the user asks to check remote NVIDIA GPU status on `boqiang@ssh.easynet.world`.
13
+
14
+ ## Non-negotiable rules
15
+
16
+ - Run all commands in the iTerm target panel via `itermRunCommandInSession`.
17
+ - Do not use local machine commands for data collection.
18
+ - Show exact terminal evidence before summary.
19
+ - Do not run `nvidia-smi` before SSH context is confirmed on `ssh.easynet.world`.
20
+
21
+ ## Workflow
22
+
23
+ 1. Connect remote host:
24
+ - `ssh boqiang@ssh.easynet.world`
25
+ 2. Confirm remote context before any GPU command:
26
+ - `hostname && whoami`
27
+ - Must show remote host/user evidence consistent with `ssh.easynet.world` / `boqiang`.
28
+ - If still local shell, stop and ask user to complete SSH login in target panel.
29
+ 3. Verify GPU command availability:
30
+ - `nvidia-smi`
31
+ - If output contains `command not found` / `not recognized` / missing driver errors:
32
+ - Stop monitoring workflow immediately.
33
+ - Report only failure evidence from terminal output.
34
+ - Suggest next checks on remote host:
35
+ - `which nvidia-smi`
36
+ - `echo $PATH`
37
+ - `uname -a`
38
+ - `cat /etc/os-release`
39
+ - `ls -l /usr/bin/nvidia-smi /usr/local/bin/nvidia-smi 2>/dev/null`
40
+ - Do not report GPU model/memory/utilization fields when `nvidia-smi` is unavailable.
41
+ 4. Start live monitor:
42
+ - Preferred: `watch -n 1 nvidia-smi`
43
+ - Fallback when `watch` is unavailable:
44
+ - `while true; do clear; nvidia-smi; sleep 1; done`
45
+ 5. Stop monitor:
46
+ - `Ctrl+C`
47
+
48
+ ## Reporting format
49
+
50
+ - First show key terminal output in fenced `text` code blocks.
51
+ - Then provide a short summary:
52
+ - GPU count and model
53
+ - Memory usage per GPU
54
+ - GPU utilization and temperature
55
+ - Any obvious anomaly (e.g. 0 MiB but high util, ECC/Xid errors)
56
+ - If `nvidia-smi` failed, summary must only contain:
57
+ - failure reason from output,
58
+ - one concrete next command,
59
+ - no unrelated environment/file observations.
60
+
61
+ ## Notes
62
+
63
+ - If SSH prompts for host key confirmation, proceed with user confirmation.
64
+ - If password or MFA is required, ask user to complete it in the target panel.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: repo-triage
3
+ description: Triage a repository task and produce entry points, risks, and an execution checklist.
4
+ allowed-tools: fs.listDir, fs.readText, fs.searchText, git.status, git.diff
5
+ metadata:
6
+ owner: itermbot
7
+ domain: engineering
8
+ ---
9
+
10
+ # Repo Triage
11
+
12
+ Use this skill when a user asks for a code change and you need a practical first pass.
13
+
14
+ ## What to produce
15
+
16
+ 1. A short plan summary tied to the user goal.
17
+ 2. Likely entry files to inspect first.
18
+ 3. Main risks and assumptions.
19
+ 4. A concrete execution checklist.
20
+
21
+ ## Guardrails
22
+
23
+ - Do not claim certainty if you only have partial repo data.
24
+ - Prefer high-signal files: app entry, router, service layer, tests, config.
25
+ - Explicitly call out missing tests as a risk.
26
+
27
+ ## Input contract
28
+
29
+ - `goal`: user objective in one sentence.
30
+ - `scopePath`: module or directory scope.
31
+ - `changedFiles` (optional): known touched files.
32
+
33
+ ## Output contract
34
+
35
+ Return:
36
+
37
+ - `summary`
38
+ - `entryFiles[]`
39
+ - `risks[]`
40
+ - `checklist[]`
@@ -0,0 +1,56 @@
1
+ const ENTRY_HINTS = [
2
+ /app\.(ts|tsx|js|mjs)$/i,
3
+ /main\.(ts|tsx|js|mjs)$/i,
4
+ /index\.(ts|tsx|js|mjs)$/i,
5
+ /router\.(ts|tsx|js|mjs)$/i,
6
+ /config\.(ts|tsx|js|mjs|yaml|yml|json)$/i,
7
+ /service/i,
8
+ /controller/i,
9
+ /test|spec/i,
10
+ ];
11
+
12
+ function uniq(list) {
13
+ return Array.from(new Set(list.filter(Boolean)));
14
+ }
15
+
16
+ function pickEntryFiles(changedFiles) {
17
+ const files = Array.isArray(changedFiles) ? changedFiles : [];
18
+ if (files.length === 0) return [];
19
+ const prioritized = files.filter((f) => ENTRY_HINTS.some((re) => re.test(String(f))));
20
+ return uniq((prioritized.length > 0 ? prioritized : files).slice(0, 8));
21
+ }
22
+
23
+ export default async function handler(args) {
24
+ const goal = typeof args?.goal === "string" ? args.goal.trim() : "";
25
+ const scopePath = typeof args?.scopePath === "string" ? args.scopePath.trim() : ".";
26
+ const changedFiles = Array.isArray(args?.changedFiles) ? args.changedFiles.map(String) : [];
27
+
28
+ const entryFiles = pickEntryFiles(changedFiles);
29
+
30
+ const risks = [
31
+ "Behavior regression in adjacent modules not listed in changedFiles.",
32
+ "Missing or stale tests for the modified path.",
33
+ "Config drift between development and production environments.",
34
+ ];
35
+
36
+ const checklist = [
37
+ `Clarify acceptance criteria for: ${goal || "target change"}.`,
38
+ `Inspect ${scopePath} for entrypoint and dependency boundaries.`,
39
+ "Implement minimal change set before refactor.",
40
+ "Run focused tests and one end-to-end sanity check.",
41
+ "Document tradeoffs and any known limitations.",
42
+ ];
43
+
44
+ const summary = goal
45
+ ? `Triage for goal \"${goal}\" under \"${scopePath}\" with a low-risk execution path.`
46
+ : `Triage for scope \"${scopePath}\" with a low-risk execution path.`;
47
+
48
+ return {
49
+ result: {
50
+ summary,
51
+ entryFiles,
52
+ risks,
53
+ checklist,
54
+ },
55
+ };
56
+ }
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: test-failure-diagnose
3
+ description: Diagnose failing tests and generate root cause, confidence, and fix plan.
4
+ allowed-tools: fs.readText, fs.searchText, exec.runCommand
5
+ metadata:
6
+ owner: itermbot
7
+ domain: testing
8
+ ---
9
+
10
+ # Test Failure Diagnose
11
+
12
+ Use this skill for red CI or local failing tests.
13
+
14
+ ## Goals
15
+
16
+ 1. Classify failure type quickly.
17
+ 2. Propose the smallest plausible fix.
18
+ 3. Provide verification steps.
19
+
20
+ ## Classification buckets
21
+
22
+ - dependency/setup
23
+ - type/lint
24
+ - assertion mismatch
25
+ - snapshot drift
26
+ - timeout/flaky
27
+ - unknown
28
+
29
+ ## Input contract
30
+
31
+ - `testCommand`: command used to run tests.
32
+ - `logText`: failing output text.
33
+ - `failingTests` (optional): list of failing test names.
34
+
35
+ ## Output contract
36
+
37
+ Return:
38
+
39
+ - `rootCause`
40
+ - `category`
41
+ - `confidence` (0-1)
42
+ - `fixPlan[]`
43
+ - `verification[]`
@@ -0,0 +1,107 @@
1
+ function has(text, re) {
2
+ return re.test(text);
3
+ }
4
+
5
+ function classify(logText) {
6
+ const t = logText.toLowerCase();
7
+
8
+ if (has(t, /cannot find module|module not found|enoent|missing script|not installed/)) {
9
+ return {
10
+ category: "dependency/setup",
11
+ rootCause: "Dependency or test runtime setup is missing or misconfigured.",
12
+ confidence: 0.87,
13
+ fixPlan: [
14
+ "Verify lockfile and reinstall dependencies in a clean environment.",
15
+ "Check test config paths and required env vars.",
16
+ "Re-run only the failing suite to confirm setup issue is resolved.",
17
+ ],
18
+ };
19
+ }
20
+
21
+ if (has(t, /ts\d{4}|typescript error|type .* is not assignable|eslint|prettier/)) {
22
+ return {
23
+ category: "type/lint",
24
+ rootCause: "Type checking or lint rule violation blocks test run.",
25
+ confidence: 0.84,
26
+ fixPlan: [
27
+ "Fix the first reported type/lint error instead of bulk-editing.",
28
+ "Re-run typecheck/lint target before full test run.",
29
+ "Add a regression test if the fix changes behavior.",
30
+ ],
31
+ };
32
+ }
33
+
34
+ if (has(t, /expected:|received:|toequal|tobe|assertionerror/)) {
35
+ return {
36
+ category: "assertion mismatch",
37
+ rootCause: "Implementation output no longer matches test expectations.",
38
+ confidence: 0.8,
39
+ fixPlan: [
40
+ "Inspect the failing assertion and compare old vs new behavior.",
41
+ "Fix implementation if behavior regressed; otherwise update test expectations intentionally.",
42
+ "Re-run nearby tests for related behavior.",
43
+ ],
44
+ };
45
+ }
46
+
47
+ if (has(t, /snapshot|does not match stored snapshot|obsolete snapshot/)) {
48
+ return {
49
+ category: "snapshot drift",
50
+ rootCause: "Snapshot output drifted from committed baseline.",
51
+ confidence: 0.9,
52
+ fixPlan: [
53
+ "Review snapshot diff for unintended output changes.",
54
+ "Update snapshot only after confirming behavior is expected.",
55
+ "Add assertion-based checks for critical fields to reduce snapshot brittleness.",
56
+ ],
57
+ };
58
+ }
59
+
60
+ if (has(t, /timed out|timeout|jest did not exit|flaky|retry/)) {
61
+ return {
62
+ category: "timeout/flaky",
63
+ rootCause: "Async timing or resource contention causes unstable test completion.",
64
+ confidence: 0.73,
65
+ fixPlan: [
66
+ "Identify unresolved async handles and await all background work.",
67
+ "Stabilize time/network dependencies with mocks.",
68
+ "Run the failing test repeatedly to verify flake reduction.",
69
+ ],
70
+ };
71
+ }
72
+
73
+ return {
74
+ category: "unknown",
75
+ rootCause: "Unable to classify failure from current logs.",
76
+ confidence: 0.4,
77
+ fixPlan: [
78
+ "Capture complete failing logs with verbose mode.",
79
+ "Narrow down to one failing test and isolate minimal reproduction.",
80
+ "Inspect recent diffs affecting test setup or core logic.",
81
+ ],
82
+ };
83
+ }
84
+
85
+ export default async function handler(args) {
86
+ const testCommand = typeof args?.testCommand === "string" ? args.testCommand : "";
87
+ const logText = typeof args?.logText === "string" ? args.logText : "";
88
+ const failingTests = Array.isArray(args?.failingTests) ? args.failingTests.map(String) : [];
89
+
90
+ const diagnosis = classify(logText);
91
+
92
+ return {
93
+ result: {
94
+ testCommand,
95
+ failingTests,
96
+ category: diagnosis.category,
97
+ rootCause: diagnosis.rootCause,
98
+ confidence: diagnosis.confidence,
99
+ fixPlan: diagnosis.fixPlan,
100
+ verification: [
101
+ "Run the previously failing test file in isolation.",
102
+ "Run related suite and one full project test run.",
103
+ "Ensure CI environment reproduces the same pass state.",
104
+ ],
105
+ },
106
+ };
107
+ }
@@ -0,0 +1,95 @@
1
+ import { asObject, resolveKindResourceFile } from "@easynet/agent-common";
2
+ import {
3
+ createRuntimeConfig,
4
+ getModelsConfigPath as getRuntimeModelsConfigPath,
5
+ getMemoryConfigPath as getRuntimeMemoryConfigPath,
6
+ getToolConfigPath as getRuntimeToolConfigPath,
7
+ resolveDefaultAgentName as resolveRuntimeDefaultAgentName,
8
+ type AgentRuntimeConfig,
9
+ } from "@easynet/agent-runtime";
10
+
11
+ type PromptTemplates = {
12
+ itermPolicy?: string;
13
+ targetSession?: string;
14
+ };
15
+
16
+ type ItermAppSpec = {
17
+ agent?: string;
18
+ printSteps?: boolean;
19
+ fallbackText?: string;
20
+ commandWindowLabel?: string;
21
+ promptTemplates?: PromptTemplates;
22
+ };
23
+
24
+ export type AppConfig = AgentRuntimeConfig & {
25
+ app?: (AgentRuntimeConfig["app"] & {
26
+ defaultAgent?: string;
27
+ printSteps?: boolean;
28
+ fallbackText?: string;
29
+ commandWindowLabel?: string;
30
+ promptTemplates?: PromptTemplates;
31
+ });
32
+ };
33
+
34
+ export interface AppConfigDefaults {
35
+ modelsPath?: string;
36
+ memoryPath?: string;
37
+ toolPath?: string;
38
+ toolDevPath?: string;
39
+ toolProdPath?: string;
40
+ }
41
+
42
+ export async function loadAppConfig(configPath?: string): Promise<AppConfig> {
43
+ const appResource = await resolveKindResourceFile<ItermAppSpec>(configPath ?? "config/app.yaml", {
44
+ baseDir: process.cwd(),
45
+ expectedApiVersion: "easynet.world/v1",
46
+ expectedKind: "AppConfig",
47
+ });
48
+ const spec = asObject(appResource.spec) as ItermAppSpec | undefined;
49
+ const runtimeConfig = await createRuntimeConfig({
50
+ configPath,
51
+ overrides: {
52
+ app: {
53
+ defaultAgent: spec?.agent,
54
+ printSteps: spec?.printSteps,
55
+ fallbackText: spec?.fallbackText,
56
+ commandWindowLabel: spec?.commandWindowLabel,
57
+ promptTemplates: spec?.promptTemplates,
58
+ },
59
+ },
60
+ });
61
+ const defaultAgent = resolveRuntimeDefaultAgentName(
62
+ runtimeConfig,
63
+ (runtimeConfig.app?.defaultAgent as string | undefined) ?? spec?.agent,
64
+ );
65
+ return {
66
+ app: {
67
+ ...runtimeConfig.app,
68
+ defaultAgent,
69
+ },
70
+ };
71
+ }
72
+
73
+ export function getModelsConfigPath(
74
+ config: AppConfig,
75
+ agentName?: string,
76
+ defaults?: AppConfigDefaults,
77
+ ): string {
78
+ return getRuntimeModelsConfigPath(config, agentName, defaults);
79
+ }
80
+
81
+ export function getMemoryConfigPath(
82
+ config: AppConfig,
83
+ agentName?: string,
84
+ defaults?: AppConfigDefaults,
85
+ ): string {
86
+ return getRuntimeMemoryConfigPath(config, agentName, defaults);
87
+ }
88
+
89
+ export function getToolConfigPath(
90
+ config: AppConfig,
91
+ agentName?: string,
92
+ defaults?: AppConfigDefaults,
93
+ ): string {
94
+ return getRuntimeToolConfigPath(config, agentName, defaults);
95
+ }