@codemieai/code 0.0.45 → 0.0.47

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 (398) hide show
  1. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  2. package/dist/agents/core/BaseAgentAdapter.js +20 -3
  3. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  4. package/dist/agents/core/metrics/types.d.ts +0 -6
  5. package/dist/agents/core/metrics/types.d.ts.map +1 -1
  6. package/dist/agents/core/session/BaseSessionAdapter.d.ts +0 -6
  7. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  8. package/dist/agents/plugins/claude/claude.plugin-installer.d.ts +0 -11
  9. package/dist/agents/plugins/claude/claude.plugin-installer.d.ts.map +1 -1
  10. package/dist/agents/plugins/claude/claude.plugin-installer.js +0 -32
  11. package/dist/agents/plugins/claude/claude.plugin-installer.js.map +1 -1
  12. package/dist/agents/plugins/claude/claude.plugin.js +1 -1
  13. package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
  14. package/dist/agents/plugins/claude/claude.session.js +1 -28
  15. package/dist/agents/plugins/claude/claude.session.js.map +1 -1
  16. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  17. package/dist/agents/plugins/claude/plugin/README.md +1 -14
  18. package/dist/agents/plugins/claude/plugin/hooks/hooks.json +4 -4
  19. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/SKILL.md +206 -0
  20. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-agent.md +45 -0
  21. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-claude-md-snippet.md +40 -0
  22. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-command.md +30 -0
  23. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-hooks.json +23 -0
  24. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-skill.md +48 -0
  25. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-agent.md +145 -0
  26. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-claude-md-snippet.md +126 -0
  27. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-command.md +170 -0
  28. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-hooks.json +46 -0
  29. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-skill.md +144 -0
  30. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/sample-report.md +223 -0
  31. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/best-practices.md +510 -0
  32. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/component-checklists.md +413 -0
  33. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/scripts/scan-repo.sh +162 -0
  34. package/dist/agents/plugins/claude/plugin/skills/msgraph/README.md +183 -0
  35. package/dist/agents/plugins/claude/plugin/skills/msgraph/SKILL.md +233 -0
  36. package/dist/agents/plugins/claude/plugin/skills/msgraph/scripts/msgraph.py +785 -0
  37. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
  38. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +3 -78
  39. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
  40. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -1
  41. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +7 -16
  42. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -1
  43. package/dist/agents/plugins/claude/sounds-installer.d.ts +1 -1
  44. package/dist/agents/plugins/claude/sounds-installer.d.ts.map +1 -1
  45. package/dist/agents/plugins/claude/sounds-installer.js +1 -4
  46. package/dist/agents/plugins/claude/sounds-installer.js.map +1 -1
  47. package/dist/agents/plugins/codemie-code.plugin.d.ts +1 -4
  48. package/dist/agents/plugins/codemie-code.plugin.d.ts.map +1 -1
  49. package/dist/agents/plugins/codemie-code.plugin.js +26 -81
  50. package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
  51. package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts +1 -8
  52. package/dist/agents/plugins/gemini/gemini.session-adapter.d.ts.map +1 -1
  53. package/dist/agents/plugins/gemini/gemini.session-adapter.js +2 -30
  54. package/dist/agents/plugins/gemini/gemini.session-adapter.js.map +1 -1
  55. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.d.ts.map +1 -1
  56. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js +2 -8
  57. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js.map +1 -1
  58. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.d.ts.map +1 -1
  59. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js +0 -7
  60. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js.map +1 -1
  61. package/dist/agents/plugins/opencode/index.d.ts +1 -1
  62. package/dist/agents/plugins/opencode/index.d.ts.map +1 -1
  63. package/dist/agents/plugins/opencode/index.js.map +1 -1
  64. package/dist/agents/plugins/opencode/opencode-message-types.d.ts +2 -22
  65. package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -1
  66. package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -1
  67. package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -1
  68. package/dist/agents/plugins/opencode/opencode.session.js +5 -30
  69. package/dist/agents/plugins/opencode/opencode.session.js.map +1 -1
  70. package/dist/agents/plugins/opencode/opencode.sqlite-reader.d.ts.map +1 -1
  71. package/dist/agents/plugins/opencode/opencode.sqlite-reader.js +0 -2
  72. package/dist/agents/plugins/opencode/opencode.sqlite-reader.js.map +1 -1
  73. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +0 -8
  74. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -1
  75. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +8 -97
  76. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -1
  77. package/dist/cli/commands/analytics/aggregator.d.ts +0 -8
  78. package/dist/cli/commands/analytics/aggregator.d.ts.map +1 -1
  79. package/dist/cli/commands/analytics/aggregator.js +5 -100
  80. package/dist/cli/commands/analytics/aggregator.js.map +1 -1
  81. package/dist/cli/commands/analytics/data-loader.d.ts +0 -7
  82. package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
  83. package/dist/cli/commands/analytics/data-loader.js +3 -10
  84. package/dist/cli/commands/analytics/data-loader.js.map +1 -1
  85. package/dist/cli/commands/analytics/exporter.d.ts.map +1 -1
  86. package/dist/cli/commands/analytics/exporter.js +0 -12
  87. package/dist/cli/commands/analytics/exporter.js.map +1 -1
  88. package/dist/cli/commands/analytics/formatter.d.ts.map +1 -1
  89. package/dist/cli/commands/analytics/formatter.js +0 -9
  90. package/dist/cli/commands/analytics/formatter.js.map +1 -1
  91. package/dist/cli/commands/analytics/types.d.ts +0 -17
  92. package/dist/cli/commands/analytics/types.d.ts.map +1 -1
  93. package/dist/cli/commands/assistants/chat/historyLoader.d.ts +22 -0
  94. package/dist/cli/commands/assistants/chat/historyLoader.d.ts.map +1 -0
  95. package/dist/cli/commands/assistants/chat/historyLoader.js +80 -0
  96. package/dist/cli/commands/assistants/chat/historyLoader.js.map +1 -0
  97. package/dist/cli/commands/assistants/{chat.d.ts → chat/index.d.ts} +1 -1
  98. package/dist/cli/commands/assistants/chat/index.d.ts.map +1 -0
  99. package/dist/cli/commands/assistants/{chat.js → chat/index.js} +54 -45
  100. package/dist/cli/commands/assistants/chat/index.js.map +1 -0
  101. package/dist/cli/commands/assistants/chat/types.d.ts +27 -0
  102. package/dist/cli/commands/assistants/chat/types.d.ts.map +1 -0
  103. package/dist/cli/commands/assistants/chat/types.js +5 -0
  104. package/dist/cli/commands/assistants/chat/types.js.map +1 -0
  105. package/dist/cli/commands/assistants/chat/utils.d.ts +12 -0
  106. package/dist/cli/commands/assistants/chat/utils.d.ts.map +1 -0
  107. package/dist/cli/commands/assistants/chat/utils.js +24 -0
  108. package/dist/cli/commands/assistants/chat/utils.js.map +1 -0
  109. package/dist/cli/commands/assistants/constants.d.ts +1 -0
  110. package/dist/cli/commands/assistants/constants.d.ts.map +1 -1
  111. package/dist/cli/commands/assistants/constants.js.map +1 -1
  112. package/dist/cli/commands/assistants/index.js +2 -2
  113. package/dist/cli/commands/assistants/index.js.map +1 -1
  114. package/dist/cli/commands/assistants/setup/generators/claude-agent-generator.js +1 -1
  115. package/dist/cli/commands/assistants/setup/generators/claude-skill-generator.js +1 -1
  116. package/dist/cli/commands/assistants/setup/index.js +4 -4
  117. package/dist/cli/commands/assistants/setup/index.js.map +1 -1
  118. package/dist/cli/commands/assistants/setup/selection/index.d.ts +1 -1
  119. package/dist/cli/commands/assistants/setup/selection/index.d.ts.map +1 -1
  120. package/dist/cli/commands/assistants/setup/selection/index.js +5 -3
  121. package/dist/cli/commands/assistants/setup/selection/index.js.map +1 -1
  122. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.d.ts.map +1 -1
  123. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.js +7 -1
  124. package/dist/cli/commands/assistants/setup/selection/interactive-prompt.js.map +1 -1
  125. package/dist/cli/commands/assistants/setup/selection/types.d.ts +2 -0
  126. package/dist/cli/commands/assistants/setup/selection/types.d.ts.map +1 -1
  127. package/dist/cli/commands/assistants/setup/selection/ui.d.ts.map +1 -1
  128. package/dist/cli/commands/assistants/setup/selection/ui.js +15 -4
  129. package/dist/cli/commands/assistants/setup/selection/ui.js.map +1 -1
  130. package/dist/cli/commands/hook.js +1 -1
  131. package/dist/cli/commands/hook.js.map +1 -1
  132. package/dist/cli/commands/plugin.d.ts +16 -0
  133. package/dist/cli/commands/plugin.d.ts.map +1 -0
  134. package/dist/cli/commands/plugin.js +210 -0
  135. package/dist/cli/commands/plugin.js.map +1 -0
  136. package/dist/cli/commands/setup.js +1 -1
  137. package/dist/cli/commands/skill.d.ts.map +1 -1
  138. package/dist/cli/commands/skill.js +3 -1
  139. package/dist/cli/commands/skill.js.map +1 -1
  140. package/dist/cli/commands/sound.d.ts +3 -0
  141. package/dist/cli/commands/sound.d.ts.map +1 -0
  142. package/dist/cli/commands/sound.js +87 -0
  143. package/dist/cli/commands/sound.js.map +1 -0
  144. package/dist/cli/commands/test-metrics.js +3 -5
  145. package/dist/cli/commands/test-metrics.js.map +1 -1
  146. package/dist/cli/index.js +4 -0
  147. package/dist/cli/index.js.map +1 -1
  148. package/dist/env/types.d.ts +8 -0
  149. package/dist/env/types.d.ts.map +1 -1
  150. package/dist/env/types.js.map +1 -1
  151. package/dist/plugins/core/index.d.ts +13 -0
  152. package/dist/plugins/core/index.d.ts.map +1 -0
  153. package/dist/plugins/core/index.js +15 -0
  154. package/dist/plugins/core/index.js.map +1 -0
  155. package/dist/plugins/core/manifest-parser.d.ts +28 -0
  156. package/dist/plugins/core/manifest-parser.d.ts.map +1 -0
  157. package/dist/plugins/core/manifest-parser.js +137 -0
  158. package/dist/plugins/core/manifest-parser.js.map +1 -0
  159. package/dist/plugins/core/plugin-cache.d.ts +65 -0
  160. package/dist/plugins/core/plugin-cache.d.ts.map +1 -0
  161. package/dist/plugins/core/plugin-cache.js +170 -0
  162. package/dist/plugins/core/plugin-cache.js.map +1 -0
  163. package/dist/plugins/core/plugin-loader.d.ts +21 -0
  164. package/dist/plugins/core/plugin-loader.d.ts.map +1 -0
  165. package/dist/plugins/core/plugin-loader.js +55 -0
  166. package/dist/plugins/core/plugin-loader.js.map +1 -0
  167. package/dist/plugins/core/plugin-resolver.d.ts +33 -0
  168. package/dist/plugins/core/plugin-resolver.d.ts.map +1 -0
  169. package/dist/plugins/core/plugin-resolver.js +118 -0
  170. package/dist/plugins/core/plugin-resolver.js.map +1 -0
  171. package/dist/plugins/core/types.d.ts +183 -0
  172. package/dist/plugins/core/types.d.ts.map +1 -0
  173. package/dist/plugins/core/types.js +22 -0
  174. package/dist/plugins/core/types.js.map +1 -0
  175. package/dist/plugins/loaders/agents-loader.d.ts +19 -0
  176. package/dist/plugins/loaders/agents-loader.d.ts.map +1 -0
  177. package/dist/plugins/loaders/agents-loader.js +92 -0
  178. package/dist/plugins/loaders/agents-loader.js.map +1 -0
  179. package/dist/plugins/loaders/hooks-loader.d.ts +27 -0
  180. package/dist/plugins/loaders/hooks-loader.d.ts.map +1 -0
  181. package/dist/plugins/loaders/hooks-loader.js +94 -0
  182. package/dist/plugins/loaders/hooks-loader.js.map +1 -0
  183. package/dist/plugins/loaders/mcp-loader.d.ts +24 -0
  184. package/dist/plugins/loaders/mcp-loader.d.ts.map +1 -0
  185. package/dist/plugins/loaders/mcp-loader.js +86 -0
  186. package/dist/plugins/loaders/mcp-loader.js.map +1 -0
  187. package/dist/plugins/loaders/skills-loader.d.ts +30 -0
  188. package/dist/plugins/loaders/skills-loader.d.ts.map +1 -0
  189. package/dist/plugins/loaders/skills-loader.js +167 -0
  190. package/dist/plugins/loaders/skills-loader.js.map +1 -0
  191. package/dist/providers/plugins/bedrock/bedrock.template.js +1 -1
  192. package/dist/providers/plugins/jwt/jwt.setup-steps.js +1 -1
  193. package/dist/providers/plugins/jwt/jwt.template.js +1 -1
  194. package/dist/providers/plugins/litellm/litellm.template.js +1 -1
  195. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +10 -0
  196. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
  197. package/dist/providers/plugins/sso/proxy/proxy-types.d.ts +3 -0
  198. package/dist/providers/plugins/sso/proxy/proxy-types.d.ts.map +1 -1
  199. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  200. package/dist/providers/plugins/sso/session/SessionSyncer.js +2 -3
  201. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  202. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts +21 -0
  203. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts.map +1 -0
  204. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js +159 -0
  205. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js.map +1 -0
  206. package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts +24 -0
  207. package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts.map +1 -0
  208. package/dist/providers/plugins/sso/session/processors/conversations/constants.js +36 -0
  209. package/dist/providers/plugins/sso/session/processors/conversations/constants.js.map +1 -0
  210. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts +19 -0
  211. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -0
  212. package/dist/providers/plugins/sso/session/processors/conversations/{conversation-sync-processor.js → syncProcessor.js} +48 -33
  213. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -0
  214. package/dist/providers/plugins/sso/session/processors/conversations/{conversation-types.d.ts → types.d.ts} +14 -2
  215. package/dist/providers/plugins/sso/session/processors/conversations/types.d.ts.map +1 -0
  216. package/dist/providers/plugins/sso/session/processors/conversations/types.js +14 -0
  217. package/dist/providers/plugins/sso/session/processors/conversations/types.js.map +1 -0
  218. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -1
  219. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js +16 -17
  220. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -1
  221. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts +3 -3
  222. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -1
  223. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js +8 -38
  224. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -1
  225. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
  226. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +2 -6
  227. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
  228. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts +49 -31
  229. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts.map +1 -1
  230. package/dist/providers/plugins/sso/sso.template.js +1 -1
  231. package/dist/{agents/codemie-code/skills → skills}/core/SkillDiscovery.d.ts +10 -0
  232. package/dist/skills/core/SkillDiscovery.d.ts.map +1 -0
  233. package/dist/{agents/codemie-code/skills → skills}/core/SkillDiscovery.js +64 -7
  234. package/dist/skills/core/SkillDiscovery.js.map +1 -0
  235. package/dist/skills/core/SkillManager.d.ts.map +1 -0
  236. package/dist/{agents/codemie-code/skills → skills}/core/SkillManager.js +15 -10
  237. package/dist/skills/core/SkillManager.js.map +1 -0
  238. package/dist/{agents/codemie-code/skills → skills}/core/types.d.ts +3 -25
  239. package/dist/skills/core/types.d.ts.map +1 -0
  240. package/dist/skills/core/types.js.map +1 -0
  241. package/dist/{agents/codemie-code/skills → skills}/index.d.ts +3 -3
  242. package/dist/skills/index.d.ts.map +1 -0
  243. package/dist/{agents/codemie-code/skills → skills}/index.js +2 -2
  244. package/dist/skills/index.js.map +1 -0
  245. package/dist/skills/sync/SkillSync.d.ts.map +1 -0
  246. package/dist/{agents/codemie-code/skills → skills}/sync/SkillSync.js +5 -3
  247. package/dist/skills/sync/SkillSync.js.map +1 -0
  248. package/dist/{agents/codemie-code/skills → skills}/utils/content-loader.d.ts +2 -12
  249. package/dist/skills/utils/content-loader.d.ts.map +1 -0
  250. package/dist/{agents/codemie-code/skills → skills}/utils/content-loader.js +3 -8
  251. package/dist/skills/utils/content-loader.js.map +1 -0
  252. package/dist/skills/utils/pattern-matcher.d.ts.map +1 -0
  253. package/dist/skills/utils/pattern-matcher.js.map +1 -0
  254. package/dist/utils/frontmatter.d.ts.map +1 -0
  255. package/dist/utils/frontmatter.js.map +1 -0
  256. package/package.json +1 -1
  257. package/dist/agents/codemie-code/agent.d.ts +0 -129
  258. package/dist/agents/codemie-code/agent.d.ts.map +0 -1
  259. package/dist/agents/codemie-code/agent.js +0 -1106
  260. package/dist/agents/codemie-code/agent.js.map +0 -1
  261. package/dist/agents/codemie-code/config.d.ts +0 -40
  262. package/dist/agents/codemie-code/config.d.ts.map +0 -1
  263. package/dist/agents/codemie-code/config.js +0 -293
  264. package/dist/agents/codemie-code/config.js.map +0 -1
  265. package/dist/agents/codemie-code/filters.d.ts +0 -91
  266. package/dist/agents/codemie-code/filters.d.ts.map +0 -1
  267. package/dist/agents/codemie-code/filters.js +0 -328
  268. package/dist/agents/codemie-code/filters.js.map +0 -1
  269. package/dist/agents/codemie-code/index.d.ts +0 -93
  270. package/dist/agents/codemie-code/index.d.ts.map +0 -1
  271. package/dist/agents/codemie-code/index.js +0 -359
  272. package/dist/agents/codemie-code/index.js.map +0 -1
  273. package/dist/agents/codemie-code/modes/contextAwarePlanning.d.ts +0 -87
  274. package/dist/agents/codemie-code/modes/contextAwarePlanning.d.ts.map +0 -1
  275. package/dist/agents/codemie-code/modes/contextAwarePlanning.js +0 -957
  276. package/dist/agents/codemie-code/modes/contextAwarePlanning.js.map +0 -1
  277. package/dist/agents/codemie-code/modes/planMode.d.ts +0 -116
  278. package/dist/agents/codemie-code/modes/planMode.d.ts.map +0 -1
  279. package/dist/agents/codemie-code/modes/planMode.js +0 -537
  280. package/dist/agents/codemie-code/modes/planMode.js.map +0 -1
  281. package/dist/agents/codemie-code/prompts.d.ts +0 -47
  282. package/dist/agents/codemie-code/prompts.d.ts.map +0 -1
  283. package/dist/agents/codemie-code/prompts.js +0 -207
  284. package/dist/agents/codemie-code/prompts.js.map +0 -1
  285. package/dist/agents/codemie-code/skills/core/SkillDiscovery.d.ts.map +0 -1
  286. package/dist/agents/codemie-code/skills/core/SkillDiscovery.js.map +0 -1
  287. package/dist/agents/codemie-code/skills/core/SkillManager.d.ts.map +0 -1
  288. package/dist/agents/codemie-code/skills/core/SkillManager.js.map +0 -1
  289. package/dist/agents/codemie-code/skills/core/types.d.ts.map +0 -1
  290. package/dist/agents/codemie-code/skills/core/types.js.map +0 -1
  291. package/dist/agents/codemie-code/skills/index.d.ts.map +0 -1
  292. package/dist/agents/codemie-code/skills/index.js.map +0 -1
  293. package/dist/agents/codemie-code/skills/sync/SkillSync.d.ts.map +0 -1
  294. package/dist/agents/codemie-code/skills/sync/SkillSync.js.map +0 -1
  295. package/dist/agents/codemie-code/skills/utils/content-loader.d.ts.map +0 -1
  296. package/dist/agents/codemie-code/skills/utils/content-loader.js.map +0 -1
  297. package/dist/agents/codemie-code/skills/utils/frontmatter.d.ts.map +0 -1
  298. package/dist/agents/codemie-code/skills/utils/frontmatter.js.map +0 -1
  299. package/dist/agents/codemie-code/skills/utils/pattern-matcher.d.ts.map +0 -1
  300. package/dist/agents/codemie-code/skills/utils/pattern-matcher.js.map +0 -1
  301. package/dist/agents/codemie-code/storage/todoStorage.d.ts +0 -78
  302. package/dist/agents/codemie-code/storage/todoStorage.d.ts.map +0 -1
  303. package/dist/agents/codemie-code/storage/todoStorage.js +0 -225
  304. package/dist/agents/codemie-code/storage/todoStorage.js.map +0 -1
  305. package/dist/agents/codemie-code/tokenUtils.d.ts +0 -108
  306. package/dist/agents/codemie-code/tokenUtils.d.ts.map +0 -1
  307. package/dist/agents/codemie-code/tokenUtils.js +0 -220
  308. package/dist/agents/codemie-code/tokenUtils.js.map +0 -1
  309. package/dist/agents/codemie-code/toolMetadata.d.ts +0 -15
  310. package/dist/agents/codemie-code/toolMetadata.d.ts.map +0 -1
  311. package/dist/agents/codemie-code/toolMetadata.js +0 -316
  312. package/dist/agents/codemie-code/toolMetadata.js.map +0 -1
  313. package/dist/agents/codemie-code/tools/assistant-invocation.d.ts +0 -47
  314. package/dist/agents/codemie-code/tools/assistant-invocation.d.ts.map +0 -1
  315. package/dist/agents/codemie-code/tools/assistant-invocation.js +0 -129
  316. package/dist/agents/codemie-code/tools/assistant-invocation.js.map +0 -1
  317. package/dist/agents/codemie-code/tools/index.d.ts +0 -111
  318. package/dist/agents/codemie-code/tools/index.d.ts.map +0 -1
  319. package/dist/agents/codemie-code/tools/index.js +0 -424
  320. package/dist/agents/codemie-code/tools/index.js.map +0 -1
  321. package/dist/agents/codemie-code/tools/planning.d.ts +0 -54
  322. package/dist/agents/codemie-code/tools/planning.d.ts.map +0 -1
  323. package/dist/agents/codemie-code/tools/planning.js +0 -226
  324. package/dist/agents/codemie-code/tools/planning.js.map +0 -1
  325. package/dist/agents/codemie-code/types.d.ts +0 -459
  326. package/dist/agents/codemie-code/types.d.ts.map +0 -1
  327. package/dist/agents/codemie-code/types.js +0 -59
  328. package/dist/agents/codemie-code/types.js.map +0 -1
  329. package/dist/agents/codemie-code/ui/autocomplete.d.ts +0 -98
  330. package/dist/agents/codemie-code/ui/autocomplete.d.ts.map +0 -1
  331. package/dist/agents/codemie-code/ui/autocomplete.js +0 -145
  332. package/dist/agents/codemie-code/ui/autocomplete.js.map +0 -1
  333. package/dist/agents/codemie-code/ui/keyHandlers.d.ts +0 -112
  334. package/dist/agents/codemie-code/ui/keyHandlers.d.ts.map +0 -1
  335. package/dist/agents/codemie-code/ui/keyHandlers.js +0 -415
  336. package/dist/agents/codemie-code/ui/keyHandlers.js.map +0 -1
  337. package/dist/agents/codemie-code/ui/mentions.d.ts +0 -86
  338. package/dist/agents/codemie-code/ui/mentions.d.ts.map +0 -1
  339. package/dist/agents/codemie-code/ui/mentions.js +0 -122
  340. package/dist/agents/codemie-code/ui/mentions.js.map +0 -1
  341. package/dist/agents/codemie-code/ui/progressTracker.d.ts +0 -125
  342. package/dist/agents/codemie-code/ui/progressTracker.d.ts.map +0 -1
  343. package/dist/agents/codemie-code/ui/progressTracker.js +0 -343
  344. package/dist/agents/codemie-code/ui/progressTracker.js.map +0 -1
  345. package/dist/agents/codemie-code/ui/terminalCodes.d.ts +0 -38
  346. package/dist/agents/codemie-code/ui/terminalCodes.d.ts.map +0 -1
  347. package/dist/agents/codemie-code/ui/terminalCodes.js +0 -42
  348. package/dist/agents/codemie-code/ui/terminalCodes.js.map +0 -1
  349. package/dist/agents/codemie-code/ui/todoPanel.d.ts +0 -112
  350. package/dist/agents/codemie-code/ui/todoPanel.d.ts.map +0 -1
  351. package/dist/agents/codemie-code/ui/todoPanel.js +0 -321
  352. package/dist/agents/codemie-code/ui/todoPanel.js.map +0 -1
  353. package/dist/agents/codemie-code/ui.d.ts +0 -180
  354. package/dist/agents/codemie-code/ui.d.ts.map +0 -1
  355. package/dist/agents/codemie-code/ui.js +0 -1345
  356. package/dist/agents/codemie-code/ui.js.map +0 -1
  357. package/dist/agents/codemie-code/utils/progressionEnforcer.d.ts +0 -87
  358. package/dist/agents/codemie-code/utils/progressionEnforcer.d.ts.map +0 -1
  359. package/dist/agents/codemie-code/utils/progressionEnforcer.js +0 -293
  360. package/dist/agents/codemie-code/utils/progressionEnforcer.js.map +0 -1
  361. package/dist/agents/codemie-code/utils/todoParser.d.ts +0 -41
  362. package/dist/agents/codemie-code/utils/todoParser.d.ts.map +0 -1
  363. package/dist/agents/codemie-code/utils/todoParser.js +0 -305
  364. package/dist/agents/codemie-code/utils/todoParser.js.map +0 -1
  365. package/dist/agents/codemie-code/utils/todoValidator.d.ts +0 -65
  366. package/dist/agents/codemie-code/utils/todoValidator.d.ts.map +0 -1
  367. package/dist/agents/codemie-code/utils/todoValidator.js +0 -249
  368. package/dist/agents/codemie-code/utils/todoValidator.js.map +0 -1
  369. package/dist/agents/codemie-code/validators/planValidator.d.ts +0 -94
  370. package/dist/agents/codemie-code/validators/planValidator.d.ts.map +0 -1
  371. package/dist/agents/codemie-code/validators/planValidator.js +0 -281
  372. package/dist/agents/codemie-code/validators/planValidator.js.map +0 -1
  373. package/dist/agents/plugins/claude/plugin/hooks/hooks.windows.json +0 -98
  374. package/dist/agents/plugins/claude/plugin/sounds/play-random-sound.ps1 +0 -112
  375. package/dist/agents/plugins/claude/plugin/sounds/play-random-sound.sh +0 -58
  376. package/dist/agents/plugins/gemini/session/utils/token-aggregator.d.ts +0 -26
  377. package/dist/agents/plugins/gemini/session/utils/token-aggregator.d.ts.map +0 -1
  378. package/dist/agents/plugins/gemini/session/utils/token-aggregator.js +0 -38
  379. package/dist/agents/plugins/gemini/session/utils/token-aggregator.js.map +0 -1
  380. package/dist/cli/commands/assistants/chat.d.ts.map +0 -1
  381. package/dist/cli/commands/assistants/chat.js.map +0 -1
  382. package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.d.ts +0 -26
  383. package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.d.ts.map +0 -1
  384. package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.js +0 -146
  385. package/dist/providers/plugins/sso/session/processors/conversations/conversation-api-client.js.map +0 -1
  386. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts +0 -22
  387. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.d.ts.map +0 -1
  388. package/dist/providers/plugins/sso/session/processors/conversations/conversation-sync-processor.js.map +0 -1
  389. package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.d.ts.map +0 -1
  390. package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.js +0 -7
  391. package/dist/providers/plugins/sso/session/processors/conversations/conversation-types.js.map +0 -1
  392. /package/dist/{agents/codemie-code/skills → skills}/core/SkillManager.d.ts +0 -0
  393. /package/dist/{agents/codemie-code/skills → skills}/core/types.js +0 -0
  394. /package/dist/{agents/codemie-code/skills → skills}/sync/SkillSync.d.ts +0 -0
  395. /package/dist/{agents/codemie-code/skills → skills}/utils/pattern-matcher.d.ts +0 -0
  396. /package/dist/{agents/codemie-code/skills → skills}/utils/pattern-matcher.js +0 -0
  397. /package/dist/{agents/codemie-code/skills/utils → utils}/frontmatter.d.ts +0 -0
  398. /package/dist/{agents/codemie-code/skills/utils → utils}/frontmatter.js +0 -0
@@ -0,0 +1,785 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ msgraph.py — Microsoft Graph API CLI for Claude Code skill
4
+
5
+ Authentication: MSAL device code flow with persistent token cache.
6
+ First time: python msgraph.py login
7
+ Subsequent: token refreshed silently from cache.
8
+ """
9
+
10
+ import argparse
11
+ import json
12
+ import sys
13
+ from datetime import datetime, timezone
14
+ from pathlib import Path
15
+
16
+ try:
17
+ from msal import PublicClientApplication, SerializableTokenCache
18
+ import requests
19
+ except ImportError:
20
+ print("Missing dependencies. Install with:")
21
+ print(" pip install msal requests")
22
+ sys.exit(1)
23
+
24
+ # ── Config ────────────────────────────────────────────────────────────────────
25
+ CLIENT_ID = "14d82eec-204b-4c2f-b7e8-296a70dab67e" # MS GraphAPI public client
26
+ AUTHORITY = "https://login.microsoftonline.com/common"
27
+ SCOPES = [
28
+ "User.Read",
29
+ "Mail.Read",
30
+ "Mail.Send",
31
+ "Calendars.Read",
32
+ "Calendars.ReadWrite",
33
+ "Files.Read",
34
+ "Files.ReadWrite",
35
+ "Sites.Read.All",
36
+ "Chat.Read",
37
+ "Chat.ReadWrite",
38
+ "People.Read",
39
+ "Contacts.Read",
40
+ ]
41
+ CACHE_FILE = Path.home() / ".ms_graph_token_cache.json"
42
+ GRAPH_BASE = "https://graph.microsoft.com/v1.0"
43
+
44
+ # ── Token Cache ───────────────────────────────────────────────────────────────
45
+ def load_cache() -> SerializableTokenCache:
46
+ cache = SerializableTokenCache()
47
+ if CACHE_FILE.exists():
48
+ cache.deserialize(CACHE_FILE.read_text())
49
+ return cache
50
+
51
+ def save_cache(cache: SerializableTokenCache):
52
+ if cache.has_state_changed:
53
+ CACHE_FILE.write_text(cache.serialize())
54
+
55
+ # ── Authentication ────────────────────────────────────────────────────────────
56
+ def get_access_token(force_login: bool = False) -> str:
57
+ cache = load_cache()
58
+ app = PublicClientApplication(
59
+ client_id=CLIENT_ID,
60
+ authority=AUTHORITY,
61
+ token_cache=cache
62
+ )
63
+
64
+ if not force_login:
65
+ accounts = app.get_accounts()
66
+ if accounts:
67
+ result = app.acquire_token_silent(SCOPES, account=accounts[0])
68
+ if result and "access_token" in result:
69
+ save_cache(cache)
70
+ return result["access_token"]
71
+
72
+ # Device Code Flow
73
+ flow = app.initiate_device_flow(scopes=SCOPES)
74
+ if "user_code" not in flow:
75
+ raise RuntimeError(f"Failed to initiate device flow: {flow.get('error_description')}")
76
+
77
+ print("\n" + "=" * 60)
78
+ print(flow["message"])
79
+ print("=" * 60 + "\n")
80
+
81
+ result = app.acquire_token_by_device_flow(flow)
82
+ if "access_token" not in result:
83
+ raise RuntimeError(f"Authentication failed: {result.get('error_description')}")
84
+
85
+ save_cache(cache)
86
+ return result["access_token"]
87
+
88
+ def get_token_or_exit() -> str:
89
+ """Get token from cache only — exit with helpful message if not logged in or token expired."""
90
+ cache = load_cache()
91
+ app = PublicClientApplication(
92
+ client_id=CLIENT_ID,
93
+ authority=AUTHORITY,
94
+ token_cache=cache
95
+ )
96
+ accounts = app.get_accounts()
97
+ if not accounts:
98
+ print("NOT_LOGGED_IN")
99
+ sys.exit(2)
100
+ result = app.acquire_token_silent(SCOPES, account=accounts[0])
101
+ if not result or "access_token" not in result:
102
+ print("TOKEN_EXPIRED")
103
+ sys.exit(2)
104
+ save_cache(cache)
105
+ return result["access_token"]
106
+
107
+ # ── Graph API Helpers ─────────────────────────────────────────────────────────
108
+ def graph_get(endpoint: str, token: str, params: dict | None = None) -> dict:
109
+ r = requests.get(
110
+ f"{GRAPH_BASE}{endpoint}",
111
+ headers={"Authorization": f"Bearer {token}"},
112
+ params=params or {}
113
+ )
114
+ r.raise_for_status()
115
+ return r.json()
116
+
117
+ def graph_post(endpoint: str, token: str, body: dict) -> dict:
118
+ r = requests.post(
119
+ f"{GRAPH_BASE}{endpoint}",
120
+ headers={
121
+ "Authorization": f"Bearer {token}",
122
+ "Content-Type": "application/json"
123
+ },
124
+ json=body
125
+ )
126
+ r.raise_for_status()
127
+ return r.json() if r.content else {}
128
+
129
+ def graph_download(endpoint: str, token: str) -> bytes:
130
+ r = requests.get(
131
+ f"{GRAPH_BASE}{endpoint}",
132
+ headers={"Authorization": f"Bearer {token}"},
133
+ allow_redirects=True
134
+ )
135
+ r.raise_for_status()
136
+ return r.content
137
+
138
+ def graph_upload(endpoint: str, token: str, content: bytes, content_type: str = "application/octet-stream") -> dict:
139
+ r = requests.put(
140
+ f"{GRAPH_BASE}{endpoint}",
141
+ headers={
142
+ "Authorization": f"Bearer {token}",
143
+ "Content-Type": content_type
144
+ },
145
+ data=content
146
+ )
147
+ r.raise_for_status()
148
+ return r.json()
149
+
150
+ # ── Formatters ────────────────────────────────────────────────────────────────
151
+ def fmt_dt(iso: str) -> str:
152
+ """Format ISO datetime to readable string."""
153
+ try:
154
+ dt = datetime.fromisoformat(iso.replace("Z", "+00:00"))
155
+ return dt.strftime("%Y-%m-%d %H:%M")
156
+ except Exception:
157
+ return iso[:16].replace("T", " ")
158
+
159
+ def fmt_size(size: int) -> str:
160
+ for unit in ["B", "KB", "MB", "GB"]:
161
+ if size < 1024:
162
+ return f"{size:.1f} {unit}"
163
+ size /= 1024
164
+ return f"{size:.1f} TB"
165
+
166
+ def print_json(data: dict | list):
167
+ print(json.dumps(data, indent=2, ensure_ascii=False))
168
+
169
+ # ── Commands ──────────────────────────────────────────────────────────────────
170
+
171
+ def cmd_login(args):
172
+ """Authenticate and cache credentials."""
173
+ print("Starting Microsoft authentication...")
174
+ token = get_access_token(force_login=True)
175
+ me = graph_get("/me", token)
176
+ print(f"\nLogged in as: {me['displayName']} <{me['userPrincipalName']}>")
177
+ print(f"User ID: {me['id']}")
178
+ print(f"Token cached at: {CACHE_FILE}")
179
+
180
+ def cmd_logout(args):
181
+ """Remove cached credentials."""
182
+ if CACHE_FILE.exists():
183
+ CACHE_FILE.unlink()
184
+ print(f"Logged out. Cache removed: {CACHE_FILE}")
185
+ else:
186
+ print("No cached credentials found.")
187
+
188
+ def cmd_status(args):
189
+ """Check login status."""
190
+ cache = load_cache()
191
+ app = PublicClientApplication(client_id=CLIENT_ID, authority=AUTHORITY, token_cache=cache)
192
+ accounts = app.get_accounts()
193
+ if not accounts:
194
+ print("NOT_LOGGED_IN")
195
+ print(f"\nTo login, run:\n python {Path(__file__).name} login")
196
+ return
197
+ # Verify token can actually be acquired (not just that account exists in cache)
198
+ result = app.acquire_token_silent(SCOPES, account=accounts[0])
199
+ if result and "access_token" in result:
200
+ save_cache(cache)
201
+ print(f"Logged in as: {accounts[0]['username']}")
202
+ print(f"Cache file: {CACHE_FILE}")
203
+ else:
204
+ print("TOKEN_EXPIRED")
205
+ print(f"Account: {accounts[0]['username']}")
206
+ print(f"\nSession expired. Re-authenticate with:\n python {Path(__file__).name} login")
207
+
208
+ def cmd_me(args):
209
+ """Show user profile information."""
210
+ token = get_token_or_exit()
211
+ me = graph_get("/me", token)
212
+ fields = ["displayName", "userPrincipalName", "id", "mail", "jobTitle",
213
+ "department", "officeLocation", "businessPhones", "mobilePhone"]
214
+ if args.json:
215
+ print_json({k: me.get(k) for k in fields if me.get(k)})
216
+ return
217
+ print(f"Name : {me.get('displayName', 'N/A')}")
218
+ print(f"Email : {me.get('userPrincipalName', 'N/A')}")
219
+ print(f"Job Title : {me.get('jobTitle', 'N/A')}")
220
+ print(f"Department : {me.get('department', 'N/A')}")
221
+ print(f"Office : {me.get('officeLocation', 'N/A')}")
222
+ print(f"Phone : {me.get('businessPhones', ['N/A'])[0] if me.get('businessPhones') else 'N/A'}")
223
+ print(f"User ID : {me.get('id', 'N/A')}")
224
+
225
+ def cmd_emails(args):
226
+ """List, read, send or search emails."""
227
+ token = get_token_or_exit()
228
+
229
+ if args.send:
230
+ # Send email: --send "To <email>" --subject "Subject" --body "Body"
231
+ to_email = args.send
232
+ body_content = args.body or ""
233
+ subject = args.subject or "(no subject)"
234
+ payload = {
235
+ "message": {
236
+ "subject": subject,
237
+ "body": {"contentType": "Text", "content": body_content},
238
+ "toRecipients": [{"emailAddress": {"address": to_email}}]
239
+ }
240
+ }
241
+ graph_post("/me/sendMail", token, payload)
242
+ print(f"Email sent to {to_email}")
243
+ return
244
+
245
+ if args.read:
246
+ # Read a specific email by ID
247
+ msg = graph_get(f"/me/messages/{args.read}", token)
248
+ print(f"Subject : {msg.get('subject')}")
249
+ print(f"From : {msg['from']['emailAddress']['name']} <{msg['from']['emailAddress']['address']}>")
250
+ print(f"Date : {fmt_dt(msg['receivedDateTime'])}")
251
+ print(f"Read : {'Yes' if msg['isRead'] else 'No'}")
252
+ print(f"\n{'─'*60}")
253
+ body = msg.get("body", {})
254
+ if body.get("contentType") == "text":
255
+ print(body.get("content", ""))
256
+ else:
257
+ # Strip basic HTML tags for readability
258
+ import re
259
+ text = re.sub(r'<[^>]+>', '', body.get("content", ""))
260
+ print(text[:2000])
261
+ return
262
+
263
+ # List/search emails
264
+ params: dict = {
265
+ "$top": args.limit,
266
+ "$select": "id,subject,from,receivedDateTime,isRead,hasAttachments,importance",
267
+ "$orderby": "receivedDateTime desc"
268
+ }
269
+ if args.search:
270
+ params["$search"] = f'"{args.search}"'
271
+ params.pop("$orderby", None) # $search incompatible with $orderby
272
+ if args.folder:
273
+ endpoint = f"/me/mailFolders/{args.folder}/messages"
274
+ elif args.unread:
275
+ params["$filter"] = "isRead eq false"
276
+ endpoint = "/me/messages"
277
+ else:
278
+ endpoint = "/me/messages"
279
+
280
+ data = graph_get(endpoint, token, params)
281
+ emails = data.get("value", [])
282
+
283
+ if args.json:
284
+ print_json(emails)
285
+ return
286
+
287
+ if not emails:
288
+ print("No emails found.")
289
+ return
290
+
291
+ print(f"\n{'ID':<36} {'Date':<16} {'Rd'} {'Subject'}")
292
+ print("─" * 80)
293
+ for e in emails:
294
+ read_mark = "✓" if e["isRead"] else "●"
295
+ attach = "📎" if e.get("hasAttachments") else " "
296
+ subject = e.get("subject", "(no subject)")[:45]
297
+ sender = e["from"]["emailAddress"].get("name", "")[:20]
298
+ date = fmt_dt(e["receivedDateTime"])
299
+ print(f"{e['id'][:36]} {date} {read_mark} {attach} {subject} ({sender})")
300
+
301
+ def cmd_calendar(args):
302
+ """List or create calendar events."""
303
+ token = get_token_or_exit()
304
+
305
+ if args.create:
306
+ # Create event: --create "Title" --start "2024-03-15T10:00" --end "2024-03-15T11:00"
307
+ if not args.start or not args.end:
308
+ print("Error: --create requires --start and --end (format: YYYY-MM-DDTHH:MM)")
309
+ sys.exit(1)
310
+ tz = args.timezone or "UTC"
311
+ payload = {
312
+ "subject": args.create,
313
+ "start": {"dateTime": args.start, "timeZone": tz},
314
+ "end": {"dateTime": args.end, "timeZone": tz},
315
+ }
316
+ if args.location:
317
+ payload["location"] = {"displayName": args.location}
318
+ if args.body:
319
+ payload["body"] = {"contentType": "Text", "content": args.body}
320
+ event = graph_post("/me/events", token, payload)
321
+ print(f"Event created: {event.get('subject')}")
322
+ print(f"ID: {event.get('id')}")
323
+ return
324
+
325
+ if args.availability:
326
+ # Check free/busy for a time range
327
+ start = args.start or datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S")
328
+ end = args.end or datetime.now(timezone.utc).replace(hour=23, minute=59).strftime("%Y-%m-%dT%H:%M:%S")
329
+ view = graph_get(
330
+ "/me/calendarView",
331
+ token,
332
+ {"startDateTime": start, "endDateTime": end,
333
+ "$select": "subject,start,end,showAs", "$orderby": "start/dateTime"}
334
+ )
335
+ events = view.get("value", [])
336
+ if not events:
337
+ print(f"You're free between {start[:16]} and {end[:16]}.")
338
+ else:
339
+ print(f"\nBusy slots ({len(events)} events):")
340
+ for e in events:
341
+ print(f" {fmt_dt(e['start']['dateTime'])} — {fmt_dt(e['end']['dateTime'])}: {e.get('subject', '(no title)')}")
342
+ return
343
+
344
+ # List upcoming events
345
+ now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
346
+ data = graph_get(
347
+ "/me/calendarView",
348
+ token,
349
+ {
350
+ "startDateTime": now,
351
+ "endDateTime": f"{datetime.now(timezone.utc).year + 1}-01-01T00:00:00Z",
352
+ "$top": args.limit,
353
+ "$select": "id,subject,start,end,location,organizer,isOnlineMeeting,onlineMeetingUrl",
354
+ "$orderby": "start/dateTime"
355
+ }
356
+ )
357
+ events = data.get("value", [])
358
+
359
+ if args.json:
360
+ print_json(events)
361
+ return
362
+
363
+ if not events:
364
+ print("No upcoming events.")
365
+ return
366
+
367
+ print(f"\n{'Date & Time':<20} {'Duration':<10} {'Title'}")
368
+ print("─" * 80)
369
+ for e in events:
370
+ start = fmt_dt(e["start"]["dateTime"])
371
+ title = e.get("subject", "(no title)")[:45]
372
+ organizer = e["organizer"]["emailAddress"].get("name", "")[:20]
373
+ online = "🎥" if e.get("isOnlineMeeting") else " "
374
+ loc = e.get("location", {}).get("displayName", "")[:20]
375
+ print(f"{start:<20} {online} {title} ({organizer})" + (f" @ {loc}" if loc else ""))
376
+
377
+ def cmd_sharepoint(args):
378
+ """Browse SharePoint sites and files."""
379
+ token = get_token_or_exit()
380
+
381
+ if args.sites:
382
+ # List all joined sites
383
+ data = graph_get("/me/followedSites", token, {"$select": "id,displayName,webUrl"})
384
+ sites = data.get("value", [])
385
+ if not sites:
386
+ # Fallback: search for sites
387
+ data = graph_get("/sites", token, {"search": "*", "$top": args.limit})
388
+ sites = data.get("value", [])
389
+ if args.json:
390
+ print_json(sites)
391
+ return
392
+ print(f"\n{'ID':<50} {'Name'}")
393
+ print("─" * 80)
394
+ for s in sites[:args.limit]:
395
+ print(f"{s['id']:<50} {s.get('displayName', 'N/A')}")
396
+ print(f" URL: {s.get('webUrl', 'N/A')}")
397
+ return
398
+
399
+ if args.site:
400
+ # Browse files in a site's drive
401
+ site_id = args.site
402
+ path = args.path or "root"
403
+ endpoint = f"/sites/{site_id}/drive/root/children" if path == "root" else f"/sites/{site_id}/drive/root:/{path}:/children"
404
+ data = graph_get(endpoint, token, {"$top": args.limit, "$select": "id,name,size,lastModifiedDateTime,file,folder"})
405
+ items = data.get("value", [])
406
+ if args.json:
407
+ print_json(items)
408
+ return
409
+ print(f"\nFiles in site {site_id} / {path}:")
410
+ print("─" * 60)
411
+ for item in items:
412
+ kind = "📁" if "folder" in item else "📄"
413
+ size = fmt_size(item.get("size", 0)) if "file" in item else ""
414
+ modified = fmt_dt(item.get("lastModifiedDateTime", ""))
415
+ print(f" {kind} {item['name']:<40} {size:<10} {modified}")
416
+ return
417
+
418
+ if args.download:
419
+ # Download a file by item ID from personal drive (use --site for SharePoint)
420
+ content = graph_download(f"/me/drive/items/{args.download}/content", token)
421
+ out_path = Path(args.output or f"downloaded_{args.download[:8]}")
422
+ out_path.write_bytes(content)
423
+ print(f"Downloaded {len(content)} bytes to {out_path}")
424
+ return
425
+
426
+ print("SharePoint commands: --sites | --site SITE_ID [--path PATH] | --download ITEM_ID")
427
+
428
+ def cmd_teams(args):
429
+ """List Teams chats and messages."""
430
+ token = get_token_or_exit()
431
+
432
+ if args.chats:
433
+ # List all chats
434
+ data = graph_get("/me/chats", token, {
435
+ "$top": args.limit,
436
+ "$select": "id,topic,chatType,lastUpdatedDateTime"
437
+ })
438
+ chats = data.get("value", [])
439
+ if args.json:
440
+ print_json(chats)
441
+ return
442
+ print(f"\n{'Chat ID':<50} {'Type':<10} {'Topic'}")
443
+ print("─" * 80)
444
+ for c in chats:
445
+ topic = c.get("topic") or "(direct message)"
446
+ print(f"{c['id']:<50} {c.get('chatType',''):<10} {topic}")
447
+ return
448
+
449
+ if args.messages:
450
+ # Get messages in a chat
451
+ data = graph_get(f"/me/chats/{args.messages}/messages", token, {
452
+ "$top": args.limit,
453
+ "$select": "id,from,body,createdDateTime"
454
+ })
455
+ msgs = data.get("value", [])
456
+ if args.json:
457
+ print_json(msgs)
458
+ return
459
+ print(f"\nMessages in chat {args.messages[:20]}...:")
460
+ print("─" * 60)
461
+ for m in reversed(msgs):
462
+ sender = m.get("from", {}).get("user", {}).get("displayName", "Unknown") if m.get("from") else "System"
463
+ time = fmt_dt(m.get("createdDateTime", ""))
464
+ import re
465
+ body = re.sub(r'<[^>]+>', '', m.get("body", {}).get("content", ""))[:200]
466
+ print(f"[{time}] {sender}: {body}")
467
+ return
468
+
469
+ if args.send and args.chat_id:
470
+ # Send message to a chat
471
+ payload = {"body": {"content": args.send}}
472
+ result = graph_post(f"/me/chats/{args.chat_id}/messages", token, payload)
473
+ print(f"Message sent. ID: {result.get('id')}")
474
+ return
475
+
476
+ if args.teams_list:
477
+ # List joined teams
478
+ data = graph_get("/me/joinedTeams", token, {"$select": "id,displayName,description"})
479
+ teams = data.get("value", [])
480
+ if args.json:
481
+ print_json(teams)
482
+ return
483
+ for t in teams:
484
+ print(f"{t['id'][:36]} {t['displayName']}")
485
+ return
486
+
487
+ print("Teams commands: --chats | --messages CHAT_ID | --send MSG --chat-id CHAT_ID | --teams-list")
488
+
489
+ def cmd_onedrive(args):
490
+ """Browse, upload and download OneDrive files."""
491
+ token = get_token_or_exit()
492
+
493
+ if args.upload:
494
+ src = Path(args.upload)
495
+ if not src.exists():
496
+ print(f"File not found: {src}")
497
+ sys.exit(1)
498
+ dest_path = args.dest or src.name
499
+ content = src.read_bytes()
500
+ result = graph_upload(f"/me/drive/root:/{dest_path}:/content", token, content)
501
+ print(f"Uploaded: {result.get('name')} ({fmt_size(result.get('size', 0))})")
502
+ print(f"ID: {result.get('id')}")
503
+ return
504
+
505
+ if args.download:
506
+ content = graph_download(f"/me/drive/items/{args.download}/content", token)
507
+ out_path = Path(args.output or f"download_{args.download[:8]}")
508
+ out_path.write_bytes(content)
509
+ print(f"Downloaded {fmt_size(len(content))} to {out_path}")
510
+ return
511
+
512
+ if args.info:
513
+ item = graph_get(f"/me/drive/items/{args.info}", token)
514
+ if args.json:
515
+ print_json(item)
516
+ return
517
+ print(f"Name : {item.get('name')}")
518
+ print(f"Size : {fmt_size(item.get('size', 0))}")
519
+ print(f"Modified: {fmt_dt(item.get('lastModifiedDateTime', ''))}")
520
+ print(f"URL : {item.get('webUrl', 'N/A')}")
521
+ return
522
+
523
+ # List files in a path
524
+ path = args.path or ""
525
+ endpoint = "/me/drive/root/children" if not path else f"/me/drive/root:/{path}:/children"
526
+ data = graph_get(endpoint, token, {
527
+ "$top": args.limit,
528
+ "$select": "id,name,size,lastModifiedDateTime,file,folder",
529
+ "$orderby": "name"
530
+ })
531
+ items = data.get("value", [])
532
+
533
+ if args.json:
534
+ print_json(items)
535
+ return
536
+
537
+ if not items:
538
+ print(f"No files found in /{path or ''}")
539
+ return
540
+
541
+ print(f"\nOneDrive: /{path or ''}")
542
+ print("─" * 60)
543
+ for item in items:
544
+ kind = "📁" if "folder" in item else "📄"
545
+ size = fmt_size(item.get("size", 0)) if "file" in item else ""
546
+ modified = fmt_dt(item.get("lastModifiedDateTime", ""))
547
+ count = f" ({item['folder']['childCount']} items)" if "folder" in item else ""
548
+ print(f" {kind} {item['id'][:16]} {item['name']:<40} {size:<10} {modified}{count}")
549
+
550
+ def cmd_people(args):
551
+ """List relevant people and contacts."""
552
+ token = get_token_or_exit()
553
+
554
+ if args.contacts:
555
+ # Outlook contacts
556
+ params = {"$top": args.limit, "$select": "displayName,emailAddresses,mobilePhone,jobTitle,companyName"}
557
+ if args.search:
558
+ params["$search"] = f'"{args.search}"'
559
+ data = graph_get("/me/contacts", token, params)
560
+ contacts = data.get("value", [])
561
+ if args.json:
562
+ print_json(contacts)
563
+ return
564
+ print(f"\n{'Name':<30} {'Email':<35} {'Title'}")
565
+ print("─" * 80)
566
+ for c in contacts:
567
+ emails = [e["address"] for e in c.get("emailAddresses", [])]
568
+ email = emails[0] if emails else "N/A"
569
+ print(f"{c.get('displayName',''):<30} {email:<35} {c.get('jobTitle','')}")
570
+ return
571
+
572
+ # Relevant people (AI-ranked by interaction)
573
+ params = {"$top": args.limit}
574
+ if args.search:
575
+ params["$search"] = f'"{args.search}"'
576
+ data = graph_get("/me/people", token, params)
577
+ people = data.get("value", [])
578
+
579
+ if args.json:
580
+ print_json(people)
581
+ return
582
+
583
+ if not people:
584
+ print("No people found.")
585
+ return
586
+
587
+ print(f"\n{'Name':<30} {'Email':<35} {'Title'}")
588
+ print("─" * 80)
589
+ for p in people:
590
+ emails = [s["address"] for s in p.get("scoredEmailAddresses", [])]
591
+ email = emails[0] if emails else "N/A"
592
+ print(f"{p.get('displayName',''):<30} {email:<35} {p.get('jobTitle','')}")
593
+
594
+ def cmd_org(args):
595
+ """Show organizational info: manager, reports, colleagues."""
596
+ token = get_token_or_exit()
597
+
598
+ if args.manager:
599
+ try:
600
+ mgr = graph_get("/me/manager", token)
601
+ print(f"Manager: {mgr.get('displayName')} <{mgr.get('userPrincipalName')}>")
602
+ print(f"Title : {mgr.get('jobTitle', 'N/A')}")
603
+ except requests.HTTPError as e:
604
+ if e.response.status_code == 404:
605
+ print("No manager found (you may be at the top of the org).")
606
+ else:
607
+ raise
608
+ return
609
+
610
+ if args.reports:
611
+ data = graph_get("/me/directReports", token,
612
+ {"$select": "displayName,userPrincipalName,jobTitle"})
613
+ reports = data.get("value", [])
614
+ print(f"\nDirect Reports ({len(reports)}):")
615
+ for r in reports:
616
+ print(f" {r.get('displayName'):<30} {r.get('userPrincipalName')}")
617
+ return
618
+
619
+ # Default: show org context
620
+ try:
621
+ mgr = graph_get("/me/manager", token)
622
+ print(f"Manager: {mgr.get('displayName')}")
623
+ except Exception:
624
+ pass
625
+ reports = graph_get("/me/directReports", token, {"$select": "displayName"}).get("value", [])
626
+ print(f"Direct Reports: {len(reports)}")
627
+ colleagues = graph_get("/me/people", token, {"$top": 5}).get("value", [])
628
+ print(f"\nFrequent colleagues:")
629
+ for p in colleagues:
630
+ print(f" {p.get('displayName')}")
631
+
632
+ # ── CLI Setup ─────────────────────────────────────────────────────────────────
633
+ def main():
634
+ parser = argparse.ArgumentParser(
635
+ description="Microsoft Graph API CLI",
636
+ formatter_class=argparse.RawDescriptionHelpFormatter,
637
+ epilog="""
638
+ Examples:
639
+ python msgraph.py login # Authenticate
640
+ python msgraph.py status # Check login status
641
+ python msgraph.py me # Show profile
642
+ python msgraph.py emails --limit 10 # List 10 emails
643
+ python msgraph.py emails --unread # Unread emails
644
+ python msgraph.py emails --search "invoice" # Search emails
645
+ python msgraph.py emails --read MSG_ID # Read specific email
646
+ python msgraph.py emails --send "a@b.com" --subject "Hi" --body "Hello"
647
+ python msgraph.py calendar --limit 10 # Upcoming events
648
+ python msgraph.py calendar --create "Meeting" --start 2024-03-15T10:00 --end 2024-03-15T11:00
649
+ python msgraph.py sharepoint --sites # List SharePoint sites
650
+ python msgraph.py teams --chats # List Teams chats
651
+ python msgraph.py teams --messages CHAT_ID # Read chat messages
652
+ python msgraph.py onedrive # List OneDrive root
653
+ python msgraph.py onedrive --path "Documents" # Browse folder
654
+ python msgraph.py onedrive --upload file.txt # Upload file
655
+ python msgraph.py people # Frequent contacts
656
+ python msgraph.py org --manager # Show your manager
657
+ """
658
+ )
659
+
660
+ # Global flags
661
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
662
+
663
+ subparsers = parser.add_subparsers(dest="command")
664
+
665
+ # login
666
+ subparsers.add_parser("login", help="Authenticate with Microsoft")
667
+
668
+ # logout
669
+ subparsers.add_parser("logout", help="Remove cached credentials")
670
+
671
+ # status
672
+ subparsers.add_parser("status", help="Check login status")
673
+
674
+ # me
675
+ p_me = subparsers.add_parser("me", help="Show user profile")
676
+ p_me.add_argument("--json", action="store_true")
677
+
678
+ # emails
679
+ p_email = subparsers.add_parser("emails", help="Work with emails")
680
+ p_email.add_argument("--limit", type=int, default=10, help="Number of emails to show")
681
+ p_email.add_argument("--search", help="Search query")
682
+ p_email.add_argument("--unread", action="store_true", help="Show only unread emails")
683
+ p_email.add_argument("--folder", help="Mail folder (inbox, sentitems, drafts, etc.)")
684
+ p_email.add_argument("--read", metavar="ID", help="Read email by ID")
685
+ p_email.add_argument("--send", metavar="TO", help="Send email to address")
686
+ p_email.add_argument("--subject", help="Email subject (for --send)")
687
+ p_email.add_argument("--body", help="Email body text")
688
+ p_email.add_argument("--json", action="store_true")
689
+
690
+ # calendar
691
+ p_cal = subparsers.add_parser("calendar", help="Work with calendar")
692
+ p_cal.add_argument("--limit", type=int, default=10)
693
+ p_cal.add_argument("--create", metavar="TITLE", help="Create event with this title")
694
+ p_cal.add_argument("--start", help="Start datetime (YYYY-MM-DDTHH:MM)")
695
+ p_cal.add_argument("--end", help="End datetime (YYYY-MM-DDTHH:MM)")
696
+ p_cal.add_argument("--location", help="Event location")
697
+ p_cal.add_argument("--body", help="Event description")
698
+ p_cal.add_argument("--timezone", default="UTC", help="Timezone (e.g. Europe/Berlin)")
699
+ p_cal.add_argument("--availability", action="store_true", help="Check free/busy")
700
+ p_cal.add_argument("--json", action="store_true")
701
+
702
+ # sharepoint
703
+ p_sp = subparsers.add_parser("sharepoint", help="Browse SharePoint")
704
+ p_sp.add_argument("--sites", action="store_true", help="List followed sites")
705
+ p_sp.add_argument("--site", metavar="SITE_ID", help="Browse files in site")
706
+ p_sp.add_argument("--path", help="Path within site drive")
707
+ p_sp.add_argument("--download", metavar="ITEM_ID", help="Download file by ID")
708
+ p_sp.add_argument("--output", help="Output file path")
709
+ p_sp.add_argument("--limit", type=int, default=20)
710
+ p_sp.add_argument("--json", action="store_true")
711
+
712
+ # teams
713
+ p_teams = subparsers.add_parser("teams", help="Work with Teams")
714
+ p_teams.add_argument("--chats", action="store_true", help="List all chats")
715
+ p_teams.add_argument("--messages", metavar="CHAT_ID", help="Get messages from chat")
716
+ p_teams.add_argument("--send", metavar="TEXT", help="Send a message")
717
+ p_teams.add_argument("--chat-id", dest="chat_id", help="Target chat ID for --send")
718
+ p_teams.add_argument("--teams-list", action="store_true", help="List joined teams")
719
+ p_teams.add_argument("--limit", type=int, default=20)
720
+ p_teams.add_argument("--json", action="store_true")
721
+
722
+ # onedrive
723
+ p_od = subparsers.add_parser("onedrive", help="Work with OneDrive")
724
+ p_od.add_argument("--path", help="Folder path to browse")
725
+ p_od.add_argument("--upload", metavar="FILE", help="Upload a local file")
726
+ p_od.add_argument("--dest", help="Destination path in OneDrive (for --upload)")
727
+ p_od.add_argument("--download", metavar="ITEM_ID", help="Download by item ID")
728
+ p_od.add_argument("--output", help="Output file path")
729
+ p_od.add_argument("--info", metavar="ITEM_ID", help="Get file metadata")
730
+ p_od.add_argument("--limit", type=int, default=20)
731
+ p_od.add_argument("--json", action="store_true")
732
+
733
+ # people
734
+ p_ppl = subparsers.add_parser("people", help="Browse people and contacts")
735
+ p_ppl.add_argument("--contacts", action="store_true", help="Use Outlook contacts (not people)")
736
+ p_ppl.add_argument("--search", help="Search by name")
737
+ p_ppl.add_argument("--limit", type=int, default=20)
738
+ p_ppl.add_argument("--json", action="store_true")
739
+
740
+ # org
741
+ p_org = subparsers.add_parser("org", help="Organizational info")
742
+ p_org.add_argument("--manager", action="store_true", help="Show your manager")
743
+ p_org.add_argument("--reports", action="store_true", help="Show direct reports")
744
+ p_org.add_argument("--json", action="store_true")
745
+
746
+ args = parser.parse_args()
747
+
748
+ if not args.command:
749
+ parser.print_help()
750
+ sys.exit(0)
751
+
752
+ command_map = {
753
+ "login": cmd_login,
754
+ "logout": cmd_logout,
755
+ "status": cmd_status,
756
+ "me": cmd_me,
757
+ "emails": cmd_emails,
758
+ "calendar": cmd_calendar,
759
+ "sharepoint": cmd_sharepoint,
760
+ "teams": cmd_teams,
761
+ "onedrive": cmd_onedrive,
762
+ "people": cmd_people,
763
+ "org": cmd_org,
764
+ }
765
+
766
+ try:
767
+ command_map[args.command](args)
768
+ except requests.HTTPError as e:
769
+ status = e.response.status_code
770
+ if status == 401:
771
+ print("Error: Authentication expired. Run: python msgraph.py login")
772
+ elif status == 403:
773
+ print(f"Error: Permission denied for this operation ({e.response.url})")
774
+ print("You may need additional OAuth scopes.")
775
+ elif status == 404:
776
+ print(f"Error: Resource not found ({e.response.url})")
777
+ else:
778
+ print(f"HTTP Error {status}: {e.response.text[:200]}")
779
+ sys.exit(1)
780
+ except KeyboardInterrupt:
781
+ print("\nCancelled.")
782
+ sys.exit(0)
783
+
784
+ if __name__ == "__main__":
785
+ main()