kiriya 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/dist/src/config/clean-rules.js +39 -0
  5. package/dist/src/config/config-keys.js +24 -0
  6. package/dist/src/config/dependency-directories.js +16 -0
  7. package/dist/src/config/modules.js +38 -0
  8. package/dist/src/config/protected-paths.js +32 -0
  9. package/dist/src/config/rebuildable-directories.js +20 -0
  10. package/dist/src/core/application/command-registry.js +57 -0
  11. package/dist/src/core/application/config-values.js +33 -0
  12. package/dist/src/core/application/path-guard.js +69 -0
  13. package/dist/src/core/application/paths.js +77 -0
  14. package/dist/src/core/application/plugin-loader.js +100 -0
  15. package/dist/src/core/application/process-ending.js +28 -0
  16. package/dist/src/core/application/root-scope.js +123 -0
  17. package/dist/src/core/application/safety.js +26 -0
  18. package/dist/src/core/application/text-input.js +44 -0
  19. package/dist/src/core/application/walk.js +34 -0
  20. package/dist/src/core/domain/command.js +8 -0
  21. package/dist/src/core/domain/encodings.js +70 -0
  22. package/dist/src/core/domain/errors.js +49 -0
  23. package/dist/src/core/domain/glob.js +57 -0
  24. package/dist/src/core/domain/global-options.js +10 -0
  25. package/dist/src/core/domain/input-schema.js +54 -0
  26. package/dist/src/core/domain/message.js +7 -0
  27. package/dist/src/core/domain/module.js +2 -0
  28. package/dist/src/core/domain/names.js +22 -0
  29. package/dist/src/core/domain/ports/clipboard.js +2 -0
  30. package/dist/src/core/domain/ports/clock.js +2 -0
  31. package/dist/src/core/domain/ports/command-catalog.js +2 -0
  32. package/dist/src/core/domain/ports/compression.js +2 -0
  33. package/dist/src/core/domain/ports/config-store.js +2 -0
  34. package/dist/src/core/domain/ports/confirmation.js +2 -0
  35. package/dist/src/core/domain/ports/environment.js +2 -0
  36. package/dist/src/core/domain/ports/file-content.js +2 -0
  37. package/dist/src/core/domain/ports/file-system.js +2 -0
  38. package/dist/src/core/domain/ports/hasher.js +2 -0
  39. package/dist/src/core/domain/ports/network.js +2 -0
  40. package/dist/src/core/domain/ports/opener.js +2 -0
  41. package/dist/src/core/domain/ports/passthrough.js +2 -0
  42. package/dist/src/core/domain/ports/plugin-inventory.js +2 -0
  43. package/dist/src/core/domain/ports/plugin-source.js +2 -0
  44. package/dist/src/core/domain/ports/port-table.js +2 -0
  45. package/dist/src/core/domain/ports/process-runner.js +2 -0
  46. package/dist/src/core/domain/ports/process-table.js +2 -0
  47. package/dist/src/core/domain/ports/protected-paths.js +2 -0
  48. package/dist/src/core/domain/ports/random-source.js +2 -0
  49. package/dist/src/core/domain/ports/standard-input.js +2 -0
  50. package/dist/src/core/domain/ports/system-info.js +2 -0
  51. package/dist/src/core/domain/ports/trash.js +2 -0
  52. package/dist/src/core/domain/secrets.js +59 -0
  53. package/dist/src/core/domain/targets.js +41 -0
  54. package/dist/src/core/domain/text-case.js +39 -0
  55. package/dist/src/core/domain/values/bytes.js +13 -0
  56. package/dist/src/core/domain/view.js +2 -0
  57. package/dist/src/core/infrastructure/node/can-listen.js +10 -0
  58. package/dist/src/core/infrastructure/node/closed-standard-input.adapter.js +12 -0
  59. package/dist/src/core/infrastructure/node/config-location.js +27 -0
  60. package/dist/src/core/infrastructure/node/fs-errors.js +22 -0
  61. package/dist/src/core/infrastructure/node/json-config-store.adapter.js +69 -0
  62. package/dist/src/core/infrastructure/node/node-compression.adapter.js +82 -0
  63. package/dist/src/core/infrastructure/node/node-environment.adapter.js +21 -0
  64. package/dist/src/core/infrastructure/node/node-file-content.adapter.js +99 -0
  65. package/dist/src/core/infrastructure/node/node-file-system.adapter.js +169 -0
  66. package/dist/src/core/infrastructure/node/node-hasher.adapter.js +32 -0
  67. package/dist/src/core/infrastructure/node/node-network.adapter.js +168 -0
  68. package/dist/src/core/infrastructure/node/node-plugin-source.adapter.js +89 -0
  69. package/dist/src/core/infrastructure/node/node-process-runner.adapter.js +48 -0
  70. package/dist/src/core/infrastructure/node/node-random-source.adapter.js +7 -0
  71. package/dist/src/core/infrastructure/node/node-standard-input.adapter.js +24 -0
  72. package/dist/src/core/infrastructure/node/node-system-info.adapter.js +63 -0
  73. package/dist/src/core/infrastructure/node/process-signals.js +51 -0
  74. package/dist/src/core/infrastructure/node/run-program.js +65 -0
  75. package/dist/src/core/infrastructure/node/system-clock.adapter.js +22 -0
  76. package/dist/src/core/infrastructure/node/typed-programs.js +45 -0
  77. package/dist/src/core/infrastructure/platform/linux/freedesktop-trash.adapter.js +115 -0
  78. package/dist/src/core/infrastructure/platform/linux/linux-clipboard.adapter.js +70 -0
  79. package/dist/src/core/infrastructure/platform/linux/linux-opener.adapter.js +21 -0
  80. package/dist/src/core/infrastructure/platform/linux/linux-port-table.adapter.js +97 -0
  81. package/dist/src/core/infrastructure/platform/linux/linux-process-table.adapter.js +61 -0
  82. package/dist/src/core/infrastructure/platform/macos/macos-clipboard.adapter.js +29 -0
  83. package/dist/src/core/infrastructure/platform/macos/macos-opener.adapter.js +13 -0
  84. package/dist/src/core/infrastructure/platform/macos/macos-port-table.adapter.js +86 -0
  85. package/dist/src/core/infrastructure/platform/macos/macos-process-table.adapter.js +62 -0
  86. package/dist/src/core/infrastructure/platform/macos/macos-trash.adapter.js +64 -0
  87. package/dist/src/core/infrastructure/platform/windows/system32.js +6 -0
  88. package/dist/src/core/infrastructure/platform/windows/windows-clipboard.adapter.js +50 -0
  89. package/dist/src/core/infrastructure/platform/windows/windows-opener.adapter.js +11 -0
  90. package/dist/src/core/infrastructure/platform/windows/windows-port-table.adapter.js +38 -0
  91. package/dist/src/core/infrastructure/platform/windows/windows-process-table.adapter.js +134 -0
  92. package/dist/src/core/infrastructure/platform/windows/windows-trash.adapter.js +86 -0
  93. package/dist/src/core/presentation/cli/argv.js +83 -0
  94. package/dist/src/core/presentation/cli/cli-application.js +201 -0
  95. package/dist/src/core/presentation/cli/cli-view-format.js +46 -0
  96. package/dist/src/core/presentation/cli/help.js +202 -0
  97. package/dist/src/core/presentation/cli/json-output.js +28 -0
  98. package/dist/src/core/presentation/cli/style.js +21 -0
  99. package/dist/src/core/presentation/cli/suggest.js +25 -0
  100. package/dist/src/core/presentation/cli/terminal-confirmation.js +63 -0
  101. package/dist/src/core/presentation/ended-processes.js +18 -0
  102. package/dist/src/core/presentation/i18n/translator.js +23 -0
  103. package/dist/src/core/presentation/list-preview.js +10 -0
  104. package/dist/src/core/presentation/mcp/elicitation.js +55 -0
  105. package/dist/src/core/presentation/mcp/mcp-application.js +60 -0
  106. package/dist/src/core/presentation/mcp/mcp-confirmation.js +59 -0
  107. package/dist/src/core/presentation/mcp/mcp-server.js +355 -0
  108. package/dist/src/core/presentation/mcp/protocol.js +32 -0
  109. package/dist/src/core/presentation/mcp/request-state.js +66 -0
  110. package/dist/src/core/presentation/mcp/tool-definitions.js +149 -0
  111. package/dist/src/core/presentation/mcp/tool-results.js +56 -0
  112. package/dist/src/i18n/locales/en.js +827 -0
  113. package/dist/src/main.js +154 -0
  114. package/dist/src/modules/archive/application/archive-sources.js +55 -0
  115. package/dist/src/modules/archive/application/create-tar.use-case.js +123 -0
  116. package/dist/src/modules/archive/application/create-zip.use-case.js +106 -0
  117. package/dist/src/modules/archive/application/extract-tar.use-case.js +240 -0
  118. package/dist/src/modules/archive/application/extract-zip.use-case.js +181 -0
  119. package/dist/src/modules/archive/application/tar-reader.js +45 -0
  120. package/dist/src/modules/archive/application/zip-reader.js +57 -0
  121. package/dist/src/modules/archive/archive.module.js +27 -0
  122. package/dist/src/modules/archive/domain/crc32.js +18 -0
  123. package/dist/src/modules/archive/domain/tar-format.js +97 -0
  124. package/dist/src/modules/archive/domain/tar-stream.js +223 -0
  125. package/dist/src/modules/archive/domain/zip-format.js +158 -0
  126. package/dist/src/modules/archive/presentation/tar.view.js +17 -0
  127. package/dist/src/modules/archive/presentation/untar.view.js +30 -0
  128. package/dist/src/modules/archive/presentation/unzip.view.js +24 -0
  129. package/dist/src/modules/archive/presentation/zip.view.js +17 -0
  130. package/dist/src/modules/clip/application/copy-text.use-case.js +43 -0
  131. package/dist/src/modules/clip/application/paste-text.use-case.js +25 -0
  132. package/dist/src/modules/clip/clip.module.js +16 -0
  133. package/dist/src/modules/clip/presentation/clip.views.js +7 -0
  134. package/dist/src/modules/completion/application/print-script.use-case.js +38 -0
  135. package/dist/src/modules/completion/application/suggest-words.use-case.js +37 -0
  136. package/dist/src/modules/completion/completion.module.js +14 -0
  137. package/dist/src/modules/completion/domain/scripts.js +91 -0
  138. package/dist/src/modules/completion/domain/suggest.js +134 -0
  139. package/dist/src/modules/completion/presentation/completion.views.js +6 -0
  140. package/dist/src/modules/config/application/config-commands.js +14 -0
  141. package/dist/src/modules/config/application/get-setting.use-case.js +25 -0
  142. package/dist/src/modules/config/application/list-config-keys.use-case.js +26 -0
  143. package/dist/src/modules/config/application/list-settings.use-case.js +28 -0
  144. package/dist/src/modules/config/application/set-setting.use-case.js +53 -0
  145. package/dist/src/modules/config/application/show-config-path.use-case.js +21 -0
  146. package/dist/src/modules/config/application/unset-setting.use-case.js +28 -0
  147. package/dist/src/modules/config/config.module.js +28 -0
  148. package/dist/src/modules/config/presentation/config.views.js +33 -0
  149. package/dist/src/modules/convert/application/convert-case.use-case.js +38 -0
  150. package/dist/src/modules/convert/application/convert-codecs.use-case.js +92 -0
  151. package/dist/src/modules/convert/application/convert-input.js +16 -0
  152. package/dist/src/modules/convert/application/convert-json.use-case.js +51 -0
  153. package/dist/src/modules/convert/application/convert-time.use-case.js +39 -0
  154. package/dist/src/modules/convert/application/decode-jwt.use-case.js +52 -0
  155. package/dist/src/modules/convert/convert.module.js +29 -0
  156. package/dist/src/modules/convert/domain/json-syntax.js +135 -0
  157. package/dist/src/modules/convert/domain/jwt.js +29 -0
  158. package/dist/src/modules/convert/domain/moments.js +20 -0
  159. package/dist/src/modules/convert/presentation/convert.views.js +44 -0
  160. package/dist/src/modules/docker/application/clean-engine.use-case.js +77 -0
  161. package/dist/src/modules/docker/application/compose-project.js +45 -0
  162. package/dist/src/modules/docker/application/docker-engine.js +40 -0
  163. package/dist/src/modules/docker/application/list-containers.use-case.js +69 -0
  164. package/dist/src/modules/docker/application/run-compose.use-case.js +83 -0
  165. package/dist/src/modules/docker/application/show-logs.use-case.js +51 -0
  166. package/dist/src/modules/docker/application/stop-project.use-case.js +56 -0
  167. package/dist/src/modules/docker/docker.module.js +23 -0
  168. package/dist/src/modules/docker/domain/compose-file.js +105 -0
  169. package/dist/src/modules/docker/domain/engine-output.js +65 -0
  170. package/dist/src/modules/docker/presentation/docker.views.js +63 -0
  171. package/dist/src/modules/doctor/application/run-checks.use-case.js +128 -0
  172. package/dist/src/modules/doctor/doctor.module.js +13 -0
  173. package/dist/src/modules/doctor/domain/versions.js +22 -0
  174. package/dist/src/modules/doctor/presentation/doctor.view.js +30 -0
  175. package/dist/src/modules/env/application/check-dotenv.use-case.js +116 -0
  176. package/dist/src/modules/env/application/inspect-path.use-case.js +71 -0
  177. package/dist/src/modules/env/application/path-entries.js +28 -0
  178. package/dist/src/modules/env/application/show-variables.use-case.js +47 -0
  179. package/dist/src/modules/env/domain/dotenv.js +62 -0
  180. package/dist/src/modules/env/env.module.js +17 -0
  181. package/dist/src/modules/env/presentation/env.views.js +43 -0
  182. package/dist/src/modules/files/application/clean-builds.use-case.js +149 -0
  183. package/dist/src/modules/files/application/compare-paths.use-case.js +127 -0
  184. package/dist/src/modules/files/application/copy-paths.use-case.js +101 -0
  185. package/dist/src/modules/files/application/create-paths.use-case.js +85 -0
  186. package/dist/src/modules/files/application/delete-paths.use-case.js +127 -0
  187. package/dist/src/modules/files/application/find-duplicates.use-case.js +105 -0
  188. package/dist/src/modules/files/application/find-files.use-case.js +131 -0
  189. package/dist/src/modules/files/application/hash-files.use-case.js +73 -0
  190. package/dist/src/modules/files/application/list-entries.use-case.js +87 -0
  191. package/dist/src/modules/files/application/measure-folders.use-case.js +102 -0
  192. package/dist/src/modules/files/application/move-entry.js +19 -0
  193. package/dist/src/modules/files/application/move-paths.use-case.js +82 -0
  194. package/dist/src/modules/files/application/read-text.use-case.js +92 -0
  195. package/dist/src/modules/files/application/rename-paths.use-case.js +184 -0
  196. package/dist/src/modules/files/application/replace-text.use-case.js +146 -0
  197. package/dist/src/modules/files/application/search-text.use-case.js +115 -0
  198. package/dist/src/modules/files/application/show-info.use-case.js +80 -0
  199. package/dist/src/modules/files/application/show-tree.use-case.js +75 -0
  200. package/dist/src/modules/files/application/sync-folders.use-case.js +162 -0
  201. package/dist/src/modules/files/application/text-files.js +46 -0
  202. package/dist/src/modules/files/application/transfers.js +35 -0
  203. package/dist/src/modules/files/domain/case-style.js +18 -0
  204. package/dist/src/modules/files/domain/filters.js +9 -0
  205. package/dist/src/modules/files/domain/sync-plan.js +35 -0
  206. package/dist/src/modules/files/domain/text-encoding.js +75 -0
  207. package/dist/src/modules/files/domain/values.js +28 -0
  208. package/dist/src/modules/files/files.module.js +70 -0
  209. package/dist/src/modules/files/presentation/clean.view.js +15 -0
  210. package/dist/src/modules/files/presentation/compare.view.js +50 -0
  211. package/dist/src/modules/files/presentation/copy.view.js +17 -0
  212. package/dist/src/modules/files/presentation/delete.view.js +16 -0
  213. package/dist/src/modules/files/presentation/dupes.view.js +20 -0
  214. package/dist/src/modules/files/presentation/find.view.js +16 -0
  215. package/dist/src/modules/files/presentation/grep.view.js +27 -0
  216. package/dist/src/modules/files/presentation/hash.view.js +15 -0
  217. package/dist/src/modules/files/presentation/info.view.js +36 -0
  218. package/dist/src/modules/files/presentation/list.view.js +17 -0
  219. package/dist/src/modules/files/presentation/move.view.js +14 -0
  220. package/dist/src/modules/files/presentation/new.view.js +8 -0
  221. package/dist/src/modules/files/presentation/read.view.js +6 -0
  222. package/dist/src/modules/files/presentation/rename.view.js +16 -0
  223. package/dist/src/modules/files/presentation/replace.view.js +26 -0
  224. package/dist/src/modules/files/presentation/size.view.js +24 -0
  225. package/dist/src/modules/files/presentation/sync.view.js +37 -0
  226. package/dist/src/modules/files/presentation/tree.view.js +22 -0
  227. package/dist/src/modules/gen/application/gen-options.js +18 -0
  228. package/dist/src/modules/gen/application/generate-passwords.use-case.js +39 -0
  229. package/dist/src/modules/gen/application/generate-tokens.use-case.js +38 -0
  230. package/dist/src/modules/gen/application/generate-ulids.use-case.js +40 -0
  231. package/dist/src/modules/gen/application/generate-uuids.use-case.js +32 -0
  232. package/dist/src/modules/gen/domain/identifiers.js +65 -0
  233. package/dist/src/modules/gen/domain/secrets.js +43 -0
  234. package/dist/src/modules/gen/gen.module.js +20 -0
  235. package/dist/src/modules/git/application/fetch-repositories.use-case.js +50 -0
  236. package/dist/src/modules/git/application/git-client.js +62 -0
  237. package/dist/src/modules/git/application/pull-repositories.use-case.js +67 -0
  238. package/dist/src/modules/git/application/repositories.js +67 -0
  239. package/dist/src/modules/git/application/show-status.use-case.js +49 -0
  240. package/dist/src/modules/git/application/switch-branch.use-case.js +118 -0
  241. package/dist/src/modules/git/domain/repository-status.js +37 -0
  242. package/dist/src/modules/git/git.module.js +25 -0
  243. package/dist/src/modules/git/presentation/git.views.js +100 -0
  244. package/dist/src/modules/net/application/check-connection.use-case.js +71 -0
  245. package/dist/src/modules/net/application/list-addresses.use-case.js +29 -0
  246. package/dist/src/modules/net/application/lookup-name.use-case.js +55 -0
  247. package/dist/src/modules/net/net.module.js +17 -0
  248. package/dist/src/modules/net/presentation/net.views.js +39 -0
  249. package/dist/src/modules/open/application/open-target.use-case.js +53 -0
  250. package/dist/src/modules/open/domain/targets.js +45 -0
  251. package/dist/src/modules/open/open.module.js +12 -0
  252. package/dist/src/modules/open/presentation/open.view.js +6 -0
  253. package/dist/src/modules/port/application/end-port-owners.use-case.js +68 -0
  254. package/dist/src/modules/port/application/find-free-port.use-case.js +40 -0
  255. package/dist/src/modules/port/application/find-listeners.use-case.js +34 -0
  256. package/dist/src/modules/port/application/port-owners.js +25 -0
  257. package/dist/src/modules/port/domain/port-number.js +8 -0
  258. package/dist/src/modules/port/port.module.js +17 -0
  259. package/dist/src/modules/port/presentation/port.views.js +27 -0
  260. package/dist/src/modules/proc/application/end-processes.use-case.js +77 -0
  261. package/dist/src/modules/proc/application/find-processes.use-case.js +50 -0
  262. package/dist/src/modules/proc/application/list-processes.use-case.js +41 -0
  263. package/dist/src/modules/proc/application/show-tree.use-case.js +40 -0
  264. package/dist/src/modules/proc/domain/process-tree.js +55 -0
  265. package/dist/src/modules/proc/presentation/proc.views.js +28 -0
  266. package/dist/src/modules/proc/proc.module.js +19 -0
  267. package/dist/src/modules/sys/application/create-report.use-case.js +30 -0
  268. package/dist/src/modules/sys/application/find-tools.use-case.js +20 -0
  269. package/dist/src/modules/sys/application/machine-facts.js +44 -0
  270. package/dist/src/modules/sys/application/show-info.use-case.js +29 -0
  271. package/dist/src/modules/sys/domain/tools.js +17 -0
  272. package/dist/src/modules/sys/presentation/sys.views.js +67 -0
  273. package/dist/src/modules/sys/sys.module.js +17 -0
  274. package/dist/src/modules/wait/application/poll.js +26 -0
  275. package/dist/src/modules/wait/application/wait-file.use-case.js +55 -0
  276. package/dist/src/modules/wait/application/wait-port.use-case.js +76 -0
  277. package/dist/src/modules/wait/application/wait-url.use-case.js +71 -0
  278. package/dist/src/modules/wait/domain/reasons.js +14 -0
  279. package/dist/src/modules/wait/domain/wait-input.js +50 -0
  280. package/dist/src/modules/wait/presentation/wait.views.js +31 -0
  281. package/dist/src/modules/wait/wait.module.js +21 -0
  282. package/package.json +57 -0
@@ -0,0 +1,6 @@
1
+ import { message } from "../../../core/domain/message.js";
2
+ /** The script exactly, so it can be piped into a file or evaluated. */
3
+ export const scriptView = (output) => output.script.replace(/\n$/, "").split("\n");
4
+ /** One suggestion per line: the value, a tab, and its description, which may be empty. */
5
+ export const suggestView = (output, format) => output.suggestions.map((suggestion) => `${suggestion.value}\t${suggestion.description === null ? "" : format.text(message(suggestion.description))}`);
6
+ //# sourceMappingURL=completion.views.js.map
@@ -0,0 +1,14 @@
1
+ import { RawReader } from "../../../core/domain/input-schema.js";
2
+ export const noInput = { positionals: [], options: {}, parse: () => ({}) };
3
+ export const keyInput = {
4
+ positionals: [{ name: "key", description: "config.arg.key", required: true, variadic: false }],
5
+ options: {},
6
+ parse: (raw) => ({ key: new RawReader(raw).positional(0) ?? "" }),
7
+ };
8
+ /** What every config command shares: they read or write one small local file. */
9
+ export const CONFIG_COMMAND = {
10
+ idempotent: true,
11
+ usesNetwork: false,
12
+ runsUserCommands: false,
13
+ };
14
+ //# sourceMappingURL=config-commands.js.map
@@ -0,0 +1,25 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { NotFoundError } from "../../../core/domain/errors.js";
3
+ import { CONFIG_COMMAND, keyInput } from "./config-commands.js";
4
+ export const getSpec = {
5
+ id: "config.get",
6
+ summary: "config.get.summary",
7
+ examples: ["kiriya config get plugins"],
8
+ safety: "read",
9
+ ...CONFIG_COMMAND,
10
+ input: keyInput,
11
+ };
12
+ export class GetSetting {
13
+ config;
14
+ spec = getSpec;
15
+ constructor(config) {
16
+ this.config = config;
17
+ }
18
+ async execute(input) {
19
+ const value = (await this.config.read())[input.key];
20
+ if (value === undefined)
21
+ throw new NotFoundError("config.get.not-set", { key: input.key });
22
+ return done({ key: input.key, value });
23
+ }
24
+ }
25
+ //# sourceMappingURL=get-setting.use-case.js.map
@@ -0,0 +1,26 @@
1
+ import { CONFIG_KEYS } from "../../../config/config-keys.js";
2
+ import { done } from "../../../core/domain/command.js";
3
+ import { message } from "../../../core/domain/message.js";
4
+ import { CONFIG_COMMAND, noInput } from "./config-commands.js";
5
+ export const keysSpec = {
6
+ id: "config.keys",
7
+ summary: "config.keys.summary",
8
+ examples: ["kiriya config keys"],
9
+ safety: "read",
10
+ ...CONFIG_COMMAND,
11
+ input: noInput,
12
+ };
13
+ export class ListConfigKeys {
14
+ spec = keysSpec;
15
+ execute() {
16
+ const keys = CONFIG_KEYS.map((entry) => ({
17
+ key: entry.key,
18
+ type: entry.type,
19
+ description: message(entry.description),
20
+ example: entry.example,
21
+ choices: entry.choices ?? null,
22
+ }));
23
+ return Promise.resolve(done({ keys }));
24
+ }
25
+ }
26
+ //# sourceMappingURL=list-config-keys.use-case.js.map
@@ -0,0 +1,28 @@
1
+ import { CONFIG_KEYS } from "../../../config/config-keys.js";
2
+ import { checkConfigTypes, configKey } from "../../../core/application/config-values.js";
3
+ import { done } from "../../../core/domain/command.js";
4
+ import { byCodePoint } from "../../../core/domain/names.js";
5
+ import { CONFIG_COMMAND, noInput } from "./config-commands.js";
6
+ export const listSpec = {
7
+ id: "config.list",
8
+ summary: "config.list.summary",
9
+ examples: ["kiriya config list", "kiriya config list --json"],
10
+ safety: "read",
11
+ ...CONFIG_COMMAND,
12
+ input: noInput,
13
+ };
14
+ export class ListSettings {
15
+ config;
16
+ spec = listSpec;
17
+ constructor(config) {
18
+ this.config = config;
19
+ }
20
+ async execute() {
21
+ const values = await this.config.read();
22
+ checkConfigTypes(values, this.config.path);
23
+ const keys = [...new Set([...CONFIG_KEYS.map((entry) => entry.key), ...Object.keys(values)])].sort(byCodePoint);
24
+ const settings = keys.map((key) => ({ key, value: values[key] ?? null, known: configKey(key) !== undefined }));
25
+ return done({ path: this.config.path, settings });
26
+ }
27
+ }
28
+ //# sourceMappingURL=list-settings.use-case.js.map
@@ -0,0 +1,53 @@
1
+ import { checkConfigTypes, configKey } from "../../../core/application/config-values.js";
2
+ import { done } from "../../../core/domain/command.js";
3
+ import { RefusedError, UsageError } from "../../../core/domain/errors.js";
4
+ import { RawReader } from "../../../core/domain/input-schema.js";
5
+ import { looksSecret } from "../../../core/domain/secrets.js";
6
+ import { CONFIG_COMMAND } from "./config-commands.js";
7
+ export const setSpec = {
8
+ id: "config.set",
9
+ summary: "config.set.summary",
10
+ examples: ["kiriya config set plugins kiriya-plugin-example", "kiriya config set plugins ./team/plugin ./my/plugin"],
11
+ safety: "write",
12
+ ...CONFIG_COMMAND,
13
+ // Over MCP an agent could turn on more tools for itself, or list a plugin that runs its own code.
14
+ terminalOnly: true,
15
+ input: {
16
+ positionals: [
17
+ { name: "key", description: "config.set.arg.key", required: true, variadic: false },
18
+ { name: "values", description: "config.set.arg.values", required: true, variadic: true },
19
+ ],
20
+ options: {},
21
+ parse(raw) {
22
+ const reader = new RawReader(raw);
23
+ return { key: reader.positional(0) ?? "", values: reader.positionalsFrom(1) };
24
+ },
25
+ },
26
+ };
27
+ export class SetSetting {
28
+ config;
29
+ spec = setSpec;
30
+ constructor(config) {
31
+ this.config = config;
32
+ }
33
+ async execute(input) {
34
+ const known = configKey(input.key);
35
+ if (known === undefined)
36
+ throw new UsageError("config.set.unknown-key", { key: input.key });
37
+ if (known.type === "string" && input.values.length !== 1) {
38
+ throw new UsageError("config.set.one-value", { key: input.key });
39
+ }
40
+ if (known.choices !== undefined && !known.choices.includes(input.values[0] ?? "")) {
41
+ throw new UsageError("config.set.not-a-choice", { key: input.key, choices: known.choices.join(", ") });
42
+ }
43
+ // The file sits in plain text in the user's profile, so it never takes a secret.
44
+ if (input.values.some(looksSecret))
45
+ throw new RefusedError("config.set.secret");
46
+ const current = await this.config.read();
47
+ checkConfigTypes(current, this.config.path);
48
+ const value = known.type === "list" ? [...input.values] : (input.values[0] ?? "");
49
+ await this.config.write({ ...current, [input.key]: value });
50
+ return done({ key: input.key, value, previous: current[input.key] ?? null });
51
+ }
52
+ }
53
+ //# sourceMappingURL=set-setting.use-case.js.map
@@ -0,0 +1,21 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { CONFIG_COMMAND, noInput } from "./config-commands.js";
3
+ export const pathSpec = {
4
+ id: "config.path",
5
+ summary: "config.path.summary",
6
+ examples: ["kiriya config path"],
7
+ safety: "read",
8
+ ...CONFIG_COMMAND,
9
+ input: noInput,
10
+ };
11
+ export class ShowConfigPath {
12
+ config;
13
+ spec = pathSpec;
14
+ constructor(config) {
15
+ this.config = config;
16
+ }
17
+ async execute() {
18
+ return done({ path: this.config.path, exists: await this.config.exists() });
19
+ }
20
+ }
21
+ //# sourceMappingURL=show-config-path.use-case.js.map
@@ -0,0 +1,28 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { CONFIG_COMMAND, keyInput } from "./config-commands.js";
3
+ export const unsetSpec = {
4
+ id: "config.unset",
5
+ summary: "config.unset.summary",
6
+ examples: ["kiriya config unset plugins"],
7
+ safety: "write",
8
+ ...CONFIG_COMMAND,
9
+ // Over MCP an agent could take back a limit the user set.
10
+ terminalOnly: true,
11
+ input: keyInput,
12
+ };
13
+ export class UnsetSetting {
14
+ config;
15
+ spec = unsetSpec;
16
+ constructor(config) {
17
+ this.config = config;
18
+ }
19
+ async execute(input) {
20
+ const current = await this.config.read();
21
+ if (!(input.key in current))
22
+ return done({ key: input.key, removed: false });
23
+ const remaining = Object.fromEntries(Object.entries(current).filter(([key]) => key !== input.key));
24
+ await this.config.write(remaining);
25
+ return done({ key: input.key, removed: true });
26
+ }
27
+ }
28
+ //# sourceMappingURL=unset-setting.use-case.js.map
@@ -0,0 +1,28 @@
1
+ import { GetSetting } from "./application/get-setting.use-case.js";
2
+ import { ListConfigKeys } from "./application/list-config-keys.use-case.js";
3
+ import { ListSettings } from "./application/list-settings.use-case.js";
4
+ import { SetSetting } from "./application/set-setting.use-case.js";
5
+ import { ShowConfigPath } from "./application/show-config-path.use-case.js";
6
+ import { UnsetSetting } from "./application/unset-setting.use-case.js";
7
+ import { getView, keysView, listView, pathView, setView, unsetView } from "./presentation/config.views.js";
8
+ export const configModule = {
9
+ id: "config",
10
+ summary: "config.summary",
11
+ about: "config.about",
12
+ examples: [
13
+ "kiriya config path",
14
+ "kiriya config keys",
15
+ "kiriya config set plugins kiriya-plugin-example",
16
+ "kiriya config set mcp.allowWrite true",
17
+ ],
18
+ guide: "https://github.com/SatPaingOo/kiriya/blob/main/docs/modules/config.md",
19
+ register(registrar, ports) {
20
+ registrar.add(new ShowConfigPath(ports.config), pathView);
21
+ registrar.add(new ListConfigKeys(), keysView);
22
+ registrar.add(new ListSettings(ports.config), listView);
23
+ registrar.add(new GetSetting(ports.config), getView);
24
+ registrar.add(new SetSetting(ports.config), setView);
25
+ registrar.add(new UnsetSetting(ports.config), unsetView);
26
+ },
27
+ };
28
+ //# sourceMappingURL=config.module.js.map
@@ -0,0 +1,33 @@
1
+ import { message } from "../../../core/domain/message.js";
2
+ const shown = (value) => (typeof value === "string" ? value : value.join(", "));
3
+ /** Only the path, so `$(kiriya config path)` works in a script. */
4
+ export const pathView = (output) => [output.path];
5
+ export const keysView = (output, format) => output.keys.flatMap((entry) => [
6
+ `${format.bold(entry.key)} ${format.dim(entry.type)} ${format.text(entry.description)}`,
7
+ ...(entry.choices === null
8
+ ? []
9
+ : [format.dim(` ${format.text(message("config.keys.choices", { choices: entry.choices.join(", ") }))}`)]),
10
+ format.dim(` ${format.text(message("config.keys.example", { command: `kiriya config set ${entry.key} ${entry.example}` }))}`),
11
+ ]);
12
+ export const listView = (output, format) => {
13
+ const width = Math.max(0, ...output.settings.map((setting) => setting.key.length));
14
+ return [
15
+ format.dim(output.path),
16
+ ...output.settings.map((setting) => {
17
+ const value = setting.value === null ? format.dim(format.text(message("config.list.not-set"))) : shown(setting.value);
18
+ const unknown = setting.known ? "" : ` ${format.dim(format.text(message("config.list.unknown")))}`;
19
+ return ` ${setting.key.padEnd(width)} ${value}${unknown}`;
20
+ }),
21
+ ];
22
+ };
23
+ /** One value per line, so a list setting can be read line by line. */
24
+ export const getView = (output) => typeof output.value === "string" ? [output.value] : [...output.value];
25
+ export const setView = (output, format) => [
26
+ format.green(format.text(message("config.set.done", { key: output.key, value: shown(output.value) }))),
27
+ ];
28
+ export const unsetView = (output, format) => [
29
+ output.removed
30
+ ? format.green(format.text(message("config.unset.done", { key: output.key })))
31
+ : format.dim(format.text(message("config.unset.not-set", { key: output.key }))),
32
+ ];
33
+ //# sourceMappingURL=config.views.js.map
@@ -0,0 +1,38 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { UsageError } from "../../../core/domain/errors.js";
3
+ import { RawReader } from "../../../core/domain/input-schema.js";
4
+ import { TEXT_CASES, toCase } from "../../../core/domain/text-case.js";
5
+ import { CONVERTER, fileOption, inputText, readInput, valuePositional } from "./convert-input.js";
6
+ export const caseSpec = {
7
+ id: "convert.case",
8
+ summary: "convert.case.summary",
9
+ examples: ['kiriya convert case "user profile id" --to camel', "kiriya convert case OrderItems --to kebab"],
10
+ ...CONVERTER,
11
+ input: {
12
+ positionals: [valuePositional],
13
+ options: {
14
+ to: { type: "string", description: "convert.case.option.to", valueName: `<${TEXT_CASES.join("|")}>` },
15
+ file: fileOption,
16
+ },
17
+ parse(raw) {
18
+ const reader = new RawReader(raw);
19
+ if (reader.string("to") === undefined)
20
+ throw new UsageError("convert.case.to-required");
21
+ return { value: reader.positional(0), file: reader.string("file"), to: reader.choice("to", TEXT_CASES, "kebab") };
22
+ },
23
+ },
24
+ };
25
+ export class ConvertCase {
26
+ sources;
27
+ spec = caseSpec;
28
+ constructor(sources) {
29
+ this.sources = sources;
30
+ }
31
+ async execute(input, context) {
32
+ const text = inputText(await readInput(this.sources, context.cwd, input.value, input.file));
33
+ // Each line changes on its own, so a list of names stays a list.
34
+ const lines = text.split(/\r?\n/).map((line) => toCase(line, input.to));
35
+ return done({ output: lines.join("\n") });
36
+ }
37
+ }
38
+ //# sourceMappingURL=convert-case.use-case.js.map
@@ -0,0 +1,92 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { fromBase64, fromHex, toBase64, toHex, utf8Text } from "../../../core/domain/encodings.js";
3
+ import { OperationFailedError, UsageError } from "../../../core/domain/errors.js";
4
+ import { RawReader } from "../../../core/domain/input-schema.js";
5
+ import { CONVERTER, fileOption, inputBytes, inputText, readInput, valuePositional, } from "./convert-input.js";
6
+ function decodedText(bytes, invalid) {
7
+ if (bytes === null)
8
+ throw new UsageError(invalid);
9
+ const text = utf8Text(bytes);
10
+ if (text === null)
11
+ throw new OperationFailedError("convert.decoded-binary");
12
+ return text;
13
+ }
14
+ const CODECS = {
15
+ base64: {
16
+ encode: (input, urlSafe) => toBase64(inputBytes(input), urlSafe),
17
+ decode: (text) => decodedText(fromBase64(text), "convert.base64.invalid"),
18
+ },
19
+ hex: {
20
+ encode: (input) => toHex(inputBytes(input)),
21
+ decode: (text) => decodedText(fromHex(text), "convert.hex.invalid"),
22
+ },
23
+ url: {
24
+ encode: (input) => encodeURIComponent(inputText(input)),
25
+ decode: (text) => {
26
+ try {
27
+ return decodeURIComponent(text);
28
+ }
29
+ catch {
30
+ throw new UsageError("convert.url.invalid");
31
+ }
32
+ },
33
+ },
34
+ };
35
+ const SUMMARIES = {
36
+ base64: "convert.base64.summary",
37
+ hex: "convert.hex.summary",
38
+ url: "convert.url.summary",
39
+ };
40
+ const EXAMPLES = {
41
+ base64: [
42
+ 'kiriya convert base64 "hello"',
43
+ "kiriya convert base64 --decode aGVsbG8=",
44
+ "kiriya convert base64 --file logo.png",
45
+ ],
46
+ hex: ['kiriya convert hex "hello"', "kiriya convert hex --decode 68656c6c6f"],
47
+ url: ['kiriya convert url "a b&c"', "kiriya convert url --decode a%20b%26c"],
48
+ };
49
+ function codecSpec(name) {
50
+ const options = {
51
+ decode: { type: "boolean", description: "convert.option.decode", short: "d" },
52
+ file: fileOption,
53
+ };
54
+ if (name === "base64")
55
+ options["url"] = { type: "boolean", description: "convert.base64.option.url" };
56
+ return {
57
+ id: `convert.${name}`,
58
+ summary: SUMMARIES[name],
59
+ examples: EXAMPLES[name],
60
+ ...CONVERTER,
61
+ input: {
62
+ positionals: [valuePositional],
63
+ options,
64
+ parse(raw) {
65
+ const reader = new RawReader(raw);
66
+ return {
67
+ value: reader.positional(0),
68
+ file: reader.string("file"),
69
+ decode: reader.flag("decode"),
70
+ urlSafe: reader.flag("url"),
71
+ };
72
+ },
73
+ },
74
+ };
75
+ }
76
+ /** One command per codec: `convert base64`, `convert hex` and `convert url`. */
77
+ export class ConvertCodec {
78
+ sources;
79
+ spec;
80
+ codec;
81
+ constructor(name, sources) {
82
+ this.sources = sources;
83
+ this.spec = codecSpec(name);
84
+ this.codec = CODECS[name];
85
+ }
86
+ async execute(input, context) {
87
+ const read = await readInput(this.sources, context.cwd, input.value, input.file);
88
+ const output = input.decode ? this.codec.decode(inputText(read)) : this.codec.encode(read, input.urlSafe);
89
+ return done({ output });
90
+ }
91
+ }
92
+ //# sourceMappingURL=convert-codecs.use-case.js.map
@@ -0,0 +1,16 @@
1
+ export { inputBytes, inputText, readInput } from "../../../core/application/text-input.js";
2
+ /** Every conversion runs on this machine, changes nothing, and gives the same result for the same input. */
3
+ export const CONVERTER = { safety: "read", idempotent: true, usesNetwork: false, runsUserCommands: false };
4
+ export const valuePositional = {
5
+ name: "value",
6
+ description: "convert.arg.value",
7
+ required: false,
8
+ variadic: false,
9
+ };
10
+ export const fileOption = {
11
+ type: "string",
12
+ description: "convert.option.file",
13
+ valueName: "<path>",
14
+ path: true,
15
+ };
16
+ //# sourceMappingURL=convert-input.js.map
@@ -0,0 +1,51 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { RawReader } from "../../../core/domain/input-schema.js";
3
+ import { message } from "../../../core/domain/message.js";
4
+ import { findJsonProblem } from "../domain/json-syntax.js";
5
+ import { CONVERTER, fileOption, inputText, readInput, valuePositional } from "./convert-input.js";
6
+ export const jsonSpec = {
7
+ id: "convert.json",
8
+ summary: "convert.json.summary",
9
+ examples: [
10
+ "kiriya convert json --file package.json",
11
+ "kiriya convert json --minify < data.json",
12
+ "kiriya convert json --check --file config.json",
13
+ ],
14
+ ...CONVERTER,
15
+ input: {
16
+ positionals: [valuePositional],
17
+ options: {
18
+ minify: { type: "boolean", description: "convert.json.option.minify" },
19
+ check: { type: "boolean", description: "convert.json.option.check" },
20
+ file: fileOption,
21
+ },
22
+ parse(raw) {
23
+ const reader = new RawReader(raw);
24
+ return {
25
+ value: reader.positional(0),
26
+ file: reader.string("file"),
27
+ minify: reader.flag("minify"),
28
+ check: reader.flag("check"),
29
+ };
30
+ },
31
+ },
32
+ };
33
+ export class ConvertJson {
34
+ sources;
35
+ spec = jsonSpec;
36
+ constructor(sources) {
37
+ this.sources = sources;
38
+ }
39
+ async execute(input, context) {
40
+ const text = inputText(await readInput(this.sources, context.cwd, input.value, input.file));
41
+ const problem = findJsonProblem(text);
42
+ if (problem !== null) {
43
+ const where = { line: problem.line, column: problem.column };
44
+ return done({ valid: false, output: null, ...where }, { failures: [message("convert.json.invalid", where)] });
45
+ }
46
+ const parsed = JSON.parse(text);
47
+ const output = input.check ? null : JSON.stringify(parsed, null, input.minify ? undefined : 2);
48
+ return done({ valid: true, output, line: null, column: null });
49
+ }
50
+ }
51
+ //# sourceMappingURL=convert-json.use-case.js.map
@@ -0,0 +1,39 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { UsageError } from "../../../core/domain/errors.js";
3
+ import { RawReader } from "../../../core/domain/input-schema.js";
4
+ import { EPOCH_UNITS, parseMoment } from "../domain/moments.js";
5
+ import { CONVERTER } from "./convert-input.js";
6
+ export const timeSpec = {
7
+ id: "convert.time",
8
+ summary: "convert.time.summary",
9
+ examples: [
10
+ "kiriya convert time",
11
+ "kiriya convert time 1767225600",
12
+ "kiriya convert time 2026-01-31T12:00:00Z --json",
13
+ ],
14
+ ...CONVERTER,
15
+ // Without a value it shows now.
16
+ idempotent: false,
17
+ input: {
18
+ positionals: [{ name: "value", description: "convert.time.arg.value", required: false, variadic: false }],
19
+ options: { unit: { type: "string", description: "convert.time.option.unit", valueName: "<auto|seconds|ms>" } },
20
+ parse(raw) {
21
+ const reader = new RawReader(raw);
22
+ return { value: reader.positional(0), unit: reader.choice("unit", EPOCH_UNITS, "auto") };
23
+ },
24
+ },
25
+ };
26
+ export class ConvertTime {
27
+ clock;
28
+ spec = timeSpec;
29
+ constructor(clock) {
30
+ this.clock = clock;
31
+ }
32
+ execute(input) {
33
+ const ms = input.value === undefined ? this.clock.now() : parseMoment(input.value, input.unit);
34
+ if (ms === null)
35
+ throw new UsageError("convert.time.invalid", { value: input.value ?? "" });
36
+ return Promise.resolve(done({ iso: new Date(ms).toISOString(), epochSeconds: Math.floor(ms / 1000), epochMs: ms }));
37
+ }
38
+ }
39
+ //# sourceMappingURL=convert-time.use-case.js.map
@@ -0,0 +1,52 @@
1
+ import { done } from "../../../core/domain/command.js";
2
+ import { UsageError } from "../../../core/domain/errors.js";
3
+ import { RawReader } from "../../../core/domain/input-schema.js";
4
+ import { message } from "../../../core/domain/message.js";
5
+ import { claimTime, decodeJwt } from "../domain/jwt.js";
6
+ import { CONVERTER, fileOption, inputText, readInput, valuePositional } from "./convert-input.js";
7
+ export const jwtSpec = {
8
+ id: "convert.jwt",
9
+ summary: "convert.jwt.summary",
10
+ examples: ["kiriya convert jwt < token.txt", "kiriya convert jwt --file token.txt --json"],
11
+ ...CONVERTER,
12
+ // Whether a token has expired depends on when it is asked.
13
+ idempotent: false,
14
+ input: {
15
+ positionals: [valuePositional],
16
+ options: { file: fileOption },
17
+ parse(raw) {
18
+ const reader = new RawReader(raw);
19
+ return { value: reader.positional(0), file: reader.string("file") };
20
+ },
21
+ },
22
+ };
23
+ const isoTime = (ms) => (ms === null ? null : new Date(ms).toISOString());
24
+ /** Decodes on this machine and never checks the signature: the claims say what the token says, not that it is genuine. */
25
+ export class DecodeJwt {
26
+ sources;
27
+ clock;
28
+ spec = jwtSpec;
29
+ constructor(sources, clock) {
30
+ this.sources = sources;
31
+ this.clock = clock;
32
+ }
33
+ async execute(input, context) {
34
+ const read = await readInput(this.sources, context.cwd, input.value, input.file);
35
+ const decoded = decodeJwt(inputText(read));
36
+ if (decoded === null)
37
+ throw new UsageError("convert.jwt.invalid");
38
+ const expires = claimTime(decoded.payload, "exp");
39
+ const warnings = [message("convert.jwt.unverified")];
40
+ if (read.from === "argument")
41
+ warnings.push(message("convert.jwt.from-argument"));
42
+ return done({
43
+ header: decoded.header,
44
+ payload: decoded.payload,
45
+ issuedAt: isoTime(claimTime(decoded.payload, "iat")),
46
+ notBefore: isoTime(claimTime(decoded.payload, "nbf")),
47
+ expiresAt: isoTime(expires),
48
+ expired: expires === null ? null : expires <= this.clock.now(),
49
+ }, { warnings });
50
+ }
51
+ }
52
+ //# sourceMappingURL=decode-jwt.use-case.js.map
@@ -0,0 +1,29 @@
1
+ import { ConvertCase } from "./application/convert-case.use-case.js";
2
+ import { ConvertCodec } from "./application/convert-codecs.use-case.js";
3
+ import { ConvertJson } from "./application/convert-json.use-case.js";
4
+ import { ConvertTime } from "./application/convert-time.use-case.js";
5
+ import { DecodeJwt } from "./application/decode-jwt.use-case.js";
6
+ import { jsonView, jwtView, outputView, timeView } from "./presentation/convert.views.js";
7
+ export const convertModule = {
8
+ id: "convert",
9
+ summary: "convert.summary",
10
+ about: "convert.about",
11
+ examples: [
12
+ "kiriya convert base64 --decode aGVsbG8=",
13
+ "kiriya convert json --file package.json",
14
+ "kiriya convert jwt --file token.txt",
15
+ "kiriya convert time 1767225600",
16
+ ],
17
+ guide: "https://github.com/SatPaingOo/kiriya/blob/main/docs/modules/convert.md",
18
+ register(registrar, ports) {
19
+ const sources = { stdin: ports.stdin, fileSystem: ports.fileSystem, content: ports.fileContent };
20
+ registrar.add(new ConvertCodec("base64", sources), outputView);
21
+ registrar.add(new ConvertCodec("hex", sources), outputView);
22
+ registrar.add(new ConvertCodec("url", sources), outputView);
23
+ registrar.add(new ConvertJson(sources), jsonView);
24
+ registrar.add(new DecodeJwt(sources, ports.clock), jwtView);
25
+ registrar.add(new ConvertTime(ports.clock), timeView);
26
+ registrar.add(new ConvertCase(sources), outputView);
27
+ },
28
+ };
29
+ //# sourceMappingURL=convert.module.js.map