@askdkc/dsh-cli 0.11.7 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +47 -283
- package/cordis.patch.yml +1 -0
- package/cordis.yml +1 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +1 -0
- package/lib/types/adapter/ports/channel-ui.d.ts +2 -0
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/components/LogoV2.d.ts +2 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +9 -15
- package/lib/types/components/ModelPicker.d.ts +9 -11
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +6 -9
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +6 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +8 -9
- package/lib/types/components/WorkingSpinner.d.ts +3 -1
- package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
- package/lib/types/components/WorkingSpinner.js +9 -4
- package/lib/types/components/bigfont.d.ts +2 -0
- package/lib/types/components/bigfont.d.ts.map +1 -1
- package/lib/types/components/bigfont.js +5 -1
- package/lib/types/components/splashLayout.d.ts +12 -0
- package/lib/types/components/splashLayout.d.ts.map +1 -0
- package/lib/types/components/splashLayout.js +18 -0
- package/lib/types/dsh-adapter/activity-store.d.ts +1 -1
- package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection.js +4 -0
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.js +2 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +2 -1
- package/lib/types/i18n.d.ts +32 -2
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +19 -1
- package/lib/types/modelGroups.d.ts +3 -1
- package/lib/types/modelGroups.d.ts.map +1 -1
- package/lib/types/modelGroups.js +4 -0
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +37 -37
- package/node_modules/@askdkc/dsh-auth/LICENSE +1 -0
- package/node_modules/@askdkc/dsh-auth/README.ja.md +17 -12
- package/node_modules/@askdkc/dsh-auth/README.md +18 -13
- package/node_modules/@askdkc/dsh-auth/package.json +7 -2
- package/node_modules/dsh-working-activity/LICENSE +28 -0
- package/node_modules/dsh-working-activity/README.md +16 -0
- package/node_modules/dsh-working-activity/cordis.patch.yml +19 -0
- package/node_modules/dsh-working-activity/lib/client.js +169 -0
- package/node_modules/dsh-working-activity/lib/client.js.map +1 -0
- package/node_modules/dsh-working-activity/lib/types/activity-event.d.ts +147 -0
- package/node_modules/dsh-working-activity/lib/types/activity-event.js +18 -0
- package/node_modules/dsh-working-activity/lib/types/client/WorkingLine.d.ts +8 -0
- package/node_modules/dsh-working-activity/lib/types/client/WorkingLine.d.ts.map +1 -0
- package/node_modules/dsh-working-activity/lib/types/client/WorkingLine.js +57 -0
- package/node_modules/dsh-working-activity/lib/types/client/activity.d.ts +37 -0
- package/node_modules/dsh-working-activity/lib/types/client/activity.d.ts.map +1 -0
- package/node_modules/dsh-working-activity/lib/types/client/activity.js +26 -0
- package/node_modules/dsh-working-activity/lib/types/client/elapsed.d.ts +41 -0
- package/node_modules/dsh-working-activity/lib/types/client/elapsed.d.ts.map +1 -0
- package/node_modules/dsh-working-activity/lib/types/client/elapsed.js +78 -0
- package/node_modules/dsh-working-activity/lib/types/client/index.d.ts +26 -0
- package/node_modules/dsh-working-activity/lib/types/client/index.d.ts.map +1 -0
- package/node_modules/dsh-working-activity/lib/types/client/index.js +19 -0
- package/node_modules/dsh-working-activity/lib/types/compat/assistant-stream.d.ts +59 -0
- package/node_modules/dsh-working-activity/lib/types/compat/assistant-stream.js +189 -0
- package/node_modules/dsh-working-activity/lib/types/compat/session-events.d.ts +38 -0
- package/node_modules/dsh-working-activity/lib/types/compat/session-events.js +193 -0
- package/node_modules/dsh-working-activity/lib/types/compat/tool-result.d.ts +72 -0
- package/node_modules/dsh-working-activity/lib/types/compat/tool-result.js +136 -0
- package/node_modules/dsh-working-activity/lib/types/config.d.ts +74 -0
- package/node_modules/dsh-working-activity/lib/types/config.js +142 -0
- package/node_modules/dsh-working-activity/lib/types/events.d.ts +41 -0
- package/node_modules/dsh-working-activity/lib/types/events.js +9 -0
- package/node_modules/dsh-working-activity/lib/types/frames.d.ts +36 -0
- package/node_modules/dsh-working-activity/lib/types/frames.js +126 -0
- package/node_modules/dsh-working-activity/lib/types/index.d.ts +71 -0
- package/node_modules/dsh-working-activity/lib/types/index.js +350 -0
- package/node_modules/dsh-working-activity/lib/types/invariant.d.ts +15 -0
- package/node_modules/dsh-working-activity/lib/types/invariant.js +72 -0
- package/node_modules/dsh-working-activity/lib/types/japanese.d.ts +28 -0
- package/node_modules/dsh-working-activity/lib/types/japanese.js +47 -0
- package/node_modules/dsh-working-activity/lib/types/lang.d.ts +140 -0
- package/node_modules/dsh-working-activity/lib/types/lang.js +209 -0
- package/node_modules/dsh-working-activity/lib/types/phrases.d.ts +246 -0
- package/node_modules/dsh-working-activity/lib/types/phrases.js +611 -0
- package/node_modules/dsh-working-activity/lib/types/projection.d.ts +168 -0
- package/node_modules/dsh-working-activity/lib/types/projection.js +162 -0
- package/node_modules/dsh-working-activity/lib/types/registration.d.ts +6 -0
- package/node_modules/dsh-working-activity/lib/types/registration.js +94 -0
- package/node_modules/dsh-working-activity/lib/types/status.d.ts +400 -0
- package/node_modules/dsh-working-activity/lib/types/status.js +1306 -0
- package/node_modules/dsh-working-activity/package.json +108 -0
- package/node_modules/dsh-working-activity/src/activity-event.ts +106 -0
- package/node_modules/dsh-working-activity/src/client/WorkingLine.module.css +74 -0
- package/node_modules/dsh-working-activity/src/client/WorkingLine.tsx +94 -0
- package/node_modules/dsh-working-activity/src/client/activity.ts +43 -0
- package/node_modules/dsh-working-activity/src/client/css-modules.d.ts +6 -0
- package/node_modules/dsh-working-activity/src/client/elapsed.ts +88 -0
- package/node_modules/dsh-working-activity/src/client/index.ts +45 -0
- package/node_modules/dsh-working-activity/src/compat/assistant-stream.ts +209 -0
- package/node_modules/dsh-working-activity/src/compat/session-events.ts +201 -0
- package/node_modules/dsh-working-activity/src/compat/tool-result.ts +132 -0
- package/node_modules/dsh-working-activity/src/config.ts +176 -0
- package/node_modules/dsh-working-activity/src/events.ts +45 -0
- package/node_modules/dsh-working-activity/src/frames.ts +138 -0
- package/node_modules/dsh-working-activity/src/index.ts +467 -0
- package/node_modules/dsh-working-activity/src/invariant.ts +98 -0
- package/node_modules/dsh-working-activity/src/japanese.ts +47 -0
- package/node_modules/dsh-working-activity/src/lang.ts +221 -0
- package/node_modules/dsh-working-activity/src/phrases.ts +715 -0
- package/node_modules/dsh-working-activity/src/projection.ts +259 -0
- package/node_modules/dsh-working-activity/src/registration.ts +99 -0
- package/node_modules/dsh-working-activity/src/status.ts +1474 -0
- package/package.json +13 -9
- package/vendor/dsh-working-activity/node_modules/zod/LICENSE +21 -0
- package/vendor/dsh-working-activity/node_modules/zod/README.md +191 -0
- package/vendor/dsh-working-activity/node_modules/zod/index.cjs +33 -0
- package/vendor/dsh-working-activity/node_modules/zod/index.d.cts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/index.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/index.js +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/locales/index.cjs +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/locales/index.d.cts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/locales/index.d.ts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/locales/index.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/locales/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/mini/index.cjs +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/mini/index.d.cts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/mini/index.d.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/mini/index.js +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/mini/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/package.json +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/index.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/locales/index.ts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/mini/index.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/ZodError.ts +330 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/datetime.ts +58 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +80 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/index.ts +59 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/ipv4.ts +57 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/object.ts +69 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/primitives.ts +162 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/realworld.ts +63 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/string.ts +55 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/benchmarks/union.ts +80 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/errors.ts +13 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/external.ts +6 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/enumUtil.ts +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/errorUtil.ts +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/parseUtil.ts +176 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/partialUtil.ts +34 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/typeAliases.ts +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/helpers/util.ts +224 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/index.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/locales/en.ts +124 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/standard-schema.ts +113 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/Mocker.ts +54 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/all-errors.test.ts +157 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/anyunknown.test.ts +28 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/array.test.ts +71 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/async-parsing.test.ts +388 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/async-refinements.test.ts +46 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/base.test.ts +29 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/bigint.test.ts +55 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/branded.test.ts +53 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/catch.test.ts +220 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/coerce.test.ts +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/complex.test.ts +70 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/custom.test.ts +31 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/date.test.ts +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/deepmasking.test.ts +186 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/default.test.ts +112 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/description.test.ts +33 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +315 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/enum.test.ts +80 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/error.test.ts +551 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/firstparty.test.ts +87 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +21 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/function.test.ts +261 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/generics.test.ts +48 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/instanceof.test.ts +37 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/intersection.test.ts +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/language-server.source.ts +76 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/language-server.test.ts +207 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/literal.test.ts +36 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/map.test.ts +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/masking.test.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/mocker.test.ts +19 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/nan.test.ts +24 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/nativeEnum.test.ts +87 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/nullable.test.ts +42 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/number.test.ts +176 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/object-augmentation.test.ts +29 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +29 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/object.test.ts +434 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/optional.test.ts +42 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/parseUtil.test.ts +23 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/parser.test.ts +41 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/partials.test.ts +243 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/pickomit.test.ts +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/pipeline.test.ts +29 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/preprocess.test.ts +186 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/primitive.test.ts +440 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/promise.test.ts +90 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/readonly.test.ts +194 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/record.test.ts +171 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/recursive.test.ts +197 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/refine.test.ts +313 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/safeparse.test.ts +27 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/set.test.ts +142 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/standard-schema.test.ts +83 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/string.test.ts +916 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/transformer.test.ts +233 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/tuple.test.ts +90 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/unions.test.ts +57 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/validations.test.ts +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/tests/void.test.ts +15 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v3/types.ts +5138 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/checks.ts +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/coerce.ts +27 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/compat.ts +70 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/errors.ts +82 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/external.ts +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/from-json-schema.ts +659 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/index.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/iso.ts +90 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/parse.ts +82 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/schemas.ts +2672 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +26 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/apply.test.ts +59 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/array.test.ts +264 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/assignability.test.ts +216 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +381 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +68 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/base.test.ts +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/bigint.test.ts +54 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/brand.test.ts +106 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/catch.test.ts +326 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +20 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +573 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/codec.test.ts +703 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/coerce.test.ts +160 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/continuability.test.ts +374 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/custom.test.ts +40 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/date.test.ts +62 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/datetime.test.ts +302 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/default.test.ts +409 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/describe-meta-checks.test.ts +27 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/description.test.ts +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +197 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +694 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/enum.test.ts +285 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +807 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/error.test.ts +711 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/file.test.ts +96 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +179 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/fix-json-issue.test.ts +26 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +895 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/function.test.ts +360 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/generics.test.ts +72 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/global-config.test.ts +39 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/hash.test.ts +68 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/index.test.ts +939 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +60 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/intersection.test.ts +198 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +46 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/json.test.ts +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/lazy.test.ts +227 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/literal.test.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +29 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +24 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/map.test.ts +330 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/nan.test.ts +21 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +168 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +101 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/nullable.test.ts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/number.test.ts +325 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/object.test.ts +717 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/optional.test.ts +333 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/partial.test.ts +450 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +211 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/pipe.test.ts +101 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/prefault.test.ts +74 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +26 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +351 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/primitive.test.ts +175 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/promise.test.ts +81 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +23 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/readonly.test.ts +252 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/record.test.ts +717 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +631 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/refine.test.ts +633 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/registries.test.ts +243 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/set.test.ts +181 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +125 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/string.test.ts +1224 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +106 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +771 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/to-json-schema-methods.test.ts +438 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +3125 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/transform.test.ts +378 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/tuple.test.ts +496 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/union.test.ts +273 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/url.test.ts +13 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/validations.test.ts +283 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/classic/tests/void.test.ts +12 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/api.ts +1823 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/checks.ts +1293 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/config.ts +15 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/core.ts +153 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/doc.ts +44 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/errors.ts +455 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/index.ts +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/json-schema-generator.ts +126 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/json-schema-processors.ts +666 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/json-schema.ts +147 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/parse.ts +195 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/regexes.ts +190 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/registries.ts +105 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/schemas.ts +4730 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/standard-schema.ts +159 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/extend.test.ts +59 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/index.test.ts +46 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/be.test.ts +124 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/el.test.ts +215 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/en.test.ts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/es.test.ts +181 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +72 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/he.test.ts +379 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +163 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/nl.test.ts +46 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +128 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +69 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +105 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +125 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/tests/recursive-tuples.test.ts +45 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/to-json-schema.ts +622 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/util.ts +983 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/versions.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/core/zsf.ts +323 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/index.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ar.ts +115 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/az.ts +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/be.ts +176 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/bg.ts +128 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ca.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/cs.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/da.ts +123 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/de.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/el.ts +121 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/en.ts +123 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/eo.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/es.ts +141 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/fa.ts +126 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/fi.ts +121 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/fr-CA.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/fr.ts +132 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/he.ts +246 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/hr.ts +131 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/hu.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/hy.ts +164 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/id.ts +115 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/index.ts +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/is.ts +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/it.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ja.ts +114 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ka.ts +123 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/kh.ts +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/km.ts +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ko.ts +121 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/lt.ts +239 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/mk.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ms.ts +115 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/nl.ts +121 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/no.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ota.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/pl.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ps.ts +126 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/pt.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ro.ts +129 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ru.ts +176 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/sl.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/sv.ts +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ta.ts +118 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/th.ts +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/tr.ts +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ua.ts +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/uk.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/ur.ts +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/uz.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/vi.ts +117 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/yo.ts +124 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/zh-CN.ts +116 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/locales/zh-TW.ts +115 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/checks.ts +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/coerce.ts +27 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/external.ts +41 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/index.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/iso.ts +66 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/parse.ts +14 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/schemas.ts +1947 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/apply.test.ts +24 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/assignability.test.ts +129 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/brand.test.ts +94 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/checks.test.ts +144 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/codec.test.ts +548 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/computed.test.ts +36 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/error.test.ts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/functions.test.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/index.test.ts +993 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/number.test.ts +95 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/object.test.ts +227 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +43 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +325 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/standard-schema.test.ts +50 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4/mini/tests/string.test.ts +352 -0
- package/vendor/dsh-working-activity/node_modules/zod/src/v4-mini/index.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/ZodError.cjs +138 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/ZodError.d.cts +164 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/ZodError.d.ts +164 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/ZodError.js +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/errors.cjs +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/errors.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/errors.d.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/errors.js +9 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/external.cjs +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/external.d.cts +6 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/external.d.ts +6 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/external.js +6 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/enumUtil.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/enumUtil.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/errorUtil.cjs +9 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/errorUtil.js +6 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/parseUtil.cjs +124 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/parseUtil.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/partialUtil.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/partialUtil.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/typeAliases.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/typeAliases.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/util.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/util.d.cts +85 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/util.d.ts +85 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/helpers/util.js +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/index.cjs +33 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/index.d.cts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/index.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/index.js +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/locales/en.cjs +112 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/locales/en.d.cts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/locales/en.d.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/locales/en.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/standard-schema.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/standard-schema.d.cts +102 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/standard-schema.d.ts +102 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/standard-schema.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/types.cjs +3777 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/types.d.cts +1034 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/types.d.ts +1034 -0
- package/vendor/dsh-working-activity/node_modules/zod/v3/types.js +3695 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/checks.cjs +33 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/checks.d.cts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/checks.d.ts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/checks.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/coerce.cjs +47 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/coerce.d.cts +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/coerce.d.ts +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/coerce.js +17 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/compat.cjs +61 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/compat.d.cts +50 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/compat.d.ts +50 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/compat.js +31 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/errors.cjs +74 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/errors.d.cts +30 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/errors.d.ts +30 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/errors.js +48 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/external.cjs +73 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/external.d.cts +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/external.d.ts +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/external.js +20 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/from-json-schema.cjs +625 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/from-json-schema.d.cts +12 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/from-json-schema.d.ts +12 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/from-json-schema.js +599 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/index.cjs +33 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/index.d.cts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/index.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/index.js +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/iso.cjs +60 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/iso.d.cts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/iso.d.ts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/iso.js +30 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/parse.cjs +41 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/parse.d.cts +31 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/parse.d.ts +31 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/parse.js +15 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/schemas.cjs +1511 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/schemas.d.cts +767 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/schemas.d.ts +767 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/classic/schemas.js +1395 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/api.cjs +1227 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/api.d.cts +325 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/api.d.ts +325 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/api.js +1087 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/checks.cjs +601 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/checks.d.cts +278 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/checks.d.ts +278 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/checks.js +575 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/core.cjs +85 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/core.d.cts +70 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/core.d.ts +70 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/core.js +78 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/doc.cjs +39 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/doc.d.cts +14 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/doc.d.ts +14 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/doc.js +35 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/errors.cjs +216 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/errors.d.cts +221 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/errors.d.ts +221 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/errors.js +185 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/index.cjs +47 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/index.d.cts +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/index.d.ts +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/index.js +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-generator.cjs +99 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-generator.d.cts +65 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-generator.d.ts +65 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-generator.js +95 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-processors.cjs +644 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-processors.d.cts +49 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-processors.d.ts +49 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema-processors.js +601 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema.d.cts +88 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema.d.ts +88 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/json-schema.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/parse.cjs +131 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/parse.d.cts +49 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/parse.d.ts +49 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/parse.js +93 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/regexes.cjs +172 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/regexes.d.cts +85 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/regexes.d.ts +85 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/regexes.js +139 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/registries.cjs +56 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/registries.d.cts +35 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/registries.d.ts +35 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/registries.js +51 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/schemas.cjs +2270 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/schemas.d.cts +1184 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/schemas.d.ts +1184 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/schemas.js +2239 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/standard-schema.cjs +2 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/standard-schema.d.cts +126 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/standard-schema.d.ts +126 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/standard-schema.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/to-json-schema.cjs +457 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/to-json-schema.d.cts +114 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/to-json-schema.d.ts +114 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/to-json-schema.js +448 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/util.cjs +734 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/util.d.cts +200 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/util.d.ts +200 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/util.js +674 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/versions.cjs +8 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/versions.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/versions.d.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/core/versions.js +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/index.cjs +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/index.d.cts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/index.d.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/index.js +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ar.cjs +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ar.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ar.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ar.js +106 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/az.cjs +132 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/az.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/az.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/az.js +105 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/be.cjs +183 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/be.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/be.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/be.js +156 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/bg.cjs +147 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/bg.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/bg.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/bg.js +120 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ca.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ca.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ca.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ca.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/cs.cjs +138 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/cs.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/cs.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/cs.js +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/da.cjs +142 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/da.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/da.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/da.js +115 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/de.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/de.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/de.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/de.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/el.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/el.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/el.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/el.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/en.cjs +140 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/en.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/en.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/en.js +113 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/eo.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/eo.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/eo.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/eo.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/es.cjs +159 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/es.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/es.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/es.js +132 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fa.cjs +141 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fa.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fa.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fa.js +114 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fi.cjs +139 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fi.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fi.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fi.js +112 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr-CA.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr-CA.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr-CA.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr.cjs +152 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/fr.js +125 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/he.cjs +241 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/he.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/he.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/he.js +214 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hr.cjs +149 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hr.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hr.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hr.js +122 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hu.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hu.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hu.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hu.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hy.cjs +174 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hy.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hy.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/hy.js +147 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/id.cjs +133 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/id.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/id.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/id.js +106 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/index.cjs +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/index.d.cts +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/index.d.ts +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/index.js +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/is.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/is.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/is.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/is.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/it.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/it.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/it.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/it.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ja.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ja.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ja.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ja.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ka.cjs +139 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ka.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ka.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ka.js +112 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/kh.cjs +12 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/kh.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/kh.d.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/kh.js +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/km.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/km.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/km.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/km.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ko.cjs +138 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ko.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ko.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ko.js +111 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/lt.cjs +230 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/lt.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/lt.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/lt.js +203 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/mk.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/mk.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/mk.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/mk.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ms.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ms.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ms.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ms.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/nl.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/nl.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/nl.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/nl.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/no.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/no.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/no.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/no.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ota.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ota.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ota.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ota.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pl.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pl.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pl.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pl.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ps.cjs +141 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ps.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ps.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ps.js +114 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pt.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pt.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pt.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/pt.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ro.cjs +146 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ro.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ro.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ro.js +119 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ru.cjs +183 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ru.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ru.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ru.js +156 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sl.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sl.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sl.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sl.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sv.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sv.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sv.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/sv.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ta.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ta.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ta.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ta.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/th.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/th.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/th.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/th.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/tr.cjs +132 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/tr.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/tr.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/tr.js +105 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ua.cjs +12 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ua.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ua.d.ts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ua.js +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uk.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uk.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uk.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uk.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ur.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ur.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ur.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/ur.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uz.cjs +137 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uz.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uz.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/uz.js +110 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/vi.cjs +135 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/vi.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/vi.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/vi.js +108 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/yo.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/yo.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/yo.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/yo.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-CN.cjs +136 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-CN.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-CN.js +109 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-TW.cjs +134 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-TW.d.cts +5 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/locales/zh-TW.js +107 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/checks.cjs +34 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/checks.d.cts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/checks.d.ts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/checks.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/coerce.cjs +52 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/coerce.d.cts +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/coerce.d.ts +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/coerce.js +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/external.cjs +63 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/external.d.cts +13 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/external.d.ts +13 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/external.js +14 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/index.cjs +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/index.d.cts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/index.d.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/index.js +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/iso.cjs +64 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/iso.d.cts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/iso.d.ts +22 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/iso.js +34 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/parse.cjs +16 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/parse.d.cts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/parse.d.ts +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/parse.js +1 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/schemas.cjs +1083 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/schemas.d.cts +445 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/schemas.d.ts +445 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/mini/schemas.js +961 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4/package.json +7 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4-mini/index.cjs +32 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4-mini/index.d.cts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4-mini/index.d.ts +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4-mini/index.js +3 -0
- package/vendor/dsh-working-activity/node_modules/zod/v4-mini/package.json +7 -0
|
@@ -0,0 +1,1474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure activity state machine for the working-activity status line. Consumes
|
|
3
|
+
* session events (turn/step/tool/stream) plus agent running/idle transitions
|
|
4
|
+
* and renders a human-readable status line at any wall-clock instant. No I/O,
|
|
5
|
+
* no timers, no cordis — deterministic given the event stream and a clock.
|
|
6
|
+
* @module @deepseek-ai/dsh-working-activity/status
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ActivityEvent, WaitingReason } from './activity-event.js'
|
|
10
|
+
import {
|
|
11
|
+
actionFor, compactPhrase, continuePhrase, donePhrase, failPhrase, fmtDuration,
|
|
12
|
+
holidayPhrase, isGitTool, isNight, isWeekend, mixSlot, modelQuip, overflowPhrase, rarePhrase,
|
|
13
|
+
RARE_CHANCE, thinkingPhrase, toolOpeningPhrase, weekendPhrase, waitingPhrase, waitingReasonPhrase,
|
|
14
|
+
type PhraseSlot,
|
|
15
|
+
} from './phrases.js'
|
|
16
|
+
import { feedSessionEvent } from './compat/session-events.js'
|
|
17
|
+
import { detectInputLanguage, isLang, langNow, t, terminalProgressLang, withProgressLang, type Lang } from './lang.js'
|
|
18
|
+
|
|
19
|
+
/** Public status phases a UI can render. */
|
|
20
|
+
export type ActivityPhase = 'idle' | 'waiting' | 'thinking' | 'tool' | 'done'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Compatibility handle for {@link ActivityTracker.snapshot} output.
|
|
24
|
+
*
|
|
25
|
+
* The snapshot shape is private to this module; this number is the only part a
|
|
26
|
+
* consumer may rely on. Bump it whenever the emitted shape changes, so a
|
|
27
|
+
* persisted projection checkpoint from an older build is discarded (the host
|
|
28
|
+
* refolds the log) instead of being misread as the new shape.
|
|
29
|
+
*/
|
|
30
|
+
export const TRACKER_SNAPSHOT_VERSION = 6
|
|
31
|
+
|
|
32
|
+
/** One snapshot of the model's activity, renderable by any UI. */
|
|
33
|
+
export interface ActivityState {
|
|
34
|
+
/** Which activity phase the model is in right now. */
|
|
35
|
+
readonly phase: ActivityPhase
|
|
36
|
+
/** Full human-readable status line (plain text, no ANSI). */
|
|
37
|
+
readonly line: string
|
|
38
|
+
/** Short label of the current work (tool action or stage), when any. */
|
|
39
|
+
readonly label?: string
|
|
40
|
+
/** Detail fragment (path / command / search pattern), when any. */
|
|
41
|
+
readonly detail?: string
|
|
42
|
+
/** The playful phrase currently shown. */
|
|
43
|
+
readonly phrase?: string
|
|
44
|
+
/** Tools completed in the current turn. */
|
|
45
|
+
readonly toolCount: number
|
|
46
|
+
/** Wall-clock milliseconds since the current turn started (0 when idle). */
|
|
47
|
+
readonly turnElapsedMs: number
|
|
48
|
+
/** Wall-clock time the current phase started, for animations. */
|
|
49
|
+
readonly phaseStartedAt: number
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Per-turn thinking/tooling split, exposed for done summaries and stats. */
|
|
53
|
+
export interface TurnStats {
|
|
54
|
+
/** Milliseconds the model was thinking (between turn start and first tool / turn end). */
|
|
55
|
+
readonly thinkingMs: number
|
|
56
|
+
/** Milliseconds spent inside tool executions. */
|
|
57
|
+
readonly toolMs: number
|
|
58
|
+
/** Tools completed in the turn. */
|
|
59
|
+
readonly toolCount: number
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Easter-egg toggles for the thinking phrase (pi extension parity). */
|
|
63
|
+
export interface TrackerFeatures {
|
|
64
|
+
/** Rare 1/150 easter eggs. */
|
|
65
|
+
readonly rareEggs?: boolean
|
|
66
|
+
/** Weekend greetings on Sat/Sun. */
|
|
67
|
+
readonly weekend?: boolean
|
|
68
|
+
/** Date-matched holiday / Lunar New Year copy. */
|
|
69
|
+
readonly holidays?: boolean
|
|
70
|
+
/** Night-owl copy between 00:00 and 06:00. */
|
|
71
|
+
readonly nightPhrases?: boolean
|
|
72
|
+
/** Consecutive-tool streak badge. */
|
|
73
|
+
readonly combo?: boolean
|
|
74
|
+
/** Playful failure copy when the turn's last tool failed. */
|
|
75
|
+
readonly failPhrases?: boolean
|
|
76
|
+
/** Quips on a model route change. */
|
|
77
|
+
readonly modelQuips?: boolean
|
|
78
|
+
/** Comeback quip after the user interrupts. */
|
|
79
|
+
readonly continuePhrases?: boolean
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Configuration knobs for the state machine (subset of plugin Config). */
|
|
83
|
+
export interface TrackerConfig {
|
|
84
|
+
/** Detect progress language from accepted user messages, per session. */
|
|
85
|
+
readonly inputLanguage?: boolean
|
|
86
|
+
/** Existing projection language supplier, used outside input-following mode. */
|
|
87
|
+
readonly language?: () => Lang
|
|
88
|
+
/** Playful copy pool on/off; false renders plain functional labels. */
|
|
89
|
+
readonly phrases: boolean
|
|
90
|
+
/** Maximum characters of a detail fragment (paths/commands). */
|
|
91
|
+
readonly detailLimit: number
|
|
92
|
+
/** Hide the status line while idle. */
|
|
93
|
+
readonly showIdle: boolean
|
|
94
|
+
/** Easter-egg toggles; absent flags default to on. */
|
|
95
|
+
readonly features?: TrackerFeatures
|
|
96
|
+
/** User custom phrases appended to the base thinking pool. */
|
|
97
|
+
readonly customPhrases?: readonly string[]
|
|
98
|
+
/** Show an estimated tokens/s prefix while streaming (pi parity). */
|
|
99
|
+
readonly showTokPerSec?: boolean
|
|
100
|
+
/** Work reminder after this many turn-hours (0 = off). */
|
|
101
|
+
readonly workRemindAt?: number
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** A tool execution in flight. */
|
|
105
|
+
interface ActiveTool {
|
|
106
|
+
readonly callId: string
|
|
107
|
+
readonly name: string
|
|
108
|
+
action: string
|
|
109
|
+
readonly detail: string
|
|
110
|
+
readonly isGit: boolean
|
|
111
|
+
readonly startedAt: number
|
|
112
|
+
/** Whether the tool failed; set on tool/result while the card lingers. */
|
|
113
|
+
failed: boolean
|
|
114
|
+
/** tool/result time when settled, else undefined. */
|
|
115
|
+
endedAt?: number
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** A tool that finished but keeps its card in the replay queue. */
|
|
119
|
+
interface DoneTool {
|
|
120
|
+
readonly name: string
|
|
121
|
+
action: string
|
|
122
|
+
readonly detail: string
|
|
123
|
+
readonly failed: boolean
|
|
124
|
+
readonly endedAt: number
|
|
125
|
+
/** How long the tool ran; shown while the settled line lingers. */
|
|
126
|
+
readonly durationMs: number
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The wire shape of {@link ActivityTracker.snapshot} — module-private on
|
|
131
|
+
* purpose. Consumers hand the value straight back to
|
|
132
|
+
* {@link ActivityTracker.restore}; `snapshot()` is typed as `unknown` so the
|
|
133
|
+
* field list never becomes published API that has to be kept stable.
|
|
134
|
+
*/
|
|
135
|
+
interface TrackerSnapshotShape {
|
|
136
|
+
readonly version: number
|
|
137
|
+
readonly progressLang: Lang
|
|
138
|
+
readonly phase: ActivityPhase
|
|
139
|
+
readonly phaseStartedAt: number
|
|
140
|
+
readonly turnStartedAt: number
|
|
141
|
+
readonly thinkingStartedAt: number
|
|
142
|
+
readonly thinkingMs: number
|
|
143
|
+
readonly toolMs: number
|
|
144
|
+
readonly toolCount: number
|
|
145
|
+
readonly activeTools: readonly ActiveTool[]
|
|
146
|
+
readonly doneQueue: readonly DoneTool[]
|
|
147
|
+
/** Thinking phases entered this turn — the rare egg shows in the first one. */
|
|
148
|
+
readonly thinkingPhases: number
|
|
149
|
+
/** When the turn's first tool started (drives the thinking→doing opening line). */
|
|
150
|
+
readonly firstToolStartedAt: number
|
|
151
|
+
readonly waitingFirstToken: boolean
|
|
152
|
+
readonly narratedText: string | null
|
|
153
|
+
readonly lastChunkAt: number
|
|
154
|
+
readonly recentStream: string
|
|
155
|
+
readonly turnTokens: number
|
|
156
|
+
readonly donePrefix: string
|
|
157
|
+
readonly pendingPhrase: string | null
|
|
158
|
+
readonly pendingUntil: number
|
|
159
|
+
readonly gitBranch: string | null
|
|
160
|
+
/** Last announced model route, so a restored tracker keeps the dedupe. */
|
|
161
|
+
readonly model: string | null
|
|
162
|
+
readonly streak: number
|
|
163
|
+
readonly lastToolEndAt: number
|
|
164
|
+
readonly maxStreak: number
|
|
165
|
+
readonly subagentCount: number
|
|
166
|
+
/** Current stall, or null (`WaitingReason` for the reason). */
|
|
167
|
+
readonly waitingReason: WaitingReason | null
|
|
168
|
+
/** When the current stall began (0 with none). */
|
|
169
|
+
readonly waitingReasonAt: number
|
|
170
|
+
readonly tokBuf: number
|
|
171
|
+
readonly tokWindowStart: number
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Format one tool into its display fragment (`跑个命令 npm test`). */
|
|
175
|
+
function toolFragment(tool: { action: string; detail: string }): string {
|
|
176
|
+
return tool.detail.length === 0 ? tool.action : `${tool.action} ${tool.detail}`
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** The phase vocabulary, for snapshot shape validation (see {@link ActivityTracker.restore}). */
|
|
180
|
+
const PHASES: readonly ActivityPhase[] = ['idle', 'waiting', 'thinking', 'tool', 'done']
|
|
181
|
+
|
|
182
|
+
/** Whether `value` is one of {@link PHASES}. */
|
|
183
|
+
function isPhase(value: unknown): value is ActivityPhase {
|
|
184
|
+
return PHASES.includes(value as ActivityPhase)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Duration label for a settled tool: sub-second tools read in milliseconds.
|
|
189
|
+
*
|
|
190
|
+
* The shared `fmtDuration` is second-granular, which renders the measured
|
|
191
|
+
* median tool (87 ms) as a meaningless `0s` — the settled line exists to make
|
|
192
|
+
* that work visible, so it has to say how long it took.
|
|
193
|
+
* @param ms - Tool duration in milliseconds.
|
|
194
|
+
*/
|
|
195
|
+
function durationLabel(ms: number): string {
|
|
196
|
+
// Floor, not round: 999.6 ms is "999ms", not a "1000ms" that never happened.
|
|
197
|
+
return ms < 1000 ? `${Math.max(0, Math.floor(ms))}ms` : fmtDuration(ms)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Simple non-ANSI string shortener by grapheme count. */
|
|
201
|
+
function shorten(value: string, limit: number): string {
|
|
202
|
+
const graphemes = Array.from(value)
|
|
203
|
+
if (graphemes.length <= limit) return value
|
|
204
|
+
return `${graphemes.slice(0, Math.max(0, limit - 1)).join('')}…`
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Flatten model-written text for the single-line render path.
|
|
209
|
+
*
|
|
210
|
+
* The line is composed from text the model wrote (its `⏵` narration, the path
|
|
211
|
+
* or command inside a tool call), and it is displayed by a terminal and by the
|
|
212
|
+
* Web UI. So this is where that text stops being able to do anything but be
|
|
213
|
+
* read: complete ANSI/OSC sequences go first (stripping only their control
|
|
214
|
+
* bytes would leave `[31m` residue behind), every remaining C0/C1 control char
|
|
215
|
+
* becomes a space — a `\n` inside a multi-line shell command would otherwise
|
|
216
|
+
* split the status line in two — and whitespace collapses, because a render
|
|
217
|
+
* path is one line by definition.
|
|
218
|
+
* @param value - Raw model-written fragment.
|
|
219
|
+
* @returns the fragment, safe and single-line.
|
|
220
|
+
*/
|
|
221
|
+
function sanitizeFragment(value: string): string {
|
|
222
|
+
return value
|
|
223
|
+
.replace(/\u001B\][^\u0007]*(?:\u0007|\u001B\\)/gu, '')
|
|
224
|
+
.replace(/\u001B\[[0-?]*[ -/]*[@-~]/gu, '')
|
|
225
|
+
// eslint-disable-next-line no-control-regex -- deliberate: model text is untrusted render input
|
|
226
|
+
.replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ')
|
|
227
|
+
.replace(/\s+/g, ' ')
|
|
228
|
+
.trim()
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Extract a displayable detail fragment from a tool call's parsed arguments.
|
|
233
|
+
* @param toolName - Registry tool name.
|
|
234
|
+
* @param args - Parsed tool arguments (lossless JSON by registry contract).
|
|
235
|
+
*/
|
|
236
|
+
export function detailFor(toolName: string, args: Readonly<Record<string, unknown>> | undefined, limit: number): string {
|
|
237
|
+
if (args === undefined) return ''
|
|
238
|
+
const pickString = (...keys: readonly string[]): string => {
|
|
239
|
+
for (const key of keys) {
|
|
240
|
+
const value = args[key]
|
|
241
|
+
if (typeof value === 'string' && value.trim().length > 0) return sanitizeFragment(value)
|
|
242
|
+
}
|
|
243
|
+
return ''
|
|
244
|
+
}
|
|
245
|
+
const normalized = toolName.toLowerCase()
|
|
246
|
+
if (normalized === 'mcp' || normalized.startsWith('mcp__') || normalized.includes('__')) {
|
|
247
|
+
const action = pickString('action', 'tool', 'server', 'connect', 'describe')
|
|
248
|
+
return shorten(action, limit)
|
|
249
|
+
}
|
|
250
|
+
const path = pickString('path', 'file', 'file_path', 'filepath', 'target')
|
|
251
|
+
if (path.length > 0) return shorten(path, limit)
|
|
252
|
+
const command = pickString('command', 'cmd', 'cmdline')
|
|
253
|
+
if (command.length > 0) return shorten(command, limit)
|
|
254
|
+
const pattern = pickString('pattern', 'query', 'search')
|
|
255
|
+
if (pattern.length > 0) return shorten(pattern, limit)
|
|
256
|
+
const url = pickString('url')
|
|
257
|
+
if (url.length > 0) return shorten(url, limit)
|
|
258
|
+
if (/^(?:subagent|agent|task)$/i.test(toolName)) {
|
|
259
|
+
const description = pickString('description')
|
|
260
|
+
if (description.length > 0) return shorten(description, limit)
|
|
261
|
+
const prompt = pickString('prompt')
|
|
262
|
+
if (prompt.length > 0) return shorten(prompt, limit)
|
|
263
|
+
}
|
|
264
|
+
const named = pickString('name', 'server', 'tool', 'id', 'goal')
|
|
265
|
+
if (named.length > 0) return shorten(named, limit)
|
|
266
|
+
return ''
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Track one agent's activity from its durable session events. Events from
|
|
271
|
+
* other sessions are ignored (the owning plugin feeds only the agent it
|
|
272
|
+
* displays). The tracker is deliberately single-agent: multi-session UIs
|
|
273
|
+
* instantiate one tracker per agent.
|
|
274
|
+
*/
|
|
275
|
+
export class ActivityTracker {
|
|
276
|
+
private progressLang: Lang = terminalProgressLang()
|
|
277
|
+
private phase: ActivityPhase = 'idle'
|
|
278
|
+
private phaseStartedAt = 0
|
|
279
|
+
private turnStartedAt = 0
|
|
280
|
+
private thinkingStartedAt = 0
|
|
281
|
+
private thinkingMs = 0
|
|
282
|
+
private toolMs = 0
|
|
283
|
+
private toolCount = 0
|
|
284
|
+
/** When the turn's first tool started; 0 until it does (see {@link toolOpening}). */
|
|
285
|
+
private firstToolStartedAt = 0
|
|
286
|
+
private activeTools = new Map<string, ActiveTool>()
|
|
287
|
+
private doneQueue: DoneTool[] = []
|
|
288
|
+
private thinkingPhases = 0
|
|
289
|
+
private waitingFirstToken = false
|
|
290
|
+
/** Latest `⏵` self-narration line extracted from the stream, or null. */
|
|
291
|
+
private narratedText: string | null = null
|
|
292
|
+
/** Wall-clock time of the most recent stream delta (narration freshness). */
|
|
293
|
+
private lastChunkAt = 0
|
|
294
|
+
/** Rolling window of VISIBLE text deltas, for `⏵` extraction (see onEvent). */
|
|
295
|
+
private recentStream = ''
|
|
296
|
+
/** Total tokens reported across the turn's assistant messages. */
|
|
297
|
+
private turnTokens = 0
|
|
298
|
+
/** Completion prefix drawn ONCE at turn end so the done line stays stable. */
|
|
299
|
+
private donePrefix = t('done-prefix')
|
|
300
|
+
/** One-off copy pinned by an external event (interrupt / model switch /
|
|
301
|
+
* compaction / work reminder), shown until it expires. */
|
|
302
|
+
private pendingPhrase: string | null = null
|
|
303
|
+
private pendingUntil = 0
|
|
304
|
+
/** Git branch of the session cwd (fed by the host, best-effort). */
|
|
305
|
+
private gitBranch: string | undefined
|
|
306
|
+
/** Last model route announced, so a repeated selection stays quiet. */
|
|
307
|
+
private model: string | undefined
|
|
308
|
+
/** Consecutive fast tool streak (combo). */
|
|
309
|
+
private streak = 0
|
|
310
|
+
private lastToolEndAt = 0
|
|
311
|
+
private maxStreak = 0
|
|
312
|
+
/** Subagent (agent/task) calls in the current turn. */
|
|
313
|
+
private subagentCount = 0
|
|
314
|
+
/**
|
|
315
|
+
* Why the turn is stalled, when it is (retry / approval / compaction).
|
|
316
|
+
*
|
|
317
|
+
* A stall is state, not decoration: "waiting on the model" and "the model is
|
|
318
|
+
* waiting on YOU" need different copy, so it outranks the phrase pools and
|
|
319
|
+
* survives `phrases: false`.
|
|
320
|
+
*/
|
|
321
|
+
private waitingReason: WaitingReason | undefined
|
|
322
|
+
/** When the current stall began (seeds its copy; 0 with no stall). */
|
|
323
|
+
private waitingReasonAt = 0
|
|
324
|
+
/** Streaming token estimate for the tps prefix. */
|
|
325
|
+
private tokBuf = 0
|
|
326
|
+
private tokWindowStart = 0
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* @param config - Behavioral knobs.
|
|
330
|
+
* @param now - Wall-clock supplier (injectable for tests).
|
|
331
|
+
* @param customActions - Exact-name custom action pools for {@link actionFor}.
|
|
332
|
+
*/
|
|
333
|
+
constructor(
|
|
334
|
+
private readonly config: TrackerConfig,
|
|
335
|
+
private readonly now: () => number = Date.now,
|
|
336
|
+
private readonly customActions?: Readonly<Record<string, readonly string[]>>,
|
|
337
|
+
) {}
|
|
338
|
+
|
|
339
|
+
/** The locale used by this session's line. Existing modes still follow /lang. */
|
|
340
|
+
language(): Lang {
|
|
341
|
+
return this.config.inputLanguage ? this.progressLang : (this.config.language?.() ?? langNow())
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Agent transitioned to running/idle. */
|
|
345
|
+
onAgentStatus(status: 'idle' | 'running'): void {
|
|
346
|
+
if (status === 'idle') {
|
|
347
|
+
// The turn end already moved us to the done phase; idle only clears the
|
|
348
|
+
// lingering done card after its display window.
|
|
349
|
+
if (this.phase !== 'done') this.phase = 'idle'
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
if (this.phase === 'idle') {
|
|
353
|
+
this.phase = 'waiting'
|
|
354
|
+
this.phaseStartedAt = this.now()
|
|
355
|
+
this.waitingFirstToken = true
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/** The user interrupted the running turn: show a comeback quip next. */
|
|
360
|
+
onInterrupted(): void {
|
|
361
|
+
if (!this.config.phrases) return
|
|
362
|
+
if ((this.config.features ?? {}).continuePhrases === false) return
|
|
363
|
+
this.pendingPhrase = continuePhrase()
|
|
364
|
+
this.pendingUntil = this.now() + PENDING_MS
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* The model was switched: quip for the new model id.
|
|
369
|
+
*
|
|
370
|
+
* Repeats are ignored. A `model/selection` event is logged whenever the host
|
|
371
|
+
* validates a selection — including a re-selection of the current model and
|
|
372
|
+
* every replay of the log — and re-announcing the same model would replace
|
|
373
|
+
* whatever the line is saying with a stale quip.
|
|
374
|
+
*/
|
|
375
|
+
onModelSwitch(modelId: string): void {
|
|
376
|
+
if (modelId === this.model) return
|
|
377
|
+
this.model = modelId
|
|
378
|
+
if (!this.config.phrases) return
|
|
379
|
+
if ((this.config.features ?? {}).modelQuips === false) return
|
|
380
|
+
const quip = modelQuip(modelId)
|
|
381
|
+
if (quip !== null) {
|
|
382
|
+
this.pendingPhrase = quip
|
|
383
|
+
this.pendingUntil = this.now() + PENDING_MS
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** A context compaction finished (or overflowed): quip about it. */
|
|
388
|
+
onCompact(kind: 'done' | 'overflow'): void {
|
|
389
|
+
// The compaction stall (if any) is over either way.
|
|
390
|
+
if (this.waitingReason === 'compaction') this.clearWaitingReason()
|
|
391
|
+
if (!this.config.phrases) return
|
|
392
|
+
this.pendingPhrase = kind === 'overflow' ? overflowPhrase() : compactPhrase()
|
|
393
|
+
this.pendingUntil = this.now() + PENDING_MS
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Feed the session cwd's git branch (best-effort, host-resolved). */
|
|
397
|
+
onGitBranch(branch: string | undefined): void {
|
|
398
|
+
this.gitBranch = branch
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Consume one normalized activity event. This is the state machine's only
|
|
403
|
+
* input: host payload shapes are normalized in `src/compat/*` first, so a
|
|
404
|
+
* host-line drift never reaches this switch.
|
|
405
|
+
*/
|
|
406
|
+
onEvent(event: ActivityEvent): void {
|
|
407
|
+
if (event.kind === 'user-prompt') {
|
|
408
|
+
if (this.config.inputLanguage) {
|
|
409
|
+
const next = detectInputLanguage(event.text)
|
|
410
|
+
if (next !== undefined && next !== this.progressLang) {
|
|
411
|
+
this.progressLang = next
|
|
412
|
+
withProgressLang(next, () => {
|
|
413
|
+
for (const tool of this.activeTools.values()) {
|
|
414
|
+
tool.action = this.config.phrases ? actionFor(tool.name, this.customActions) : tool.name
|
|
415
|
+
}
|
|
416
|
+
for (const tool of this.doneQueue) {
|
|
417
|
+
tool.action = this.config.phrases ? actionFor(tool.name, this.customActions) : tool.name
|
|
418
|
+
}
|
|
419
|
+
this.donePrefix = t('done-prefix')
|
|
420
|
+
})
|
|
421
|
+
this.pendingPhrase = null
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return
|
|
425
|
+
}
|
|
426
|
+
withProgressLang(this.language(), () => this.applyEvent(event))
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private applyEvent(event: ActivityEvent): void {
|
|
430
|
+
switch (event.kind) {
|
|
431
|
+
case 'turn-start': {
|
|
432
|
+
const at = event.at
|
|
433
|
+
this.turnStartedAt = at
|
|
434
|
+
this.thinkingStartedAt = at
|
|
435
|
+
this.thinkingMs = 0
|
|
436
|
+
this.toolMs = 0
|
|
437
|
+
this.toolCount = 0
|
|
438
|
+
this.turnTokens = 0
|
|
439
|
+
this.activeTools.clear()
|
|
440
|
+
this.doneQueue = []
|
|
441
|
+
this.waitingFirstToken = true
|
|
442
|
+
this.narratedText = null
|
|
443
|
+
this.lastChunkAt = 0
|
|
444
|
+
this.recentStream = ''
|
|
445
|
+
// Eggs are once-per-turn and derived from the turn's seed, so a fresh
|
|
446
|
+
// turn only needs its phase counter cleared.
|
|
447
|
+
this.thinkingPhases = 0
|
|
448
|
+
this.firstToolStartedAt = 0
|
|
449
|
+
// Per-turn stats reset; the pending quip (interrupt/model/compact)
|
|
450
|
+
// survives across the turn boundary so it shows on the next think.
|
|
451
|
+
this.streak = 0
|
|
452
|
+
this.maxStreak = 0
|
|
453
|
+
this.subagentCount = 0
|
|
454
|
+
this.clearWaitingReason()
|
|
455
|
+
this.tokBuf = 0
|
|
456
|
+
this.tokWindowStart = at
|
|
457
|
+
this.setPhase('waiting', at)
|
|
458
|
+
return
|
|
459
|
+
}
|
|
460
|
+
case 'step-start':
|
|
461
|
+
// No phase change of its own: a step without streamed output stays
|
|
462
|
+
// waiting until its first delta promotes it.
|
|
463
|
+
return
|
|
464
|
+
case 'stream-start':
|
|
465
|
+
// A new attempt must not inherit the previous attempt's provisional
|
|
466
|
+
// text: the narration buffer and the token estimate are attempt-scoped.
|
|
467
|
+
// The phase is untouched — the first delta promotes waiting → thinking.
|
|
468
|
+
this.recentStream = ''
|
|
469
|
+
this.narratedText = null
|
|
470
|
+
this.tokBuf = 0
|
|
471
|
+
this.lastChunkAt = 0
|
|
472
|
+
return
|
|
473
|
+
case 'stream-delta': {
|
|
474
|
+
const at = event.at
|
|
475
|
+
this.lastChunkAt = at
|
|
476
|
+
// Output is flowing again — whatever stalled the turn is over.
|
|
477
|
+
this.clearWaitingReason()
|
|
478
|
+
if (this.waitingFirstToken) {
|
|
479
|
+
this.waitingFirstToken = false
|
|
480
|
+
// A delta that arrives while a tool runs must not steal the phase:
|
|
481
|
+
// models may stream text after a tool call inside the same attempt,
|
|
482
|
+
// and the tool is what the user is actually waiting on. The tool
|
|
483
|
+
// result hands the phase back to thinking on its own.
|
|
484
|
+
if (this.activeTools.size === 0) {
|
|
485
|
+
this.setPhase('thinking', at)
|
|
486
|
+
this.thinkingStartedAt = at
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
// Streaming token estimate for the tps prefix (pi parity).
|
|
490
|
+
this.tokBuf += estimateTokens(event.text)
|
|
491
|
+
// Only VISIBLE output narrates. The injected contract asks for the `⏵`
|
|
492
|
+
// line at the beginning of the *response body*, and the durable path
|
|
493
|
+
// (`assistant-settled`) already reads text blocks only — folding
|
|
494
|
+
// reasoning deltas in here made the line quote the model's private
|
|
495
|
+
// thinking back at the user. Reported live: the status line showed a
|
|
496
|
+
// half sentence from reasoning, because thinking about this very
|
|
497
|
+
// format means writing `⏵` about it.
|
|
498
|
+
if (event.stream !== 'text') return
|
|
499
|
+
this.recentStream = (this.recentStream + event.text).slice(-STREAM_BUFFER_CHARS)
|
|
500
|
+
const narration = extractNarration(this.recentStream)
|
|
501
|
+
if (narration !== null) this.narratedText = narration
|
|
502
|
+
return
|
|
503
|
+
}
|
|
504
|
+
case 'stream-reset': {
|
|
505
|
+
// An abandoned attempt (or a partial settlement) must not leave its
|
|
506
|
+
// provisional narration or token estimate behind for the next attempt.
|
|
507
|
+
this.recentStream = ''
|
|
508
|
+
this.narratedText = null
|
|
509
|
+
this.tokBuf = 0
|
|
510
|
+
this.lastChunkAt = 0
|
|
511
|
+
this.waitingFirstToken = true
|
|
512
|
+
if (this.activeTools.size === 0) this.setPhase('waiting', event.at)
|
|
513
|
+
return
|
|
514
|
+
}
|
|
515
|
+
case 'assistant-settled': {
|
|
516
|
+
const usage = event.usage
|
|
517
|
+
if (usage !== undefined) {
|
|
518
|
+
this.turnTokens += usage.inputTokens + usage.outputTokens
|
|
519
|
+
+ (usage.cacheReadTokens ?? 0) + (usage.cacheWriteTokens ?? 0)
|
|
520
|
+
}
|
|
521
|
+
// The settled text is where a projection (or a replayed log) recovers
|
|
522
|
+
// the narration: frames are live-only, this event is durable.
|
|
523
|
+
if (event.text !== undefined) {
|
|
524
|
+
const narration = extractNarration(event.text)
|
|
525
|
+
if (narration !== null) {
|
|
526
|
+
this.narratedText = narration
|
|
527
|
+
this.lastChunkAt = event.at
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return
|
|
531
|
+
}
|
|
532
|
+
case 'tool-start': {
|
|
533
|
+
const at = event.at
|
|
534
|
+
if (this.phase === 'thinking' || this.phase === 'waiting') {
|
|
535
|
+
this.thinkingMs += at - this.thinkingStartedAt
|
|
536
|
+
}
|
|
537
|
+
// The turn's first tool is where "thinking" turns into "doing": its
|
|
538
|
+
// opening line is derived from this instant (see toolOpening).
|
|
539
|
+
if (this.firstToolStartedAt === 0) this.firstToolStartedAt = at
|
|
540
|
+
// Combo streak: consecutive tools within COMBO_GAP_MS count up.
|
|
541
|
+
this.streak = (this.lastToolEndAt > 0 && at - this.lastToolEndAt <= COMBO_GAP_MS)
|
|
542
|
+
? this.streak + 1
|
|
543
|
+
: 1
|
|
544
|
+
if (this.streak > this.maxStreak) this.maxStreak = this.streak
|
|
545
|
+
if (/^(?:subagent|agent|task)$/i.test(event.name)) this.subagentCount += 1
|
|
546
|
+
const parsed = parseArguments(event.arguments)
|
|
547
|
+
const action = this.config.phrases ? actionFor(event.name, this.customActions) : event.name
|
|
548
|
+
const detail = detailFor(event.name, parsed, this.config.detailLimit)
|
|
549
|
+
const active: ActiveTool = {
|
|
550
|
+
callId: event.callId,
|
|
551
|
+
name: event.name,
|
|
552
|
+
action,
|
|
553
|
+
detail,
|
|
554
|
+
isGit: isGitTool(event.name, parsed),
|
|
555
|
+
startedAt: at,
|
|
556
|
+
failed: false,
|
|
557
|
+
}
|
|
558
|
+
this.activeTools.set(event.callId, active)
|
|
559
|
+
this.setPhase('tool', at)
|
|
560
|
+
return
|
|
561
|
+
}
|
|
562
|
+
case 'tool-end': {
|
|
563
|
+
const at = event.at
|
|
564
|
+
const callId = event.callId
|
|
565
|
+
const active = this.activeTools.get(callId)
|
|
566
|
+
if (active === undefined) return
|
|
567
|
+
active.failed = event.failed
|
|
568
|
+
active.endedAt = at
|
|
569
|
+
this.toolMs += at - active.startedAt
|
|
570
|
+
this.toolCount += 1
|
|
571
|
+
this.lastToolEndAt = at
|
|
572
|
+
this.doneQueue.push({
|
|
573
|
+
name: active.name,
|
|
574
|
+
action: active.action,
|
|
575
|
+
detail: active.detail,
|
|
576
|
+
failed: active.failed,
|
|
577
|
+
endedAt: at,
|
|
578
|
+
// Kept so the settled line can show how long it took: on real
|
|
579
|
+
// sessions the median tool is 87 ms, so the duration is most of what
|
|
580
|
+
// there is to read.
|
|
581
|
+
durationMs: Math.max(0, at - active.startedAt),
|
|
582
|
+
})
|
|
583
|
+
if (this.doneQueue.length > DONE_QUEUE_MAX) this.doneQueue.shift()
|
|
584
|
+
this.activeTools.delete(callId)
|
|
585
|
+
// An approval-parked tool resolved the moment it settled.
|
|
586
|
+
if (this.waitingReason === 'approval') this.clearWaitingReason()
|
|
587
|
+
if (this.activeTools.size === 0) {
|
|
588
|
+
// Back to thinking (or a trailing done card if the turn just closed).
|
|
589
|
+
this.setPhase('thinking', at)
|
|
590
|
+
this.thinkingStartedAt = at
|
|
591
|
+
}
|
|
592
|
+
return
|
|
593
|
+
}
|
|
594
|
+
case 'turn-end': {
|
|
595
|
+
const at = event.at
|
|
596
|
+
if (this.activeTools.size > 0) {
|
|
597
|
+
// Tools still running at turn end: count their elapsed time as tool time.
|
|
598
|
+
for (const tool of this.activeTools.values()) {
|
|
599
|
+
this.toolMs += Math.max(0, at - tool.startedAt)
|
|
600
|
+
}
|
|
601
|
+
this.activeTools.clear()
|
|
602
|
+
} else if (this.phase === 'thinking' || this.phase === 'waiting') {
|
|
603
|
+
this.thinkingMs += Math.max(0, at - this.thinkingStartedAt)
|
|
604
|
+
}
|
|
605
|
+
// Draw the completion prefix ONCE so repeated renders of the done line
|
|
606
|
+
// stay stable (a fresh random per render would make it flicker). The
|
|
607
|
+
// pools are language-aware, so the line matches the language the turn
|
|
608
|
+
// ended in.
|
|
609
|
+
const lastTool = this.doneQueue.at(-1)
|
|
610
|
+
if (this.config.phrases) {
|
|
611
|
+
this.donePrefix = lastTool?.failed
|
|
612
|
+
? ((this.config.features ?? {}).failPhrases !== false ? failPhrase() : t('done-prefix'))
|
|
613
|
+
: donePhrase()
|
|
614
|
+
} else {
|
|
615
|
+
this.donePrefix = t('done-prefix')
|
|
616
|
+
}
|
|
617
|
+
if (event.interrupted === true) this.onInterrupted()
|
|
618
|
+
this.clearWaitingReason()
|
|
619
|
+
this.setPhase('done', at)
|
|
620
|
+
return
|
|
621
|
+
}
|
|
622
|
+
case 'route-change':
|
|
623
|
+
this.onModelSwitch(event.model)
|
|
624
|
+
return
|
|
625
|
+
case 'compaction':
|
|
626
|
+
this.onCompact(event.overflow === true ? 'overflow' : 'done')
|
|
627
|
+
return
|
|
628
|
+
case 'waiting-reason':
|
|
629
|
+
this.waitingReason = event.reason
|
|
630
|
+
this.waitingReasonAt = event.at
|
|
631
|
+
return
|
|
632
|
+
case 'waiting-cleared':
|
|
633
|
+
this.clearWaitingReason()
|
|
634
|
+
return
|
|
635
|
+
case 'agent-status':
|
|
636
|
+
this.onAgentStatus(event.status)
|
|
637
|
+
return
|
|
638
|
+
default:
|
|
639
|
+
return
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Feed one raw durable session event.
|
|
645
|
+
* @deprecated Host-shape input kept for one release so an already-published
|
|
646
|
+
* consumer that drives this tracker itself (dsh-TUI ≤ 0.11.x calls this
|
|
647
|
+
* method) keeps working across the upgrade. New code normalizes through
|
|
648
|
+
* `src/compat/*` and calls {@link onEvent}. The parameter type is inferred
|
|
649
|
+
* from the compat function on purpose — this module must not import a DSH
|
|
650
|
+
* type.
|
|
651
|
+
* @param event - Raw durable session event.
|
|
652
|
+
*/
|
|
653
|
+
onSessionEvent(event: Parameters<typeof feedSessionEvent>[1]): void {
|
|
654
|
+
feedSessionEvent(this, event)
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/** Render the current status snapshot at a wall-clock instant. */
|
|
658
|
+
render(nowMs: number = this.now()): ActivityState {
|
|
659
|
+
return withProgressLang(this.language(), () => this.renderCurrent(nowMs))
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
private renderCurrent(nowMs: number): ActivityState {
|
|
663
|
+
switch (this.phase) {
|
|
664
|
+
case 'idle':
|
|
665
|
+
return {
|
|
666
|
+
phase: 'idle',
|
|
667
|
+
line: '',
|
|
668
|
+
toolCount: 0,
|
|
669
|
+
turnElapsedMs: 0,
|
|
670
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
671
|
+
}
|
|
672
|
+
case 'done': {
|
|
673
|
+
const summary = this.doneSummary(nowMs)
|
|
674
|
+
return {
|
|
675
|
+
phase: 'done',
|
|
676
|
+
line: summary.line,
|
|
677
|
+
toolCount: this.toolCount,
|
|
678
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
679
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
680
|
+
...(summary.phrase === undefined ? {} : { phrase: summary.phrase }),
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
case 'tool': {
|
|
684
|
+
const tool = this.primaryTool()
|
|
685
|
+
if (tool === undefined) {
|
|
686
|
+
return this.renderThinking(nowMs)
|
|
687
|
+
}
|
|
688
|
+
const fragment = toolFragment(tool)
|
|
689
|
+
// Same granularity as the settled line: a fast tool's counter would
|
|
690
|
+
// otherwise sit at `0s` for its whole (measured 87 ms median) life.
|
|
691
|
+
const elapsed = durationLabel(Math.max(0, nowMs - tool.startedAt))
|
|
692
|
+
const git = tool.isGit
|
|
693
|
+
? (this.gitBranch !== undefined ? ` · git ${this.gitBranch}` : ' · git')
|
|
694
|
+
: ''
|
|
695
|
+
const combo = (this.config.features ?? {}).combo !== false && this.streak >= COMBO_SHOW_AT
|
|
696
|
+
? ` · ${t('tool-streak', { count: this.streak })}`
|
|
697
|
+
: ''
|
|
698
|
+
// An approval-parked tool says so even in minimal mode: this is the one
|
|
699
|
+
// state where the user, not the model, is the one being waited on.
|
|
700
|
+
const approval = this.waitingReason === 'approval' ? ` · ${t('tool-waiting-approval')}` : ''
|
|
701
|
+
const narration = this.freshNarration(nowMs)
|
|
702
|
+
// The turn's first tool opens with a short "thought it through, getting
|
|
703
|
+
// to work" line, prepended so the tool's own copy stays readable.
|
|
704
|
+
const opening = this.toolOpening(nowMs)
|
|
705
|
+
const prefix = opening === '' ? '' : `${opening} · `
|
|
706
|
+
const line = narration === null
|
|
707
|
+
? `${prefix}${fragment} · ${elapsed}${git}${combo}${approval}`
|
|
708
|
+
: `⏵ ${narration} · ${prefix}${fragment} · ${elapsed}${git}${combo}${approval}`
|
|
709
|
+
return {
|
|
710
|
+
phase: 'tool',
|
|
711
|
+
line,
|
|
712
|
+
label: tool.action,
|
|
713
|
+
detail: tool.detail,
|
|
714
|
+
...(narration === null ? (opening === '' ? {} : { phrase: opening }) : { phrase: narration }),
|
|
715
|
+
toolCount: this.toolCount,
|
|
716
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
717
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
case 'waiting':
|
|
721
|
+
case 'thinking': {
|
|
722
|
+
const rendered = this.renderThinking(nowMs)
|
|
723
|
+
if (this.phase === 'waiting') {
|
|
724
|
+
return { ...rendered, phase: 'waiting' }
|
|
725
|
+
}
|
|
726
|
+
return rendered
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/** Per-turn thinking/tooling split for stats consumers. */
|
|
732
|
+
stats(): TurnStats {
|
|
733
|
+
return {
|
|
734
|
+
thinkingMs: this.thinkingMs,
|
|
735
|
+
toolMs: this.toolMs,
|
|
736
|
+
toolCount: this.toolCount,
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Opaque, JSON-safe snapshot of this tracker's complete state.
|
|
742
|
+
*
|
|
743
|
+
* A persisted projection checkpoint has to resume folding **without**
|
|
744
|
+
* replaying a session's whole log, so the state machine must be able to hand
|
|
745
|
+
* its state out and take it back. The shape is not public API: pass the value
|
|
746
|
+
* straight back to {@link ActivityTracker.restore}. {@link TRACKER_SNAPSHOT_VERSION}
|
|
747
|
+
* is the compatibility handle between the two.
|
|
748
|
+
* @returns every field the fold depends on, as JSON-safe values.
|
|
749
|
+
*/
|
|
750
|
+
snapshot(): unknown {
|
|
751
|
+
const data: TrackerSnapshotShape = {
|
|
752
|
+
version: TRACKER_SNAPSHOT_VERSION,
|
|
753
|
+
progressLang: this.progressLang,
|
|
754
|
+
phase: this.phase,
|
|
755
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
756
|
+
turnStartedAt: this.turnStartedAt,
|
|
757
|
+
thinkingStartedAt: this.thinkingStartedAt,
|
|
758
|
+
thinkingMs: this.thinkingMs,
|
|
759
|
+
toolMs: this.toolMs,
|
|
760
|
+
toolCount: this.toolCount,
|
|
761
|
+
activeTools: [...this.activeTools.values()],
|
|
762
|
+
doneQueue: this.doneQueue,
|
|
763
|
+
thinkingPhases: this.thinkingPhases,
|
|
764
|
+
firstToolStartedAt: this.firstToolStartedAt,
|
|
765
|
+
waitingFirstToken: this.waitingFirstToken,
|
|
766
|
+
narratedText: this.narratedText,
|
|
767
|
+
lastChunkAt: this.lastChunkAt,
|
|
768
|
+
recentStream: this.recentStream,
|
|
769
|
+
turnTokens: this.turnTokens,
|
|
770
|
+
donePrefix: this.donePrefix,
|
|
771
|
+
pendingPhrase: this.pendingPhrase,
|
|
772
|
+
pendingUntil: this.pendingUntil,
|
|
773
|
+
gitBranch: this.gitBranch ?? null,
|
|
774
|
+
model: this.model ?? null,
|
|
775
|
+
streak: this.streak,
|
|
776
|
+
lastToolEndAt: this.lastToolEndAt,
|
|
777
|
+
maxStreak: this.maxStreak,
|
|
778
|
+
subagentCount: this.subagentCount,
|
|
779
|
+
waitingReason: this.waitingReason ?? null,
|
|
780
|
+
waitingReasonAt: this.waitingReasonAt,
|
|
781
|
+
tokBuf: this.tokBuf,
|
|
782
|
+
tokWindowStart: this.tokWindowStart,
|
|
783
|
+
}
|
|
784
|
+
return data
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Rebuild a tracker from {@link snapshot} output.
|
|
789
|
+
*
|
|
790
|
+
* The behavioral knobs are not part of the snapshot, so they are passed in
|
|
791
|
+
* again; everything the fold accumulates is restored. Mutable entries are
|
|
792
|
+
* cloned, so the restored tracker can never write back into the value the
|
|
793
|
+
* caller still holds as a checkpoint.
|
|
794
|
+
* @param config - Behavioral knobs.
|
|
795
|
+
* @param now - Wall-clock supplier.
|
|
796
|
+
* @param customActions - Custom action pools.
|
|
797
|
+
* @param payload - A value previously returned by `snapshot()`.
|
|
798
|
+
* @returns an equivalent tracker that can keep folding.
|
|
799
|
+
* @throws when the payload is not a snapshot of {@link TRACKER_SNAPSHOT_VERSION}
|
|
800
|
+
* — a caller holding a stale checkpoint must refold the log rather than render
|
|
801
|
+
* a state it cannot interpret.
|
|
802
|
+
*/
|
|
803
|
+
static restore(
|
|
804
|
+
config: TrackerConfig,
|
|
805
|
+
now: () => number = Date.now,
|
|
806
|
+
customActions?: Readonly<Record<string, readonly string[]>>,
|
|
807
|
+
payload?: unknown,
|
|
808
|
+
): ActivityTracker {
|
|
809
|
+
const data = payload as TrackerSnapshotShape | undefined
|
|
810
|
+
// The shape guards are deliberately cheap (phase + the two anchor clocks):
|
|
811
|
+
// they catch the torn-write / hand-edited cache cases a version number
|
|
812
|
+
// alone cannot, so a corrupt-but-current-version checkpoint fails HERE —
|
|
813
|
+
// where the projection can catch it and refold — instead of mid-render.
|
|
814
|
+
if (data === undefined || data === null || typeof data !== 'object'
|
|
815
|
+
|| data.version !== TRACKER_SNAPSHOT_VERSION
|
|
816
|
+
|| !isLang(data.progressLang)
|
|
817
|
+
|| !isPhase(data.phase)
|
|
818
|
+
|| typeof data.phaseStartedAt !== 'number'
|
|
819
|
+
|| typeof data.turnStartedAt !== 'number') {
|
|
820
|
+
throw new Error(
|
|
821
|
+
`working-activity: unsupported tracker snapshot (expected version ${TRACKER_SNAPSHOT_VERSION})`,
|
|
822
|
+
)
|
|
823
|
+
}
|
|
824
|
+
const tracker = new ActivityTracker(config, now, customActions)
|
|
825
|
+
tracker.progressLang = data.progressLang
|
|
826
|
+
tracker.phase = data.phase
|
|
827
|
+
tracker.phaseStartedAt = data.phaseStartedAt
|
|
828
|
+
tracker.turnStartedAt = data.turnStartedAt
|
|
829
|
+
tracker.thinkingStartedAt = data.thinkingStartedAt
|
|
830
|
+
tracker.thinkingMs = data.thinkingMs
|
|
831
|
+
tracker.toolMs = data.toolMs
|
|
832
|
+
tracker.toolCount = data.toolCount
|
|
833
|
+
tracker.activeTools = new Map(data.activeTools.map(tool => [tool.callId, { ...tool }]))
|
|
834
|
+
tracker.doneQueue = data.doneQueue.map(tool => ({ ...tool }))
|
|
835
|
+
tracker.thinkingPhases = data.thinkingPhases
|
|
836
|
+
tracker.firstToolStartedAt = data.firstToolStartedAt
|
|
837
|
+
tracker.waitingFirstToken = data.waitingFirstToken
|
|
838
|
+
tracker.narratedText = data.narratedText
|
|
839
|
+
tracker.lastChunkAt = data.lastChunkAt
|
|
840
|
+
tracker.recentStream = data.recentStream
|
|
841
|
+
tracker.turnTokens = data.turnTokens
|
|
842
|
+
tracker.donePrefix = data.donePrefix
|
|
843
|
+
tracker.pendingPhrase = data.pendingPhrase
|
|
844
|
+
tracker.pendingUntil = data.pendingUntil
|
|
845
|
+
tracker.gitBranch = data.gitBranch ?? undefined
|
|
846
|
+
tracker.model = data.model ?? undefined
|
|
847
|
+
tracker.streak = data.streak
|
|
848
|
+
tracker.lastToolEndAt = data.lastToolEndAt
|
|
849
|
+
tracker.maxStreak = data.maxStreak
|
|
850
|
+
tracker.subagentCount = data.subagentCount
|
|
851
|
+
tracker.waitingReason = data.waitingReason ?? undefined
|
|
852
|
+
tracker.waitingReasonAt = data.waitingReasonAt
|
|
853
|
+
tracker.tokBuf = data.tokBuf
|
|
854
|
+
tracker.tokWindowStart = data.tokWindowStart
|
|
855
|
+
return tracker
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* The next instant at which {@link render} can produce a different line, or
|
|
860
|
+
* `undefined` when the line stays exactly as it is until another event
|
|
861
|
+
* arrives.
|
|
862
|
+
*
|
|
863
|
+
* A status line does not need a heartbeat: it needs to be redrawn when
|
|
864
|
+
* something it displays moves. Those movements are all known here — the
|
|
865
|
+
* elapsed second, the phrase rotation, a narration or tok/s window closing,
|
|
866
|
+
* and the done card swapping its tool fragment for the summary — so a caller
|
|
867
|
+
* can sleep exactly that long instead of polling. Idle and settled lines
|
|
868
|
+
* return `undefined`: nothing about them changes on its own, so they need no
|
|
869
|
+
* timer at all. Transitions on a longer horizon than the displayed second
|
|
870
|
+
* (the work reminder, for one) need no candidate of their own: the elapsed
|
|
871
|
+
* counter redraws long before them.
|
|
872
|
+
*
|
|
873
|
+
* The value is a lower bound on the next visible change, so waking at it can
|
|
874
|
+
* only be early, never late.
|
|
875
|
+
* @param nowMs - Wall-clock instant to measure from.
|
|
876
|
+
* @returns the next wake instant in epoch milliseconds, or `undefined`.
|
|
877
|
+
*/
|
|
878
|
+
nextWakeAt(nowMs: number = this.now()): number | undefined {
|
|
879
|
+
switch (this.phase) {
|
|
880
|
+
case 'idle':
|
|
881
|
+
return undefined
|
|
882
|
+
case 'done': {
|
|
883
|
+
// The done line shows the last tool's fragment for a short window and
|
|
884
|
+
// then the summary; after that it is static until the next turn.
|
|
885
|
+
const last = this.doneQueue.at(-1)
|
|
886
|
+
if (last === undefined) return undefined
|
|
887
|
+
const swapAt = last.endedAt + DONE_FRAGMENT_MS
|
|
888
|
+
return nowMs < swapAt ? swapAt : undefined
|
|
889
|
+
}
|
|
890
|
+
case 'tool': {
|
|
891
|
+
const tool = this.primaryTool()
|
|
892
|
+
// `render` falls back to the thinking line when no tool is tracked.
|
|
893
|
+
if (tool === undefined) return this.liveWakeAt(nowMs, this.thinkingStartedAt)
|
|
894
|
+
return minWake(
|
|
895
|
+
secondBoundary(tool.startedAt, nowMs),
|
|
896
|
+
this.narrationWakeAt(nowMs),
|
|
897
|
+
this.tpsWakeAt(nowMs),
|
|
898
|
+
)
|
|
899
|
+
}
|
|
900
|
+
case 'waiting':
|
|
901
|
+
case 'thinking':
|
|
902
|
+
return this.liveWakeAt(nowMs, this.turnStartedAt)
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Wake instant for a live phase that displays the turn's elapsed second: the
|
|
908
|
+
* next whole second, whichever of the other displayed windows closes first,
|
|
909
|
+
* and the phrase rotation — or the expiry of a one-off quip, which the render
|
|
910
|
+
* after it replaces.
|
|
911
|
+
* @param nowMs - Wall-clock instant to measure from.
|
|
912
|
+
* @param elapsedFrom - Instant the displayed second counter counts from.
|
|
913
|
+
*/
|
|
914
|
+
private liveWakeAt(nowMs: number, elapsedFrom: number): number | undefined {
|
|
915
|
+
return minWake(
|
|
916
|
+
secondBoundary(elapsedFrom, nowMs),
|
|
917
|
+
this.rotationWakeAt(nowMs),
|
|
918
|
+
this.narrationWakeAt(nowMs),
|
|
919
|
+
this.tpsWakeAt(nowMs),
|
|
920
|
+
)
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/** When the displayed phrase is replaced: a rotation, or a quip expiring. */
|
|
924
|
+
private rotationWakeAt(nowMs: number): number | undefined {
|
|
925
|
+
if (!this.config.phrases) return undefined
|
|
926
|
+
// An expired quip is no longer displayed (see pendingPhraseAt), so the
|
|
927
|
+
// wake falls through to the pool rotation — returning its past expiry
|
|
928
|
+
// would arm a zero-delay timer that re-arms forever.
|
|
929
|
+
if (this.pendingPhrase !== null && nowMs < this.pendingUntil) return this.pendingUntil
|
|
930
|
+
// The next window boundary of the phase's own pool. Derived rather than
|
|
931
|
+
// remembered: a read must never be what advances the copy (see phraseForSlot).
|
|
932
|
+
const rotateMs = this.rarePool() ? RARE_ROTATE_MS : PHRASE_ROTATE_MS
|
|
933
|
+
return this.phraseAnchorAt() + (this.phraseSlot(nowMs, rotateMs) + 1) * rotateMs
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/** When the currently displayed narration expires, if one is displayed. */
|
|
937
|
+
private narrationWakeAt(nowMs: number): number | undefined {
|
|
938
|
+
if (this.freshNarration(nowMs) === null) return undefined
|
|
939
|
+
return this.lastChunkAt + NARRATE_GRACE_MS
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** When the displayed tok/s estimate ages out, if one is displayed. */
|
|
943
|
+
private tpsWakeAt(nowMs: number): number | undefined {
|
|
944
|
+
if (this.config.showTokPerSec !== true || this.tokBuf <= 0) return undefined
|
|
945
|
+
if (this.tpsPrefix(nowMs) === '') return undefined
|
|
946
|
+
return this.lastChunkAt + TPS_WINDOW_MS
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
private renderThinking(nowMs: number): ActivityState {
|
|
950
|
+
const thinkingMs = this.phase === 'waiting'
|
|
951
|
+
? 0
|
|
952
|
+
: this.thinkingMs + Math.max(0, nowMs - this.thinkingStartedAt)
|
|
953
|
+
const elapsed = fmtDuration(this.turnElapsedMs(nowMs))
|
|
954
|
+
const elapsedLine = t('line-elapsed', { elapsed })
|
|
955
|
+
// A tool that just settled keeps its own copy on screen for a beat. Measured
|
|
956
|
+
// on real sessions: the median tool lasts 87 ms and 73% last under 500 ms, so
|
|
957
|
+
// without this the tool line is a single frame nobody can read. It outranks
|
|
958
|
+
// the narration for its window — the narration is usually the same `⏵` line
|
|
959
|
+
// from before the tool, while this one is the news.
|
|
960
|
+
const settled = this.settledToolLine(nowMs)
|
|
961
|
+
if (settled !== null) return settled
|
|
962
|
+
const narration = this.freshNarration(nowMs)
|
|
963
|
+
if (narration !== null) {
|
|
964
|
+
return {
|
|
965
|
+
phase: this.phase,
|
|
966
|
+
line: `⏵ ${narration} · ${elapsedLine}`,
|
|
967
|
+
phrase: narration,
|
|
968
|
+
toolCount: this.toolCount,
|
|
969
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
970
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
// A stall outranks the copy pools (and survives minimal mode): the pool
|
|
974
|
+
// says "still queuing", which reads as model latency — a retry or a parked
|
|
975
|
+
// approval is a different fact the user cannot act on unless it is said.
|
|
976
|
+
const stall = this.stallPhrase()
|
|
977
|
+
if (stall !== null) {
|
|
978
|
+
return {
|
|
979
|
+
phase: this.phase,
|
|
980
|
+
line: `${stall} · ${elapsedLine}`,
|
|
981
|
+
phrase: stall,
|
|
982
|
+
toolCount: this.toolCount,
|
|
983
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
984
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (this.config.phrases) {
|
|
988
|
+
const pending = this.pendingPhraseAt(nowMs)
|
|
989
|
+
// Waiting (pre-first-token) draws from the waiting pool; thinking draws
|
|
990
|
+
// the egg-aware lively pool (holiday / rare / weekend / night). The pool
|
|
991
|
+
// follows the CURRENT phase and the window follows the phase's own start,
|
|
992
|
+
// so neither the copy nor the cadence depends on how often this is read.
|
|
993
|
+
const rotateMs = this.rarePool() ? RARE_ROTATE_MS : PHRASE_ROTATE_MS
|
|
994
|
+
const phrase = pending ?? this.phraseForSlot(this.phraseSlot(nowMs, rotateMs), rotateMs, nowMs)
|
|
995
|
+
// The indicator animation (whale etc.) already signals activity, so the
|
|
996
|
+
// pi DOT_FRAMES ellipsis breathing is dropped for the DSH line.
|
|
997
|
+
const tps = this.tpsPrefix(nowMs)
|
|
998
|
+
return {
|
|
999
|
+
phase: this.phase,
|
|
1000
|
+
line: `${tps}${phrase} · ${elapsedLine}`,
|
|
1001
|
+
phrase,
|
|
1002
|
+
toolCount: this.toolCount,
|
|
1003
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
1004
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
const label = this.phase === 'waiting' ? t('waiting-label') : t('thinking-label')
|
|
1008
|
+
return {
|
|
1009
|
+
phase: this.phase,
|
|
1010
|
+
line: `${label} · ${elapsedLine}`,
|
|
1011
|
+
label,
|
|
1012
|
+
toolCount: this.toolCount,
|
|
1013
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
1014
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* The live narration this tracker is currently showing, if any.
|
|
1020
|
+
*
|
|
1021
|
+
* A projection folds DURABLE events only, so a live host that also sees
|
|
1022
|
+
* stream frames has to hand the frame-derived narration to the projected
|
|
1023
|
+
* value separately (see `ActivityProjectionOptions.live`); this is that
|
|
1024
|
+
* payload, and `undefined` means "nothing live to overlay".
|
|
1025
|
+
*/
|
|
1026
|
+
liveNarration(): { readonly narration: string; readonly lastChunkAt: number } | undefined {
|
|
1027
|
+
if (this.narratedText === null) return undefined
|
|
1028
|
+
return { narration: this.narratedText, lastChunkAt: this.lastChunkAt }
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Show `narration` as if it had just streamed in.
|
|
1033
|
+
*
|
|
1034
|
+
* Used by the live overlay: the projected state carries no frames, so the
|
|
1035
|
+
* host paints the freshest narration it has over the folded value.
|
|
1036
|
+
*/
|
|
1037
|
+
applyLiveNarration(narration: string, at: number): void {
|
|
1038
|
+
this.narratedText = narration
|
|
1039
|
+
this.lastChunkAt = at
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* The "thought it through, getting to work" line for the turn's first tool.
|
|
1044
|
+
*
|
|
1045
|
+
* Shown as a prefix for a short window after that tool starts, then gone: it
|
|
1046
|
+
* marks the thinking→doing boundary once per turn, and being derived (like
|
|
1047
|
+
* every other phrase) it neither rotates nor repeats within the window.
|
|
1048
|
+
* @param nowMs - Wall-clock instant to test.
|
|
1049
|
+
* @returns the opening copy, or '' when the window is closed.
|
|
1050
|
+
*/
|
|
1051
|
+
private toolOpening(nowMs: number): string {
|
|
1052
|
+
if (!this.config.phrases) return ''
|
|
1053
|
+
if (this.firstToolStartedAt === 0) return ''
|
|
1054
|
+
if (nowMs - this.firstToolStartedAt >= TOOL_OPENING_MS) return ''
|
|
1055
|
+
return toolOpeningPhrase({ seed: this.turnStartedAt, slot: 0 })
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* The just-finished tool, while its copy is still worth reading.
|
|
1060
|
+
*
|
|
1061
|
+
* Derived from the last settled tool's end time, so it neither lingers past
|
|
1062
|
+
* its window nor depends on how often the line is read. `✓` marks it as
|
|
1063
|
+
* settled, so it cannot be mistaken for the running-tool line.
|
|
1064
|
+
* @param nowMs - Wall-clock instant to test.
|
|
1065
|
+
* @returns the settled-tool state, or null when the window is closed.
|
|
1066
|
+
*/
|
|
1067
|
+
private settledToolLine(nowMs: number): ActivityState | null {
|
|
1068
|
+
if (!this.config.phrases) return null
|
|
1069
|
+
const last = this.doneQueue.at(-1)
|
|
1070
|
+
if (last === undefined) return null
|
|
1071
|
+
const age = nowMs - last.endedAt
|
|
1072
|
+
if (age < 0 || age >= TOOL_LINGER_MS) return null
|
|
1073
|
+
const fragment = toolFragment(last)
|
|
1074
|
+
return {
|
|
1075
|
+
phase: this.phase === 'waiting' ? 'thinking' : this.phase,
|
|
1076
|
+
line: `✓ ${fragment} · ${durationLabel(last.durationMs)}`,
|
|
1077
|
+
label: last.action,
|
|
1078
|
+
detail: last.detail,
|
|
1079
|
+
phrase: last.action,
|
|
1080
|
+
toolCount: this.toolCount,
|
|
1081
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
1082
|
+
phaseStartedAt: this.phaseStartedAt,
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* The pending one-off quip (interrupt / model / compact), while fresh.
|
|
1088
|
+
*
|
|
1089
|
+
* A pure read: an expired quip is simply not returned (the field is
|
|
1090
|
+
* overwritten by the next one), and the work reminder has its own derived
|
|
1091
|
+
* window — the old version wrote here (`pendingPhrase = null`,
|
|
1092
|
+
* `reminded = true`), which a projection's throwaway restore discarded, so
|
|
1093
|
+
* the reminder re-fired on EVERY read and pinned the line for the rest of
|
|
1094
|
+
* the turn.
|
|
1095
|
+
*/
|
|
1096
|
+
private pendingPhraseAt(nowMs: number): string | null {
|
|
1097
|
+
if (this.pendingPhrase !== null && nowMs < this.pendingUntil) return this.pendingPhrase
|
|
1098
|
+
return this.workReminderAt(nowMs)
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* The work reminder, purely derived from elapsed time.
|
|
1103
|
+
*
|
|
1104
|
+
* Shown for {@link PENDING_MS} of wall time each time another `workRemindAt`
|
|
1105
|
+
* hours of continuous work accumulate (`hours % workRemindAt` is the distance
|
|
1106
|
+
* into the current bucket). No state: repeated reads agree, a resumed
|
|
1107
|
+
* checkpoint renders the same answer, and the reminder returns every bucket
|
|
1108
|
+
* instead of once per process.
|
|
1109
|
+
*/
|
|
1110
|
+
private workReminderAt(nowMs: number): string | null {
|
|
1111
|
+
const remindAt = this.config.workRemindAt ?? 0
|
|
1112
|
+
if (remindAt <= 0) return null
|
|
1113
|
+
const hours = this.turnElapsedMs(nowMs) / 3_600_000
|
|
1114
|
+
if (hours < remindAt) return null
|
|
1115
|
+
const intoBucketMs = (hours % remindAt) * 3_600_000
|
|
1116
|
+
if (intoBucketMs >= PENDING_MS) return null
|
|
1117
|
+
return t('work-remind', { hours: Math.floor(hours) })
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/** Estimated tokens/s while the stream is fresh (pi parity, opt-in). */
|
|
1121
|
+
private tpsPrefix(nowMs: number): string {
|
|
1122
|
+
if (!this.config.showTokPerSec || this.tokBuf <= 0) return ''
|
|
1123
|
+
if (nowMs - this.lastChunkAt > TPS_WINDOW_MS) return ''
|
|
1124
|
+
const windowSec = Math.max(1, (nowMs - this.tokWindowStart) / 1000)
|
|
1125
|
+
const tps = Math.round(this.tokBuf / windowSec)
|
|
1126
|
+
return tps > 0 ? `~${tps} tok/s · ` : ''
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
private doneSummary(nowMs: number): { line: string; phrase?: string } {
|
|
1130
|
+
const { thinkingMs, toolMs, toolCount } = this.stats()
|
|
1131
|
+
const tokens = this.turnTokens > 0 ? ` · 🔥 ${fmtTokens(this.turnTokens)}` : ''
|
|
1132
|
+
const sub = this.subagentCount > 0 ? ` · ${t('subagent-count', { count: this.subagentCount })}` : ''
|
|
1133
|
+
const combo = (this.config.features ?? {}).combo !== false && this.maxStreak >= COMBO_SHOW_AT
|
|
1134
|
+
? ` · ${t('tool-streak', { count: this.maxStreak })}`
|
|
1135
|
+
: ''
|
|
1136
|
+
const tools = t(toolCount === 1 ? 'tool-count-one' : 'tool-count-many', { count: toolCount })
|
|
1137
|
+
// Sub-second splits read in milliseconds for the same reason a settled
|
|
1138
|
+
// tool does: a quick turn would otherwise summarize as 想0s 干0s.
|
|
1139
|
+
const summary = t('done-summary', {
|
|
1140
|
+
tools,
|
|
1141
|
+
thinking: durationLabel(thinkingMs),
|
|
1142
|
+
tooling: durationLabel(toolMs),
|
|
1143
|
+
})
|
|
1144
|
+
if (!this.config.phrases) {
|
|
1145
|
+
return { line: `${t('done-prefix')} · ${summary}${sub}${combo}${tokens}` }
|
|
1146
|
+
}
|
|
1147
|
+
const last = this.doneQueue.at(-1)
|
|
1148
|
+
if (last !== undefined && nowMs - last.endedAt < DONE_FRAGMENT_MS) {
|
|
1149
|
+
const fragment = toolFragment(last)
|
|
1150
|
+
return { line: `${this.donePrefix} · ${fragment} · ${tools}${sub}${combo}${tokens}`, phrase: this.donePrefix }
|
|
1151
|
+
}
|
|
1152
|
+
return { line: `${this.donePrefix} · ${summary}${sub}${combo}${tokens}`, phrase: this.donePrefix }
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/** The fresh self-narration line, or null once the stream has been quiet. */
|
|
1156
|
+
private freshNarration(nowMs: number): string | null {
|
|
1157
|
+
if (this.narratedText === null) return null
|
|
1158
|
+
if (nowMs - this.lastChunkAt > NARRATE_GRACE_MS) return null
|
|
1159
|
+
return this.narratedText
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
private primaryTool(): ActiveTool | undefined {
|
|
1163
|
+
let primary: ActiveTool | undefined
|
|
1164
|
+
for (const tool of this.activeTools.values()) {
|
|
1165
|
+
if (primary === undefined || tool.startedAt < primary.startedAt) primary = tool
|
|
1166
|
+
}
|
|
1167
|
+
return primary
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
private turnElapsedMs(nowMs: number): number {
|
|
1171
|
+
return this.turnStartedAt === 0 ? 0 : Math.max(0, nowMs - this.turnStartedAt)
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/** Drop the current stall, whatever it was. */
|
|
1175
|
+
private clearWaitingReason(): void {
|
|
1176
|
+
this.waitingReason = undefined
|
|
1177
|
+
this.waitingReasonAt = 0
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Copy for the current stall, or null when the turn is not stalled.
|
|
1182
|
+
*
|
|
1183
|
+
* Deterministic per stall — seeded by the turn and the stall's start, so
|
|
1184
|
+
* every read of one stall shows the same line (a per-read re-roll is the
|
|
1185
|
+
* flicker bug the slot scheme exists to prevent).
|
|
1186
|
+
*/
|
|
1187
|
+
private stallPhrase(): string | null {
|
|
1188
|
+
if (this.waitingReason === undefined) return null
|
|
1189
|
+
return waitingReasonPhrase(this.waitingReason, {
|
|
1190
|
+
seed: this.turnStartedAt + this.waitingReasonAt,
|
|
1191
|
+
slot: 0,
|
|
1192
|
+
})
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
/**
|
|
1196
|
+
* How the current line is derived — the debug trace behind the optional
|
|
1197
|
+
* `debugLog`, so "why did it say THAT" is answerable from a file instead of
|
|
1198
|
+
* from memory.
|
|
1199
|
+
* @param nowMs - Wall-clock instant to describe.
|
|
1200
|
+
* @returns the derivation inputs of the current render.
|
|
1201
|
+
*/
|
|
1202
|
+
describe(nowMs: number = this.now()): Record<string, unknown> {
|
|
1203
|
+
const rotateMs = this.rarePool() ? RARE_ROTATE_MS : PHRASE_ROTATE_MS
|
|
1204
|
+
return {
|
|
1205
|
+
phase: this.phase,
|
|
1206
|
+
phraseSlot: this.phraseSlot(nowMs, rotateMs),
|
|
1207
|
+
rotateMs,
|
|
1208
|
+
rarePool: this.rarePool(),
|
|
1209
|
+
thinkingPhases: this.thinkingPhases,
|
|
1210
|
+
waitingReason: this.waitingReason ?? null,
|
|
1211
|
+
pendingPhrase: this.pendingPhrase ?? null,
|
|
1212
|
+
narration: this.narratedText ?? null,
|
|
1213
|
+
toolCount: this.toolCount,
|
|
1214
|
+
turnElapsedMs: this.turnElapsedMs(nowMs),
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
private setPhase(phase: ActivityPhase, atMs: number): void {
|
|
1219
|
+
// A phase change switches copy pools at once — the phrase is derived from
|
|
1220
|
+
// the CURRENT phase, so nothing from the previous phase can linger.
|
|
1221
|
+
if (phase === 'thinking' && this.phase !== 'thinking') this.thinkingPhases += 1
|
|
1222
|
+
this.phase = phase
|
|
1223
|
+
this.phaseStartedAt = atMs
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
/**
|
|
1227
|
+
* The instant the current phrase's rotation window starts from.
|
|
1228
|
+
*
|
|
1229
|
+
* The phase's own start, so entering a phase immediately shows that phase's
|
|
1230
|
+
* copy; a phase still needs a turn to belong to, hence the fallback.
|
|
1231
|
+
*/
|
|
1232
|
+
private phraseAnchorAt(): number {
|
|
1233
|
+
return this.phaseStartedAt > 0 ? this.phaseStartedAt : this.turnStartedAt
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
/** The rotation window index of the current phase at `nowMs`. */
|
|
1237
|
+
private phraseSlot(nowMs: number, rotateMs: number): number {
|
|
1238
|
+
return Math.max(0, Math.floor((nowMs - this.phraseAnchorAt()) / rotateMs))
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* Whether this phase draws from the rare pool.
|
|
1243
|
+
*
|
|
1244
|
+
* Once per turn, in the turn's FIRST thinking phase, decided by the seed — a
|
|
1245
|
+
* per-read dice roll would pop an egg in and out of the line (the egg's own
|
|
1246
|
+
* display window then lasts for the whole phase).
|
|
1247
|
+
*/
|
|
1248
|
+
private rarePool(): boolean {
|
|
1249
|
+
const features = this.config.features ?? {}
|
|
1250
|
+
if (features.rareEggs === false) return false
|
|
1251
|
+
if (this.phase !== 'thinking' || this.thinkingPhases !== 1) return false
|
|
1252
|
+
return mixSlot(this.turnStartedAt, 0x5EED) % Math.round(1 / RARE_CHANCE) === 0
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* The phrase for one rotation window — a PURE function of the state and `nowMs`.
|
|
1257
|
+
*
|
|
1258
|
+
* This used to be stateful (`previousPhrase` + `phraseChangedAt` mutated on
|
|
1259
|
+
* render). That works for a long-lived in-process tracker, but a projected
|
|
1260
|
+
* value is read far more often than it is written: the read renders a
|
|
1261
|
+
* throwaway copy, so every read rolled a new phrase (measured: three different
|
|
1262
|
+
* phrases in three consecutive 500 ms reads) and a phase change could carry the
|
|
1263
|
+
* previous phase's pool in. Deriving from (phase, phase start, seed, slot)
|
|
1264
|
+
* makes a read idempotent and keeps the pools apart by construction.
|
|
1265
|
+
*/
|
|
1266
|
+
private phraseForSlot(slot: number, rotateMs: number, nowMs: number): string {
|
|
1267
|
+
const at: PhraseSlot = { seed: this.turnStartedAt, slot }
|
|
1268
|
+
const features = this.config.features ?? {}
|
|
1269
|
+
// The RENDER instant, not the tracker's clock supplier: one render, one
|
|
1270
|
+
// time source. Night/holiday copy used to read `this.now()` while the
|
|
1271
|
+
// elapsed read `nowMs`, so rendering "as of" another instant (a test, a
|
|
1272
|
+
// historical value) picked copy from a different moment than it displayed.
|
|
1273
|
+
const now = new Date(nowMs)
|
|
1274
|
+
if (this.phase === 'waiting') return waitingPhrase(undefined, at)
|
|
1275
|
+
// Eggs belong to the turn's first thinking window — the waiting phase is
|
|
1276
|
+
// usually over before a window elapses, so a greeting shown there would
|
|
1277
|
+
// flash by. Order matches the pi extension: holiday → rare → weekend, and
|
|
1278
|
+
// "first thinking phase, first window" is what makes them once per turn.
|
|
1279
|
+
if (this.thinkingPhases === 1 && slot === 0) {
|
|
1280
|
+
if (features.holidays !== false) {
|
|
1281
|
+
const holiday = holidayPhrase(now, at)
|
|
1282
|
+
if (holiday !== null) return holiday
|
|
1283
|
+
}
|
|
1284
|
+
if (this.rarePool()) return rarePhrase(undefined, at)
|
|
1285
|
+
if (features.weekend !== false && isWeekend(now)) return weekendPhrase(undefined, at)
|
|
1286
|
+
}
|
|
1287
|
+
if (this.rarePool()) return rarePhrase(undefined, at)
|
|
1288
|
+
// The long-thinking tiers are chosen at the WINDOW's start, not at the
|
|
1289
|
+
// instant of the read: a tier boundary crossed mid-window would otherwise
|
|
1290
|
+
// swap the copy seconds into a window the reader is still on.
|
|
1291
|
+
const windowStart = this.phraseAnchorAt() + slot * rotateMs
|
|
1292
|
+
const thinkingAtWindowStart = Math.max(0, windowStart - this.thinkingStartedAt)
|
|
1293
|
+
return thinkingPhrase(
|
|
1294
|
+
this.thinkingStartedAt === 0 ? this.thinkingMs : thinkingAtWindowStart,
|
|
1295
|
+
undefined,
|
|
1296
|
+
features.nightPhrases !== false && isNight(now.getHours()),
|
|
1297
|
+
this.config.customPhrases,
|
|
1298
|
+
at,
|
|
1299
|
+
)
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
/** Earliest of the candidate wake instants, ignoring the absent ones. */
|
|
1304
|
+
function minWake(...candidates: readonly (number | undefined)[]): number | undefined {
|
|
1305
|
+
let earliest: number | undefined
|
|
1306
|
+
for (const candidate of candidates) {
|
|
1307
|
+
if (candidate === undefined) continue
|
|
1308
|
+
if (earliest === undefined || candidate < earliest) earliest = candidate
|
|
1309
|
+
}
|
|
1310
|
+
return earliest
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
* The next whole second after `nowMs`, counted from `from`. The line renders
|
|
1315
|
+
* elapsed time with second resolution, so this is the finest cadence a live
|
|
1316
|
+
* phase can actually show.
|
|
1317
|
+
* @param from - Instant the displayed counter counts from.
|
|
1318
|
+
* @param nowMs - Current instant.
|
|
1319
|
+
*/
|
|
1320
|
+
function secondBoundary(from: number, nowMs: number): number {
|
|
1321
|
+
const elapsed = Math.max(0, nowMs - from)
|
|
1322
|
+
return from + (Math.floor(elapsed / 1000) + 1) * 1000
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* How long one phrase stays on screen.
|
|
1327
|
+
*
|
|
1328
|
+
* This is the pi extension's cadence, unchanged: the copy was never rotating
|
|
1329
|
+
* too fast — it was being re-rolled on every read (see phraseForSlot), which is
|
|
1330
|
+
* what read as flicker. With the read made pure, one phrase per window is
|
|
1331
|
+
* exactly what a reader sees, and 4 s is the pace that felt right.
|
|
1332
|
+
*/
|
|
1333
|
+
const PHRASE_ROTATE_MS = 4000
|
|
1334
|
+
/** Rare easter-egg phrases linger longer, since they are a one-off per turn. */
|
|
1335
|
+
const RARE_ROTATE_MS = 7500
|
|
1336
|
+
/** One-off quips (interrupt / model / compact) display window. */
|
|
1337
|
+
const PENDING_MS = 6000
|
|
1338
|
+
/** How long the thinking→doing opening line rides the turn's first tool. */
|
|
1339
|
+
const TOOL_OPENING_MS = 2500
|
|
1340
|
+
/**
|
|
1341
|
+
* How long a settled tool keeps its own line before the copy returns to phrases.
|
|
1342
|
+
*
|
|
1343
|
+
* Real-session measurement: median tool 87 ms, 73% under 500 ms — shorter than a
|
|
1344
|
+
* single client re-read, so without a linger the tool line is unreadable.
|
|
1345
|
+
*/
|
|
1346
|
+
const TOOL_LINGER_MS = 2500
|
|
1347
|
+
/** Tools closer than this count as one combo streak. */
|
|
1348
|
+
const COMBO_GAP_MS = 10_000
|
|
1349
|
+
/** Streak at which the combo badge shows. */
|
|
1350
|
+
const COMBO_SHOW_AT = 2
|
|
1351
|
+
/** The tps estimate stays fresh this long after the last chunk. */
|
|
1352
|
+
const TPS_WINDOW_MS = 3500
|
|
1353
|
+
/** Cap on replayed done cards; older entries drop. */
|
|
1354
|
+
const DONE_QUEUE_MAX = 6
|
|
1355
|
+
/** Show the last tool's fragment in the done line for this long after it ends. */
|
|
1356
|
+
const DONE_FRAGMENT_MS = 3000
|
|
1357
|
+
/** Rolling stream buffer size for `⏵` narration extraction. */
|
|
1358
|
+
const STREAM_BUFFER_CHARS = 300
|
|
1359
|
+
/** A narration stays visible this long after the stream went quiet. */
|
|
1360
|
+
const NARRATE_GRACE_MS = 5000
|
|
1361
|
+
|
|
1362
|
+
/** Narration budget in display columns: 40 CJK chars ≈ 12 English words. */
|
|
1363
|
+
const NARRATION_MAX_COLUMNS = 80
|
|
1364
|
+
|
|
1365
|
+
/** A CJK/full-width code point renders 2 terminal columns; the rest render 1. */
|
|
1366
|
+
function isWide(cp: number): boolean {
|
|
1367
|
+
return (
|
|
1368
|
+
(cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo
|
|
1369
|
+
(cp >= 0x2e80 && cp <= 0xa4cf) || // CJK radicals, kana, Yi
|
|
1370
|
+
(cp >= 0xac00 && cp <= 0xd7a3) || // Hangul syllables
|
|
1371
|
+
(cp >= 0xf900 && cp <= 0xfaff) || // CJK compatibility ideographs
|
|
1372
|
+
(cp >= 0xfe30 && cp <= 0xfe4f) || // CJK compatibility forms
|
|
1373
|
+
(cp >= 0xff00 && cp <= 0xff60) || // full-width forms
|
|
1374
|
+
(cp >= 0xffe0 && cp <= 0xffe6) || // full-width signs
|
|
1375
|
+
(cp >= 0x20000 && cp <= 0x3fffd) // CJK extensions
|
|
1376
|
+
// Emoji occupy two columns in every mainstream terminal; counting them as
|
|
1377
|
+
// one let an "80-column" narration run ~40 columns over budget (the pools
|
|
1378
|
+
// carry 🧧 🐳 🎃).
|
|
1379
|
+
|| (cp >= 0x1f000 && cp <= 0x1faff) // cards, emoji, symbols, pictographs
|
|
1380
|
+
)
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
/** Cut before `max` columns, backing off to the last word or clause boundary. */
|
|
1384
|
+
function cutToWidth(text: string, max: number): string {
|
|
1385
|
+
let width = 0
|
|
1386
|
+
let cut = text.length
|
|
1387
|
+
const chars = [...text]
|
|
1388
|
+
for (let i = 0; i < chars.length; i++) {
|
|
1389
|
+
const w = isWide(chars[i]!.codePointAt(0)!) ? 2 : 1
|
|
1390
|
+
if (width + w > max) {
|
|
1391
|
+
cut = chars.slice(0, i).join('').length
|
|
1392
|
+
break
|
|
1393
|
+
}
|
|
1394
|
+
width += w
|
|
1395
|
+
}
|
|
1396
|
+
if (cut === text.length) return text
|
|
1397
|
+
// Back off to a soft boundary so English words survive intact; dense CJK has
|
|
1398
|
+
// none and hard-cuts at the budget like the original fixed 40-char capture.
|
|
1399
|
+
const head = text.slice(0, cut)
|
|
1400
|
+
const soft = Math.max(
|
|
1401
|
+
head.lastIndexOf(' '),
|
|
1402
|
+
head.lastIndexOf('\t'),
|
|
1403
|
+
head.lastIndexOf(','),
|
|
1404
|
+
head.lastIndexOf('、'),
|
|
1405
|
+
head.lastIndexOf(';'),
|
|
1406
|
+
head.lastIndexOf(';'),
|
|
1407
|
+
head.lastIndexOf(','),
|
|
1408
|
+
)
|
|
1409
|
+
return soft > 0 ? head.slice(0, soft) : head
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
/**
|
|
1413
|
+
* Extract the latest `⏵` self-narration line from a stream buffer.
|
|
1414
|
+
*
|
|
1415
|
+
* The marker has to START a line. The injected contract asks for one standalone
|
|
1416
|
+
* line, so a `⏵` inside a sentence is the model *mentioning* the format rather
|
|
1417
|
+
* than narrating with it — measured on a live session, where the line quoted a
|
|
1418
|
+
* fragment out of the middle of the model's own prose.
|
|
1419
|
+
*
|
|
1420
|
+
* The text is model output destined for a terminal, so it is flattened here:
|
|
1421
|
+
* an ESC or a newline carried by a delta must not reach the screen (see
|
|
1422
|
+
* {@link sanitizeFragment}).
|
|
1423
|
+
* @param buffer - Rolling window of the visible streamed text.
|
|
1424
|
+
* @returns the narration, or null when the buffer carries none.
|
|
1425
|
+
*/
|
|
1426
|
+
export function extractNarration(buffer: string): string | null {
|
|
1427
|
+
const matches = [...buffer.matchAll(/(?:^|\n)⏵[ \t]*([^\n⏵]*)/g)]
|
|
1428
|
+
const matched = matches[matches.length - 1]?.[1]
|
|
1429
|
+
if (matched === undefined) return null
|
|
1430
|
+
const latest = sanitizeFragment(matched)
|
|
1431
|
+
if (!latest) return null
|
|
1432
|
+
|
|
1433
|
+
// A missing newline must not turn the rest of the response into status text.
|
|
1434
|
+
// Stop at sentence ends and clause delimiters, while leaving dotted
|
|
1435
|
+
// identifiers such as `ink.tsx`, `agent.ctx` and `README.MD` intact. A dot
|
|
1436
|
+
// ends a sentence only before whitespace, the end, or a Title-case word
|
|
1437
|
+
// (`safely.The`); dot-uppercase-uppercase stays an extension (`.MD`).
|
|
1438
|
+
const boundary = latest.search(/[。.!?!?;;]|\.(?=\s|$|[A-Z][a-z])/)
|
|
1439
|
+
const sentence = boundary < 0 ? latest : latest.slice(0, boundary + 1)
|
|
1440
|
+
|
|
1441
|
+
// The budget is display width, so English and Chinese render equally long:
|
|
1442
|
+
// 40 CJK characters and ~12 English words share the same line budget.
|
|
1443
|
+
const text = cutToWidth(sentence, NARRATION_MAX_COLUMNS).replace(/[。..!!,,、;;]+$/, '').trim()
|
|
1444
|
+
return text.length === 0 ? null : text
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
/** Format a token count compactly (`12.3k`, `1.2M`). */
|
|
1448
|
+
function fmtTokens(tokens: number): string {
|
|
1449
|
+
if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`
|
|
1450
|
+
if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}k`
|
|
1451
|
+
return String(tokens)
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
/** Coarse streaming token estimate (pi parity: CJK ×1.5, others ÷4). */
|
|
1455
|
+
function estimateTokens(text: string): number {
|
|
1456
|
+
const compact = text.replace(/\s/g, '')
|
|
1457
|
+
if (compact.length === 0) return 0
|
|
1458
|
+
const cjkCount = (compact.match(/[\u3400-\u9fff]/g) ?? []).length
|
|
1459
|
+
return Math.max(1, Math.ceil(cjkCount * 1.5 + (compact.length - cjkCount) / 4))
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/** Parse a tool call's raw arguments JSON defensively. */
|
|
1463
|
+
function parseArguments(raw: string): Readonly<Record<string, unknown>> | undefined {
|
|
1464
|
+
if (raw.trim().length === 0) return undefined
|
|
1465
|
+
try {
|
|
1466
|
+
const parsed: unknown = JSON.parse(raw)
|
|
1467
|
+
if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
1468
|
+
return parsed as Readonly<Record<string, unknown>>
|
|
1469
|
+
}
|
|
1470
|
+
return undefined
|
|
1471
|
+
} catch {
|
|
1472
|
+
return undefined
|
|
1473
|
+
}
|
|
1474
|
+
}
|