@poping/yome 0.0.2 → 0.0.3

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 (185) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +11 -0
  3. package/README.md +308 -27
  4. package/README.zh-CN.md +335 -0
  5. package/dist/agent.d.ts +24 -2
  6. package/dist/agent.js +34 -2
  7. package/dist/agent.js.map +1 -1
  8. package/dist/context.d.ts +2 -0
  9. package/dist/context.js +116 -11
  10. package/dist/context.js.map +1 -1
  11. package/dist/index.js +147 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/llm.js +45 -2
  14. package/dist/llm.js.map +1 -1
  15. package/dist/loops/chain.js +8 -0
  16. package/dist/loops/chain.js.map +1 -1
  17. package/dist/loops/evaluator.js +8 -0
  18. package/dist/loops/evaluator.js.map +1 -1
  19. package/dist/loops/orchestrator.js +8 -0
  20. package/dist/loops/orchestrator.js.map +1 -1
  21. package/dist/loops/parallel.js.map +1 -1
  22. package/dist/loops/route.js +8 -0
  23. package/dist/loops/route.js.map +1 -1
  24. package/dist/loops/simple.js +15 -0
  25. package/dist/loops/simple.js.map +1 -1
  26. package/dist/permissions/index.d.ts +1 -1
  27. package/dist/permissions/index.js +1 -1
  28. package/dist/permissions/index.js.map +1 -1
  29. package/dist/permissions/loader.d.ts +20 -1
  30. package/dist/permissions/loader.js +51 -0
  31. package/dist/permissions/loader.js.map +1 -1
  32. package/dist/redact.d.ts +56 -0
  33. package/dist/redact.js +191 -0
  34. package/dist/redact.js.map +1 -0
  35. package/dist/skills/runner/applescript.d.ts +49 -0
  36. package/dist/skills/runner/applescript.js +100 -0
  37. package/dist/skills/runner/applescript.js.map +1 -0
  38. package/dist/skills/runner/dispatcher.d.ts +57 -0
  39. package/dist/skills/runner/dispatcher.js +407 -0
  40. package/dist/skills/runner/dispatcher.js.map +1 -0
  41. package/dist/skills/runner/kernel.d.ts +8 -0
  42. package/dist/skills/runner/kernel.js +732 -0
  43. package/dist/skills/runner/kernel.js.map +1 -0
  44. package/dist/skills/runner/tokenizer.d.ts +36 -0
  45. package/dist/skills/runner/tokenizer.js +177 -0
  46. package/dist/skills/runner/tokenizer.js.map +1 -0
  47. package/dist/threadCli.d.ts +11 -0
  48. package/dist/threadCli.js +177 -0
  49. package/dist/threadCli.js.map +1 -0
  50. package/dist/threadShare.d.ts +21 -0
  51. package/dist/threadShare.js +121 -0
  52. package/dist/threadShare.js.map +1 -0
  53. package/dist/threadSubmit.d.ts +32 -0
  54. package/dist/threadSubmit.js +199 -0
  55. package/dist/threadSubmit.js.map +1 -0
  56. package/dist/tools/bash.js +68 -13
  57. package/dist/tools/bash.js.map +1 -1
  58. package/dist/tools/index.d.ts +22 -2
  59. package/dist/tools/index.js +41 -5
  60. package/dist/tools/index.js.map +1 -1
  61. package/dist/tools/skillCall.d.ts +2 -0
  62. package/dist/tools/skillCall.js +77 -0
  63. package/dist/tools/skillCall.js.map +1 -0
  64. package/dist/ui/AgentPicker.js +3 -3
  65. package/dist/ui/AgentPicker.js.map +1 -1
  66. package/dist/ui/App.js +214 -61
  67. package/dist/ui/App.js.map +1 -1
  68. package/dist/ui/Banner.d.ts +2 -1
  69. package/dist/ui/Banner.js +23 -4
  70. package/dist/ui/Banner.js.map +1 -1
  71. package/dist/ui/InputBar.js +6 -3
  72. package/dist/ui/InputBar.js.map +1 -1
  73. package/dist/ui/Markdown.d.ts +2 -2
  74. package/dist/ui/Markdown.js +22 -7
  75. package/dist/ui/Markdown.js.map +1 -1
  76. package/dist/ui/MarketplacePicker.d.ts +7 -0
  77. package/dist/ui/MarketplacePicker.js +122 -0
  78. package/dist/ui/MarketplacePicker.js.map +1 -0
  79. package/dist/ui/MessageList.d.ts +4 -1
  80. package/dist/ui/MessageList.js +72 -7
  81. package/dist/ui/MessageList.js.map +1 -1
  82. package/dist/ui/ModelPicker.js +4 -4
  83. package/dist/ui/ModelPicker.js.map +1 -1
  84. package/dist/ui/PermissionPrompt.d.ts +16 -4
  85. package/dist/ui/PermissionPrompt.js +60 -15
  86. package/dist/ui/PermissionPrompt.js.map +1 -1
  87. package/dist/ui/SessionPicker.js +2 -2
  88. package/dist/ui/SessionPicker.js.map +1 -1
  89. package/dist/ui/ShimmerText.d.ts +8 -0
  90. package/dist/ui/ShimmerText.js +40 -0
  91. package/dist/ui/ShimmerText.js.map +1 -0
  92. package/dist/ui/Spinner.js +3 -9
  93. package/dist/ui/Spinner.js.map +1 -1
  94. package/dist/ui/TogglePicker.js +4 -4
  95. package/dist/ui/TogglePicker.js.map +1 -1
  96. package/dist/ui/ToolResult.js +6 -0
  97. package/dist/ui/ToolResult.js.map +1 -1
  98. package/dist/ui/UnifiedSkillsPicker.d.ts +10 -0
  99. package/dist/ui/UnifiedSkillsPicker.js +63 -0
  100. package/dist/ui/UnifiedSkillsPicker.js.map +1 -0
  101. package/dist/ui/animation.d.ts +3 -0
  102. package/dist/ui/animation.js +48 -0
  103. package/dist/ui/animation.js.map +1 -0
  104. package/dist/ui/useThrottledStream.d.ts +7 -0
  105. package/dist/ui/useThrottledStream.js +63 -0
  106. package/dist/ui/useThrottledStream.js.map +1 -0
  107. package/dist/yomeSkills/auth.d.ts +20 -0
  108. package/dist/yomeSkills/auth.js +70 -0
  109. package/dist/yomeSkills/auth.js.map +1 -0
  110. package/dist/yomeSkills/blacklist.d.ts +33 -0
  111. package/dist/yomeSkills/blacklist.js +101 -0
  112. package/dist/yomeSkills/blacklist.js.map +1 -0
  113. package/dist/yomeSkills/capabilities.d.ts +54 -0
  114. package/dist/yomeSkills/capabilities.js +175 -0
  115. package/dist/yomeSkills/capabilities.js.map +1 -0
  116. package/dist/yomeSkills/capabilityGuard.d.ts +31 -0
  117. package/dist/yomeSkills/capabilityGuard.js +113 -0
  118. package/dist/yomeSkills/capabilityGuard.js.map +1 -0
  119. package/dist/yomeSkills/cli.d.ts +17 -0
  120. package/dist/yomeSkills/cli.js +477 -0
  121. package/dist/yomeSkills/cli.js.map +1 -0
  122. package/dist/yomeSkills/devLink.d.ts +17 -0
  123. package/dist/yomeSkills/devLink.js +91 -0
  124. package/dist/yomeSkills/devLink.js.map +1 -0
  125. package/dist/yomeSkills/doctor.d.ts +13 -0
  126. package/dist/yomeSkills/doctor.js +152 -0
  127. package/dist/yomeSkills/doctor.js.map +1 -0
  128. package/dist/yomeSkills/enable.d.ts +8 -0
  129. package/dist/yomeSkills/enable.js +67 -0
  130. package/dist/yomeSkills/enable.js.map +1 -0
  131. package/dist/yomeSkills/hubPing.d.ts +1 -0
  132. package/dist/yomeSkills/hubPing.js +41 -0
  133. package/dist/yomeSkills/hubPing.js.map +1 -0
  134. package/dist/yomeSkills/install.d.ts +18 -0
  135. package/dist/yomeSkills/install.js +143 -0
  136. package/dist/yomeSkills/install.js.map +1 -0
  137. package/dist/yomeSkills/installGithub.d.ts +26 -0
  138. package/dist/yomeSkills/installGithub.js +192 -0
  139. package/dist/yomeSkills/installGithub.js.map +1 -0
  140. package/dist/yomeSkills/installMeta.d.ts +8 -0
  141. package/dist/yomeSkills/installMeta.js +76 -0
  142. package/dist/yomeSkills/installMeta.js.map +1 -0
  143. package/dist/yomeSkills/integrity.d.ts +26 -0
  144. package/dist/yomeSkills/integrity.js +107 -0
  145. package/dist/yomeSkills/integrity.js.map +1 -0
  146. package/dist/yomeSkills/invoke.d.ts +29 -0
  147. package/dist/yomeSkills/invoke.js +103 -0
  148. package/dist/yomeSkills/invoke.js.map +1 -0
  149. package/dist/yomeSkills/list.d.ts +11 -0
  150. package/dist/yomeSkills/list.js +55 -0
  151. package/dist/yomeSkills/list.js.map +1 -0
  152. package/dist/yomeSkills/login.d.ts +41 -0
  153. package/dist/yomeSkills/login.js +221 -0
  154. package/dist/yomeSkills/login.js.map +1 -0
  155. package/dist/yomeSkills/manifest.d.ts +60 -0
  156. package/dist/yomeSkills/manifest.js +47 -0
  157. package/dist/yomeSkills/manifest.js.map +1 -0
  158. package/dist/yomeSkills/paths.d.ts +13 -0
  159. package/dist/yomeSkills/paths.js +33 -0
  160. package/dist/yomeSkills/paths.js.map +1 -0
  161. package/dist/yomeSkills/publish.d.ts +16 -0
  162. package/dist/yomeSkills/publish.js +109 -0
  163. package/dist/yomeSkills/publish.js.map +1 -0
  164. package/dist/yomeSkills/rollback.d.ts +10 -0
  165. package/dist/yomeSkills/rollback.js +83 -0
  166. package/dist/yomeSkills/rollback.js.map +1 -0
  167. package/dist/yomeSkills/search.d.ts +21 -0
  168. package/dist/yomeSkills/search.js +31 -0
  169. package/dist/yomeSkills/search.js.map +1 -0
  170. package/dist/yomeSkills/skillsIndex.d.ts +36 -0
  171. package/dist/yomeSkills/skillsIndex.js +111 -0
  172. package/dist/yomeSkills/skillsIndex.js.map +1 -0
  173. package/dist/yomeSkills/unified.d.ts +53 -0
  174. package/dist/yomeSkills/unified.js +187 -0
  175. package/dist/yomeSkills/unified.js.map +1 -0
  176. package/dist/yomeSkills/uninstall.d.ts +7 -0
  177. package/dist/yomeSkills/uninstall.js +22 -0
  178. package/dist/yomeSkills/uninstall.js.map +1 -0
  179. package/dist/yomeSkills/update.d.ts +18 -0
  180. package/dist/yomeSkills/update.js +75 -0
  181. package/dist/yomeSkills/update.js.map +1 -0
  182. package/dist/yomeSkills/validate.d.ts +11 -0
  183. package/dist/yomeSkills/validate.js +99 -0
  184. package/dist/yomeSkills/validate.js.map +1 -0
  185. package/package.json +14 -5
@@ -1 +1 @@
1
- {"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/loops/simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI1C,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,qCAAqC,CAAC;IAE7D,KAAK,CAAC,GAAG,CACP,WAAsB,EACtB,GAAqB,EACrB,EAAsB;QAEtB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAE1D,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,GAAG,CAAC,MAAM,EACV,GAAG,CAAC,YAAY,EAChB,GAAG,CAAC,QAAQ,EACZ,GAAG,CAAC,KAAK,EACT,CAAC,KAAK,EAAE,EAAE;oBACR,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBAC9C,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC,CACF,CAAC;gBAEF,UAAU,IAAI,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;gBAC1C,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC5C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAEpE,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAC3C,CAAC,CAAC,EAA4C,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CACvE,CAAC;gBAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;oBACtE,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;oBAClE,OAAO;gBACT,CAAC;gBAED,MAAM,WAAW,GAAmB,EAAE,CAAC;gBACvC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;oBAClC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBACtC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC9D,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBACpC,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,aAAa;wBACnB,WAAW,EAAE,KAAK,CAAC,EAAE;wBACrB,OAAO,EAAE,MAAM;qBAChB,CAAC,CAAC;gBACL,CAAC;gBAED,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;QACH,CAAC;QAED,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;CACF"}
1
+ {"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/loops/simple.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export type { PermissionMode, PermissionBehavior, PermissionRule, PermissionRuleValue, PermissionRuleSource, PermissionDecision, PermissionResult, ToolPermissionContext, PermissionRulesBySource, } from './types.js';
2
2
  export { parseRuleValue, serializeRuleValue, toolMatchesRule, contentMatchesRule } from './ruleParser.js';
3
- export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings } from './loader.js';
3
+ export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings, addRuleToContext, extractBashRulePrefix, } from './loader.js';
4
4
  export { checkPermission, isContentAllowed, isContentDenied } from './checker.js';
@@ -1,4 +1,4 @@
1
1
  export { parseRuleValue, serializeRuleValue, toolMatchesRule, contentMatchesRule } from './ruleParser.js';
2
- export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings } from './loader.js';
2
+ export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings, addRuleToContext, extractBashRulePrefix, } from './loader.js';
3
3
  export { checkPermission, isContentAllowed, isContentDenied } from './checker.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,2BAA2B,EAC3B,+BAA+B,EAC/B,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { PermissionBehavior, PermissionRule, PermissionMode, ToolPermissionContext } from './types.js';
1
+ import type { PermissionBehavior, PermissionRule, PermissionRuleSource, PermissionMode, ToolPermissionContext } from './types.js';
2
2
  /**
3
3
  * Load all permission rules from user settings (~/.yome/settings.json)
4
4
  * and project settings (.yome/settings.json).
@@ -20,3 +20,22 @@ export declare function initializePermissionContext(opts?: {
20
20
  * Persist a new allow/deny rule to user settings.
21
21
  */
22
22
  export declare function addPermissionRuleToUserSettings(ruleString: string, behavior: PermissionBehavior): void;
23
+ /**
24
+ * Return a new ToolPermissionContext with `ruleString` appended to the given
25
+ * source bucket under `behavior`. Pure / non-mutating — pairs naturally with
26
+ * the immutable `ToolPermissionContext` type.
27
+ *
28
+ * Use `source: 'session'` for "allow for this session only" (in-memory) and
29
+ * `source: 'userSettings'` to mirror what was just persisted to disk so the
30
+ * decision takes effect immediately without restarting the CLI.
31
+ */
32
+ export declare function addRuleToContext(ctx: ToolPermissionContext, ruleString: string, behavior: PermissionBehavior, source: PermissionRuleSource): ToolPermissionContext;
33
+ /**
34
+ * Best-effort extraction of a stable Bash command prefix to use as a permission
35
+ * rule. Returns the first 1-2 plain tokens (`git status`, `npm run build`)
36
+ * suffixed with `:*` so prefix matching catches subsequent invocations with
37
+ * different arguments. Falls back to `null` when the command contains shell
38
+ * metacharacters (pipes, &&, ;, redirects, subshells) — those should be approved
39
+ * verbatim rather than turned into a wildcard rule.
40
+ */
41
+ export declare function extractBashRulePrefix(command: string): string | null;
@@ -101,4 +101,55 @@ export function addPermissionRuleToUserSettings(ruleString, behavior) {
101
101
  }
102
102
  writeFileSync(USER_SETTINGS_FILE, JSON.stringify(data, null, 2), 'utf-8');
103
103
  }
104
+ /**
105
+ * Return a new ToolPermissionContext with `ruleString` appended to the given
106
+ * source bucket under `behavior`. Pure / non-mutating — pairs naturally with
107
+ * the immutable `ToolPermissionContext` type.
108
+ *
109
+ * Use `source: 'session'` for "allow for this session only" (in-memory) and
110
+ * `source: 'userSettings'` to mirror what was just persisted to disk so the
111
+ * decision takes effect immediately without restarting the CLI.
112
+ */
113
+ export function addRuleToContext(ctx, ruleString, behavior, source) {
114
+ const bucket = behavior === 'allow' ? { ...ctx.allowRules } : { ...ctx.denyRules };
115
+ const existing = bucket[source] ?? [];
116
+ if (existing.includes(ruleString)) {
117
+ // No-op if duplicate — return original ref so React-style equality stays cheap.
118
+ return ctx;
119
+ }
120
+ bucket[source] = [...existing, ruleString];
121
+ return behavior === 'allow'
122
+ ? { ...ctx, allowRules: bucket }
123
+ : { ...ctx, denyRules: bucket };
124
+ }
125
+ /**
126
+ * Best-effort extraction of a stable Bash command prefix to use as a permission
127
+ * rule. Returns the first 1-2 plain tokens (`git status`, `npm run build`)
128
+ * suffixed with `:*` so prefix matching catches subsequent invocations with
129
+ * different arguments. Falls back to `null` when the command contains shell
130
+ * metacharacters (pipes, &&, ;, redirects, subshells) — those should be approved
131
+ * verbatim rather than turned into a wildcard rule.
132
+ */
133
+ export function extractBashRulePrefix(command) {
134
+ const trimmed = command.trim();
135
+ if (!trimmed)
136
+ return null;
137
+ // Refuse compound shell — too risky to auto-derive a wildcard rule.
138
+ if (/[|&;`$<>(){}]/.test(trimmed))
139
+ return null;
140
+ const tokens = trimmed.split(/\s+/).filter(Boolean);
141
+ if (tokens.length === 0)
142
+ return null;
143
+ const first = tokens[0];
144
+ // Subcommand-style binaries: keep first two tokens (git status, npm run, kubectl get).
145
+ const SUBCOMMAND_BINS = new Set([
146
+ 'git', 'npm', 'pnpm', 'yarn', 'bun', 'docker', 'kubectl', 'cargo', 'go', 'gh', 'brew',
147
+ ]);
148
+ if (SUBCOMMAND_BINS.has(first) && tokens.length >= 2 && /^[a-zA-Z][\w-]*$/.test(tokens[1])) {
149
+ return `${first} ${tokens[1]}:*`;
150
+ }
151
+ if (!/^[\w./-]+$/.test(first))
152
+ return null;
153
+ return `${first}:*`;
154
+ }
104
155
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/permissions/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/permissions/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ export type RedactionRule = {
2
+ kind: 'pii';
3
+ pattern: 'email' | 'phone' | 'name' | 'id';
4
+ } | {
5
+ kind: 'path';
6
+ } | {
7
+ kind: 'mind';
8
+ } | {
9
+ kind: 'api-key';
10
+ } | {
11
+ kind: 'custom';
12
+ id: string;
13
+ find: RegExp | string;
14
+ replaceWith: string;
15
+ };
16
+ export interface RuleHit {
17
+ /** Stable identifier for grouping/UI: `pii:email`, `api-key`, `custom:my-rule`, ... */
18
+ rule: string;
19
+ count: number;
20
+ /** Up to MAX_SAMPLES short examples of the original (pre-redaction) text. */
21
+ samples: string[];
22
+ }
23
+ export interface RedactionResult {
24
+ redacted: string;
25
+ hits: RuleHit[];
26
+ }
27
+ export interface RedactionPreview {
28
+ before: string;
29
+ after: string;
30
+ ruleHits: RuleHit[];
31
+ }
32
+ /** Default rule set per spec 9.2. */
33
+ export declare const DEFAULT_RULES: RedactionRule[];
34
+ /**
35
+ * Apply text-redacting rules to a string. `mind` rule is a no-op here (it
36
+ * only matters for structured value walks); everything else operates on text.
37
+ */
38
+ export declare function redactText(text: string, rules?: RedactionRule[]): RedactionResult;
39
+ interface ValueRedactionResult {
40
+ redacted: unknown;
41
+ hits: RuleHit[];
42
+ }
43
+ /**
44
+ * Deep-walk a JSON-like value, redacting strings via `redactText` and
45
+ * dropping `mind` fields when the `mind` rule is enabled. Arrays/objects
46
+ * are cloned; primitives are returned by value.
47
+ */
48
+ export declare function redactValue(value: unknown, rules?: RedactionRule[]): ValueRedactionResult;
49
+ /**
50
+ * Build a redaction preview for one chunk of text. Returns the original,
51
+ * the redacted output, and the per-rule hit summary suitable for a diff UI.
52
+ */
53
+ export declare function buildPreview(text: string, rules?: RedactionRule[]): RedactionPreview;
54
+ /** Sum hits across an array of RuleHit groups (e.g. per-message hits). */
55
+ export declare function totalHits(perMessage: RuleHit[][]): RuleHit[];
56
+ export {};
package/dist/redact.js ADDED
@@ -0,0 +1,191 @@
1
+ // cli/src/redact.ts — Yome ThreadRedactor (spec 9, CLI side).
2
+ //
3
+ // Local-side redaction of an agent thread before it is shared as a "case"
4
+ // to a skill's GitHub repo. Runs entirely on-device — the hub's optional
5
+ // re-check is a backstop, never a replacement.
6
+ //
7
+ // Pipeline:
8
+ // text → applyRules(text, rules) → { redacted, ruleHits }
9
+ // structured value → redactValue (deep walk) → redacted clone
10
+ //
11
+ // Default rules (per spec 9.2): email | phone | api-key | mind | path.
12
+ // `mind` only applies to structured payloads (it drops fields whose key is
13
+ // `mind` or that look like a mind block). `path` rewrites `/Users/<name>/`
14
+ // to `/Users/{user}/`. The rest are pure regex substitutions on text.
15
+ //
16
+ // Determinism: same input + same rule set → same output. No randomness.
17
+ const MAX_SAMPLES = 3;
18
+ const SAMPLE_MAX_LEN = 80;
19
+ /** Default rule set per spec 9.2. */
20
+ export const DEFAULT_RULES = [
21
+ { kind: 'pii', pattern: 'email' },
22
+ { kind: 'pii', pattern: 'phone' },
23
+ { kind: 'api-key' },
24
+ { kind: 'path' },
25
+ { kind: 'mind' },
26
+ ];
27
+ // ── Built-in patterns ───────────────────────────────────────────────────────
28
+ /** RFC 5322-lite — covers the realistic 99%, not pathological corner cases. */
29
+ const EMAIL_RE = /([A-Za-z0-9._%+-]+)@([A-Za-z0-9.-]+\.[A-Za-z]{2,})/g;
30
+ /**
31
+ * Phone: international (+CC...) and CN mobile (1[3-9]\d{9}).
32
+ * NB: avoid eating arbitrary 10-digit numbers; require + or 1[3-9] anchor.
33
+ */
34
+ const PHONE_RE = /(\+\d{1,3}[ -]?\d{1,4}([ -]?\d{2,4}){2,4}|\b1[3-9]\d{9}\b)/g;
35
+ /**
36
+ * API keys we know the prefix for. Anchored to whole "word" to avoid eating
37
+ * random hex blobs. Add new patterns here as we discover them in the wild.
38
+ */
39
+ const API_KEY_RES = [
40
+ // Anthropic must come BEFORE openai because `sk-ant-...` would otherwise
41
+ // be eaten by the openai pattern (`sk-` + alphanum).
42
+ { id: 'anthropic', re: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{20,}\b/g },
43
+ { id: 'openai', re: /\bsk-(?!ant-)(?:proj-)?[A-Za-z0-9_-]{20,}\b/g },
44
+ { id: 'github', re: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g },
45
+ { id: 'aws', re: /\bAKIA[0-9A-Z]{16}\b/g },
46
+ { id: 'google', re: /\bAIza[0-9A-Za-z_-]{35}\b/g },
47
+ { id: 'slack', re: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/g },
48
+ { id: 'jwt', re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g },
49
+ { id: 'generic-bearer', re: /\bBearer\s+[A-Za-z0-9._-]{20,}\b/g },
50
+ ];
51
+ /** Match `/Users/<username>/...` (macOS) and `/home/<username>/...` (Linux). */
52
+ const PATH_RE = /(\/Users|\/home)\/([^/\s"'<>]+)/g;
53
+ // ── Helpers ─────────────────────────────────────────────────────────────────
54
+ function pushHit(hits, ruleId, sample) {
55
+ let hit = hits.get(ruleId);
56
+ if (!hit) {
57
+ hit = { rule: ruleId, count: 0, samples: [] };
58
+ hits.set(ruleId, hit);
59
+ }
60
+ hit.count++;
61
+ if (hit.samples.length < MAX_SAMPLES) {
62
+ const trimmed = sample.length > SAMPLE_MAX_LEN ? sample.slice(0, SAMPLE_MAX_LEN) + '…' : sample;
63
+ if (!hit.samples.includes(trimmed))
64
+ hit.samples.push(trimmed);
65
+ }
66
+ }
67
+ function applyRegex(text, re, ruleId, hits, replacer) {
68
+ // RegExp must be /g — clone if a caller passed one without the flag.
69
+ const safeRe = re.flags.includes('g') ? re : new RegExp(re.source, re.flags + 'g');
70
+ return text.replace(safeRe, (match, ...args) => {
71
+ pushHit(hits, ruleId, match);
72
+ // groups are everything but the last two args (offset, full string)
73
+ const groups = args.slice(0, -2);
74
+ return replacer(match, ...groups);
75
+ });
76
+ }
77
+ // ── Text-level rule application ─────────────────────────────────────────────
78
+ /**
79
+ * Apply text-redacting rules to a string. `mind` rule is a no-op here (it
80
+ * only matters for structured value walks); everything else operates on text.
81
+ */
82
+ export function redactText(text, rules = DEFAULT_RULES) {
83
+ const hits = new Map();
84
+ let out = text;
85
+ for (const rule of rules) {
86
+ if (rule.kind === 'pii') {
87
+ switch (rule.pattern) {
88
+ case 'email':
89
+ out = applyRegex(out, EMAIL_RE, 'pii:email', hits, (_m, local, domain) => `${(local || '').slice(0, 1)}***@${domain}`);
90
+ break;
91
+ case 'phone':
92
+ out = applyRegex(out, PHONE_RE, 'pii:phone', hits, () => '[REDACTED_PHONE]');
93
+ break;
94
+ case 'name':
95
+ // Name detection without a model is high-FP; for v0.1 this is an
96
+ // opt-in that does nothing unless paired with a custom rule.
97
+ break;
98
+ case 'id':
99
+ // Reserved for future use (national ID, SSN). v0.1 no-op.
100
+ break;
101
+ }
102
+ }
103
+ else if (rule.kind === 'api-key') {
104
+ for (const { id, re } of API_KEY_RES) {
105
+ out = applyRegex(out, re, `api-key:${id}`, hits, () => `[REDACTED_${id.toUpperCase()}_KEY]`);
106
+ }
107
+ }
108
+ else if (rule.kind === 'path') {
109
+ out = applyRegex(out, PATH_RE, 'path', hits, (_m, root) => `${root}/{user}`);
110
+ }
111
+ else if (rule.kind === 'custom') {
112
+ const re = typeof rule.find === 'string'
113
+ ? new RegExp(rule.find.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')
114
+ : rule.find;
115
+ out = applyRegex(out, re, `custom:${rule.id}`, hits, () => rule.replaceWith);
116
+ }
117
+ // `mind` is value-walk-only (see redactValue)
118
+ }
119
+ return { redacted: out, hits: Array.from(hits.values()) };
120
+ }
121
+ // ── Structured value walk (for thread.json / trace.json) ────────────────────
122
+ const MIND_KEY_RE = /^(mind|user_?mind|private_?mind)$/i;
123
+ function isPlainObject(v) {
124
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
125
+ }
126
+ function mergeHits(into, from) {
127
+ for (const h of from) {
128
+ const existing = into.get(h.rule);
129
+ if (!existing) {
130
+ into.set(h.rule, { rule: h.rule, count: h.count, samples: [...h.samples] });
131
+ }
132
+ else {
133
+ existing.count += h.count;
134
+ for (const s of h.samples) {
135
+ if (existing.samples.length >= MAX_SAMPLES)
136
+ break;
137
+ if (!existing.samples.includes(s))
138
+ existing.samples.push(s);
139
+ }
140
+ }
141
+ }
142
+ }
143
+ /**
144
+ * Deep-walk a JSON-like value, redacting strings via `redactText` and
145
+ * dropping `mind` fields when the `mind` rule is enabled. Arrays/objects
146
+ * are cloned; primitives are returned by value.
147
+ */
148
+ export function redactValue(value, rules = DEFAULT_RULES) {
149
+ const dropMind = rules.some(r => r.kind === 'mind');
150
+ const allHits = new Map();
151
+ function walk(v) {
152
+ if (typeof v === 'string') {
153
+ const r = redactText(v, rules);
154
+ mergeHits(allHits, r.hits);
155
+ return r.redacted;
156
+ }
157
+ if (Array.isArray(v))
158
+ return v.map(walk);
159
+ if (isPlainObject(v)) {
160
+ const out = {};
161
+ for (const [k, child] of Object.entries(v)) {
162
+ if (dropMind && MIND_KEY_RE.test(k)) {
163
+ pushHit(allHits, 'mind', `<dropped field "${k}">`);
164
+ continue;
165
+ }
166
+ out[k] = walk(child);
167
+ }
168
+ return out;
169
+ }
170
+ return v;
171
+ }
172
+ const redacted = walk(value);
173
+ return { redacted, hits: Array.from(allHits.values()) };
174
+ }
175
+ // ── Diff preview helper ─────────────────────────────────────────────────────
176
+ /**
177
+ * Build a redaction preview for one chunk of text. Returns the original,
178
+ * the redacted output, and the per-rule hit summary suitable for a diff UI.
179
+ */
180
+ export function buildPreview(text, rules = DEFAULT_RULES) {
181
+ const { redacted, hits } = redactText(text, rules);
182
+ return { before: text, after: redacted, ruleHits: hits };
183
+ }
184
+ /** Sum hits across an array of RuleHit groups (e.g. per-message hits). */
185
+ export function totalHits(perMessage) {
186
+ const merged = new Map();
187
+ for (const group of perMessage)
188
+ mergeHits(merged, group);
189
+ return Array.from(merged.values()).sort((a, b) => b.count - a.count);
190
+ }
191
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export interface AppleScriptResult {
2
+ ok: boolean;
3
+ stdout: string;
4
+ stderr: string;
5
+ /** osascript exit code (0 on success). -1 on launch failure. */
6
+ exitCode: number;
7
+ }
8
+ /**
9
+ * Run an AppleScript source string via `osascript -e`.
10
+ *
11
+ * The Swift sibling does some preflight automation-permission checks via
12
+ * AEDeterminePermissionToAutomateTarget. CLI doesn't have a UI to drive
13
+ * the system prompt, so we just let osascript surface error -1743 — the
14
+ * caller can decide whether to message the user.
15
+ */
16
+ export declare function runOsascript(source: string, opts?: {
17
+ timeoutMs?: number;
18
+ }): AppleScriptResult;
19
+ /**
20
+ * Same as `runOsascript`, but reads the script from a file path instead
21
+ * of inline `-e`. Useful for very long scripts or when keeping a single
22
+ * authoritative `.applescript` file in the skill bundle.
23
+ */
24
+ export declare function runOsascriptFile(path: string, opts?: {
25
+ timeoutMs?: number;
26
+ }): AppleScriptResult;
27
+ /**
28
+ * Open a file via macOS Launch Services (`/usr/bin/open -a`) so the
29
+ * receiving app gets sandbox-implicit access without us having to fight
30
+ * automation prompts, then poll an AppleScript until the file shows up
31
+ * inside that app.
32
+ *
33
+ * Returns the poll script's last output on success, or null on timeout.
34
+ */
35
+ export declare function openViaLaunchServices(args: {
36
+ filePath: string;
37
+ appName: string;
38
+ pollScript: string;
39
+ maxWaitSec?: number;
40
+ pollIntervalMs?: number;
41
+ }): {
42
+ ok: boolean;
43
+ stdout: string;
44
+ stderr: string;
45
+ };
46
+ /** Quote a string so it's safe to embed inside an AppleScript string literal. */
47
+ export declare function asString(s: string): string;
48
+ /** Quote a POSIX path for AppleScript ("POSIX file" wrapping is the caller's job). */
49
+ export declare function asPosixPath(p: string): string;
@@ -0,0 +1,100 @@
1
+ // cli/src/skills/runner/applescript.ts
2
+ //
3
+ // Spawn /usr/bin/osascript and friends. Mirror of Yome/macOS/Bridge/
4
+ // AppleScriptRunner.swift so the CLI gets the same execution semantics
5
+ // the macOS app uses (including the Launch Services trick that bypasses
6
+ // app-sandbox prompts for opening files).
7
+ import { spawnSync } from 'node:child_process';
8
+ /**
9
+ * Run an AppleScript source string via `osascript -e`.
10
+ *
11
+ * The Swift sibling does some preflight automation-permission checks via
12
+ * AEDeterminePermissionToAutomateTarget. CLI doesn't have a UI to drive
13
+ * the system prompt, so we just let osascript surface error -1743 — the
14
+ * caller can decide whether to message the user.
15
+ */
16
+ export function runOsascript(source, opts = {}) {
17
+ const r = spawnSync('/usr/bin/osascript', ['-e', source], {
18
+ encoding: 'utf-8',
19
+ timeout: opts.timeoutMs ?? 30_000,
20
+ maxBuffer: 10 * 1024 * 1024,
21
+ });
22
+ if (r.error) {
23
+ return { ok: false, stdout: '', stderr: String(r.error.message), exitCode: -1 };
24
+ }
25
+ const code = r.status ?? -1;
26
+ return {
27
+ ok: code === 0,
28
+ stdout: (r.stdout ?? '').replace(/\n+$/, ''),
29
+ stderr: (r.stderr ?? '').trim(),
30
+ exitCode: code,
31
+ };
32
+ }
33
+ /**
34
+ * Same as `runOsascript`, but reads the script from a file path instead
35
+ * of inline `-e`. Useful for very long scripts or when keeping a single
36
+ * authoritative `.applescript` file in the skill bundle.
37
+ */
38
+ export function runOsascriptFile(path, opts = {}) {
39
+ const r = spawnSync('/usr/bin/osascript', [path], {
40
+ encoding: 'utf-8',
41
+ timeout: opts.timeoutMs ?? 30_000,
42
+ maxBuffer: 10 * 1024 * 1024,
43
+ });
44
+ if (r.error) {
45
+ return { ok: false, stdout: '', stderr: String(r.error.message), exitCode: -1 };
46
+ }
47
+ const code = r.status ?? -1;
48
+ return {
49
+ ok: code === 0,
50
+ stdout: (r.stdout ?? '').replace(/\n+$/, ''),
51
+ stderr: (r.stderr ?? '').trim(),
52
+ exitCode: code,
53
+ };
54
+ }
55
+ /**
56
+ * Open a file via macOS Launch Services (`/usr/bin/open -a`) so the
57
+ * receiving app gets sandbox-implicit access without us having to fight
58
+ * automation prompts, then poll an AppleScript until the file shows up
59
+ * inside that app.
60
+ *
61
+ * Returns the poll script's last output on success, or null on timeout.
62
+ */
63
+ export function openViaLaunchServices(args) {
64
+ const open = spawnSync('/usr/bin/open', ['-a', args.appName, args.filePath], { encoding: 'utf-8' });
65
+ if (open.status !== 0) {
66
+ return {
67
+ ok: false,
68
+ stdout: '',
69
+ stderr: open.stderr || `open -a "${args.appName}" exited ${open.status}`,
70
+ };
71
+ }
72
+ const max = args.maxWaitSec ?? 30;
73
+ const interval = args.pollIntervalMs ?? 1000;
74
+ for (let i = 0; i < max; i++) {
75
+ sleepSync(interval);
76
+ const r = runOsascript(args.pollScript);
77
+ if (r.ok && r.stdout.trim().length > 0) {
78
+ return { ok: true, stdout: r.stdout, stderr: '' };
79
+ }
80
+ }
81
+ return { ok: false, stdout: '', stderr: `timed out waiting for ${args.appName} to load ${args.filePath}` };
82
+ }
83
+ /** Quote a string so it's safe to embed inside an AppleScript string literal. */
84
+ export function asString(s) {
85
+ return '"' + s.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
86
+ }
87
+ /** Quote a POSIX path for AppleScript ("POSIX file" wrapping is the caller's job). */
88
+ export function asPosixPath(p) {
89
+ return asString(p);
90
+ }
91
+ function sleepSync(ms) {
92
+ const end = Date.now() + ms;
93
+ // Atomics-based sleep — works in Node ≥16 without spawning a child.
94
+ const sab = new SharedArrayBuffer(4);
95
+ const view = new Int32Array(sab);
96
+ while (Date.now() < end) {
97
+ Atomics.wait(view, 0, 0, Math.max(1, end - Date.now()));
98
+ }
99
+ }
100
+ //# sourceMappingURL=applescript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applescript.js","sourceRoot":"","sources":["../../../src/skills/runner/applescript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ export interface BackendArgSpec {
2
+ name: string;
3
+ from: string;
4
+ type?: 'string' | 'bool' | 'number';
5
+ default?: string | boolean | number;
6
+ required?: boolean;
7
+ }
8
+ export interface BackendActionSpec {
9
+ script: string;
10
+ args?: BackendArgSpec[];
11
+ openViaLaunchServices?: boolean;
12
+ pollScript?: string;
13
+ uses?: string[];
14
+ /** Per-action timeout override in ms. */
15
+ timeoutMs?: number;
16
+ }
17
+ export interface MacosBackendManifest {
18
+ appBundleId?: string;
19
+ appName?: string;
20
+ actions: Record<string, BackendActionSpec>;
21
+ }
22
+ export interface SkillCall {
23
+ positionals: string[];
24
+ flags: Record<string, string | boolean | number | undefined>;
25
+ }
26
+ export interface DispatchResult {
27
+ ok: boolean;
28
+ stdout: string;
29
+ stderr: string;
30
+ exitCode: number;
31
+ }
32
+ /**
33
+ * Parse `red` | `#003366` | `003366` | `0, 51, 102` into an AppleScript
34
+ * RGB literal `{r, g, b}`. Returns null if the input doesn't match any of
35
+ * those three forms — callers should treat null as "user gave a bad color".
36
+ */
37
+ export declare function parseColorToAppleScriptRGB(input: string): string | null;
38
+ /**
39
+ * `--align` parser → AppleScript `paragraph align ...` enum.
40
+ * Defaults silently to `paragraph align left` for unknown values; that
41
+ * matches the Swift bridge behaviour and avoids breaking the script render.
42
+ */
43
+ export declare function parseAlignToAppleScript(input: string): string;
44
+ export declare function loadMacosBackend(skillDir: string): MacosBackendManifest | null;
45
+ /**
46
+ * Run an action on a macOS-backed skill. Returns the osascript outcome
47
+ * verbatim (caller decides how to render).
48
+ */
49
+ export declare function dispatchMacos(skillDir: string, action: string, call: SkillCall): DispatchResult;
50
+ export interface MergedBatchEntry {
51
+ action: string;
52
+ call: SkillCall;
53
+ }
54
+ export interface MergedBatchOptions {
55
+ keepGoing: boolean;
56
+ }
57
+ export declare function dispatchMacosBatchMerged(skillDir: string, entries: MergedBatchEntry[], opts: MergedBatchOptions): Promise<DispatchResult>;