@codemieai/code 0.15.1 → 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +75 -0
- package/bin/codemie.js +52 -0
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +6 -0
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +25 -0
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +137 -127
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/session/BaseProcessor.d.ts +10 -0
- package/dist/agents/core/session/BaseProcessor.d.ts.map +1 -1
- package/dist/agents/core/session/BaseProcessor.js +11 -1
- package/dist/agents/core/session/BaseProcessor.js.map +1 -1
- package/dist/agents/core/session/BaseSessionAdapter.d.ts +4 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
- package/dist/agents/core/types.d.ts +11 -5
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.models.js +12 -11
- package/dist/agents/plugins/claude/claude.models.js.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts +3 -3
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +14 -13
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/claude/claude.session.d.ts +17 -1
- package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.session.js +31 -1
- package/dist/agents/plugins/claude/claude.session.js.map +1 -1
- package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/agents/plugins/claude/plugin/hooks/hooks.json +7 -7
- package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/codex/codex.plugin.js +7 -6
- package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +5 -2
- package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -1
- package/dist/agents/plugins/gemini/extension/gemini-extension.json +1 -1
- package/dist/agents/plugins/gemini/extension/hooks/hooks.json +7 -7
- package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/gemini/gemini.plugin.js +7 -6
- package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
- package/dist/agents/plugins/kimi/kimi.hook-config-injector.d.ts.map +1 -1
- package/dist/agents/plugins/kimi/kimi.hook-config-injector.js +26 -5
- package/dist/agents/plugins/kimi/kimi.hook-config-injector.js.map +1 -1
- package/dist/agents/plugins/kimi/kimi.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/kimi/kimi.plugin.js +5 -2
- package/dist/agents/plugins/kimi/kimi.plugin.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode-dynamic-models.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode-dynamic-models.js +3 -4
- package/dist/agents/plugins/opencode/opencode-dynamic-models.js.map +1 -1
- package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -1
- package/dist/agents/plugins/pi/pi.models.js +3 -3
- package/dist/agents/plugins/pi/pi.models.js.map +1 -1
- package/dist/bin/proxy-daemon.js +8 -1
- package/dist/bin/proxy-daemon.js.map +1 -1
- package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts +6 -0
- package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js +115 -0
- package/dist/cli/commands/analytics/cost/claude-dispatch-allocation.js.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts +6 -0
- package/dist/cli/commands/analytics/cost/claude-lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-lifecycle.js +107 -0
- package/dist/cli/commands/analytics/cost/claude-lifecycle.js.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-native.d.ts +54 -0
- package/dist/cli/commands/analytics/cost/claude-native.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-native.js +14 -0
- package/dist/cli/commands/analytics/cost/claude-native.js.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-ownership.d.ts +23 -0
- package/dist/cli/commands/analytics/cost/claude-ownership.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-ownership.js +99 -0
- package/dist/cli/commands/analytics/cost/claude-ownership.js.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-trace.d.ts +28 -0
- package/dist/cli/commands/analytics/cost/claude-trace.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/claude-trace.js +120 -0
- package/dist/cli/commands/analytics/cost/claude-trace.js.map +1 -0
- package/dist/cli/commands/analytics/cost/cost-enricher.d.ts +1 -1
- package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/cost-enricher.js +34 -43
- package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
- package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts +18 -0
- package/dist/cli/commands/analytics/cost/dispatch-allocation.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/dispatch-allocation.js +53 -0
- package/dist/cli/commands/analytics/cost/dispatch-allocation.js.map +1 -0
- package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts +8 -13
- package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/dispatch-extractor.js +131 -69
- package/dist/cli/commands/analytics/cost/dispatch-extractor.js.map +1 -1
- package/dist/cli/commands/analytics/cost/types.d.ts +39 -0
- package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/types.js.map +1 -1
- package/dist/cli/commands/analytics/cost/usage-readers.d.ts +2 -0
- package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/usage-readers.js +14 -3
- package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
- package/dist/cli/commands/analytics/data-loader.d.ts +13 -0
- package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/data-loader.js +6 -0
- package/dist/cli/commands/analytics/data-loader.js.map +1 -1
- package/dist/cli/commands/analytics/native-loader.d.ts +1 -1
- package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/native-loader.js +25 -3
- package/dist/cli/commands/analytics/native-loader.js.map +1 -1
- package/dist/cli/commands/analytics/otel-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/otel-loader.js +5 -0
- package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
- package/dist/cli/commands/analytics/report/client/app.js +302 -125
- package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
- package/dist/cli/commands/analytics/report/payload-builder.js +64 -13
- package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
- package/dist/cli/commands/analytics/report/template.html +50 -2
- package/dist/cli/commands/analytics/report/types.d.ts +16 -0
- package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
- package/dist/cli/commands/assistants/constants.d.ts +4 -0
- package/dist/cli/commands/assistants/constants.d.ts.map +1 -1
- package/dist/cli/commands/assistants/constants.js +4 -0
- package/dist/cli/commands/assistants/constants.js.map +1 -1
- package/dist/cli/commands/assistants/setup/data.d.ts +1 -0
- package/dist/cli/commands/assistants/setup/data.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/data.js +55 -10
- package/dist/cli/commands/assistants/setup/data.js.map +1 -1
- package/dist/cli/commands/assistants/setup/helpers.d.ts +1 -1
- package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/helpers.js +2 -5
- package/dist/cli/commands/assistants/setup/helpers.js.map +1 -1
- package/dist/cli/commands/assistants/setup/index.d.ts +12 -0
- package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -1
- package/dist/cli/commands/assistants/setup/index.js +148 -20
- package/dist/cli/commands/assistants/setup/index.js.map +1 -1
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +6 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/AgentsCheck.js +37 -33
- package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
- package/dist/cli/commands/doctor/index.d.ts.map +1 -1
- package/dist/cli/commands/doctor/index.js +11 -0
- package/dist/cli/commands/doctor/index.js.map +1 -1
- package/dist/cli/commands/hook.d.ts.map +1 -1
- package/dist/cli/commands/hook.js +72 -12
- package/dist/cli/commands/hook.js.map +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +5 -9
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/mcp/index.d.ts.map +1 -1
- package/dist/cli/commands/mcp/index.js +68 -17
- package/dist/cli/commands/mcp/index.js.map +1 -1
- package/dist/cli/commands/profile/display.d.ts +5 -1
- package/dist/cli/commands/profile/display.d.ts.map +1 -1
- package/dist/cli/commands/profile/display.js +5 -1
- package/dist/cli/commands/profile/display.js.map +1 -1
- package/dist/cli/commands/profile/index.d.ts.map +1 -1
- package/dist/cli/commands/profile/index.js +7 -4
- package/dist/cli/commands/profile/index.js.map +1 -1
- package/dist/cli/commands/proxy/connect-orchestrator.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connect-orchestrator.js +3 -4
- package/dist/cli/commands/proxy/connect-orchestrator.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.d.ts +15 -12
- package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.js +36 -38
- package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/model-name-resolver.d.ts +19 -0
- package/dist/cli/commands/proxy/connectors/model-name-resolver.d.ts.map +1 -0
- package/dist/cli/commands/proxy/connectors/model-name-resolver.js +126 -0
- package/dist/cli/commands/proxy/connectors/model-name-resolver.js.map +1 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts +11 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts.map +1 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.js +108 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.js.map +1 -0
- package/dist/cli/commands/proxy/connectors/vscode-claude-code.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode-claude-code.js +49 -19
- package/dist/cli/commands/proxy/connectors/vscode-claude-code.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode-models.d.ts +3 -3
- package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode-models.js +28 -28
- package/dist/cli/commands/proxy/connectors/vscode-models.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode.d.ts +3 -2
- package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode.js +78 -39
- package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +72 -24
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/shared/headless.d.ts +69 -0
- package/dist/cli/commands/shared/headless.d.ts.map +1 -0
- package/dist/cli/commands/shared/headless.js +83 -0
- package/dist/cli/commands/shared/headless.js.map +1 -0
- package/dist/cli/commands/shared/helpers.d.ts +21 -0
- package/dist/cli/commands/shared/helpers.d.ts.map +1 -1
- package/dist/cli/commands/shared/helpers.js +73 -1
- package/dist/cli/commands/shared/helpers.js.map +1 -1
- package/dist/cli/commands/shared/identifier-resolution.d.ts +23 -0
- package/dist/cli/commands/shared/identifier-resolution.d.ts.map +1 -0
- package/dist/cli/commands/shared/identifier-resolution.js +55 -0
- package/dist/cli/commands/shared/identifier-resolution.js.map +1 -0
- package/dist/cli/commands/skills/setup/data.d.ts +3 -2
- package/dist/cli/commands/skills/setup/data.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/data.js +75 -13
- package/dist/cli/commands/skills/setup/data.js.map +1 -1
- package/dist/cli/commands/skills/setup/helpers.d.ts +1 -1
- package/dist/cli/commands/skills/setup/helpers.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/helpers.js +2 -5
- package/dist/cli/commands/skills/setup/helpers.js.map +1 -1
- package/dist/cli/commands/skills/setup/index.d.ts +17 -1
- package/dist/cli/commands/skills/setup/index.d.ts.map +1 -1
- package/dist/cli/commands/skills/setup/index.js +190 -19
- package/dist/cli/commands/skills/setup/index.js.map +1 -1
- package/dist/cli/commands/tips.d.ts +10 -0
- package/dist/cli/commands/tips.d.ts.map +1 -0
- package/dist/cli/commands/tips.js +142 -0
- package/dist/cli/commands/tips.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +12 -10
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/commands/whatsnew.d.ts +6 -0
- package/dist/cli/commands/whatsnew.d.ts.map +1 -0
- package/dist/cli/commands/whatsnew.js +37 -0
- package/dist/cli/commands/whatsnew.js.map +1 -0
- package/dist/cli/first-time.d.ts.map +1 -1
- package/dist/cli/first-time.js +4 -0
- package/dist/cli/first-time.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/providers/core/types.d.ts +15 -0
- package/dist/providers/core/types.d.ts.map +1 -1
- package/dist/providers/core/types.js.map +1 -1
- package/dist/providers/integration/setup-ui.d.ts +5 -3
- package/dist/providers/integration/setup-ui.d.ts.map +1 -1
- package/dist/providers/integration/setup-ui.js +6 -4
- package/dist/providers/integration/setup-ui.js.map +1 -1
- package/dist/providers/plugins/ollama/ollama.library.d.ts +37 -0
- package/dist/providers/plugins/ollama/ollama.library.d.ts.map +1 -0
- package/dist/providers/plugins/ollama/ollama.library.js +105 -0
- package/dist/providers/plugins/ollama/ollama.library.js.map +1 -0
- package/dist/providers/plugins/ollama/ollama.models.d.ts +3 -1
- package/dist/providers/plugins/ollama/ollama.models.d.ts.map +1 -1
- package/dist/providers/plugins/ollama/ollama.models.js +5 -39
- package/dist/providers/plugins/ollama/ollama.models.js.map +1 -1
- package/dist/providers/plugins/ollama/ollama.setup-steps.d.ts.map +1 -1
- package/dist/providers/plugins/ollama/ollama.setup-steps.js +196 -6
- package/dist/providers/plugins/ollama/ollama.setup-steps.js.map +1 -1
- package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
- package/dist/providers/plugins/ollama/ollama.template.js +12 -32
- package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.d.ts +41 -0
- package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.js +115 -0
- package/dist/providers/plugins/sso/proxy/plugins/claude-model-resolver.js.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +101 -7
- package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.d.ts +4 -0
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +28 -3
- package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/proxy-types.d.ts +5 -0
- package/dist/providers/plugins/sso/proxy/proxy-types.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/sso.proxy.js +1 -0
- package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
- package/dist/providers/plugins/sso/session/BaseProcessor.d.ts +4 -0
- package/dist/providers/plugins/sso/session/BaseProcessor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts +12 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/SessionSyncer.js +89 -0
- package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +75 -41
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js +11 -2
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +25 -5
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.d.ts +1 -0
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.d.ts.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js +30 -6
- package/dist/telemetry/clients/claude-desktop/claude-desktop.discovery.js.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.d.ts.map +1 -1
- package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.js +33 -3
- package/dist/telemetry/clients/claude-desktop/claude-desktop.parser.js.map +1 -1
- package/dist/telemetry/runtime/DesktopRepositoryResolver.d.ts +58 -0
- package/dist/telemetry/runtime/DesktopRepositoryResolver.d.ts.map +1 -0
- package/dist/telemetry/runtime/DesktopRepositoryResolver.js +370 -0
- package/dist/telemetry/runtime/DesktopRepositoryResolver.js.map +1 -0
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts +1 -0
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts.map +1 -1
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.js +89 -6
- package/dist/telemetry/runtime/DesktopTelemetryRuntime.js.map +1 -1
- package/dist/telemetry/runtime/types.d.ts +2 -0
- package/dist/telemetry/runtime/types.d.ts.map +1 -1
- package/dist/utils/auth.d.ts +13 -2
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +7 -3
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/cli-updater.d.ts.map +1 -1
- package/dist/utils/cli-updater.js +2 -8
- package/dist/utils/cli-updater.js.map +1 -1
- package/dist/utils/config.d.ts +21 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +69 -7
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/env.d.ts +12 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +18 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errors.d.ts +14 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +25 -0
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/hook-command.d.ts +6 -0
- package/dist/utils/hook-command.d.ts.map +1 -1
- package/dist/utils/hook-command.js +40 -1
- package/dist/utils/hook-command.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -2
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +11 -9
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/pricing.json +14 -6
- package/dist/utils/processes.d.ts +12 -0
- package/dist/utils/processes.d.ts.map +1 -1
- package/dist/utils/processes.js +15 -0
- package/dist/utils/processes.js.map +1 -1
- package/dist/utils/tips.d.ts +103 -0
- package/dist/utils/tips.d.ts.map +1 -0
- package/dist/utils/tips.js +221 -0
- package/dist/utils/tips.js.map +1 -0
- package/dist/utils/version-warnings.d.ts +41 -0
- package/dist/utils/version-warnings.d.ts.map +1 -0
- package/dist/utils/version-warnings.js +93 -0
- package/dist/utils/version-warnings.js.map +1 -0
- package/dist/utils/whatsnew.d.ts +83 -0
- package/dist/utils/whatsnew.d.ts.map +1 -0
- package/dist/utils/whatsnew.js +200 -0
- package/dist/utils/whatsnew.js.map +1 -0
- package/package.json +4 -1
- package/scripts/release.sh +6 -0
- package/src/utils/tips.json +806 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature Tips ("Did you know?") — selection, rotation and rendering logic.
|
|
3
|
+
*
|
|
4
|
+
* The curated catalog lives in src/utils/tips.json (pure data — edit tips
|
|
5
|
+
* there); this module loads it once at startup and exposes it as TIPS.
|
|
6
|
+
* Tips are shown at session start and end, browseable on demand via
|
|
7
|
+
* `codemie tips`, and sprinkled onto selected CLI surfaces (doctor, first-run
|
|
8
|
+
* screens) via renderTip().
|
|
9
|
+
*
|
|
10
|
+
* Catalog maintenance workflow (edit src/utils/tips.json):
|
|
11
|
+
* - Add a tip: append one `{ "id", "category", "message", "command"? }` object
|
|
12
|
+
* to the array. Use a fresh kebab-case id — ids are never reused, because
|
|
13
|
+
* the rotation state (~/.codemie/.tips-state.json) remembers them.
|
|
14
|
+
* - Retire a command: delete its tip in the same PR. If the tip is missed,
|
|
15
|
+
* `codemie tips` validates `command` references against the live CLI command
|
|
16
|
+
* tree and silently drops (plus debug-logs) tips pointing at retired
|
|
17
|
+
* commands — session rendering never validates and never breaks.
|
|
18
|
+
* - Reword a tip: edit `message` in place and keep `id` stable so the rotation
|
|
19
|
+
* history stays meaningful.
|
|
20
|
+
*
|
|
21
|
+
* This module must stay safe to import from the agent runtime, so it depends
|
|
22
|
+
* only on fs/path, chalk, the logger and the paths utility — never on
|
|
23
|
+
* commander or the CLI layer.
|
|
24
|
+
*
|
|
25
|
+
* Environment Variables:
|
|
26
|
+
* - CODEMIE_TIPS=true (default): show tips at session start/end
|
|
27
|
+
* - CODEMIE_TIPS=false|0|no: disable session tips (`codemie tips` still works)
|
|
28
|
+
*/
|
|
29
|
+
import { readFileSync, writeFileSync, mkdirSync, renameSync } from 'fs';
|
|
30
|
+
import path from 'path';
|
|
31
|
+
import { fileURLToPath } from 'url';
|
|
32
|
+
import chalk from 'chalk';
|
|
33
|
+
import { logger } from './logger.js';
|
|
34
|
+
import { getCodemiePath } from './paths.js';
|
|
35
|
+
import { parseBooleanEnv } from './env.js';
|
|
36
|
+
const isStringArray = (value) => Array.isArray(value) && value.every(item => typeof item === 'string');
|
|
37
|
+
/**
|
|
38
|
+
* Load the tip catalog from src/utils/tips.json at the package root (resolved
|
|
39
|
+
* relative to this module, so it works from src/utils in dev and dist/utils in
|
|
40
|
+
* the installed package, where the JSON ships via the package.json files list).
|
|
41
|
+
*
|
|
42
|
+
* Best-effort: any failure — missing file, malformed JSON, wrong shape — is
|
|
43
|
+
* debug-logged and yields an empty catalog. Tips must never break a session.
|
|
44
|
+
*/
|
|
45
|
+
function loadTipsCatalog() {
|
|
46
|
+
try {
|
|
47
|
+
// Resolve via import.meta.url, not paths.js: tests legitimately mock
|
|
48
|
+
// ./paths.js without declaring every export, and this module is loaded
|
|
49
|
+
// eagerly through BaseAgentAdapter — a mocked-out helper must never break
|
|
50
|
+
// module evaluation. Resolves identically from src/utils (dev) and
|
|
51
|
+
// dist/utils (built/installed package, where tips.json ships in src/utils).
|
|
52
|
+
const catalogPath = fileURLToPath(new URL('../../src/utils/tips.json', import.meta.url));
|
|
53
|
+
const parsed = JSON.parse(readFileSync(catalogPath, 'utf-8'));
|
|
54
|
+
if (!Array.isArray(parsed)) {
|
|
55
|
+
logger.debug('[tips] tips.json is not an array — using empty catalog', { catalogPath });
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const tips = parsed
|
|
59
|
+
.filter((entry) => typeof entry === 'object' &&
|
|
60
|
+
entry !== null &&
|
|
61
|
+
typeof entry.id === 'string' &&
|
|
62
|
+
typeof entry.category === 'string' &&
|
|
63
|
+
typeof entry.message === 'string')
|
|
64
|
+
.map(entry => {
|
|
65
|
+
// Tolerate a malformed optional `commands` field by dropping just it
|
|
66
|
+
if (entry.commands !== undefined && !isStringArray(entry.commands)) {
|
|
67
|
+
logger.debug(`[tips] tips.json: ignoring malformed 'commands' on tip '${entry.id}'`);
|
|
68
|
+
return { ...entry, commands: undefined };
|
|
69
|
+
}
|
|
70
|
+
return entry;
|
|
71
|
+
});
|
|
72
|
+
if (tips.length !== parsed.length) {
|
|
73
|
+
logger.debug(`[tips] tips.json: dropped ${parsed.length - tips.length} malformed entrie(s)`, { catalogPath });
|
|
74
|
+
}
|
|
75
|
+
return tips;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logger.debug('[tips] Failed to load tips.json — using empty catalog:', error);
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Curated tip catalog, loaded eagerly from src/utils/tips.json. Every
|
|
84
|
+
* `command` value references a top-level command registered in
|
|
85
|
+
* src/cli/index.ts; `codemie tips` re-validates these at runtime.
|
|
86
|
+
*/
|
|
87
|
+
export const TIPS = loadTipsCatalog();
|
|
88
|
+
const stateFilePath = () => getCodemiePath('.tips-state.json');
|
|
89
|
+
/**
|
|
90
|
+
* Check if session tips are enabled (default: true).
|
|
91
|
+
* Reads the CODEMIE_TIPS environment variable.
|
|
92
|
+
*
|
|
93
|
+
* @returns true unless CODEMIE_TIPS is set to a falsy value ('false', '0', 'no')
|
|
94
|
+
*/
|
|
95
|
+
export function isTipsEnabled() {
|
|
96
|
+
return parseBooleanEnv(process.env.CODEMIE_TIPS, true);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Return the full tip catalog (used by `codemie tips`).
|
|
100
|
+
*/
|
|
101
|
+
export function listTips() {
|
|
102
|
+
return TIPS;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Pick the tip to show at a session lifecycle point.
|
|
106
|
+
*
|
|
107
|
+
* Randomly selects a tip that has not been shown yet (per the rotation state
|
|
108
|
+
* file), records the pick, and resets the shown list once every tip has been
|
|
109
|
+
* shown. Both contexts share one catalog and one rotation for now; the context
|
|
110
|
+
* is recorded in the debug log so future per-context catalogs can reuse it.
|
|
111
|
+
*
|
|
112
|
+
* Best-effort: unreadable/corrupt state is treated as empty, write failures
|
|
113
|
+
* are swallowed — a tip must never block or break a session.
|
|
114
|
+
*
|
|
115
|
+
* @param context - Where the tip is rendered ('start' or 'end' of session)
|
|
116
|
+
* @returns A tip, or null when tips are disabled or the catalog is empty
|
|
117
|
+
*/
|
|
118
|
+
export function getSessionTip(context) {
|
|
119
|
+
if (!isTipsEnabled() || TIPS.length === 0) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const state = loadRotationState();
|
|
123
|
+
// Prune ids of retired tips so the rotation can still complete and reset.
|
|
124
|
+
const catalogIds = new Set(TIPS.map(tip => tip.id));
|
|
125
|
+
state.shownTipIds = state.shownTipIds.filter(id => catalogIds.has(id));
|
|
126
|
+
let candidates = TIPS.filter(tip => !state.shownTipIds.includes(tip.id));
|
|
127
|
+
if (candidates.length === 0) {
|
|
128
|
+
// Full rotation complete — start a fresh cycle.
|
|
129
|
+
state.shownTipIds = [];
|
|
130
|
+
candidates = [...TIPS];
|
|
131
|
+
}
|
|
132
|
+
const tip = candidates[Math.floor(Math.random() * candidates.length)];
|
|
133
|
+
state.shownTipIds.push(tip.id);
|
|
134
|
+
saveRotationState(state);
|
|
135
|
+
logger.debug('[tips] Selected session tip', { context, id: tip.id });
|
|
136
|
+
return tip;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Format a tip for terminal display: a gold ✨ prefix followed by the message
|
|
140
|
+
* in the same warm gold, bold. Yellow is the CLI's established accent color
|
|
141
|
+
* (matches the Kimi-style prompt echo) — deliberately no background bars or
|
|
142
|
+
* badge, just plain foreground styling.
|
|
143
|
+
* Shared by session lifecycle rendering (BaseAgentAdapter), renderTip(), and
|
|
144
|
+
* `codemie tips --random` so tips look identical everywhere.
|
|
145
|
+
*/
|
|
146
|
+
export function formatTipLine(tip) {
|
|
147
|
+
return chalk.bold.yellow(`✨ ${tip.message}`);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Print a single random tip to the console for CLI surfaces (doctor,
|
|
151
|
+
* first-run and post-setup screens, ...). Unlike getSessionTip(), this does
|
|
152
|
+
* not read or update the rotation state — rotation stays exclusive to session
|
|
153
|
+
* start/end.
|
|
154
|
+
*
|
|
155
|
+
* Best-effort: never throws, and is a no-op when tips are disabled.
|
|
156
|
+
*
|
|
157
|
+
* @param options.category - Restrict the pick to one category; falls back to
|
|
158
|
+
* the full catalog when the category has no tips
|
|
159
|
+
*/
|
|
160
|
+
export function renderTip(options) {
|
|
161
|
+
try {
|
|
162
|
+
if (!isTipsEnabled() || TIPS.length === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
let pool = TIPS;
|
|
166
|
+
if (options?.category) {
|
|
167
|
+
const filtered = TIPS.filter(tip => tip.category === options.category);
|
|
168
|
+
if (filtered.length > 0) {
|
|
169
|
+
pool = filtered;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const tip = pool[Math.floor(Math.random() * pool.length)];
|
|
173
|
+
console.log();
|
|
174
|
+
console.log(formatTipLine(tip));
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
logger.debug('[tips] renderTip failed (non-fatal):', error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function loadRotationState() {
|
|
181
|
+
const file = stateFilePath();
|
|
182
|
+
try {
|
|
183
|
+
const content = readFileSync(file, 'utf-8');
|
|
184
|
+
const parsed = JSON.parse(content);
|
|
185
|
+
if (typeof parsed === 'object' &&
|
|
186
|
+
parsed !== null &&
|
|
187
|
+
Array.isArray(parsed.shownTipIds)) {
|
|
188
|
+
const shownTipIds = parsed.shownTipIds
|
|
189
|
+
.filter((id) => typeof id === 'string');
|
|
190
|
+
return { shownTipIds };
|
|
191
|
+
}
|
|
192
|
+
return { shownTipIds: [] };
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
const code = error.code;
|
|
196
|
+
if (code !== 'ENOENT') {
|
|
197
|
+
logger.debug('[tips] Rotation state unreadable — treating as empty', { file });
|
|
198
|
+
}
|
|
199
|
+
return { shownTipIds: [] };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Persist rotation state. The write goes through a same-directory temp file
|
|
204
|
+
* plus rename, so a concurrent reader never sees a truncated file (rename is
|
|
205
|
+
* atomic on POSIX and Windows for same-dir renames). Read-modify-write races
|
|
206
|
+
* between concurrent sessions remain theoretically possible — accepted as
|
|
207
|
+
* low-harm (worst case: a tip repeats); deliberately no locking.
|
|
208
|
+
*/
|
|
209
|
+
function saveRotationState(state) {
|
|
210
|
+
const file = stateFilePath();
|
|
211
|
+
try {
|
|
212
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
213
|
+
const tmpFile = `${file}.tmp`;
|
|
214
|
+
writeFileSync(tmpFile, JSON.stringify(state, null, 2), 'utf-8');
|
|
215
|
+
renameSync(tmpFile, file);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
logger.debug('[tips] Failed to persist rotation state (non-fatal):', error);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=tips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tips.js","sourceRoot":"","sources":["../../src/utils/tips.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VersionWarningStore
|
|
3
|
+
*
|
|
4
|
+
* Records one-time "untested version" markers at user scope.
|
|
5
|
+
* Backing file: `~/.codemie/version-warnings.json`.
|
|
6
|
+
*
|
|
7
|
+
* A marker is keyed by (agent, installed agent version) and additionally stores
|
|
8
|
+
* the `supportedVersion` baseline it was acknowledged against. The marker is
|
|
9
|
+
* honoured only while that baseline still matches: a CodeMie release that moves
|
|
10
|
+
* the recommended version forward invalidates old markers and buys exactly one
|
|
11
|
+
* re-notice, while CodeMie releases that leave the baseline alone never re-nag.
|
|
12
|
+
*
|
|
13
|
+
* See EPMCDME-13734.
|
|
14
|
+
*/
|
|
15
|
+
export interface VersionWarningRecord {
|
|
16
|
+
agentName: string;
|
|
17
|
+
agentVersion: string;
|
|
18
|
+
/** Recommended version at the time the notice was acknowledged. */
|
|
19
|
+
supportedVersion: string;
|
|
20
|
+
/** CodeMie version that emitted the notice (context for `codemie doctor`). */
|
|
21
|
+
codemieVersion: string;
|
|
22
|
+
warnedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export interface VersionWarningHistory {
|
|
25
|
+
version: 1;
|
|
26
|
+
warnings: VersionWarningRecord[];
|
|
27
|
+
}
|
|
28
|
+
export declare class VersionWarningStore {
|
|
29
|
+
static loadHistory(): Promise<VersionWarningHistory>;
|
|
30
|
+
static saveHistory(history: VersionWarningHistory): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* True when this agent version was already acknowledged against the same
|
|
33
|
+
* recommended baseline. A moved baseline makes the stored marker stale.
|
|
34
|
+
*/
|
|
35
|
+
static hasWarned(agentName: string, agentVersion: string, supportedVersion: string): Promise<boolean>;
|
|
36
|
+
static recordWarning(agentName: string, agentVersion: string, supportedVersion: string, codemieVersion: string): Promise<void>;
|
|
37
|
+
static clear(): Promise<{
|
|
38
|
+
removed: number;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=version-warnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-warnings.d.ts","sourceRoot":"","sources":["../../src/utils/version-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAMD,qBAAa,mBAAmB;WACjB,WAAW,IAAI,OAAO,CAAC,qBAAqB,CAAC;WA0B7C,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvE;;;OAGG;WACU,SAAS,CACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,OAAO,CAAC;WAUN,aAAa,CACxB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EACxB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC;WAeH,KAAK,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAkBnD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VersionWarningStore
|
|
3
|
+
*
|
|
4
|
+
* Records one-time "untested version" markers at user scope.
|
|
5
|
+
* Backing file: `~/.codemie/version-warnings.json`.
|
|
6
|
+
*
|
|
7
|
+
* A marker is keyed by (agent, installed agent version) and additionally stores
|
|
8
|
+
* the `supportedVersion` baseline it was acknowledged against. The marker is
|
|
9
|
+
* honoured only while that baseline still matches: a CodeMie release that moves
|
|
10
|
+
* the recommended version forward invalidates old markers and buys exactly one
|
|
11
|
+
* re-notice, while CodeMie releases that leave the baseline alone never re-nag.
|
|
12
|
+
*
|
|
13
|
+
* See EPMCDME-13734.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from 'fs/promises';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { logger } from './logger.js';
|
|
18
|
+
import { getCodemiePath } from './paths.js';
|
|
19
|
+
const filePath = () => getCodemiePath('version-warnings.json');
|
|
20
|
+
const emptyHistory = () => ({ version: 1, warnings: [] });
|
|
21
|
+
export class VersionWarningStore {
|
|
22
|
+
static async loadHistory() {
|
|
23
|
+
const file = filePath();
|
|
24
|
+
try {
|
|
25
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
26
|
+
const parsed = JSON.parse(content);
|
|
27
|
+
if (typeof parsed === 'object' &&
|
|
28
|
+
parsed !== null &&
|
|
29
|
+
Array.isArray(parsed.warnings)) {
|
|
30
|
+
return {
|
|
31
|
+
version: 1,
|
|
32
|
+
warnings: parsed.warnings,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return emptyHistory();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const code = error.code;
|
|
39
|
+
if (code === 'ENOENT') {
|
|
40
|
+
return emptyHistory();
|
|
41
|
+
}
|
|
42
|
+
logger.warn('[VersionWarningStore] Corrupt or unreadable file — treating as empty', { file });
|
|
43
|
+
return emptyHistory();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
static async saveHistory(history) {
|
|
47
|
+
const file = filePath();
|
|
48
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
49
|
+
await fs.writeFile(file, JSON.stringify(history, null, 2), 'utf-8');
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* True when this agent version was already acknowledged against the same
|
|
53
|
+
* recommended baseline. A moved baseline makes the stored marker stale.
|
|
54
|
+
*/
|
|
55
|
+
static async hasWarned(agentName, agentVersion, supportedVersion) {
|
|
56
|
+
const history = await this.loadHistory();
|
|
57
|
+
return history.warnings.some((warning) => warning.agentName === agentName &&
|
|
58
|
+
warning.agentVersion === agentVersion &&
|
|
59
|
+
warning.supportedVersion === supportedVersion);
|
|
60
|
+
}
|
|
61
|
+
static async recordWarning(agentName, agentVersion, supportedVersion, codemieVersion) {
|
|
62
|
+
const history = await this.loadHistory();
|
|
63
|
+
const others = history.warnings.filter((warning) => !(warning.agentName === agentName && warning.agentVersion === agentVersion));
|
|
64
|
+
others.push({
|
|
65
|
+
agentName,
|
|
66
|
+
agentVersion,
|
|
67
|
+
supportedVersion,
|
|
68
|
+
codemieVersion,
|
|
69
|
+
warnedAt: new Date().toISOString(),
|
|
70
|
+
});
|
|
71
|
+
await this.saveHistory({ version: 1, warnings: others });
|
|
72
|
+
}
|
|
73
|
+
static async clear() {
|
|
74
|
+
const file = filePath();
|
|
75
|
+
const history = await this.loadHistory();
|
|
76
|
+
const removed = history.warnings.length;
|
|
77
|
+
try {
|
|
78
|
+
await fs.unlink(file);
|
|
79
|
+
return { removed };
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const code = error.code;
|
|
83
|
+
if (code === 'ENOENT') {
|
|
84
|
+
return { removed: 0 };
|
|
85
|
+
}
|
|
86
|
+
// The user ran the reset intentionally — failing `codemie doctor` here
|
|
87
|
+
// would be worse than reporting "0 removed" and continuing the checks.
|
|
88
|
+
logger.warn('[VersionWarningStore] clear() failed; markers left in place', { file, code });
|
|
89
|
+
return { removed: 0 };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=version-warnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-warnings.js","sourceRoot":"","sources":["../../src/utils/version-warnings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What's New — release notes from CHANGELOG.md
|
|
3
|
+
*
|
|
4
|
+
* CHANGELOG.md (Keep a Changelog format) is the curated source of truth for
|
|
5
|
+
* release notes. It ships inside the npm package and is consumed by:
|
|
6
|
+
* - `codemie whatsnew` — browse notes for the current, one, or all versions
|
|
7
|
+
* - the once-per-upgrade startup notice in bin/codemie.js, which shows the
|
|
8
|
+
* current version's notes once and records a `.last-seen-version` marker
|
|
9
|
+
* under the CodeMie home directory
|
|
10
|
+
*
|
|
11
|
+
* This module must stay safe to import from the bin entry point, so its
|
|
12
|
+
* dependencies are limited to fs/path/chalk plus the logger, paths, and tips
|
|
13
|
+
* utilities — never commander or the CLI layer.
|
|
14
|
+
*
|
|
15
|
+
* Environment Variables:
|
|
16
|
+
* - CODEMIE_TIPS=false|0|no: also suppresses the upgrade notice. The "reduce
|
|
17
|
+
* chatter" switch is shared with feature tips on purpose — see tips.ts.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* One `### Section` block inside a release entry.
|
|
21
|
+
*/
|
|
22
|
+
export interface ReleaseSection {
|
|
23
|
+
title: string;
|
|
24
|
+
items: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One `## [version]` release entry from the changelog.
|
|
28
|
+
*/
|
|
29
|
+
export interface ReleaseEntry {
|
|
30
|
+
version: string;
|
|
31
|
+
date?: string;
|
|
32
|
+
sections: ReleaseSection[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Tolerant Keep-a-Changelog parser. Recognizes `## [x.y.z] - date` headings,
|
|
36
|
+
* `### Section` subheadings, and `- item` bullets; everything else is skipped.
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseChangelog(content: string): ReleaseEntry[];
|
|
39
|
+
/**
|
|
40
|
+
* Locate CHANGELOG.md at the package root. Works both from src/utils (dev
|
|
41
|
+
* repo) and dist/utils (built/installed package) — the root is two levels up
|
|
42
|
+
* in both layouts.
|
|
43
|
+
*
|
|
44
|
+
* @returns Absolute path to CHANGELOG.md, or null when it is not shipped
|
|
45
|
+
*/
|
|
46
|
+
export declare function getChangelogPath(): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Read release notes from the changelog.
|
|
49
|
+
*
|
|
50
|
+
* @param version - When given, the entry for this exact version; if there is
|
|
51
|
+
* no matching heading, falls back to the newest versioned entry (or
|
|
52
|
+
* Unreleased when that is all there is) so the once-per-upgrade notice
|
|
53
|
+
* always has something to show
|
|
54
|
+
* @returns Parsed entries (newest first, as written), or an empty array when
|
|
55
|
+
* the changelog is missing or unparseable
|
|
56
|
+
*/
|
|
57
|
+
export declare function getReleaseNotes(version?: string): ReleaseEntry[];
|
|
58
|
+
/**
|
|
59
|
+
* Version for which the upgrade notice was last shown, or null if never.
|
|
60
|
+
* Best-effort: an unreadable marker is treated as "never seen".
|
|
61
|
+
*/
|
|
62
|
+
export declare function getLastSeenVersion(): string | null;
|
|
63
|
+
/**
|
|
64
|
+
* Record that the upgrade notice was shown for a version. Best-effort: write
|
|
65
|
+
* failures are swallowed — worst case the notice shows once more.
|
|
66
|
+
*/
|
|
67
|
+
export declare function markVersionSeen(version: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Render release notes to the console. Never throws.
|
|
70
|
+
*
|
|
71
|
+
* @param options.maxItems - Cap on the total number of bullets printed across
|
|
72
|
+
* all entries; when truncated, a pointer to `codemie whatsnew` is appended
|
|
73
|
+
*/
|
|
74
|
+
export declare function renderReleaseNotes(entries: ReleaseEntry[], options?: {
|
|
75
|
+
maxItems?: number;
|
|
76
|
+
}): void;
|
|
77
|
+
/**
|
|
78
|
+
* Whether the once-per-upgrade notice may print. Deliberately shares the
|
|
79
|
+
* CODEMIE_TIPS switch with feature tips — one "reduce chatter" toggle for all
|
|
80
|
+
* informational CLI output.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isWhatsNewEnabled(): boolean;
|
|
83
|
+
//# sourceMappingURL=whatsnew.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsnew.d.ts","sourceRoot":"","sources":["../../src/utils/whatsnew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAoC9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAGhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAkChE;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAMlD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAQrD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgDjG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What's New — release notes from CHANGELOG.md
|
|
3
|
+
*
|
|
4
|
+
* CHANGELOG.md (Keep a Changelog format) is the curated source of truth for
|
|
5
|
+
* release notes. It ships inside the npm package and is consumed by:
|
|
6
|
+
* - `codemie whatsnew` — browse notes for the current, one, or all versions
|
|
7
|
+
* - the once-per-upgrade startup notice in bin/codemie.js, which shows the
|
|
8
|
+
* current version's notes once and records a `.last-seen-version` marker
|
|
9
|
+
* under the CodeMie home directory
|
|
10
|
+
*
|
|
11
|
+
* This module must stay safe to import from the bin entry point, so its
|
|
12
|
+
* dependencies are limited to fs/path/chalk plus the logger, paths, and tips
|
|
13
|
+
* utilities — never commander or the CLI layer.
|
|
14
|
+
*
|
|
15
|
+
* Environment Variables:
|
|
16
|
+
* - CODEMIE_TIPS=false|0|no: also suppresses the upgrade notice. The "reduce
|
|
17
|
+
* chatter" switch is shared with feature tips on purpose — see tips.ts.
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import chalk from 'chalk';
|
|
22
|
+
import { logger } from './logger.js';
|
|
23
|
+
import { getCodemiePath, getDirname } from './paths.js';
|
|
24
|
+
import { isTipsEnabled } from './tips.js';
|
|
25
|
+
/**
|
|
26
|
+
* Tolerant Keep-a-Changelog parser. Recognizes `## [x.y.z] - date` headings,
|
|
27
|
+
* `### Section` subheadings, and `- item` bullets; everything else is skipped.
|
|
28
|
+
*/
|
|
29
|
+
export function parseChangelog(content) {
|
|
30
|
+
const entries = [];
|
|
31
|
+
let currentEntry = null;
|
|
32
|
+
let currentSection = null;
|
|
33
|
+
for (const line of content.split(/\r?\n/)) {
|
|
34
|
+
const versionMatch = line.match(/^##\s+\[([^\]]+)\](?:\s*-\s*(.+?))?\s*$/);
|
|
35
|
+
if (versionMatch) {
|
|
36
|
+
currentEntry = {
|
|
37
|
+
version: versionMatch[1].trim(),
|
|
38
|
+
date: versionMatch[2]?.trim(),
|
|
39
|
+
sections: []
|
|
40
|
+
};
|
|
41
|
+
entries.push(currentEntry);
|
|
42
|
+
currentSection = null;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!currentEntry) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const sectionMatch = line.match(/^###\s+(.+?)\s*$/);
|
|
49
|
+
if (sectionMatch) {
|
|
50
|
+
currentSection = { title: sectionMatch[1].trim(), items: [] };
|
|
51
|
+
currentEntry.sections.push(currentSection);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const itemMatch = line.match(/^\s*[-*]\s+(.+?)\s*$/);
|
|
55
|
+
if (itemMatch && currentSection) {
|
|
56
|
+
currentSection.items.push(itemMatch[1].trim());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return entries;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Locate CHANGELOG.md at the package root. Works both from src/utils (dev
|
|
63
|
+
* repo) and dist/utils (built/installed package) — the root is two levels up
|
|
64
|
+
* in both layouts.
|
|
65
|
+
*
|
|
66
|
+
* @returns Absolute path to CHANGELOG.md, or null when it is not shipped
|
|
67
|
+
*/
|
|
68
|
+
export function getChangelogPath() {
|
|
69
|
+
const changelogPath = path.resolve(getDirname(import.meta.url), '../../CHANGELOG.md');
|
|
70
|
+
return existsSync(changelogPath) ? changelogPath : null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Read release notes from the changelog.
|
|
74
|
+
*
|
|
75
|
+
* @param version - When given, the entry for this exact version; if there is
|
|
76
|
+
* no matching heading, falls back to the newest versioned entry (or
|
|
77
|
+
* Unreleased when that is all there is) so the once-per-upgrade notice
|
|
78
|
+
* always has something to show
|
|
79
|
+
* @returns Parsed entries (newest first, as written), or an empty array when
|
|
80
|
+
* the changelog is missing or unparseable
|
|
81
|
+
*/
|
|
82
|
+
export function getReleaseNotes(version) {
|
|
83
|
+
const changelogPath = getChangelogPath();
|
|
84
|
+
if (!changelogPath) {
|
|
85
|
+
logger.debug('[whatsnew] CHANGELOG.md not found at package root');
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const entries = parseChangelog(readFileSync(changelogPath, 'utf-8'));
|
|
90
|
+
if (entries.length === 0) {
|
|
91
|
+
logger.debug('[whatsnew] CHANGELOG.md parsed to zero release entries', { changelogPath });
|
|
92
|
+
}
|
|
93
|
+
if (!version) {
|
|
94
|
+
return entries;
|
|
95
|
+
}
|
|
96
|
+
const exact = entries.filter(entry => entry.version === version);
|
|
97
|
+
if (exact.length > 0) {
|
|
98
|
+
return exact;
|
|
99
|
+
}
|
|
100
|
+
// No heading for this exact version (changelog not updated for the
|
|
101
|
+
// release) — fall back to the newest versioned entry so the once-per-
|
|
102
|
+
// upgrade notice still shows something before the version is marked seen.
|
|
103
|
+
const fallback = entries.find(entry => entry.version !== 'Unreleased') ?? entries[0];
|
|
104
|
+
if (fallback) {
|
|
105
|
+
logger.debug(`[whatsnew] No changelog entry for ${version} — falling back to ${fallback.version}`);
|
|
106
|
+
return [fallback];
|
|
107
|
+
}
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
logger.debug('[whatsnew] Failed to read changelog:', error);
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const lastSeenFilePath = () => getCodemiePath('.last-seen-version');
|
|
116
|
+
/**
|
|
117
|
+
* Version for which the upgrade notice was last shown, or null if never.
|
|
118
|
+
* Best-effort: an unreadable marker is treated as "never seen".
|
|
119
|
+
*/
|
|
120
|
+
export function getLastSeenVersion() {
|
|
121
|
+
try {
|
|
122
|
+
return readFileSync(lastSeenFilePath(), 'utf-8').trim() || null;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Record that the upgrade notice was shown for a version. Best-effort: write
|
|
130
|
+
* failures are swallowed — worst case the notice shows once more.
|
|
131
|
+
*/
|
|
132
|
+
export function markVersionSeen(version) {
|
|
133
|
+
try {
|
|
134
|
+
const file = lastSeenFilePath();
|
|
135
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
136
|
+
writeFileSync(file, version, 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
logger.debug('[whatsnew] Failed to persist last-seen version (non-fatal):', error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Render release notes to the console. Never throws.
|
|
144
|
+
*
|
|
145
|
+
* @param options.maxItems - Cap on the total number of bullets printed across
|
|
146
|
+
* all entries; when truncated, a pointer to `codemie whatsnew` is appended
|
|
147
|
+
*/
|
|
148
|
+
export function renderReleaseNotes(entries, options) {
|
|
149
|
+
try {
|
|
150
|
+
if (entries.length === 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
let remaining = options?.maxItems ?? Number.POSITIVE_INFINITY;
|
|
154
|
+
let truncated = false;
|
|
155
|
+
console.log();
|
|
156
|
+
for (const entry of entries) {
|
|
157
|
+
if (remaining <= 0) {
|
|
158
|
+
truncated = true;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
const dateSuffix = entry.date ? ` (${entry.date})` : '';
|
|
162
|
+
console.log(chalk.bold.cyan(`## What's new in ${entry.version}${dateSuffix}`));
|
|
163
|
+
for (const section of entry.sections) {
|
|
164
|
+
if (remaining <= 0) {
|
|
165
|
+
truncated = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
if (section.items.length === 0) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
console.log(chalk.dim(` ${section.title}`));
|
|
172
|
+
for (const item of section.items) {
|
|
173
|
+
if (remaining <= 0) {
|
|
174
|
+
truncated = true;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
console.log(` • ${item}`);
|
|
178
|
+
remaining--;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
console.log();
|
|
182
|
+
}
|
|
183
|
+
if (truncated) {
|
|
184
|
+
console.log(chalk.dim(' … run `codemie whatsnew` for the full notes'));
|
|
185
|
+
console.log();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
logger.debug('[whatsnew] renderReleaseNotes failed (non-fatal):', error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Whether the once-per-upgrade notice may print. Deliberately shares the
|
|
194
|
+
* CODEMIE_TIPS switch with feature tips — one "reduce chatter" toggle for all
|
|
195
|
+
* informational CLI output.
|
|
196
|
+
*/
|
|
197
|
+
export function isWhatsNewEnabled() {
|
|
198
|
+
return isTipsEnabled();
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=whatsnew.js.map
|