@codemieai/code 0.15.2 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +9 -0
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +34 -9
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/plugins/claude/claude.models.d.ts +58 -0
- package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.models.js +196 -10
- package/dist/agents/plugins/claude/claude.models.js.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +149 -47
- 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 +4 -0
- package/dist/agents/plugins/claude/claude.session.js.map +1 -1
- package/dist/agents/plugins/claude/plugin/statusline.bundle.mjs +729 -0
- package/dist/agents/plugins/claude/statusline-installer.d.ts +1 -1
- package/dist/agents/plugins/claude/statusline-installer.d.ts.map +1 -1
- package/dist/agents/plugins/claude/statusline-installer.js +41 -3
- package/dist/agents/plugins/claude/statusline-installer.js.map +1 -1
- package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -1
- package/dist/agents/plugins/codex/codex-models.js +109 -8
- package/dist/agents/plugins/codex/codex-models.js.map +1 -1
- package/dist/agents/plugins/codex/codex.correlation.d.ts +39 -0
- package/dist/agents/plugins/codex/codex.correlation.d.ts.map +1 -0
- package/dist/agents/plugins/codex/codex.correlation.js +150 -0
- package/dist/agents/plugins/codex/codex.correlation.js.map +1 -0
- package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/codex/codex.plugin.js +8 -40
- package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
- package/dist/agents/plugins/kimi/kimi.env-model.d.ts +27 -0
- package/dist/agents/plugins/kimi/kimi.env-model.d.ts.map +1 -0
- package/dist/agents/plugins/kimi/kimi.env-model.js +52 -0
- package/dist/agents/plugins/kimi/kimi.env-model.js.map +1 -0
- package/dist/agents/plugins/kimi/kimi.session.d.ts +6 -0
- package/dist/agents/plugins/kimi/kimi.session.d.ts.map +1 -1
- package/dist/agents/plugins/kimi/kimi.session.js +24 -2
- package/dist/agents/plugins/kimi/kimi.session.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 +4 -5
- 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/cost-enricher.d.ts +19 -2
- package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/cost-enricher.js +171 -14
- package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
- package/dist/cli/commands/analytics/cost/local-models.d.ts +15 -0
- package/dist/cli/commands/analytics/cost/local-models.d.ts.map +1 -0
- package/dist/cli/commands/analytics/cost/local-models.js +21 -0
- package/dist/cli/commands/analytics/cost/local-models.js.map +1 -0
- package/dist/cli/commands/analytics/cost/types.d.ts +60 -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 +25 -2
- package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
- package/dist/cli/commands/analytics/cost/usage-readers.js +61 -3
- package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
- package/dist/cli/commands/analytics/formatter.d.ts +11 -0
- package/dist/cli/commands/analytics/formatter.d.ts.map +1 -1
- package/dist/cli/commands/analytics/formatter.js +28 -0
- package/dist/cli/commands/analytics/formatter.js.map +1 -1
- package/dist/cli/commands/analytics/index.d.ts.map +1 -1
- package/dist/cli/commands/analytics/index.js +70 -73
- package/dist/cli/commands/analytics/index.js.map +1 -1
- package/dist/cli/commands/analytics/otel-loader.d.ts.map +1 -1
- package/dist/cli/commands/analytics/otel-loader.js +60 -14
- package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
- package/dist/cli/commands/analytics/otel-pricing.d.ts +38 -0
- package/dist/cli/commands/analytics/otel-pricing.d.ts.map +1 -0
- package/dist/cli/commands/analytics/otel-pricing.js +33 -0
- package/dist/cli/commands/analytics/otel-pricing.js.map +1 -0
- package/dist/cli/commands/analytics/report/client/app.js +279 -18
- package/dist/cli/commands/analytics/report/output-target.d.ts +22 -0
- package/dist/cli/commands/analytics/report/output-target.d.ts.map +1 -0
- package/dist/cli/commands/analytics/report/output-target.js +56 -0
- package/dist/cli/commands/analytics/report/output-target.js.map +1 -0
- package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
- package/dist/cli/commands/analytics/report/payload-builder.js +6 -0
- package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
- package/dist/cli/commands/analytics/report/report-generator.d.ts +1 -1
- package/dist/cli/commands/analytics/report/report-generator.js +1 -1
- package/dist/cli/commands/analytics/report/session-report.d.ts +1 -3
- package/dist/cli/commands/analytics/report/session-report.d.ts.map +1 -1
- package/dist/cli/commands/analytics/report/session-report.js +1 -3
- package/dist/cli/commands/analytics/report/session-report.js.map +1 -1
- package/dist/cli/commands/analytics/report/template.html +6 -6
- package/dist/cli/commands/analytics/report/types.d.ts +17 -1
- package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
- package/dist/cli/commands/analytics/sources/sessions-source.d.ts.map +1 -1
- package/dist/cli/commands/analytics/sources/sessions-source.js +9 -11
- package/dist/cli/commands/analytics/sources/sessions-source.js.map +1 -1
- package/dist/cli/commands/analytics/sources/types.d.ts +0 -2
- package/dist/cli/commands/analytics/sources/types.d.ts.map +1 -1
- package/dist/cli/commands/analytics/types.d.ts +8 -8
- package/dist/cli/commands/analytics/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/models.d.ts.map +1 -1
- package/dist/cli/commands/models.js +16 -3
- package/dist/cli/commands/models.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 +2 -3
- package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.js +9 -25
- 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 +23 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts.map +1 -0
- package/dist/cli/commands/proxy/connectors/tenant-catalog.js +136 -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 +21 -3
- package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode-models.js +86 -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 +67 -39
- package/dist/cli/commands/proxy/connectors/vscode.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/providers/core/codemie-auth-helpers.d.ts.map +1 -1
- package/dist/providers/core/codemie-auth-helpers.js +6 -1
- package/dist/providers/core/codemie-auth-helpers.js.map +1 -1
- package/dist/providers/core/default-agent-hooks.d.ts.map +1 -1
- package/dist/providers/core/default-agent-hooks.js +9 -0
- package/dist/providers/core/default-agent-hooks.js.map +1 -1
- package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -1
- package/dist/providers/plugins/bedrock/bedrock.template.js +5 -31
- package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.d.ts +44 -0
- package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.js +106 -0
- package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.js.map +1 -0
- 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/plugins/index.d.ts +3 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js +5 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.d.ts +67 -0
- package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.js +203 -0
- package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.js.map +1 -0
- 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/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 +2 -1
- package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.d.ts +95 -0
- package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js +79 -0
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
- package/dist/providers/plugins/sso/sso.models.d.ts +7 -0
- package/dist/providers/plugins/sso/sso.models.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.models.js +22 -14
- package/dist/providers/plugins/sso/sso.models.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/bedrock-pricing.mjs +111 -0
- package/dist/utils/cli-updater.d.ts.map +1 -1
- package/dist/utils/cli-updater.js +32 -7
- 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/credential-crypto.d.ts +51 -0
- package/dist/utils/credential-crypto.d.ts.map +1 -0
- package/dist/utils/credential-crypto.js +96 -0
- package/dist/utils/credential-crypto.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/model-normalizer.d.ts +6 -0
- package/dist/utils/model-normalizer.d.ts.map +1 -1
- package/dist/utils/model-normalizer.js +37 -19
- package/dist/utils/model-normalizer.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/price-resolution.d.ts +42 -0
- package/dist/utils/price-resolution.d.ts.map +1 -0
- package/dist/utils/price-resolution.js +112 -0
- package/dist/utils/price-resolution.js.map +1 -0
- package/dist/utils/pricing.d.ts +65 -6
- package/dist/utils/pricing.d.ts.map +1 -1
- package/dist/utils/pricing.js +91 -117
- package/dist/utils/pricing.js.map +1 -1
- package/dist/utils/pricing.json +201 -20
- 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/routing-headers.mjs +104 -0
- package/dist/utils/security.d.ts +0 -32
- package/dist/utils/security.d.ts.map +1 -1
- package/dist/utils/security.js +20 -102
- package/dist/utils/security.js.map +1 -1
- package/package.json +5 -2
- package/scripts/bundle-statusline.mjs +37 -0
- package/scripts/copy-plugins.js +19 -2
- package/src/utils/tips.json +9 -9
- package/dist/agents/plugins/claude/plugin/__tests__/statusline.test.ts +0 -323
- package/dist/agents/plugins/claude/plugin/statusline.mjs +0 -282
- package/dist/cli/commands/analytics/exporter.d.ts +0 -20
- package/dist/cli/commands/analytics/exporter.d.ts.map +0 -1
- package/dist/cli/commands/analytics/exporter.js +0 -91
- package/dist/cli/commands/analytics/exporter.js.map +0 -1
package/scripts/copy-plugins.js
CHANGED
|
@@ -17,7 +17,12 @@ const copyConfigs = [
|
|
|
17
17
|
{
|
|
18
18
|
name: 'Claude plugin',
|
|
19
19
|
src: join(rootDir, 'src/agents/plugins/claude/plugin'),
|
|
20
|
-
dest: join(rootDir, 'dist/agents/plugins/claude/plugin')
|
|
20
|
+
dest: join(rootDir, 'dist/agents/plugins/claude/plugin'),
|
|
21
|
+
// statusline.ts lives in this tree as normal TS source; tsc compiles it and
|
|
22
|
+
// scripts/bundle-statusline.mjs bundles it separately, both under dist/. Exclude .ts here so
|
|
23
|
+
// this wholesale asset copy doesn't also duplicate the raw source (and its __tests__ file)
|
|
24
|
+
// into the published package.
|
|
25
|
+
filter: (src) => !src.endsWith('.ts')
|
|
21
26
|
},
|
|
22
27
|
{
|
|
23
28
|
name: 'Gemini extension',
|
|
@@ -63,6 +68,18 @@ const fileConfigs = [
|
|
|
63
68
|
name: 'Model pricing table',
|
|
64
69
|
src: join(rootDir, 'src/utils/pricing.json'),
|
|
65
70
|
dest: join(rootDir, 'dist/utils/pricing.json')
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
// Plain JS, zero project imports — deployed as-is beside any agent's statusline (see
|
|
74
|
+
// statusline-installer.ts) as well as imported normally by pricing.ts/usage-readers.ts.
|
|
75
|
+
name: 'Routing headers domain module',
|
|
76
|
+
src: join(rootDir, 'src/utils/routing-headers.mjs'),
|
|
77
|
+
dest: join(rootDir, 'dist/utils/routing-headers.mjs')
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'Bedrock pricing domain module',
|
|
81
|
+
src: join(rootDir, 'src/utils/bedrock-pricing.mjs'),
|
|
82
|
+
dest: join(rootDir, 'dist/utils/bedrock-pricing.mjs')
|
|
66
83
|
}
|
|
67
84
|
];
|
|
68
85
|
|
|
@@ -89,7 +106,7 @@ for (const config of copyConfigs) {
|
|
|
89
106
|
|
|
90
107
|
// Copy recursively
|
|
91
108
|
console.log(` - Copying from ${config.src}`);
|
|
92
|
-
cpSync(config.src, config.dest, { recursive: true });
|
|
109
|
+
cpSync(config.src, config.dest, { recursive: true, ...(config.filter ? { filter: config.filter } : {}) });
|
|
93
110
|
|
|
94
111
|
console.log(` ✓ ${config.name} copied successfully\n`);
|
|
95
112
|
}
|
package/src/utils/tips.json
CHANGED
|
@@ -527,20 +527,20 @@
|
|
|
527
527
|
{
|
|
528
528
|
"id": "cmd-analytics-report",
|
|
529
529
|
"category": "Insights",
|
|
530
|
-
"message": "`codemie analytics --
|
|
530
|
+
"message": "`codemie analytics --open` builds a self-contained HTML dashboard of your usage and opens it in the browser.",
|
|
531
531
|
"command": "analytics",
|
|
532
532
|
"commands": [
|
|
533
|
-
"codemie analytics --
|
|
533
|
+
"codemie analytics --open"
|
|
534
534
|
]
|
|
535
535
|
},
|
|
536
536
|
{
|
|
537
537
|
"id": "cmd-analytics-filter",
|
|
538
538
|
"category": "Insights",
|
|
539
|
-
"message": "Slice the numbers: `codemie analytics --agent claude --last 7d --branch main`, then `--export
|
|
539
|
+
"message": "Slice the numbers: `codemie analytics --agent claude --last 7d --branch main`, then `--export json -o report.json` to share.",
|
|
540
540
|
"command": "analytics",
|
|
541
541
|
"commands": [
|
|
542
542
|
"codemie analytics --agent claude --last 7d --branch main",
|
|
543
|
-
"codemie analytics --agent claude --last 7d --branch main --export
|
|
543
|
+
"codemie analytics --agent claude --last 7d --branch main --export json -o report.json"
|
|
544
544
|
]
|
|
545
545
|
},
|
|
546
546
|
{
|
|
@@ -660,22 +660,22 @@
|
|
|
660
660
|
]
|
|
661
661
|
},
|
|
662
662
|
{
|
|
663
|
-
"id": "cmd-analytics-
|
|
663
|
+
"id": "cmd-analytics-export-json",
|
|
664
664
|
"category": "Insights",
|
|
665
|
-
"message": "Feed the numbers to your own tools: `codemie analytics --
|
|
665
|
+
"message": "Feed the numbers to your own tools: `codemie analytics --export json` writes the exact priced dataset behind the HTML dashboard.",
|
|
666
666
|
"command": "analytics",
|
|
667
667
|
"commands": [
|
|
668
|
-
"codemie analytics --
|
|
668
|
+
"codemie analytics --export json"
|
|
669
669
|
]
|
|
670
670
|
},
|
|
671
671
|
{
|
|
672
672
|
"id": "cmd-analytics-native",
|
|
673
673
|
"category": "Insights",
|
|
674
|
-
"message": "
|
|
674
|
+
"message": "Analytics counts only sessions CodeMie launched by default; `codemie analytics --include-external` also counts agents you ran directly, like plain `claude`.",
|
|
675
675
|
"command": "analytics",
|
|
676
676
|
"commands": [
|
|
677
677
|
"codemie analytics",
|
|
678
|
-
"codemie analytics --
|
|
678
|
+
"codemie analytics --include-external"
|
|
679
679
|
]
|
|
680
680
|
},
|
|
681
681
|
{
|
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { resolve } from 'path';
|
|
3
|
-
import { pathToFileURL } from 'url';
|
|
4
|
-
import {
|
|
5
|
-
matchBudgetRow,
|
|
6
|
-
formatBudgetSegment,
|
|
7
|
-
extractBasicInfo,
|
|
8
|
-
formatDuration,
|
|
9
|
-
fmt,
|
|
10
|
-
buildStatusLine,
|
|
11
|
-
resolveBudget,
|
|
12
|
-
isMainModule,
|
|
13
|
-
ctxBar,
|
|
14
|
-
} from '../statusline.mjs';
|
|
15
|
-
|
|
16
|
-
const YELLOW = '\x1b[0;33m';
|
|
17
|
-
const GREEN = '\x1b[0;32m';
|
|
18
|
-
const RED = '\x1b[0;31m';
|
|
19
|
-
|
|
20
|
-
describe('matchBudgetRow', () => {
|
|
21
|
-
const rows = [
|
|
22
|
-
{ project_name: 'nikita_levyankov@epam.com (cli)', current_spending: 500.26, total: 100.05, budget_reset_at: '2026-07-13T00:00:18.663000Z' },
|
|
23
|
-
{ project_name: 'nikita_levyankov@epam.com', current_spending: 6.05, total: 5.04, budget_reset_at: '2026-07-17T09:30:34.278000Z' },
|
|
24
|
-
{ project_name: 'nikita_levyankov@epam.com (premium)', current_spending: 24.93, total: 83.11, budget_reset_at: '2026-07-18T16:55:53.270000Z' },
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
it('matches only the "(cli)" suffixed row for the given email', () => {
|
|
28
|
-
const row = matchBudgetRow(rows, 'nikita_levyankov@epam.com');
|
|
29
|
-
expect(row).toEqual(rows[0]);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('returns null when no row matches the email', () => {
|
|
33
|
-
expect(matchBudgetRow(rows, 'someone-else@epam.com')).toBeNull();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('returns null when rows is not an array', () => {
|
|
37
|
-
expect(matchBudgetRow(undefined, 'x@y.com')).toBeNull();
|
|
38
|
-
expect(matchBudgetRow(null, 'x@y.com')).toBeNull();
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('returns null when userEmail is falsy', () => {
|
|
42
|
-
expect(matchBudgetRow(rows, '')).toBeNull();
|
|
43
|
-
expect(matchBudgetRow(rows, undefined)).toBeNull();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('matches regardless of email casing or surrounding whitespace', () => {
|
|
47
|
-
expect(matchBudgetRow(rows, 'Nikita_Levyankov@EPAM.com')).toEqual(rows[0]);
|
|
48
|
-
expect(matchBudgetRow(rows, ' nikita_levyankov@epam.com ')).toEqual(rows[0]);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('formatBudgetSegment', () => {
|
|
53
|
-
it('formats current spend, percentage, and reset date — never budget_limit', () => {
|
|
54
|
-
const row = { current_spending: 12.34, budget_limit: 999, total: 41, budget_reset_at: '2026-07-15T00:00:00.000Z' };
|
|
55
|
-
const result = formatBudgetSegment(row);
|
|
56
|
-
expect(result.text).toContain('$12.34');
|
|
57
|
-
expect(result.text).toContain('41%');
|
|
58
|
-
expect(result.text).not.toContain('999');
|
|
59
|
-
expect(result.pct).toBe(41);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('returns null for a null row', () => {
|
|
63
|
-
expect(formatBudgetSegment(null)).toBeNull();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('extractBasicInfo', () => {
|
|
68
|
-
it('extracts model, project, context, cost, and duration from a full Claude Code payload', () => {
|
|
69
|
-
const ctx = {
|
|
70
|
-
workspace: { current_dir: '/Users/me/repos/my-project' },
|
|
71
|
-
model: { display_name: 'Claude Sonnet 5' },
|
|
72
|
-
context_window: { used_percentage: 42, total_input_tokens: 12345, total_output_tokens: 678 },
|
|
73
|
-
cost: { total_cost_usd: 1.2345, total_duration_ms: 125000 },
|
|
74
|
-
};
|
|
75
|
-
const info = extractBasicInfo(ctx);
|
|
76
|
-
expect(info.projectName).toBe('my-project');
|
|
77
|
-
expect(info.model).toBe('Claude Sonnet 5');
|
|
78
|
-
expect(info.ctxPct).toBe(42);
|
|
79
|
-
expect(info.tokIn).toBe(12345);
|
|
80
|
-
expect(info.tokOut).toBe(678);
|
|
81
|
-
expect(info.cost).toBe(1.2345);
|
|
82
|
-
expect(info.durationMs).toBe(125000);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('returns safe defaults for an empty/malformed payload', () => {
|
|
86
|
-
const info = extractBasicInfo({});
|
|
87
|
-
expect(info.projectName).toBe('');
|
|
88
|
-
expect(info.model).toBe('');
|
|
89
|
-
expect(info.ctxPct).toBeNull();
|
|
90
|
-
expect(info.cost).toBeNull();
|
|
91
|
-
expect(info.durationMs).toBeNull();
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('formatDuration', () => {
|
|
96
|
-
it('formats milliseconds as "Xm Ys"', () => {
|
|
97
|
-
expect(formatDuration(125000)).toBe('2m 5s');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('returns null for null/undefined input', () => {
|
|
101
|
-
expect(formatDuration(null)).toBeNull();
|
|
102
|
-
expect(formatDuration(undefined)).toBeNull();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('returns null instead of "NaNm NaNs" for non-numeric or negative input', () => {
|
|
106
|
-
expect(formatDuration(NaN)).toBeNull();
|
|
107
|
-
expect(formatDuration(-1)).toBeNull();
|
|
108
|
-
expect(formatDuration('not-a-number')).toBeNull();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('fmt', () => {
|
|
113
|
-
it('formats large numbers with k/M suffixes', () => {
|
|
114
|
-
expect(fmt(500)).toBe('500');
|
|
115
|
-
expect(fmt(1500)).toBe('1.5k');
|
|
116
|
-
expect(fmt(2_500_000)).toBe('2.5M');
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('ctxBar', () => {
|
|
121
|
-
it('renders a 10-segment filled/empty bar plus the percentage', () => {
|
|
122
|
-
const bar = ctxBar(50);
|
|
123
|
-
expect(bar).toContain('50%');
|
|
124
|
-
expect(bar).toContain('█████░░░░░');
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('colors the bar green below 70%, yellow from 70-89%, red at 90%+', () => {
|
|
128
|
-
expect(ctxBar(50)).toContain(GREEN);
|
|
129
|
-
expect(ctxBar(75)).toContain(YELLOW);
|
|
130
|
-
expect(ctxBar(95)).toContain(RED);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('returns null for non-numeric or missing input', () => {
|
|
134
|
-
expect(ctxBar(null)).toBeNull();
|
|
135
|
-
expect(ctxBar(undefined)).toBeNull();
|
|
136
|
-
expect(ctxBar(NaN)).toBeNull();
|
|
137
|
-
expect(ctxBar('not-a-number')).toBeNull();
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('buildStatusLine', () => {
|
|
142
|
-
const basic = {
|
|
143
|
-
projectName: 'my-project', branch: 'main', model: 'Claude Sonnet 5',
|
|
144
|
-
ctxPct: 42, tokIn: 1000, tokOut: 200, cost: 1.5, durationMs: 65000,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
it('always renders basic info (including session cost and duration) with no budget/profile', () => {
|
|
148
|
-
const line = buildStatusLine({ ...basic, budget: null, budgetError: null });
|
|
149
|
-
expect(line).not.toContain('⚠');
|
|
150
|
-
expect(line).toContain('$1.5000');
|
|
151
|
-
expect(line).toContain('1m 5s');
|
|
152
|
-
expect(line).toContain('[my-project]');
|
|
153
|
-
expect(line).toContain('(main)');
|
|
154
|
-
expect(line).toContain('[Claude Sonnet 5]');
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('renders the context-% as a colored bar, and the cost in its own distinct (yellow) color', () => {
|
|
158
|
-
const line = buildStatusLine({ ...basic, budget: null, budgetError: null });
|
|
159
|
-
expect(line).toContain('42%');
|
|
160
|
-
expect(line).toContain('████░░░░░░'); // 42% -> 4 filled segments
|
|
161
|
-
expect(line).toContain(`${YELLOW}$1.5000${'\x1b[0m'}`);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('shows a minimal warning indicator (not blocking basic info) when the budget fetch fails', () => {
|
|
165
|
-
const line = buildStatusLine({ ...basic, budget: null, budgetError: 'reauthenticate' });
|
|
166
|
-
expect(line).toContain('⚠ reauthenticate');
|
|
167
|
-
expect(line).toContain('$1.5000');
|
|
168
|
-
expect(line).toContain('[my-project]');
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('shows the budget segment (and no warning) when budget resolves successfully', () => {
|
|
172
|
-
const line = buildStatusLine({ ...basic, budget: { text: '$12.34 (41%) resets 7/15/2026', pct: 41 }, budgetError: null });
|
|
173
|
-
expect(line).toContain('$12.34 (41%)');
|
|
174
|
-
expect(line).not.toContain('⚠');
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('does not throw and omits the cost segment when cost is non-numeric', () => {
|
|
178
|
-
expect(() => buildStatusLine({ ...basic, cost: 'not-a-number', budget: null, budgetError: null })).not.toThrow();
|
|
179
|
-
const line = buildStatusLine({ ...basic, cost: 'not-a-number', budget: null, budgetError: null });
|
|
180
|
-
expect(line).not.toContain('NaN');
|
|
181
|
-
expect(line).toContain('[my-project]'); // basic info still renders
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
describe('resolveBudget', () => {
|
|
186
|
-
it('skips silently (no error) when there is no CodeMie config at all', async () => {
|
|
187
|
-
const readFile = vi.fn().mockRejectedValue(new Error('ENOENT'));
|
|
188
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl: vi.fn(), getAuthHeadersImpl: vi.fn() });
|
|
189
|
-
expect(result).toEqual({ budget: null, budgetError: null });
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it('skips silently when the profile is missing codeMieUrl/baseUrl/userEmail', async () => {
|
|
193
|
-
const readFile = vi.fn()
|
|
194
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
195
|
-
.mockResolvedValueOnce(JSON.stringify({ activeProfile: 'default', profiles: { default: {} } }));
|
|
196
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl: vi.fn(), getAuthHeadersImpl: vi.fn() });
|
|
197
|
-
expect(result).toEqual({ budget: null, budgetError: null });
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('skips silently when codeMieUrl/userEmail only exist on the profile — migration 006 moved them to workspace/top-level', async () => {
|
|
201
|
-
const readFile = vi.fn()
|
|
202
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
203
|
-
.mockResolvedValueOnce(JSON.stringify({
|
|
204
|
-
activeProfile: 'default',
|
|
205
|
-
// Pre-fix (stale) shape: codeMieUrl/userEmail stranded on the profile with no
|
|
206
|
-
// top-level `workspace`/`userEmail`. Must not be read from the profile object —
|
|
207
|
-
// regression test for the statusline reading raw profile fields post-migration.
|
|
208
|
-
profiles: { default: { codeMieUrl: 'https://x', baseUrl: 'https://x/api', userEmail: 'me@x.com' } },
|
|
209
|
-
}));
|
|
210
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl: vi.fn(), getAuthHeadersImpl: vi.fn() });
|
|
211
|
-
expect(result).toEqual({ budget: null, budgetError: null });
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('returns a "reauthenticate" error when no auth headers are available', async () => {
|
|
215
|
-
const readFile = vi.fn()
|
|
216
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
217
|
-
.mockResolvedValueOnce(JSON.stringify({
|
|
218
|
-
activeProfile: 'default',
|
|
219
|
-
userEmail: 'me@x.com',
|
|
220
|
-
workspace: { codeMieUrl: 'https://x' },
|
|
221
|
-
profiles: { default: { baseUrl: 'https://x/api' } },
|
|
222
|
-
}));
|
|
223
|
-
const getAuthHeadersImpl = vi.fn().mockResolvedValue(null);
|
|
224
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl: vi.fn(), getAuthHeadersImpl });
|
|
225
|
-
expect(result).toEqual({ budget: null, budgetError: 'reauthenticate' });
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it('returns the HTTP error message when the fetch fails', async () => {
|
|
229
|
-
const readFile = vi.fn()
|
|
230
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
231
|
-
.mockResolvedValueOnce(JSON.stringify({
|
|
232
|
-
activeProfile: 'default',
|
|
233
|
-
userEmail: 'me@x.com',
|
|
234
|
-
workspace: { codeMieUrl: 'https://x' },
|
|
235
|
-
profiles: { default: { baseUrl: 'https://x/api' } },
|
|
236
|
-
}));
|
|
237
|
-
const getAuthHeadersImpl = vi.fn().mockResolvedValue({ cookie: 'a=b' });
|
|
238
|
-
const fetchImpl = vi.fn().mockResolvedValue({ ok: false, status: 500 });
|
|
239
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl, getAuthHeadersImpl });
|
|
240
|
-
expect(result).toEqual({ budget: null, budgetError: 'HTTP 500' });
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
it('resolves and caches the matched budget row on success', async () => {
|
|
244
|
-
const readFile = vi.fn()
|
|
245
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
246
|
-
.mockResolvedValueOnce(JSON.stringify({
|
|
247
|
-
activeProfile: 'default',
|
|
248
|
-
userEmail: 'me@x.com',
|
|
249
|
-
workspace: { codeMieUrl: 'https://x' },
|
|
250
|
-
profiles: { default: { baseUrl: 'https://x/api' } },
|
|
251
|
-
}));
|
|
252
|
-
const getAuthHeadersImpl = vi.fn().mockResolvedValue({ cookie: 'a=b' });
|
|
253
|
-
const fetchImpl = vi.fn().mockResolvedValue({
|
|
254
|
-
ok: true,
|
|
255
|
-
json: async () => ({ data: { rows: [{ project_name: 'me@x.com (cli)', current_spending: 5, total: 10, budget_reset_at: '2026-07-15T00:00:00.000Z' }] } }),
|
|
256
|
-
});
|
|
257
|
-
const writeFile = vi.fn().mockResolvedValue(undefined);
|
|
258
|
-
const result = await resolveBudget({ readFile, writeFile, fetchImpl, getAuthHeadersImpl });
|
|
259
|
-
expect(result.budgetError).toBeNull();
|
|
260
|
-
expect(result.budget.text).toContain('$5.00');
|
|
261
|
-
expect(writeFile).toHaveBeenCalledWith(expect.stringContaining('budget-cache.json'), expect.any(String), 'utf8');
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it('returns the fresh cached value without touching config/network when cache is fresh', async () => {
|
|
265
|
-
const readFile = vi.fn().mockResolvedValueOnce(JSON.stringify({ schema: 2, ts: Date.now(), value: { text: 'cached', pct: 5 } }));
|
|
266
|
-
const fetchImpl = vi.fn();
|
|
267
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl, getAuthHeadersImpl: vi.fn() });
|
|
268
|
-
expect(result).toEqual({ budget: { text: 'cached', pct: 5 }, budgetError: null });
|
|
269
|
-
expect(fetchImpl).not.toHaveBeenCalled();
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it('treats a pre-upgrade string-shaped cache entry as a cache miss instead of using it', async () => {
|
|
273
|
-
// Old cache format: value was a plain string, not { text, pct }.
|
|
274
|
-
const readFile = vi.fn()
|
|
275
|
-
.mockResolvedValueOnce(JSON.stringify({ ts: Date.now(), value: '$5.00/$10 (50%)', pct: 50 }))
|
|
276
|
-
.mockRejectedValueOnce(new Error('no config'));
|
|
277
|
-
const fetchImpl = vi.fn();
|
|
278
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl, getAuthHeadersImpl: vi.fn() });
|
|
279
|
-
expect(result).toEqual({ budget: null, budgetError: null });
|
|
280
|
-
expect(fetchImpl).not.toHaveBeenCalled();
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('returns a graceful budgetError instead of an uncaught rejection when getAuthHeadersImpl throws', async () => {
|
|
284
|
-
const readFile = vi.fn()
|
|
285
|
-
.mockRejectedValueOnce(new Error('no cache'))
|
|
286
|
-
.mockResolvedValueOnce(JSON.stringify({
|
|
287
|
-
activeProfile: 'default',
|
|
288
|
-
userEmail: 'me@x.com',
|
|
289
|
-
workspace: { codeMieUrl: 'https://x' },
|
|
290
|
-
profiles: { default: { baseUrl: 'https://x/api' } },
|
|
291
|
-
}));
|
|
292
|
-
const getAuthHeadersImpl = vi.fn().mockRejectedValue(new Error('keychain locked'));
|
|
293
|
-
const result = await resolveBudget({ readFile, writeFile: vi.fn(), fetchImpl: vi.fn(), getAuthHeadersImpl });
|
|
294
|
-
expect(result).toEqual({ budget: null, budgetError: 'keychain locked' });
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
describe('isMainModule', () => {
|
|
299
|
-
// Build the file URL from a real, platform-resolved absolute path (via pathToFileURL)
|
|
300
|
-
// rather than hardcoding POSIX-style "file:///..." strings, so this test is symmetric
|
|
301
|
-
// on Windows too — fileURLToPath() decodes to a backslash-separated path there.
|
|
302
|
-
it('matches when the raw path equals the decoded file URL', () => {
|
|
303
|
-
const scriptPath = resolve('Users', 'me', 'script.mjs');
|
|
304
|
-
expect(isMainModule(scriptPath, pathToFileURL(scriptPath).href)).toBe(true);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
it('matches even when the path contains spaces (percent-encoded in the URL)', () => {
|
|
308
|
-
const scriptPath = resolve('Users', 'John Doe', '.claude', 'codemie-budget-status.js');
|
|
309
|
-
expect(isMainModule(scriptPath, pathToFileURL(scriptPath).href)).toBe(true);
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it('returns false for a different path', () => {
|
|
313
|
-
const scriptPath = resolve('Users', 'me', 'script.mjs');
|
|
314
|
-
const otherPath = resolve('Users', 'me', 'other.mjs');
|
|
315
|
-
expect(isMainModule(otherPath, pathToFileURL(scriptPath).href)).toBe(false);
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
it('returns false when argv1 is falsy', () => {
|
|
319
|
-
const url = pathToFileURL(resolve('Users', 'me', 'script.mjs')).href;
|
|
320
|
-
expect(isMainModule('', url)).toBe(false);
|
|
321
|
-
expect(isMainModule(undefined, url)).toBe(false);
|
|
322
|
-
});
|
|
323
|
-
});
|