@dd-flow/client 0.2.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 ADDED
@@ -0,0 +1,4 @@
1
+ Sustainable Use License (fair-code)
2
+
3
+ This project is licensed under the Sustainable Use License (fair-code).
4
+ See the upstream license text and terms as defined by the project owner.
package/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # @dd-flow/client
2
+
3
+ Typed HTTP/SSE client for `dd-flow-server`.
4
+
@@ -0,0 +1 @@
1
+ {"fileNames":["../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.esnext.float16.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../dd-flow-common/dist/runtime/constants.d.ts","../../dd-flow-common/dist/runtime/params.d.ts","../../dd-flow-common/dist/types/ledger.d.ts","../../dd-flow-common/dist/types/identity.d.ts","../../dd-flow-common/dist/types/runs.d.ts","../../dd-flow-common/dist/types/ui.d.ts","../../dd-flow-common/dist/types/api.d.ts","../../dd-flow-common/dist/types/commands.d.ts","../../dd-flow-common/dist/types/entities.d.ts","../../dd-flow-common/dist/types/planProgress.d.ts","../../dd-flow-common/dist/types/viewState.d.ts","../../dd-flow-common/dist/types/view.d.ts","../../dd-flow-common/dist/index.d.ts","../src/planProgress.ts","../src/index.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/compatibility/iterators.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/globals.typedarray.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/buffer.buffer.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/globals.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/abortcontroller.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/crypto.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/domexception.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/events.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/utility.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/header.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/readable.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/fetch.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/formdata.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/connector.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/client-stats.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/errors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/dispatcher.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/global-dispatcher.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/global-origin.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/pool-stats.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/handlers.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/balanced-pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/h2c-client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-interceptor.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-call-history.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-client.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-pool.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/snapshot-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/mock-errors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/proxy-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/env-http-proxy-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/retry-handler.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/retry-agent.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/api.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cache-interceptor.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/interceptors.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/util.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cookies.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/patch.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/websocket.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/eventsource.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/diagnostics-channel.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/content-type.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/cache.d.ts","../../../node_modules/.pnpm/undici-types@7.16.0/node_modules/undici-types/index.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/fetch.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/navigator.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/storage.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/web-globals/streams.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/assert.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/assert/strict.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/async_hooks.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/buffer.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/child_process.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/cluster.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/console.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/constants.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/crypto.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/dgram.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/dns.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/dns/promises.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/domain.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/events.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/fs.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/fs/promises.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/http.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/http2.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/https.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/inspector.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/inspector.generated.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/module.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/net.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/os.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/path.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/process.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/punycode.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/querystring.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/readline.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/readline/promises.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/repl.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/sea.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/sqlite.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/stream.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/stream/promises.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/stream/web.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/string_decoder.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/test.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/timers.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/timers/promises.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/tls.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/trace_events.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/tty.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/url.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/util.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/v8.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/vm.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/wasi.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/worker_threads.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/zlib.d.ts","../../../node_modules/.pnpm/@types+node@24.10.9/node_modules/@types/node/index.d.ts"],"fileIdsList":[[77,128,129,131,148,149],[77,130,131,148,149],[131,148,149],[77,131,136,148,149,166],[77,131,132,137,142,148,149,151,163,174],[77,131,132,133,142,148,149,151],[77,131,148,149],[77,131,134,148,149,175],[77,131,135,136,143,148,149,152],[77,131,136,148,149,163,171],[77,131,137,139,142,148,149,151],[77,130,131,138,148,149],[77,131,139,140,148,149],[77,131,141,142,148,149],[77,130,131,142,148,149],[77,131,142,143,144,148,149,163,174],[77,131,142,143,144,148,149,158,163,166],[77,123,131,139,142,145,148,149,151,163,174],[77,131,142,143,145,146,148,149,151,163,171,174],[77,131,145,147,148,149,163,171,174],[75,76,77,78,79,80,81,82,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],[77,131,142,148,149],[77,131,148,149,150,174],[77,131,139,142,148,149,151,163],[77,131,148,149,152],[77,131,148,149,153],[77,130,131,148,149,154],[77,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180],[77,131,148,149,156],[77,131,148,149,157],[77,131,142,148,149,158,159],[77,131,148,149,158,160,175,177],[77,131,143,148,149],[77,131,142,148,149,163,164,166],[77,131,148,149,165,166],[77,131,148,149,163,164],[77,131,148,149,166],[77,131,148,149,167],[77,128,131,148,149,163,168],[77,131,142,148,149,169,170],[77,131,148,149,169,170],[77,131,136,148,149,151,163,171],[77,131,148,149,172],[77,131,148,149,151,173],[77,131,145,148,149,157,174],[77,131,136,148,149,175],[77,131,148,149,163,176],[77,131,148,149,150,177],[77,131,148,149,178],[77,131,136,148,149],[77,123,131,148,149],[77,131,148,149,179],[77,123,131,142,144,148,149,154,163,166,174,176,177,179],[77,131,148,149,163,180],[77,89,92,95,96,131,148,149,174],[77,92,131,148,149,163,174],[77,92,96,131,148,149,174],[77,131,148,149,163],[77,86,131,148,149],[77,90,131,148,149],[77,88,89,92,131,148,149,174],[77,131,148,149,151,171],[77,131,148,149,181],[77,86,131,148,149,181],[77,88,92,131,148,149,151,174],[77,83,84,85,87,91,131,142,148,149,163,174],[77,92,100,108,131,148,149],[77,84,90,131,148,149],[77,92,117,118,131,148,149],[77,84,87,92,131,148,149,166,174,181],[77,92,131,148,149],[77,88,92,131,148,149,174],[77,83,131,148,149],[77,86,87,88,90,91,92,93,94,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,118,119,120,121,122,131,148,149],[77,92,110,113,131,139,148,149],[77,92,100,101,102,131,148,149],[77,90,92,101,103,131,148,149],[77,91,131,148,149],[77,84,86,92,131,148,149],[77,92,96,101,103,131,148,149],[77,96,131,148,149],[77,90,92,95,131,148,149,174],[77,84,88,92,100,131,148,149],[77,92,110,131,148,149],[77,103,131,148,149],[77,86,92,117,131,148,149,166,179,181],[72,73,77,131,136,148,149],[72,77,131,148,149],[60,61,62,63,64,65,66,67,68,69,70,71,77,131,148,149],[62,63,64,65,77,131,148,149],[64,77,131,148,149],[64,69,77,131,148,149]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"65a66066235187ce585b13478cbfb98ce93dd56d37bd4d15348b33aed62f1faa","impliedFormat":99},{"version":"5357512bc21e9257fac84ff6f6bfae856e2b5c4612929c0432cdacfba14604b8","impliedFormat":99},{"version":"ea61fad7d3768925779059b3c41f9ddc4c00ea2c6f74e5cb3f4dc30daf06ed46","impliedFormat":99},{"version":"c62b669477c448a2205225d5bb0da20eb634c3ab703c3c84b860321ef0375420","impliedFormat":99},{"version":"14a64205d915224fad0373ab74174198e86d524261e0db2f1fa9c9f889698d77","impliedFormat":99},{"version":"dfcbb0ce9ca326e73ece49af65d11c48cc5c47a1fd4ce30fc0e7143f5f748ee9","impliedFormat":99},{"version":"6309019bb3904adc8d19a1dc33eb824a1adc71838ced27eec7140ee5fb27c627","impliedFormat":99},{"version":"6dd4c01d21599aadb6cae55e13fbb91ed18fd1147ae48329b56504321c384f71","impliedFormat":99},{"version":"87563e76ef456d744c75a799bca4ddd59b76d7d6f36cc3251f4c78708d174f2e","impliedFormat":99},{"version":"1dd03d520b70efff3b95388cf627fe2d585d23266875cbaf148d7524e453f683","impliedFormat":99},{"version":"edbfd90ba2e1891e5beab1336c592e163394ebf342e8a074d5adb3cf2caa3201","impliedFormat":99},{"version":"df867567cfb2d3109056bd5abaa8a966f8a3fc0fd51870703a999133331f0366","impliedFormat":99},{"version":"c3f522e8eb12e817661f0ff041a4f44b8791ccc82c79d62411cdb3223aa3217d","impliedFormat":99},{"version":"580994b82ab1abcc6c2e71daa0aae5b9c11415046d9465a124576174a9fb407c","signature":"71d7a0c437427f2533f3f05021953cf6fd805fa6422ceff11c24e78ddf9d305c","impliedFormat":99},{"version":"4158bedd77b4def7c67e826e0691703f6e16cb2e72177250867c0307e0904c3d","signature":"373e93ef169b31cb5e86639789704a0e8b9e7d5d2d3f5de99aed6453002c6910","impliedFormat":99},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"378281aa35786c27d5811af7e6bcaa492eebd0c7013d48137c35bbc69a2b9751","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"1b2dd1cbeb0cc6ae20795958ba5950395ebb2849b7c8326853dd15530c77ab0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"387a023d363f755eb63450a66c28b14cdd7bc30a104565e2dbf0a8988bb4a56c","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","impliedFormat":1},{"version":"23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","impliedFormat":1},{"version":"487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","impliedFormat":1},{"version":"3a80bc85f38526ca3b08007ee80712e7bb0601df178b23fbf0bf87036fce40ce","impliedFormat":1},{"version":"ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"68834d631c8838c715f225509cfc3927913b9cc7a4870460b5b60c8dbdb99baf","impliedFormat":1},{"version":"2931540c47ee0ff8a62860e61782eb17b155615db61e36986e54645ec67f67c2","impliedFormat":1},{"version":"ccab02f3920fc75c01174c47fcf67882a11daf16baf9e81701d0a94636e94556","impliedFormat":1},{"version":"f6faf5f74e4c4cc309a6c6a6c4da02dbb840be5d3e92905a23dcd7b2b0bd1986","impliedFormat":1},{"version":"ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","impliedFormat":1},{"version":"36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","impliedFormat":1},{"version":"914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","impliedFormat":1},{"version":"33e981bf6376e939f99bd7f89abec757c64897d33c005036b9a10d9587d80187","impliedFormat":1},{"version":"7fd1b31fd35876b0aa650811c25ec2c97a3c6387e5473eb18004bed86cdd76b6","impliedFormat":1},{"version":"b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","impliedFormat":1},{"version":"3bacf516d686d08682751a3bd2519ea3b8041a164bfb4f1d35728993e70a2426","impliedFormat":1},{"version":"7fb266686238369442bd1719bc0d7edd0199da4fb8540354e1ff7f16669b4323","impliedFormat":1},{"version":"0a60a292b89ca7218b8616f78e5bbd1c96b87e048849469cccb4355e98af959a","impliedFormat":1},{"version":"0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","impliedFormat":1},{"version":"9666f2f84b985b62400d2e5ab0adae9ff44de9b2a34803c2c5bd3c8325b17dc0","impliedFormat":1},{"version":"40cd35c95e9cf22cfa5bd84e96408b6fcbca55295f4ff822390abb11afbc3dca","impliedFormat":1},{"version":"b1616b8959bf557feb16369c6124a97a0e74ed6f49d1df73bb4b9ddf68acf3f3","impliedFormat":1},{"version":"5b03a034c72146b61573aab280f295b015b9168470f2df05f6080a2122f9b4df","impliedFormat":1},{"version":"40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","impliedFormat":1},{"version":"249b9cab7f5d628b71308c7d9bb0a808b50b091e640ba3ed6e2d0516f4a8d91d","impliedFormat":1},{"version":"80aae6afc67faa5ac0b32b5b8bc8cc9f7fa299cff15cf09cc2e11fd28c6ae29e","impliedFormat":1},{"version":"f473cd2288991ff3221165dcf73cd5d24da30391f87e85b3dd4d0450c787a391","impliedFormat":1},{"version":"499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","impliedFormat":1},{"version":"54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","impliedFormat":1},{"version":"beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","impliedFormat":1},{"version":"c183b931b68ad184bc8e8372bf663f3d33304772fb482f29fb91b3c391031f3e","impliedFormat":1},{"version":"5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","impliedFormat":1},{"version":"59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","impliedFormat":1},{"version":"addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","impliedFormat":1},{"version":"48cc3ec153b50985fb95153258a710782b25975b10dd4ac8a4f3920632d10790","impliedFormat":1},{"version":"adf27937dba6af9f08a68c5b1d3fce0ca7d4b960c57e6d6c844e7d1a8e53adae","impliedFormat":1},{"version":"e1528ca65ac90f6fa0e4a247eb656b4263c470bb22d9033e466463e13395e599","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"866078923a56d026e39243b4392e282c1c63159723996fa89243140e1388a98d","impliedFormat":1},{"version":"830171b27c5fdf9bcbe4cf7d428fcf3ae2c67780fb7fbdccdf70d1623d938bc4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1cf059eaf468efcc649f8cf6075d3cb98e9a35a0fe9c44419ec3d2f5428d7123","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ea15fd99b2e34cb25fe8346c955000bb70c8b423ae4377a972ef46bfb37f595","impliedFormat":1},{"version":"7cf69dd5502c41644c9e5106210b5da7144800670cbe861f66726fa209e231c4","impliedFormat":1},{"version":"72c1f5e0a28e473026074817561d1bc9647909cf253c8d56c41d1df8d95b85f7","impliedFormat":1},{"version":"f9b4137a0d285bd77dba2e6e895530112264310ae47e07bf311feae428fb8b61","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b21e13ed07d0df176ae31d6b7f01f7b17d66dbeb489c0d31d00de2ca14883da","impliedFormat":1},{"version":"51aecd2df90a3cffea1eb4696b33b2d78594ea2aa2138e6b9471ec4841c6c2ee","impliedFormat":1},{"version":"9d8f9e63e29a3396285620908e7f14d874d066caea747dc4b2c378f0599166b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"f929f0b6b3421a2d34344b0f421f45aeb2c84ad365ebf29d04312023b3accc58","impliedFormat":1},{"version":"db9ada976f9e52e13f7ae8b9a320f4b67b87685938c5879187d8864b2fbe97f3","impliedFormat":1},{"version":"9f39e70a354d0fba29ac3cdf6eca00b7f9e96f64b2b2780c432e8ea27f133743","impliedFormat":1},{"version":"0dace96cc0f7bc6d0ee2044921bdf19fe42d16284dbcc8ae200800d1c9579335","impliedFormat":1},{"version":"a2e2bbde231b65c53c764c12313897ffdfb6c49183dd31823ee2405f2f7b5378","impliedFormat":1},{"version":"ad1cc0ed328f3f708771272021be61ab146b32ecf2b78f3224959ff1e2cd2a5c","impliedFormat":1},{"version":"c64e1888baaa3253ca4405b455e4bf44f76357868a1bd0a52998ade9a092ad78","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc8c6f5322961b56d9906601b20798725df60baeab45ec014fba9f795d5596fd","impliedFormat":1},{"version":"0904660ae854e6d41f6ff25356db1d654436c6305b0f0aa89d1532df0253486e","impliedFormat":1},{"version":"148c73ec11318850f571172ceae3e55ce479d850fe18ec8eae0abd99d9f6c319","impliedFormat":1},{"version":"230bdc111d7578276e4a3bb9d075d85c78c6b68f428c3a9935e2eaa10f4ae1f5","impliedFormat":1},{"version":"e8aabbee5e7b9101b03bb4222607d57f38859b8115a8050a4eb91b4ee43a3a73","impliedFormat":1},{"version":"bbf42f98a5819f4f06e18c8b669a994afe9a17fe520ae3454a195e6eabf7700d","impliedFormat":1},{"version":"c0bb1b65757c72bbf8ddf7eaa532223bacf58041ff16c883e76f45506596e925","impliedFormat":1},{"version":"c8b85f7aed29f8f52b813f800611406b0bfe5cf3224d20a4bdda7c7f73ce368e","affectsGlobalScope":true,"impliedFormat":1},{"version":"145dcf25fd4967c610c53d93d7bc4dce8fbb1b6dd7935362472d4ae49363c7ba","impliedFormat":1},{"version":"ff65b8a8bd380c6d129becc35de02f7c29ad7ce03300331ca91311fb4044d1a9","impliedFormat":1},{"version":"04bf1aa481d1adfb16d93d76e44ce71c51c8ef68039d849926551199489637f6","impliedFormat":1},{"version":"9043daec15206650fa119bad6b8d70136021ea7d52673a71f79a87a42ee38d44","affectsGlobalScope":true,"impliedFormat":1},{"version":"d00e86e2e74089bf416b4c5cc433d88eb2e09dcef5e3c5b79ca04a36d8d8d6f5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a58a15da4c5ba3df60c910a043281256fa52d36a0fcdef9b9100c646282e88dd","impliedFormat":1},{"version":"b36beffbf8acdc3ebc58c8bb4b75574b31a2169869c70fc03f82895b93950a12","impliedFormat":1},{"version":"de263f0089aefbfd73c89562fb7254a7468b1f33b61839aafc3f035d60766cb4","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"8c81fd4a110490c43d7c578e8c6f69b3af01717189196899a6a44f93daa57a3a","impliedFormat":1},{"version":"5fb39858b2459864b139950a09adae4f38dad87c25bf572ce414f10e4bd7baab","impliedFormat":1},{"version":"65faec1b4bd63564aeec33eab9cacfaefd84ce2400f03903a71a1841fbce195f","impliedFormat":1},{"version":"b33b74b97952d9bf4fbd2951dcfbb5136656ddb310ce1c84518aaa77dbca9992","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b306cd4282bbb54d4a6bb23cfb7a271160983dfc38c67b5a132504cfcc34896","affectsGlobalScope":true,"impliedFormat":1},{"version":"c119835edf36415081dfd9ed15fc0cd37aaa28d232be029ad073f15f3d88c323","impliedFormat":1},{"version":"450172a56b944c2d83f45cc11c9a388ea967cd301a21202aa0a23c34c7506a18","impliedFormat":1},{"version":"9705cd157ffbb91c5cab48bdd2de5a437a372e63f870f8a8472e72ff634d47c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ae86f30d5d10e4f75ce8dcb6e1bd3a12ecec3d071a21e8f462c5c85c678efb41","impliedFormat":1},{"version":"a1a3cbade20430dcb7f00fa23c2f020e827d5620c0d44213db1665c53231f1fc","impliedFormat":1},{"version":"e03460fe72b259f6d25ad029f085e4bedc3f90477da4401d8fbc1efa9793230e","impliedFormat":1},{"version":"4286a3a6619514fca656089aee160bb6f2e77f4dd53dc5a96b26a0b4fc778055","impliedFormat":1},{"version":"69e0a41d620fb678a899c65e073413b452f4db321b858fe422ad93fd686cd49a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3585d6891e9ea18e07d0755a6d90d71331558ba5dc5561933553209f886db106","affectsGlobalScope":true,"impliedFormat":1},{"version":"86be71cbb0593468644932a6eb96d527cfa600cecfc0b698af5f52e51804451d","impliedFormat":1},{"version":"84dd6b0fd2505135692935599d6606f50a421389e8d4535194bcded307ee5cf2","impliedFormat":1},{"version":"0d5b085f36e6dc55bc6332ecb9c733be3a534958c238fb8d8d18d4a2b6f2a15a","impliedFormat":1},{"version":"db19ea066fdc5f97df3f769e582ae3000380ab7942e266654bdb1a4650d19eaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"2a034894bf28c220a331c7a0229d33564803abe2ac1b9a5feee91b6b9b6e88ea","impliedFormat":1},{"version":"d7e9ab1b0996639047c61c1e62f85c620e4382206b3abb430d9a21fb7bc23c77","impliedFormat":1}],"root":[73,74],"options":{"allowSyntheticDefaultImports":true,"declaration":true,"esModuleInterop":true,"module":100,"outDir":"./","skipLibCheck":true,"strict":true,"target":9,"tsBuildInfoFile":"./dd-flow-client.tsbuildinfo"},"referencedMap":[[128,1],[129,1],[130,2],[77,3],[131,4],[132,5],[133,6],[75,7],[134,8],[135,9],[136,10],[137,11],[138,12],[139,13],[140,13],[141,14],[142,15],[143,16],[144,17],[78,7],[76,7],[145,18],[146,19],[147,20],[181,21],[148,22],[149,7],[150,23],[151,24],[152,25],[153,26],[154,27],[155,28],[156,29],[157,30],[158,31],[159,31],[160,32],[161,7],[162,33],[163,34],[165,35],[164,36],[166,37],[167,38],[168,39],[169,40],[170,41],[171,42],[172,43],[173,44],[174,45],[175,46],[176,47],[177,48],[178,49],[79,7],[80,50],[81,7],[82,7],[124,51],[125,52],[126,7],[127,37],[179,53],[180,54],[58,7],[59,7],[11,7],[10,7],[2,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7],[19,7],[3,7],[20,7],[21,7],[4,7],[22,7],[26,7],[23,7],[24,7],[25,7],[27,7],[28,7],[29,7],[5,7],[30,7],[31,7],[32,7],[33,7],[6,7],[37,7],[34,7],[35,7],[36,7],[38,7],[7,7],[39,7],[44,7],[45,7],[40,7],[41,7],[42,7],[43,7],[8,7],[49,7],[46,7],[47,7],[48,7],[50,7],[9,7],[51,7],[52,7],[53,7],[55,7],[54,7],[1,7],[56,7],[57,7],[100,55],[112,56],[98,57],[113,58],[122,59],[89,60],[90,61],[88,62],[121,63],[116,64],[120,65],[92,66],[109,67],[91,68],[119,69],[86,70],[87,64],[93,71],[94,7],[99,72],[97,71],[84,73],[123,74],[114,75],[103,76],[102,71],[104,77],[107,78],[101,79],[105,80],[117,63],[95,81],[96,82],[108,83],[85,58],[111,84],[110,71],[106,85],[115,7],[83,7],[118,86],[74,87],[73,88],[72,89],[60,7],[61,7],[66,90],[67,7],[68,91],[63,7],[62,7],[69,7],[64,7],[65,7],[71,92],[70,91]],"version":"5.9.3"}
@@ -0,0 +1,252 @@
1
+ import type { DdFlowProjectEventsEnvelopeV1, DdFlowSseTopicV1, ProjectV1, RunFileIdV1, RunFileV1, RunV1, RunViewStateV1, RunViewV1 } from "@dd-flow/common";
2
+ export { formatPlanProgressMarkdownV1 } from "./planProgress.js";
3
+ type JsonOk = {
4
+ ok: true;
5
+ };
6
+ export type CreateRunRequestV1 = {
7
+ flowId: "context";
8
+ projectRoot: string;
9
+ engine?: {
10
+ checksMode?: "sync" | "async";
11
+ verifyMode?: "sync" | "async";
12
+ };
13
+ } | {
14
+ flowId: "mini";
15
+ projectRoot: string;
16
+ params: {
17
+ mainSessionId: string;
18
+ planMode?: "review" | "auto";
19
+ profileId?: string;
20
+ allowPush?: boolean;
21
+ };
22
+ engine?: {
23
+ checksMode?: "sync" | "async";
24
+ verifyMode?: "sync" | "async";
25
+ };
26
+ };
27
+ export type GetRunResponseV1 = {
28
+ ok: true;
29
+ run: RunV1;
30
+ state: unknown;
31
+ };
32
+ export type GetRunViewResponseV1 = {
33
+ ok: true;
34
+ view: RunViewV1;
35
+ };
36
+ export type GetRunViewStateResponseV1 = {
37
+ ok: true;
38
+ state: RunViewStateV1 | null;
39
+ };
40
+ export type ListProjectsResponseV1 = {
41
+ ok: true;
42
+ projects: ProjectV1[];
43
+ };
44
+ export type RegisterProjectResponseV1 = {
45
+ ok: true;
46
+ project: ProjectV1;
47
+ };
48
+ export type ListRunsResponseV1 = {
49
+ ok: true;
50
+ runs: RunV1[];
51
+ };
52
+ export type CreateRunResponseV1 = {
53
+ ok: true;
54
+ run: RunV1;
55
+ };
56
+ export type GetRunFileResponseV1 = {
57
+ ok: true;
58
+ file: RunFileV1;
59
+ };
60
+ export type RunUserActionRequestV1 = {
61
+ runId: string;
62
+ actionId: string;
63
+ target?: {
64
+ processId?: string;
65
+ nodeId?: string;
66
+ };
67
+ formData?: Record<string, unknown>;
68
+ actor?: {
69
+ clientId: string;
70
+ connectionId?: string;
71
+ };
72
+ };
73
+ export type RunUserActionResponseV1 = JsonOk;
74
+ export type SetRunViewStateRequestV1 = {
75
+ state: RunViewStateV1;
76
+ };
77
+ export interface DdFlowClient {
78
+ listProjects(signal?: AbortSignal): Promise<ProjectV1[]>;
79
+ registerProject(params: {
80
+ projectRoot: string;
81
+ signal?: AbortSignal;
82
+ }): Promise<ProjectV1>;
83
+ openProject(params: {
84
+ projectId: string;
85
+ lastFlow?: "mini" | "context";
86
+ lastRunId?: string;
87
+ signal?: AbortSignal;
88
+ }): Promise<ProjectV1>;
89
+ listRuns(params?: {
90
+ projectId?: string;
91
+ signal?: AbortSignal;
92
+ }): Promise<RunV1[]>;
93
+ getRun(params: {
94
+ runId: string;
95
+ signal?: AbortSignal;
96
+ }): Promise<GetRunResponseV1>;
97
+ getRunView(params: {
98
+ runId: string;
99
+ signal?: AbortSignal;
100
+ }): Promise<RunViewV1>;
101
+ getRunViewState(params: {
102
+ runId: string;
103
+ clientId: string;
104
+ signal?: AbortSignal;
105
+ }): Promise<RunViewStateV1 | null>;
106
+ setRunViewState(params: {
107
+ runId: string;
108
+ clientId: string;
109
+ state: RunViewStateV1;
110
+ signal?: AbortSignal;
111
+ }): Promise<void>;
112
+ getRunFile(params: {
113
+ runId: string;
114
+ fileId: RunFileIdV1;
115
+ maxBytes?: number;
116
+ signal?: AbortSignal;
117
+ }): Promise<RunFileV1>;
118
+ createRun(params: CreateRunRequestV1 & {
119
+ signal?: AbortSignal;
120
+ }): Promise<RunV1>;
121
+ runUserAction(params: RunUserActionRequestV1 & {
122
+ signal?: AbortSignal;
123
+ }): Promise<void>;
124
+ startProjectEvents(params: {
125
+ projectId: string;
126
+ clientId: string;
127
+ topics?: DdFlowSseTopicV1[];
128
+ signal: AbortSignal;
129
+ onEvent: (event: DdFlowProjectEventsEnvelopeV1) => void;
130
+ }): Promise<void>;
131
+ planGenerateMini(run: RunV1, signal?: AbortSignal): Promise<void>;
132
+ planSyncMini(run: RunV1, signal?: AbortSignal): Promise<void>;
133
+ planCompileMini(run: RunV1, signal?: AbortSignal): Promise<void>;
134
+ planAccept(run: RunV1, signal?: AbortSignal): Promise<void>;
135
+ planPause(run: RunV1, signal?: AbortSignal): Promise<void>;
136
+ updatePlanRemarks(params: {
137
+ run: RunV1;
138
+ markdown: string;
139
+ signal?: AbortSignal;
140
+ }): Promise<void>;
141
+ startOrContinueRunInBackground(params: {
142
+ run: RunV1;
143
+ allowPush?: boolean;
144
+ }): void;
145
+ requestPauseRun(run: RunV1): void;
146
+ resumePausedRun(run: RunV1): Promise<void>;
147
+ stopRun(run: RunV1, signal?: AbortSignal): Promise<void>;
148
+ archiveRun(run: RunV1, signal?: AbortSignal): Promise<void>;
149
+ rewindRun(params: {
150
+ run: RunV1;
151
+ keepSha: string | null;
152
+ signal?: AbortSignal;
153
+ }): Promise<void>;
154
+ contextAddNote(params: {
155
+ run: RunV1;
156
+ markdown: string;
157
+ signal?: AbortSignal;
158
+ }): Promise<void>;
159
+ contextFinish(run: RunV1, signal?: AbortSignal): Promise<void>;
160
+ }
161
+ export declare class HttpDdFlowClient implements DdFlowClient {
162
+ private readonly baseUrl;
163
+ constructor(params: {
164
+ baseUrl: string;
165
+ });
166
+ private postCommand;
167
+ listProjects(signal?: AbortSignal): Promise<ProjectV1[]>;
168
+ registerProject(params: {
169
+ projectRoot: string;
170
+ signal?: AbortSignal;
171
+ }): Promise<ProjectV1>;
172
+ openProject(params: {
173
+ projectId: string;
174
+ lastFlow?: "mini" | "context";
175
+ lastRunId?: string;
176
+ signal?: AbortSignal;
177
+ }): Promise<ProjectV1>;
178
+ listRuns(params?: {
179
+ projectId?: string;
180
+ signal?: AbortSignal;
181
+ }): Promise<RunV1[]>;
182
+ getRun(params: {
183
+ runId: string;
184
+ signal?: AbortSignal;
185
+ }): Promise<GetRunResponseV1>;
186
+ getRunView(params: {
187
+ runId: string;
188
+ signal?: AbortSignal;
189
+ }): Promise<RunViewV1>;
190
+ getRunViewState(params: {
191
+ runId: string;
192
+ clientId: string;
193
+ signal?: AbortSignal;
194
+ }): Promise<RunViewStateV1 | null>;
195
+ setRunViewState(params: {
196
+ runId: string;
197
+ clientId: string;
198
+ state: RunViewStateV1;
199
+ signal?: AbortSignal;
200
+ }): Promise<void>;
201
+ getRunFile(params: {
202
+ runId: string;
203
+ fileId: RunFileIdV1;
204
+ maxBytes?: number;
205
+ signal?: AbortSignal;
206
+ }): Promise<RunFileV1>;
207
+ startProjectEvents(params: {
208
+ projectId: string;
209
+ clientId: string;
210
+ topics?: DdFlowSseTopicV1[];
211
+ signal: AbortSignal;
212
+ onEvent: (event: DdFlowProjectEventsEnvelopeV1) => void;
213
+ }): Promise<void>;
214
+ createRun(params: CreateRunRequestV1 & {
215
+ signal?: AbortSignal;
216
+ }): Promise<RunV1>;
217
+ runUserAction(params: RunUserActionRequestV1 & {
218
+ signal?: AbortSignal;
219
+ }): Promise<void>;
220
+ planGenerateMini(run: RunV1, signal?: AbortSignal): Promise<void>;
221
+ planSyncMini(run: RunV1, signal?: AbortSignal): Promise<void>;
222
+ planCompileMini(run: RunV1, signal?: AbortSignal): Promise<void>;
223
+ planAccept(run: RunV1, signal?: AbortSignal): Promise<void>;
224
+ planPause(run: RunV1, signal?: AbortSignal): Promise<void>;
225
+ updatePlanRemarks(params: {
226
+ run: RunV1;
227
+ markdown: string;
228
+ signal?: AbortSignal;
229
+ }): Promise<void>;
230
+ startOrContinueRunInBackground(params: {
231
+ run: RunV1;
232
+ allowPush?: boolean;
233
+ }): void;
234
+ requestPauseRun(run: RunV1): void;
235
+ resumePausedRun(run: RunV1): Promise<void>;
236
+ stopRun(run: RunV1, signal?: AbortSignal): Promise<void>;
237
+ archiveRun(run: RunV1, signal?: AbortSignal): Promise<void>;
238
+ rewindRun(params: {
239
+ run: RunV1;
240
+ keepSha: string | null;
241
+ signal?: AbortSignal;
242
+ }): Promise<void>;
243
+ contextAddNote(params: {
244
+ run: RunV1;
245
+ markdown: string;
246
+ signal?: AbortSignal;
247
+ }): Promise<void>;
248
+ contextFinish(run: RunV1, signal?: AbortSignal): Promise<void>;
249
+ }
250
+ export declare function createDdFlowClient(params: {
251
+ baseUrl: string;
252
+ }): DdFlowClient;
package/dist/index.js ADDED
@@ -0,0 +1,258 @@
1
+ import { randomUUID } from "node:crypto";
2
+ export { formatPlanProgressMarkdownV1 } from "./planProgress.js";
3
+ export class HttpDdFlowClient {
4
+ baseUrl;
5
+ constructor(params) {
6
+ this.baseUrl = params.baseUrl.replace(/\/+$/, "");
7
+ }
8
+ async postCommand(run, cmd, signal) {
9
+ const body = {
10
+ commandId: randomUUID(),
11
+ ts: new Date().toISOString(),
12
+ type: cmd.type,
13
+ payload: cmd.payload,
14
+ };
15
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(run.runId)}/commands`, {
16
+ method: "POST",
17
+ headers: { "content-type": "application/json" },
18
+ body: JSON.stringify(body),
19
+ signal,
20
+ });
21
+ if (!res.ok)
22
+ throw new Error(`dd-flow-server error: ${res.status}`);
23
+ const json = (await res.json());
24
+ if (!json.ok)
25
+ throw new Error("dd-flow-server error: not ok");
26
+ }
27
+ async listProjects(signal) {
28
+ const res = await fetch(`${this.baseUrl}/api/projects`, { method: "GET", signal });
29
+ if (!res.ok)
30
+ throw new Error(`dd-flow-server error: ${res.status}`);
31
+ const json = (await res.json());
32
+ if (!json.ok)
33
+ throw new Error("dd-flow-server error: not ok");
34
+ return json.projects;
35
+ }
36
+ async registerProject(params) {
37
+ const res = await fetch(`${this.baseUrl}/api/projects/register`, {
38
+ method: "POST",
39
+ headers: { "content-type": "application/json" },
40
+ body: JSON.stringify({ projectRoot: params.projectRoot }),
41
+ signal: params.signal,
42
+ });
43
+ if (!res.ok)
44
+ throw new Error(`dd-flow-server error: ${res.status}`);
45
+ const json = (await res.json());
46
+ if (!json.ok)
47
+ throw new Error("dd-flow-server error: not ok");
48
+ return json.project;
49
+ }
50
+ async openProject(params) {
51
+ const res = await fetch(`${this.baseUrl}/api/projects/${encodeURIComponent(params.projectId)}/open`, {
52
+ method: "POST",
53
+ headers: { "content-type": "application/json" },
54
+ body: JSON.stringify({
55
+ ...(params.lastFlow ? { lastFlow: params.lastFlow } : {}),
56
+ ...(params.lastRunId ? { lastRunId: params.lastRunId } : {}),
57
+ }),
58
+ signal: params.signal,
59
+ });
60
+ if (!res.ok)
61
+ throw new Error(`dd-flow-server error: ${res.status}`);
62
+ const json = (await res.json());
63
+ if (!json.ok)
64
+ throw new Error("dd-flow-server error: not ok");
65
+ return json.project;
66
+ }
67
+ async listRuns(params) {
68
+ const q = params?.projectId ? `?projectId=${encodeURIComponent(params.projectId)}` : "";
69
+ const res = await fetch(`${this.baseUrl}/api/runs${q}`, { method: "GET", signal: params?.signal });
70
+ if (!res.ok)
71
+ throw new Error(`dd-flow-server error: ${res.status}`);
72
+ const json = (await res.json());
73
+ if (!json.ok)
74
+ throw new Error("dd-flow-server error: not ok");
75
+ return json.runs;
76
+ }
77
+ async getRun(params) {
78
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}`, { method: "GET", signal: params.signal });
79
+ if (!res.ok)
80
+ throw new Error(`dd-flow-server error: ${res.status}`);
81
+ const json = (await res.json());
82
+ if (!json.ok)
83
+ throw new Error("dd-flow-server error: not ok");
84
+ return json;
85
+ }
86
+ async getRunView(params) {
87
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view`, { method: "GET", signal: params.signal });
88
+ if (!res.ok)
89
+ throw new Error(`dd-flow-server error: ${res.status}`);
90
+ const json = (await res.json());
91
+ if (!json.ok)
92
+ throw new Error("dd-flow-server error: not ok");
93
+ return json.view;
94
+ }
95
+ async getRunViewState(params) {
96
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view-state`, {
97
+ method: "GET",
98
+ headers: { "x-dd-flow-client-id": params.clientId },
99
+ signal: params.signal,
100
+ });
101
+ if (!res.ok)
102
+ throw new Error(`dd-flow-server error: ${res.status}`);
103
+ const json = (await res.json());
104
+ if (!json.ok)
105
+ throw new Error("dd-flow-server error: not ok");
106
+ return json.state ?? null;
107
+ }
108
+ async setRunViewState(params) {
109
+ const req = { state: params.state };
110
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view-state`, {
111
+ method: "POST",
112
+ headers: { "content-type": "application/json", "x-dd-flow-client-id": params.clientId },
113
+ body: JSON.stringify(req),
114
+ signal: params.signal,
115
+ });
116
+ if (!res.ok)
117
+ throw new Error(`dd-flow-server error: ${res.status}`);
118
+ const json = (await res.json());
119
+ if (!json.ok)
120
+ throw new Error("dd-flow-server error: not ok");
121
+ }
122
+ async getRunFile(params) {
123
+ const q = typeof params.maxBytes === "number" && Number.isFinite(params.maxBytes)
124
+ ? `?maxBytes=${encodeURIComponent(String(params.maxBytes))}`
125
+ : "";
126
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/files/${encodeURIComponent(params.fileId)}${q}`, { method: "GET", signal: params.signal });
127
+ if (!res.ok)
128
+ throw new Error(`dd-flow-server error: ${res.status}`);
129
+ const json = (await res.json());
130
+ if (!json.ok)
131
+ throw new Error("dd-flow-server error: not ok");
132
+ return json.file;
133
+ }
134
+ async startProjectEvents(params) {
135
+ const topics = (params.topics ?? ["runs", "ledger", "toasts"]).join(",");
136
+ const url = `${this.baseUrl}/api/events?projectId=${encodeURIComponent(params.projectId)}&clientId=${encodeURIComponent(params.clientId)}&topics=${encodeURIComponent(topics)}`;
137
+ const res = await fetch(url, {
138
+ method: "GET",
139
+ headers: { accept: "text/event-stream" },
140
+ signal: params.signal,
141
+ });
142
+ if (!res.ok)
143
+ throw new Error(`dd-flow-server error: ${res.status}`);
144
+ if (!res.body)
145
+ throw new Error("dd-flow-server error: missing SSE body");
146
+ const reader = res.body.getReader();
147
+ const dec = new TextDecoder();
148
+ let buffer = "";
149
+ const flush = (chunk) => {
150
+ const blocks = chunk.split("\n\n");
151
+ for (const b of blocks) {
152
+ const lines = b.split("\n").map((l) => l.trimEnd());
153
+ for (const line of lines) {
154
+ if (!line.startsWith("data:"))
155
+ continue;
156
+ const raw = line.slice("data:".length).trim();
157
+ if (!raw)
158
+ continue;
159
+ try {
160
+ params.onEvent(JSON.parse(raw));
161
+ }
162
+ catch {
163
+ // ignore parse errors (best-effort stream)
164
+ }
165
+ }
166
+ }
167
+ };
168
+ while (true) {
169
+ const { value, done } = await reader.read();
170
+ if (done)
171
+ break;
172
+ if (!value)
173
+ continue;
174
+ buffer += dec.decode(value, { stream: true });
175
+ const parts = buffer.split("\n\n");
176
+ if (parts.length <= 1)
177
+ continue;
178
+ const complete = parts.slice(0, -1).join("\n\n");
179
+ buffer = parts[parts.length - 1] ?? "";
180
+ flush(complete);
181
+ }
182
+ if (buffer.trim())
183
+ flush(buffer);
184
+ }
185
+ async createRun(params) {
186
+ const res = await fetch(`${this.baseUrl}/api/flows/${encodeURIComponent(params.flowId)}/runs`, {
187
+ method: "POST",
188
+ headers: { "content-type": "application/json" },
189
+ body: JSON.stringify(params),
190
+ signal: params.signal,
191
+ });
192
+ if (!res.ok)
193
+ throw new Error(`dd-flow-server error: ${res.status}`);
194
+ const json = (await res.json());
195
+ if (!json.ok)
196
+ throw new Error("dd-flow-server error: not ok");
197
+ return json.run;
198
+ }
199
+ async runUserAction(params) {
200
+ const { runId, ...body } = params;
201
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(runId)}/user-actions`, {
202
+ method: "POST",
203
+ headers: { "content-type": "application/json" },
204
+ body: JSON.stringify(body),
205
+ signal: params.signal,
206
+ });
207
+ if (!res.ok)
208
+ throw new Error(`dd-flow-server error: ${res.status}`);
209
+ const json = (await res.json());
210
+ if (!json.ok)
211
+ throw new Error("dd-flow-server error: not ok");
212
+ }
213
+ async planGenerateMini(run, signal) {
214
+ await this.postCommand(run, { type: "plan_generate_mini" }, signal);
215
+ }
216
+ async planSyncMini(run, signal) {
217
+ await this.postCommand(run, { type: "plan_sync_mini" }, signal);
218
+ }
219
+ async planCompileMini(run, signal) {
220
+ await this.postCommand(run, { type: "plan_compile_mini" }, signal);
221
+ }
222
+ async planAccept(run, signal) {
223
+ await this.postCommand(run, { type: "plan_accept" }, signal);
224
+ }
225
+ async planPause(run, signal) {
226
+ await this.postCommand(run, { type: "plan_pause" }, signal);
227
+ }
228
+ async updatePlanRemarks(params) {
229
+ await this.postCommand(params.run, { type: "update_plan_remarks", payload: { markdown: params.markdown } }, params.signal);
230
+ }
231
+ startOrContinueRunInBackground(params) {
232
+ void this.postCommand(params.run, { type: "run_start_or_continue", payload: { allowPush: Boolean(params.allowPush) } });
233
+ }
234
+ requestPauseRun(run) {
235
+ void this.postCommand(run, { type: "run_pause_request" });
236
+ }
237
+ async resumePausedRun(run) {
238
+ await this.postCommand(run, { type: "run_resume" });
239
+ }
240
+ async stopRun(run, signal) {
241
+ await this.postCommand(run, { type: "run_stop" }, signal);
242
+ }
243
+ async archiveRun(run, signal) {
244
+ await this.postCommand(run, { type: "run_archive" }, signal);
245
+ }
246
+ async rewindRun(params) {
247
+ await this.postCommand(params.run, { type: "run_rewind", payload: { keepSha: params.keepSha } }, params.signal);
248
+ }
249
+ async contextAddNote(params) {
250
+ await this.postCommand(params.run, { type: "context_add_note", payload: { markdown: params.markdown } }, params.signal);
251
+ }
252
+ async contextFinish(run, signal) {
253
+ await this.postCommand(run, { type: "context_finish" }, signal);
254
+ }
255
+ }
256
+ export function createDdFlowClient(params) {
257
+ return new HttpDdFlowClient(params);
258
+ }
@@ -0,0 +1,2 @@
1
+ import type { PlanProgressV1 } from "@dd-flow/common";
2
+ export declare function formatPlanProgressMarkdownV1(plan: PlanProgressV1): string;
@@ -0,0 +1,34 @@
1
+ function statusEmoji(status) {
2
+ if (status === "done")
3
+ return "✅";
4
+ if (status === "in_progress")
5
+ return "⏳";
6
+ return "⬜";
7
+ }
8
+ export function formatPlanProgressMarkdownV1(plan) {
9
+ const total = plan.overall.totalTasks;
10
+ const done = plan.overall.doneTasks;
11
+ const inProgress = plan.overall.inProgressTasks;
12
+ const progressLine = total > 0
13
+ ? `**Progress**: ${done}/${total} done · ${inProgress} in progress`
14
+ : plan.steps.length
15
+ ? (() => {
16
+ const totalSteps = plan.steps.length;
17
+ const doneSteps = plan.steps.filter((s) => s.status === "done").length;
18
+ const inProgressSteps = plan.steps.filter((s) => s.status === "in_progress").length;
19
+ return `**Progress**: ${doneSteps}/${totalSteps} steps done · ${inProgressSteps} steps in progress _(no tasks parsed)_`;
20
+ })()
21
+ : "**Progress**: _(no steps)_";
22
+ if (!plan.steps.length)
23
+ return `${progressLine}\n`;
24
+ const lines = [progressLine, ""];
25
+ for (const step of plan.steps) {
26
+ const isCurrent = plan.current?.step != null && plan.current.step === step.step;
27
+ const currentMark = isCurrent ? "➡️ " : "";
28
+ lines.push(`- ${currentMark}${statusEmoji(step.status)} Step ${step.step} — ${step.title}`);
29
+ for (const task of step.tasks) {
30
+ lines.push(` - ${statusEmoji(task.status)} ${task.taskKey} ${task.emoji} ${task.title}`);
31
+ }
32
+ }
33
+ return `${lines.join("\n")}\n`;
34
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@dd-flow/client",
3
+ "version": "0.2.0",
4
+ "description": "dd-flow client SDK (HTTP + SSE) for local dd-flow-server",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "src",
19
+ "README.md"
20
+ ],
21
+ "dependencies": {
22
+ "@dd-flow/common": "0.4.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^24.2.1",
26
+ "typescript": "^5.9.2"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.17.0"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc --project tsconfig.json",
36
+ "dev": "tsc --watch",
37
+ "typecheck": "tsc --noEmit --project tsconfig.json",
38
+ "lint:local": "biome check .",
39
+ "lint:fix:local": "biome check --write .",
40
+ "clean": "rm -rf dist tsconfig.tsbuildinfo"
41
+ }
42
+ }
package/src/index.ts ADDED
@@ -0,0 +1,371 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import type {
4
+ DdFlowProjectEventsEnvelopeV1,
5
+ DdFlowSseTopicV1,
6
+ ProjectV1,
7
+ RunFileIdV1,
8
+ RunFileV1,
9
+ RunV1,
10
+ RunViewStateV1,
11
+ RunViewV1,
12
+ UserCommandV1,
13
+ } from "@dd-flow/common";
14
+
15
+ export { formatPlanProgressMarkdownV1 } from "./planProgress.js";
16
+
17
+ type JsonOk = { ok: true };
18
+
19
+ export type CreateRunRequestV1 =
20
+ | {
21
+ flowId: "context";
22
+ projectRoot: string;
23
+ engine?: { checksMode?: "sync" | "async"; verifyMode?: "sync" | "async" };
24
+ }
25
+ | {
26
+ flowId: "mini";
27
+ projectRoot: string;
28
+ params: {
29
+ mainSessionId: string;
30
+ planMode?: "review" | "auto";
31
+ profileId?: string;
32
+ allowPush?: boolean;
33
+ };
34
+ engine?: { checksMode?: "sync" | "async"; verifyMode?: "sync" | "async" };
35
+ };
36
+
37
+ export type GetRunResponseV1 = { ok: true; run: RunV1; state: unknown };
38
+ export type GetRunViewResponseV1 = { ok: true; view: RunViewV1 };
39
+ export type GetRunViewStateResponseV1 = { ok: true; state: RunViewStateV1 | null };
40
+ export type ListProjectsResponseV1 = { ok: true; projects: ProjectV1[] };
41
+ export type RegisterProjectResponseV1 = { ok: true; project: ProjectV1 };
42
+ export type ListRunsResponseV1 = { ok: true; runs: RunV1[] };
43
+ export type CreateRunResponseV1 = { ok: true; run: RunV1 };
44
+ export type GetRunFileResponseV1 = { ok: true; file: RunFileV1 };
45
+ export type RunUserActionRequestV1 = {
46
+ runId: string;
47
+ actionId: string;
48
+ target?: { processId?: string; nodeId?: string };
49
+ formData?: Record<string, unknown>;
50
+ actor?: { clientId: string; connectionId?: string };
51
+ };
52
+ export type RunUserActionResponseV1 = JsonOk;
53
+ export type SetRunViewStateRequestV1 = { state: RunViewStateV1 };
54
+
55
+ export interface DdFlowClient {
56
+ listProjects(signal?: AbortSignal): Promise<ProjectV1[]>;
57
+ registerProject(params: { projectRoot: string; signal?: AbortSignal }): Promise<ProjectV1>;
58
+ openProject(params: {
59
+ projectId: string;
60
+ lastFlow?: "mini" | "context";
61
+ lastRunId?: string;
62
+ signal?: AbortSignal;
63
+ }): Promise<ProjectV1>;
64
+ listRuns(params?: { projectId?: string; signal?: AbortSignal }): Promise<RunV1[]>;
65
+ getRun(params: { runId: string; signal?: AbortSignal }): Promise<GetRunResponseV1>;
66
+ getRunView(params: { runId: string; signal?: AbortSignal }): Promise<RunViewV1>;
67
+ getRunViewState(params: { runId: string; clientId: string; signal?: AbortSignal }): Promise<RunViewStateV1 | null>;
68
+ setRunViewState(params: { runId: string; clientId: string; state: RunViewStateV1; signal?: AbortSignal }): Promise<void>;
69
+ getRunFile(params: { runId: string; fileId: RunFileIdV1; maxBytes?: number; signal?: AbortSignal }): Promise<RunFileV1>;
70
+ createRun(params: CreateRunRequestV1 & { signal?: AbortSignal }): Promise<RunV1>;
71
+ runUserAction(params: RunUserActionRequestV1 & { signal?: AbortSignal }): Promise<void>;
72
+ startProjectEvents(params: {
73
+ projectId: string;
74
+ clientId: string;
75
+ topics?: DdFlowSseTopicV1[];
76
+ signal: AbortSignal;
77
+ onEvent: (event: DdFlowProjectEventsEnvelopeV1) => void;
78
+ }): Promise<void>;
79
+
80
+ planGenerateMini(run: RunV1, signal?: AbortSignal): Promise<void>;
81
+ planSyncMini(run: RunV1, signal?: AbortSignal): Promise<void>;
82
+ planCompileMini(run: RunV1, signal?: AbortSignal): Promise<void>;
83
+ planAccept(run: RunV1, signal?: AbortSignal): Promise<void>;
84
+ planPause(run: RunV1, signal?: AbortSignal): Promise<void>;
85
+ updatePlanRemarks(params: { run: RunV1; markdown: string; signal?: AbortSignal }): Promise<void>;
86
+
87
+ startOrContinueRunInBackground(params: { run: RunV1; allowPush?: boolean }): void;
88
+ requestPauseRun(run: RunV1): void;
89
+ resumePausedRun(run: RunV1): Promise<void>;
90
+ stopRun(run: RunV1, signal?: AbortSignal): Promise<void>;
91
+ archiveRun(run: RunV1, signal?: AbortSignal): Promise<void>;
92
+ rewindRun(params: { run: RunV1; keepSha: string | null; signal?: AbortSignal }): Promise<void>;
93
+ contextAddNote(params: { run: RunV1; markdown: string; signal?: AbortSignal }): Promise<void>;
94
+ contextFinish(run: RunV1, signal?: AbortSignal): Promise<void>;
95
+ }
96
+
97
+ export class HttpDdFlowClient implements DdFlowClient {
98
+ private readonly baseUrl: string;
99
+
100
+ public constructor(params: { baseUrl: string }) {
101
+ this.baseUrl = params.baseUrl.replace(/\/+$/, "");
102
+ }
103
+
104
+ private async postCommand(
105
+ run: RunV1,
106
+ cmd: Omit<UserCommandV1, "commandId" | "ts">,
107
+ signal?: AbortSignal,
108
+ ): Promise<void> {
109
+ const body: UserCommandV1 = {
110
+ commandId: randomUUID(),
111
+ ts: new Date().toISOString(),
112
+ type: cmd.type,
113
+ payload: cmd.payload,
114
+ };
115
+
116
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(run.runId)}/commands`, {
117
+ method: "POST",
118
+ headers: { "content-type": "application/json" },
119
+ body: JSON.stringify(body),
120
+ signal,
121
+ });
122
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
123
+ const json = (await res.json()) as JsonOk;
124
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
125
+ }
126
+
127
+ public async listProjects(signal?: AbortSignal): Promise<ProjectV1[]> {
128
+ const res = await fetch(`${this.baseUrl}/api/projects`, { method: "GET", signal });
129
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
130
+ const json = (await res.json()) as ListProjectsResponseV1;
131
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
132
+ return json.projects;
133
+ }
134
+
135
+ public async registerProject(params: { projectRoot: string; signal?: AbortSignal }): Promise<ProjectV1> {
136
+ const res = await fetch(`${this.baseUrl}/api/projects/register`, {
137
+ method: "POST",
138
+ headers: { "content-type": "application/json" },
139
+ body: JSON.stringify({ projectRoot: params.projectRoot }),
140
+ signal: params.signal,
141
+ });
142
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
143
+ const json = (await res.json()) as RegisterProjectResponseV1;
144
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
145
+ return json.project;
146
+ }
147
+
148
+ public async openProject(params: {
149
+ projectId: string;
150
+ lastFlow?: "mini" | "context";
151
+ lastRunId?: string;
152
+ signal?: AbortSignal;
153
+ }): Promise<ProjectV1> {
154
+ const res = await fetch(`${this.baseUrl}/api/projects/${encodeURIComponent(params.projectId)}/open`, {
155
+ method: "POST",
156
+ headers: { "content-type": "application/json" },
157
+ body: JSON.stringify({
158
+ ...(params.lastFlow ? { lastFlow: params.lastFlow } : {}),
159
+ ...(params.lastRunId ? { lastRunId: params.lastRunId } : {}),
160
+ }),
161
+ signal: params.signal,
162
+ });
163
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
164
+ const json = (await res.json()) as RegisterProjectResponseV1;
165
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
166
+ return json.project;
167
+ }
168
+
169
+ public async listRuns(params?: { projectId?: string; signal?: AbortSignal }): Promise<RunV1[]> {
170
+ const q = params?.projectId ? `?projectId=${encodeURIComponent(params.projectId)}` : "";
171
+ const res = await fetch(`${this.baseUrl}/api/runs${q}`, { method: "GET", signal: params?.signal });
172
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
173
+ const json = (await res.json()) as ListRunsResponseV1;
174
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
175
+ return json.runs;
176
+ }
177
+
178
+ public async getRun(params: { runId: string; signal?: AbortSignal }): Promise<GetRunResponseV1> {
179
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}`, { method: "GET", signal: params.signal });
180
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
181
+ const json = (await res.json()) as GetRunResponseV1;
182
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
183
+ return json;
184
+ }
185
+
186
+ public async getRunView(params: { runId: string; signal?: AbortSignal }): Promise<RunViewV1> {
187
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view`, { method: "GET", signal: params.signal });
188
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
189
+ const json = (await res.json()) as GetRunViewResponseV1;
190
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
191
+ return json.view;
192
+ }
193
+
194
+ public async getRunViewState(params: { runId: string; clientId: string; signal?: AbortSignal }): Promise<RunViewStateV1 | null> {
195
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view-state`, {
196
+ method: "GET",
197
+ headers: { "x-dd-flow-client-id": params.clientId },
198
+ signal: params.signal,
199
+ });
200
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
201
+ const json = (await res.json()) as GetRunViewStateResponseV1;
202
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
203
+ return json.state ?? null;
204
+ }
205
+
206
+ public async setRunViewState(params: { runId: string; clientId: string; state: RunViewStateV1; signal?: AbortSignal }): Promise<void> {
207
+ const req: SetRunViewStateRequestV1 = { state: params.state };
208
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/view-state`, {
209
+ method: "POST",
210
+ headers: { "content-type": "application/json", "x-dd-flow-client-id": params.clientId },
211
+ body: JSON.stringify(req),
212
+ signal: params.signal,
213
+ });
214
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
215
+ const json = (await res.json()) as JsonOk;
216
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
217
+ }
218
+
219
+ public async getRunFile(params: { runId: string; fileId: RunFileIdV1; maxBytes?: number; signal?: AbortSignal }): Promise<RunFileV1> {
220
+ const q =
221
+ typeof params.maxBytes === "number" && Number.isFinite(params.maxBytes)
222
+ ? `?maxBytes=${encodeURIComponent(String(params.maxBytes))}`
223
+ : "";
224
+ const res = await fetch(
225
+ `${this.baseUrl}/api/runs/${encodeURIComponent(params.runId)}/files/${encodeURIComponent(params.fileId)}${q}`,
226
+ { method: "GET", signal: params.signal },
227
+ );
228
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
229
+ const json = (await res.json()) as GetRunFileResponseV1;
230
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
231
+ return json.file;
232
+ }
233
+
234
+ public async startProjectEvents(params: {
235
+ projectId: string;
236
+ clientId: string;
237
+ topics?: DdFlowSseTopicV1[];
238
+ signal: AbortSignal;
239
+ onEvent: (event: DdFlowProjectEventsEnvelopeV1) => void;
240
+ }): Promise<void> {
241
+ const topics = (params.topics ?? ["runs", "ledger", "toasts"]).join(",");
242
+ const url = `${this.baseUrl}/api/events?projectId=${encodeURIComponent(params.projectId)}&clientId=${encodeURIComponent(params.clientId)}&topics=${encodeURIComponent(topics)}`;
243
+ const res = await fetch(url, {
244
+ method: "GET",
245
+ headers: { accept: "text/event-stream" },
246
+ signal: params.signal,
247
+ });
248
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
249
+ if (!res.body) throw new Error("dd-flow-server error: missing SSE body");
250
+
251
+ const reader = res.body.getReader();
252
+ const dec = new TextDecoder();
253
+ let buffer = "";
254
+
255
+ const flush = (chunk: string): void => {
256
+ const blocks = chunk.split("\n\n");
257
+ for (const b of blocks) {
258
+ const lines = b.split("\n").map((l) => l.trimEnd());
259
+ for (const line of lines) {
260
+ if (!line.startsWith("data:")) continue;
261
+ const raw = line.slice("data:".length).trim();
262
+ if (!raw) continue;
263
+ try {
264
+ params.onEvent(JSON.parse(raw) as DdFlowProjectEventsEnvelopeV1);
265
+ } catch {
266
+ // ignore parse errors (best-effort stream)
267
+ }
268
+ }
269
+ }
270
+ };
271
+
272
+ while (true) {
273
+ const { value, done } = await reader.read();
274
+ if (done) break;
275
+ if (!value) continue;
276
+ buffer += dec.decode(value, { stream: true });
277
+ const parts = buffer.split("\n\n");
278
+ if (parts.length <= 1) continue;
279
+ const complete = parts.slice(0, -1).join("\n\n");
280
+ buffer = parts[parts.length - 1] ?? "";
281
+ flush(complete);
282
+ }
283
+ if (buffer.trim()) flush(buffer);
284
+ }
285
+
286
+ public async createRun(params: CreateRunRequestV1 & { signal?: AbortSignal }): Promise<RunV1> {
287
+ const res = await fetch(`${this.baseUrl}/api/flows/${encodeURIComponent(params.flowId)}/runs`, {
288
+ method: "POST",
289
+ headers: { "content-type": "application/json" },
290
+ body: JSON.stringify(params),
291
+ signal: params.signal,
292
+ });
293
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
294
+ const json = (await res.json()) as CreateRunResponseV1;
295
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
296
+ return json.run;
297
+ }
298
+
299
+ public async runUserAction(params: RunUserActionRequestV1 & { signal?: AbortSignal }): Promise<void> {
300
+ const { runId, ...body } = params;
301
+ const res = await fetch(`${this.baseUrl}/api/runs/${encodeURIComponent(runId)}/user-actions`, {
302
+ method: "POST",
303
+ headers: { "content-type": "application/json" },
304
+ body: JSON.stringify(body),
305
+ signal: params.signal,
306
+ });
307
+ if (!res.ok) throw new Error(`dd-flow-server error: ${res.status}`);
308
+ const json = (await res.json()) as RunUserActionResponseV1;
309
+ if (!json.ok) throw new Error("dd-flow-server error: not ok");
310
+ }
311
+
312
+ public async planGenerateMini(run: RunV1, signal?: AbortSignal): Promise<void> {
313
+ await this.postCommand(run, { type: "plan_generate_mini" }, signal);
314
+ }
315
+
316
+ public async planSyncMini(run: RunV1, signal?: AbortSignal): Promise<void> {
317
+ await this.postCommand(run, { type: "plan_sync_mini" }, signal);
318
+ }
319
+
320
+ public async planCompileMini(run: RunV1, signal?: AbortSignal): Promise<void> {
321
+ await this.postCommand(run, { type: "plan_compile_mini" }, signal);
322
+ }
323
+
324
+ public async planAccept(run: RunV1, signal?: AbortSignal): Promise<void> {
325
+ await this.postCommand(run, { type: "plan_accept" }, signal);
326
+ }
327
+
328
+ public async planPause(run: RunV1, signal?: AbortSignal): Promise<void> {
329
+ await this.postCommand(run, { type: "plan_pause" }, signal);
330
+ }
331
+
332
+ public async updatePlanRemarks(params: { run: RunV1; markdown: string; signal?: AbortSignal }): Promise<void> {
333
+ await this.postCommand(params.run, { type: "update_plan_remarks", payload: { markdown: params.markdown } }, params.signal);
334
+ }
335
+
336
+ public startOrContinueRunInBackground(params: { run: RunV1; allowPush?: boolean }): void {
337
+ void this.postCommand(params.run, { type: "run_start_or_continue", payload: { allowPush: Boolean(params.allowPush) } });
338
+ }
339
+
340
+ public requestPauseRun(run: RunV1): void {
341
+ void this.postCommand(run, { type: "run_pause_request" });
342
+ }
343
+
344
+ public async resumePausedRun(run: RunV1): Promise<void> {
345
+ await this.postCommand(run, { type: "run_resume" });
346
+ }
347
+
348
+ public async stopRun(run: RunV1, signal?: AbortSignal): Promise<void> {
349
+ await this.postCommand(run, { type: "run_stop" }, signal);
350
+ }
351
+
352
+ public async archiveRun(run: RunV1, signal?: AbortSignal): Promise<void> {
353
+ await this.postCommand(run, { type: "run_archive" }, signal);
354
+ }
355
+
356
+ public async rewindRun(params: { run: RunV1; keepSha: string | null; signal?: AbortSignal }): Promise<void> {
357
+ await this.postCommand(params.run, { type: "run_rewind", payload: { keepSha: params.keepSha } }, params.signal);
358
+ }
359
+
360
+ public async contextAddNote(params: { run: RunV1; markdown: string; signal?: AbortSignal }): Promise<void> {
361
+ await this.postCommand(params.run, { type: "context_add_note", payload: { markdown: params.markdown } }, params.signal);
362
+ }
363
+
364
+ public async contextFinish(run: RunV1, signal?: AbortSignal): Promise<void> {
365
+ await this.postCommand(run, { type: "context_finish" }, signal);
366
+ }
367
+ }
368
+
369
+ export function createDdFlowClient(params: { baseUrl: string }): DdFlowClient {
370
+ return new HttpDdFlowClient(params);
371
+ }
@@ -0,0 +1,39 @@
1
+ import type { PlanProgressTaskStatusV1, PlanProgressV1 } from "@dd-flow/common";
2
+
3
+ function statusEmoji(status: PlanProgressTaskStatusV1): string {
4
+ if (status === "done") return "✅";
5
+ if (status === "in_progress") return "⏳";
6
+ return "⬜";
7
+ }
8
+
9
+ export function formatPlanProgressMarkdownV1(plan: PlanProgressV1): string {
10
+ const total = plan.overall.totalTasks;
11
+ const done = plan.overall.doneTasks;
12
+ const inProgress = plan.overall.inProgressTasks;
13
+
14
+ const progressLine =
15
+ total > 0
16
+ ? `**Progress**: ${done}/${total} done · ${inProgress} in progress`
17
+ : plan.steps.length
18
+ ? (() => {
19
+ const totalSteps = plan.steps.length;
20
+ const doneSteps = plan.steps.filter((s) => s.status === "done").length;
21
+ const inProgressSteps = plan.steps.filter((s) => s.status === "in_progress").length;
22
+ return `**Progress**: ${doneSteps}/${totalSteps} steps done · ${inProgressSteps} steps in progress _(no tasks parsed)_`;
23
+ })()
24
+ : "**Progress**: _(no steps)_";
25
+
26
+ if (!plan.steps.length) return `${progressLine}\n`;
27
+
28
+ const lines: string[] = [progressLine, ""];
29
+ for (const step of plan.steps) {
30
+ const isCurrent = plan.current?.step != null && plan.current.step === step.step;
31
+ const currentMark = isCurrent ? "➡️ " : "";
32
+ lines.push(`- ${currentMark}${statusEmoji(step.status)} Step ${step.step} — ${step.title}`);
33
+ for (const task of step.tasks) {
34
+ lines.push(` - ${statusEmoji(task.status)} ${task.taskKey} ${task.emoji} ${task.title}`);
35
+ }
36
+ }
37
+
38
+ return `${lines.join("\n")}\n`;
39
+ }