@codeworksh/cli 0.0.1-dev.20260925163815 → 0.1.0-dev.20261007133227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/acp-DK_xXx9y.mjs +494 -0
  2. package/acp-DK_xXx9y.mjs.map +1 -0
  3. package/{add-BPuCxrRi.mjs → add-B9gIgFb3.mjs} +4 -4
  4. package/{add-BPuCxrRi.mjs.map → add-B9gIgFb3.mjs.map} +1 -1
  5. package/{catalog-DyQXd30n.mjs → catalog-D5BxyTfH.mjs} +2 -2
  6. package/{catalog-DyQXd30n.mjs.map → catalog-D5BxyTfH.mjs.map} +1 -1
  7. package/{check-CKi11Mtm.mjs → check-B9PJ6rn_.mjs} +4 -4
  8. package/{check-CKi11Mtm.mjs.map → check-B9PJ6rn_.mjs.map} +1 -1
  9. package/{entries-BXBULTVt.mjs → entries-CzgqHfKQ.mjs} +3 -3
  10. package/{entries-BXBULTVt.mjs.map → entries-CzgqHfKQ.mjs.map} +1 -1
  11. package/{error-CxoEKg-4.mjs → error-C9ACQhhu.mjs} +2 -2
  12. package/error-C9ACQhhu.mjs.map +1 -0
  13. package/index.mjs +20 -21
  14. package/index.mjs.map +1 -1
  15. package/{install-C2QXwvU6.mjs → install-Cw6h6IRB.mjs} +4 -4
  16. package/{install-C2QXwvU6.mjs.map → install-Cw6h6IRB.mjs.map} +1 -1
  17. package/{link-D5uOUo0m.mjs → link-B7iVolAn.mjs} +3 -3
  18. package/{link-D5uOUo0m.mjs.map → link-B7iVolAn.mjs.map} +1 -1
  19. package/{list-B7wmE2Hz.mjs → list-3hYMW1Wo.mjs} +4 -4
  20. package/{list-B7wmE2Hz.mjs.map → list-3hYMW1Wo.mjs.map} +1 -1
  21. package/{list-CEDVgkex.mjs → list-BAonMfru.mjs} +4 -4
  22. package/{list-CEDVgkex.mjs.map → list-BAonMfru.mjs.map} +1 -1
  23. package/{login-DD5n0PHg.mjs → login-CXelgTth.mjs} +4 -4
  24. package/{login-DD5n0PHg.mjs.map → login-CXelgTth.mjs.map} +1 -1
  25. package/{logout--lzv9ftF.mjs → logout-DrQQPxEW.mjs} +4 -4
  26. package/{logout--lzv9ftF.mjs.map → logout-DrQQPxEW.mjs.map} +1 -1
  27. package/package-7FOUqcPO.mjs +6 -0
  28. package/package-7FOUqcPO.mjs.map +1 -0
  29. package/package.json +7 -5
  30. package/{providers-CO0ERtiv.mjs → providers-DksUoT4Z.mjs} +4 -4
  31. package/{providers-CO0ERtiv.mjs.map → providers-DksUoT4Z.mjs.map} +1 -1
  32. package/{refresh-DKBOk5RX.mjs → refresh-CHBg5ya9.mjs} +4 -4
  33. package/{refresh-DKBOk5RX.mjs.map → refresh-CHBg5ya9.mjs.map} +1 -1
  34. package/{refresh-BcI6iAiQ.mjs → refresh-DPBpboO0.mjs} +4 -4
  35. package/{refresh-BcI6iAiQ.mjs.map → refresh-DPBpboO0.mjs.map} +1 -1
  36. package/{reload-L4NyTZaU.mjs → reload-DDsh7kFG.mjs} +3 -3
  37. package/{reload-L4NyTZaU.mjs.map → reload-DDsh7kFG.mjs.map} +1 -1
  38. package/{remove-CpLi76Ah.mjs → remove-__JfeHO-.mjs} +4 -4
  39. package/{remove-CpLi76Ah.mjs.map → remove-__JfeHO-.mjs.map} +1 -1
  40. package/{run-D7h83L_m.mjs → run-D47jXr5Q.mjs} +3 -5
  41. package/run-D47jXr5Q.mjs.map +1 -0
  42. package/{runtime-B3dlWGfs.mjs → runtime-D4zyJPrh.mjs} +9 -2
  43. package/runtime-D4zyJPrh.mjs.map +1 -0
  44. package/{serve-BGrH_Wr6.mjs → serve-gOODO9pv.mjs} +14 -10
  45. package/{serve-BGrH_Wr6.mjs.map → serve-gOODO9pv.mjs.map} +1 -1
  46. package/{settings-aqM_b9UE.mjs → settings-DDkmAxW5.mjs} +2 -2
  47. package/{settings-aqM_b9UE.mjs.map → settings-DDkmAxW5.mjs.map} +1 -1
  48. package/{shared-IycfDUnF.mjs → shared-DFB2--6V.mjs} +4 -4
  49. package/{shared-IycfDUnF.mjs.map → shared-DFB2--6V.mjs.map} +1 -1
  50. package/{status-CCj71RVv.mjs → status-BNc5JZ1C.mjs} +4 -4
  51. package/{status-CCj71RVv.mjs.map → status-BNc5JZ1C.mjs.map} +1 -1
  52. package/{update-C-RdaEiC.mjs → update-CaW7oDOl.mjs} +4 -4
  53. package/{update-C-RdaEiC.mjs.map → update-CaW7oDOl.mjs.map} +1 -1
  54. package/error-CxoEKg-4.mjs.map +0 -1
  55. package/run-D7h83L_m.mjs.map +0 -1
  56. package/runtime-B3dlWGfs.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"settings-aqM_b9UE.mjs","names":["parseJsonc"],"sources":["../../src/cli/cmd/handlers/plugin/settings.ts"],"sourcesContent":["import { Global, Plugin, Settings } from \"@codeworksh/harness/effect\";\nimport { Effect, FileSystem, Option, Path } from \"effect\";\nimport { applyEdits, modify, parse as parseJsonc, type ParseError } from \"jsonc-parser\";\nimport { InvalidInputError } from \"../../../error.ts\";\n\n/**\n * Reading and rewriting the `plugins` array of one settings file.\n *\n * Edits go through `jsonc-parser`, so a hand-written file keeps its comments, key order and\n * formatting: a plugin added by the CLI must not reformat a file its owner maintains. The write\n * is a temp file renamed over the original, so an interrupted run leaves the previous settings\n * intact rather than a half-written document.\n */\n\nexport interface Shared {\n\treadonly userConfigDir: Option.Option<string>;\n\treadonly home: Option.Option<string>;\n}\n\n/**\n * The user layer a command reads and writes: `--user-config-dir` when given -- a hard override of\n * the home's settings file -- resolved, like every app-level flag, against the directory the\n * command runs in (`hostCwd`), never against a linked session's `hostDir`.\n */\nexport const userLayer = (shared: Shared, hostCwd: string) =>\n\tOption.isNone(shared.userConfigDir)\n\t\t? {}\n\t\t: { userConfigDir: Settings.userConfigDir(shared.userConfigDir.value, hostCwd) };\n\nexport interface Target {\n\treadonly path: string;\n\t/** Set when this command had to create the project directory, so the caller can say so. */\n\treadonly created?: string;\n\t/** The project this file belongs to, which a local entry is written relative to. */\n\treadonly root?: string;\n}\n\n/** The module an entry names: a bare loader string, or the `package` of a config object. */\nconst moduleOf = (entry: unknown): string | undefined => {\n\tif (typeof entry === \"string\") return entry;\n\tif (typeof entry !== \"object\" || entry === null) return undefined;\n\tconst { package: located } = entry as { package?: unknown };\n\treturn typeof located === \"string\" ? located : undefined;\n};\n\n/** The plugin ID an entry configures, if it names one. */\nconst idOf = (entry: unknown): string | undefined => {\n\tif (typeof entry !== \"object\" || entry === null) return undefined;\n\tconst { plugin } = entry as { plugin?: unknown };\n\treturn typeof plugin === \"string\" ? plugin : undefined;\n};\n\n/**\n * Every spelling a reference answers to, without touching the filesystem.\n *\n * `canonical` drops a version suffix and resolves a relative path against the file that declared\n * it, so `@acme/x@1.2.0` and `@acme/x` are one name. The literal string is kept alongside it\n * because a plugin ID is not a module reference and survives `canonical` unchanged.\n */\nconst aliases = (reference: string, directory: string): Effect.Effect<ReadonlyArray<string>> =>\n\tPlugin.canonical(reference, directory).pipe(\n\t\tEffect.map((canonical) => [reference, canonical] as ReadonlyArray<string>),\n\t\t// A reference that does not parse still answers to itself: a plugin ID is not a module\n\t\t// reference, and it has to keep matching an entry that names it.\n\t\tEffect.orElseSucceed(() => [reference] as ReadonlyArray<string>),\n\t);\n\n/** Every spelling `reference` answers to, computed once for a whole command. */\nexport const spellings = (reference: string, directory: string): Effect.Effect<ReadonlySet<string>> =>\n\tEffect.map(aliases(reference, directory), (found) => new Set(found));\n\nexport interface Entry {\n\treadonly value: unknown;\n\treadonly answers: ReadonlySet<string>;\n\treadonly loads: boolean;\n}\n\n/**\n * What each configured entry answers to.\n *\n * Comparing the string as written is not enough. `plugin add @acme/x@1.2.0` records a version the\n * user will not repeat when removing it, and one plugin can be named three ways: by package, by\n * path, or by the ID it declares -- a `{ \"plugin\": \"<id>\" }` configuration object sits next to the\n * module entry that loaded it, and removing the plugin has to take both.\n *\n * The declared ID is only knowable by importing the module, so it is read from what is already\n * installed: `resolveCached` reads a published package out of the harness cache and never runs an\n * installer, so editing a settings file cannot fetch anything. An entry that does not resolve --\n * uninstalled, moved, or broken -- keeps the names it was written with rather than failing the\n * command, because an unusable plugin is exactly the one a user is trying to remove.\n */\nexport const identify = Effect.fn(\"CLI.plugin.identify\")(function* (\n\tplugins: ReadonlyArray<unknown>,\n\tfile: string,\n\tcache: string,\n) {\n\tconst nodePath = yield* Path.Path;\n\tconst directory = nodePath.dirname(file);\n\tconst entries: Entry[] = [];\n\tfor (const value of plugins) {\n\t\tconst answers = new Set<string>();\n\t\tconst id = idOf(value);\n\t\tif (id !== undefined) answers.add(id);\n\t\tconst module = moduleOf(value);\n\t\tif (module !== undefined) {\n\t\t\tfor (const alias of yield* aliases(module, directory)) answers.add(alias);\n\t\t\tconst declared = yield* Plugin.inspect(module, {\n\t\t\t\tcache,\n\t\t\t\thostDir: directory,\n\t\t\t\tfile,\n\t\t\t\tinstall: Plugin.resolveCached,\n\t\t\t}).pipe(Effect.option);\n\t\t\tif (Option.isSome(declared)) {\n\t\t\t\tanswers.add(declared.value.id);\n\t\t\t\tif (declared.value.name !== undefined) answers.add(declared.value.name);\n\t\t\t}\n\t\t}\n\t\tentries.push({ value, answers, loads: typeof value === \"string\" });\n\t}\n\treturn entries as ReadonlyArray<Entry>;\n});\n\n/**\n * What a local reference should be *written* as, which is rarely what was typed.\n *\n * A relative path on the command line is relative to the command's host directory; in a settings file it is relative to\n * that file's own directory. Those differ the moment the command runs anywhere but the directory\n * holding the file, and writing the string verbatim produces a silently wrong entry:\n *\n * ```\n * $ cd ~/workspace/app/packages/fubar\n * $ codework plugin add ./plugins/x.ts # means packages/fubar/plugins/x.ts\n * → the project is ~/workspace/app, so the entry lands in app/.codework/settings.jsonc\n * → written verbatim, the harness loads app/.codework/plugins/x.ts ← a different file\n * ```\n *\n * With both ends inside one project the entry is written relative to the file, which is portable\n * to any checkout of that repository and therefore worth committing. Otherwise -- a `-g` write\n * into `<home>`, a `--user-config-dir` elsewhere, or a target outside the project -- relative\n * would be a lie, and an absolute path means the same thing read from anywhere.\n *\n * A package spec is returned untouched: it names no location.\n */\nexport const written = Effect.fn(\"CLI.plugin.written\")(function* (\n\treference: string,\n\tinput: { readonly hostDir: string; readonly file: string; readonly root: string | undefined },\n) {\n\tconst nodePath = yield* Path.Path;\n\tconst target = yield* Plugin.parse(reference, input.hostDir).pipe(Effect.option);\n\tif (Option.isNone(target) || target.value.kind !== \"local\") return reference;\n\n\tconst absolute = target.value.path;\n\tconst inside = (root: string, path: string) => path === root || path.startsWith(`${root}${nodePath.sep}`);\n\tif (input.root !== undefined && inside(input.root, input.file) && inside(input.root, absolute)) {\n\t\tconst relative = nodePath.relative(nodePath.dirname(input.file), absolute);\n\t\treturn relative.startsWith(\"..\") ? relative : `./${relative}`;\n\t}\n\treturn absolute;\n});\n\n/** `reference` selects `entry` when any spelling of one is a spelling of the other. */\nexport const matches = (entry: Entry, spelled: ReadonlySet<string>) =>\n\t[...spelled].some((alias) => entry.answers.has(alias));\n\n/** Every entry connected to a reference through a package spelling or declared plugin ID. */\nexport const matching = (entries: ReadonlyArray<Entry>, spelled: ReadonlySet<string>) => {\n\tconst answers = new Set(spelled);\n\tconst found = new Set<Entry>();\n\tfor (;;) {\n\t\tconst next = entries.filter(\n\t\t\t(entry) => !found.has(entry) && [...entry.answers].some((answer) => answers.has(answer)),\n\t\t);\n\t\tif (next.length === 0) return found as ReadonlySet<Entry>;\n\t\tfor (const entry of next) {\n\t\t\tfound.add(entry);\n\t\t\tfor (const answer of entry.answers) answers.add(answer);\n\t\t}\n\t}\n};\n\nexport const readPlugins = Effect.fn(\"CLI.plugin.readPlugins\")(function* (path: string) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst exists = yield* fs.exists(path);\n\tconst source = exists ? yield* fs.readFileString(path) : \"{}\";\n\tconst errors: ParseError[] = [];\n\tconst document: unknown = parseJsonc(source, errors, { allowTrailingComma: true });\n\tif (errors.length > 0 || typeof document !== \"object\" || document === null || Array.isArray(document)) {\n\t\treturn yield* new InvalidInputError({ message: `${path} is not a valid settings file` });\n\t}\n\tconst plugins = (document as { plugins?: unknown }).plugins;\n\tif (plugins !== undefined && !Array.isArray(plugins)) {\n\t\treturn yield* new InvalidInputError({ message: `${path}: \"plugins\" must be an array` });\n\t}\n\treturn { source, plugins: (plugins ?? []) as ReadonlyArray<unknown> };\n});\n\nexport const writePlugins = Effect.fn(\"CLI.plugin.writePlugins\")(function* (\n\tpath: string,\n\tsource: string,\n\tplugins: ReadonlyArray<unknown>,\n) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst nodePath = yield* Path.Path;\n\tconst edited = applyEdits(\n\t\tsource,\n\t\tmodify(source, [\"plugins\"], plugins, { formattingOptions: { tabSize: 2, insertSpaces: false } }),\n\t);\n\tconst directory = nodePath.dirname(path);\n\tyield* fs.makeDirectory(directory, { recursive: true });\n\tconst mode = (yield* fs.exists(path)) ? (yield* fs.stat(path)).mode & 0o777 : 0o600;\n\tconst temporary = yield* fs.makeTempFile({ directory, prefix: `.${nodePath.basename(path)}.`, suffix: \".tmp\" });\n\tyield* fs\n\t\t.writeFileString(temporary, edited.endsWith(\"\\n\") ? edited : `${edited}\\n`)\n\t\t.pipe(\n\t\t\tEffect.andThen(fs.chmod(temporary, mode)),\n\t\t\tEffect.andThen(fs.rename(temporary, path)),\n\t\t\tEffect.ensuring(fs.remove(temporary, { force: true }).pipe(Effect.ignore)),\n\t\t);\n});\n\n/**\n * Serialize one settings read-modify-rename across CLI processes.\n *\n * The install or inspection that precedes an edit stays outside this scope; only the local edit is\n * locked, so unrelated downloads do not wait behind one another.\n */\nexport const withPluginsLock = <A, E, R>(path: string, edit: Effect.Effect<A, E, R>) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst nodePath = yield* Path.Path;\n\t\tyield* fs.makeDirectory(nodePath.dirname(path), { recursive: true });\n\t\tyield* Plugin.settingsLock(\n\t\t\t`${path}.lock`,\n\t\t\t() => new InvalidInputError({ message: `timed out waiting to edit ${path}` }),\n\t\t);\n\t\treturn yield* edit;\n\t}).pipe(Effect.scoped);\n\n/**\n * Which file the edit lands in.\n *\n * A plugin belongs to a project by default — it is part of how that repository is worked on, so\n * the entry belongs in a file the repository can commit. `--global` writes the user settings file\n * instead, the way `npm -g` installs outside a package: `<--home>/settings.jsonc`, or the\n * `--user-config-dir` one that replaces it.\n *\n * The project is found the way the harness finds it: the nearest ancestor holding a `.codework`\n * directory, so a command run from `packages/app` edits the repository's own file rather than\n * creating a second one beside it. When no ancestor has one, the project begins here -- the\n * directory is created and the caller is told, because that decision changes where every future\n * plugin entry lands, and a mistyped `cd` is the way it goes wrong.\n *\n * There is nothing to warn about between layers: plugin entries from every layer accumulate, so a\n * user-wide entry still applies inside a project that declares its own.\n */\nexport const resolveTarget = Effect.fn(\"CLI.plugin.resolveTarget\")(function* (\n\tshared: Shared,\n\tglobal: boolean,\n\t/**\n\t * Where to discover the project from, when it is not the shell's directory.\n\t *\n\t * A session's host directory is the only other honest answer: it is a declared host path. The\n\t * session's *space* is not, and neither is its project -- a `Project` is env-independent by\n\t * design, so it has no host directory to offer.\n\t */\n\tfrom?: string,\n\t/** Only `plugin add` may establish a project marker when no project exists yet. */\n\tcreate = true,\n) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst nodePath = yield* Path.Path;\n\tconst hostCwd = nodePath.resolve(\".\");\n\t// The linked session's host directory, or -- with none -- the one the command runs in.\n\tconst hostDir = from ?? hostCwd;\n\tconst home = yield* Global.resolve(Option.isNone(shared.home) ? {} : { home: shared.home.value });\n\tconst root = global ? undefined : yield* Settings.projectRoot(hostDir, home.home);\n\t// `paths` is ordered lowest priority first: the user layer, then the project.\n\tconst groups = Settings.paths({\n\t\thome: home.home,\n\t\t...(root === undefined ? {} : { root }),\n\t\t...userLayer(shared, hostCwd),\n\t});\n\tconst chosen = global ? 0 : 1;\n\t// An empty group is the project layer saying there is no project above this directory. Then\n\t// this directory becomes one -- reported, not silent, because the marker shadows any outer\n\t// project from now on, so a `.codework/` created by a mistyped `cd` is worth spotting at once.\n\tconst found = groups[chosen] ?? [];\n\tif (found.length > 0) {\n\t\tconst existing = yield* Effect.findFirst(found, (candidate) => fs.exists(candidate));\n\t\treturn {\n\t\t\tpath: Option.getOrElse(existing, () => found[0]!),\n\t\t\t...(root === undefined ? {} : { root }),\n\t\t} satisfies Target;\n\t}\n\tconst marker = nodePath.join(hostDir, \".codework\");\n\t// `created` is reported either way: with `create` unset the marker is named, not made, so a\n\t// caller can say what its write is about to establish without establishing it early.\n\tif (!create)\n\t\treturn { path: nodePath.join(marker, \"settings.jsonc\"), created: marker, root: hostDir } satisfies Target;\n\tyield* fs.makeDirectory(marker, { recursive: true });\n\treturn { path: nodePath.join(marker, \"settings.jsonc\"), created: marker, root: hostDir } satisfies Target;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"settings-DDkmAxW5.mjs","names":["parseJsonc"],"sources":["../../src/cli/cmd/handlers/plugin/settings.ts"],"sourcesContent":["import { Global, Plugin, Settings } from \"@codeworksh/harness/effect\";\nimport { Effect, FileSystem, Option, Path } from \"effect\";\nimport { applyEdits, modify, parse as parseJsonc, type ParseError } from \"jsonc-parser\";\nimport { InvalidInputError } from \"../../../error.ts\";\n\n/**\n * Reading and rewriting the `plugins` array of one settings file.\n *\n * Edits go through `jsonc-parser`, so a hand-written file keeps its comments, key order and\n * formatting: a plugin added by the CLI must not reformat a file its owner maintains. The write\n * is a temp file renamed over the original, so an interrupted run leaves the previous settings\n * intact rather than a half-written document.\n */\n\nexport interface Shared {\n\treadonly userConfigDir: Option.Option<string>;\n\treadonly home: Option.Option<string>;\n}\n\n/**\n * The user layer a command reads and writes: `--user-config-dir` when given -- a hard override of\n * the home's settings file -- resolved, like every app-level flag, against the directory the\n * command runs in (`hostCwd`), never against a linked session's `hostDir`.\n */\nexport const userLayer = (shared: Shared, hostCwd: string) =>\n\tOption.isNone(shared.userConfigDir)\n\t\t? {}\n\t\t: { userConfigDir: Settings.userConfigDir(shared.userConfigDir.value, hostCwd) };\n\nexport interface Target {\n\treadonly path: string;\n\t/** Set when this command had to create the project directory, so the caller can say so. */\n\treadonly created?: string;\n\t/** The project this file belongs to, which a local entry is written relative to. */\n\treadonly root?: string;\n}\n\n/** The module an entry names: a bare loader string, or the `package` of a config object. */\nconst moduleOf = (entry: unknown): string | undefined => {\n\tif (typeof entry === \"string\") return entry;\n\tif (typeof entry !== \"object\" || entry === null) return undefined;\n\tconst { package: located } = entry as { package?: unknown };\n\treturn typeof located === \"string\" ? located : undefined;\n};\n\n/** The plugin ID an entry configures, if it names one. */\nconst idOf = (entry: unknown): string | undefined => {\n\tif (typeof entry !== \"object\" || entry === null) return undefined;\n\tconst { plugin } = entry as { plugin?: unknown };\n\treturn typeof plugin === \"string\" ? plugin : undefined;\n};\n\n/**\n * Every spelling a reference answers to, without touching the filesystem.\n *\n * `canonical` drops a version suffix and resolves a relative path against the file that declared\n * it, so `@acme/x@1.2.0` and `@acme/x` are one name. The literal string is kept alongside it\n * because a plugin ID is not a module reference and survives `canonical` unchanged.\n */\nconst aliases = (reference: string, directory: string): Effect.Effect<ReadonlyArray<string>> =>\n\tPlugin.canonical(reference, directory).pipe(\n\t\tEffect.map((canonical) => [reference, canonical] as ReadonlyArray<string>),\n\t\t// A reference that does not parse still answers to itself: a plugin ID is not a module\n\t\t// reference, and it has to keep matching an entry that names it.\n\t\tEffect.orElseSucceed(() => [reference] as ReadonlyArray<string>),\n\t);\n\n/** Every spelling `reference` answers to, computed once for a whole command. */\nexport const spellings = (reference: string, directory: string): Effect.Effect<ReadonlySet<string>> =>\n\tEffect.map(aliases(reference, directory), (found) => new Set(found));\n\nexport interface Entry {\n\treadonly value: unknown;\n\treadonly answers: ReadonlySet<string>;\n\treadonly loads: boolean;\n}\n\n/**\n * What each configured entry answers to.\n *\n * Comparing the string as written is not enough. `plugin add @acme/x@1.2.0` records a version the\n * user will not repeat when removing it, and one plugin can be named three ways: by package, by\n * path, or by the ID it declares -- a `{ \"plugin\": \"<id>\" }` configuration object sits next to the\n * module entry that loaded it, and removing the plugin has to take both.\n *\n * The declared ID is only knowable by importing the module, so it is read from what is already\n * installed: `resolveCached` reads a published package out of the harness cache and never runs an\n * installer, so editing a settings file cannot fetch anything. An entry that does not resolve --\n * uninstalled, moved, or broken -- keeps the names it was written with rather than failing the\n * command, because an unusable plugin is exactly the one a user is trying to remove.\n */\nexport const identify = Effect.fn(\"CLI.plugin.identify\")(function* (\n\tplugins: ReadonlyArray<unknown>,\n\tfile: string,\n\tcache: string,\n) {\n\tconst nodePath = yield* Path.Path;\n\tconst directory = nodePath.dirname(file);\n\tconst entries: Entry[] = [];\n\tfor (const value of plugins) {\n\t\tconst answers = new Set<string>();\n\t\tconst id = idOf(value);\n\t\tif (id !== undefined) answers.add(id);\n\t\tconst module = moduleOf(value);\n\t\tif (module !== undefined) {\n\t\t\tfor (const alias of yield* aliases(module, directory)) answers.add(alias);\n\t\t\tconst declared = yield* Plugin.inspect(module, {\n\t\t\t\tcache,\n\t\t\t\thostDir: directory,\n\t\t\t\tfile,\n\t\t\t\tinstall: Plugin.resolveCached,\n\t\t\t}).pipe(Effect.option);\n\t\t\tif (Option.isSome(declared)) {\n\t\t\t\tanswers.add(declared.value.id);\n\t\t\t\tif (declared.value.name !== undefined) answers.add(declared.value.name);\n\t\t\t}\n\t\t}\n\t\tentries.push({ value, answers, loads: typeof value === \"string\" });\n\t}\n\treturn entries as ReadonlyArray<Entry>;\n});\n\n/**\n * What a local reference should be *written* as, which is rarely what was typed.\n *\n * A relative path on the command line is relative to the command's host directory; in a settings file it is relative to\n * that file's own directory. Those differ the moment the command runs anywhere but the directory\n * holding the file, and writing the string verbatim produces a silently wrong entry:\n *\n * ```\n * $ cd ~/workspace/app/packages/fubar\n * $ codework plugin add ./plugins/x.ts # means packages/fubar/plugins/x.ts\n * → the project is ~/workspace/app, so the entry lands in app/.codework/settings.jsonc\n * → written verbatim, the harness loads app/.codework/plugins/x.ts ← a different file\n * ```\n *\n * With both ends inside one project the entry is written relative to the file, which is portable\n * to any checkout of that repository and therefore worth committing. Otherwise -- a `-g` write\n * into `<home>`, a `--user-config-dir` elsewhere, or a target outside the project -- relative\n * would be a lie, and an absolute path means the same thing read from anywhere.\n *\n * A package spec is returned untouched: it names no location.\n */\nexport const written = Effect.fn(\"CLI.plugin.written\")(function* (\n\treference: string,\n\tinput: { readonly hostDir: string; readonly file: string; readonly root: string | undefined },\n) {\n\tconst nodePath = yield* Path.Path;\n\tconst target = yield* Plugin.parse(reference, input.hostDir).pipe(Effect.option);\n\tif (Option.isNone(target) || target.value.kind !== \"local\") return reference;\n\n\tconst absolute = target.value.path;\n\tconst inside = (root: string, path: string) => path === root || path.startsWith(`${root}${nodePath.sep}`);\n\tif (input.root !== undefined && inside(input.root, input.file) && inside(input.root, absolute)) {\n\t\tconst relative = nodePath.relative(nodePath.dirname(input.file), absolute);\n\t\treturn relative.startsWith(\"..\") ? relative : `./${relative}`;\n\t}\n\treturn absolute;\n});\n\n/** `reference` selects `entry` when any spelling of one is a spelling of the other. */\nexport const matches = (entry: Entry, spelled: ReadonlySet<string>) =>\n\t[...spelled].some((alias) => entry.answers.has(alias));\n\n/** Every entry connected to a reference through a package spelling or declared plugin ID. */\nexport const matching = (entries: ReadonlyArray<Entry>, spelled: ReadonlySet<string>) => {\n\tconst answers = new Set(spelled);\n\tconst found = new Set<Entry>();\n\tfor (;;) {\n\t\tconst next = entries.filter(\n\t\t\t(entry) => !found.has(entry) && [...entry.answers].some((answer) => answers.has(answer)),\n\t\t);\n\t\tif (next.length === 0) return found as ReadonlySet<Entry>;\n\t\tfor (const entry of next) {\n\t\t\tfound.add(entry);\n\t\t\tfor (const answer of entry.answers) answers.add(answer);\n\t\t}\n\t}\n};\n\nexport const readPlugins = Effect.fn(\"CLI.plugin.readPlugins\")(function* (path: string) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst exists = yield* fs.exists(path);\n\tconst source = exists ? yield* fs.readFileString(path) : \"{}\";\n\tconst errors: ParseError[] = [];\n\tconst document: unknown = parseJsonc(source, errors, { allowTrailingComma: true });\n\tif (errors.length > 0 || typeof document !== \"object\" || document === null || Array.isArray(document)) {\n\t\treturn yield* new InvalidInputError({ message: `${path} is not a valid settings file` });\n\t}\n\tconst plugins = (document as { plugins?: unknown }).plugins;\n\tif (plugins !== undefined && !Array.isArray(plugins)) {\n\t\treturn yield* new InvalidInputError({ message: `${path}: \"plugins\" must be an array` });\n\t}\n\treturn { source, plugins: (plugins ?? []) as ReadonlyArray<unknown> };\n});\n\nexport const writePlugins = Effect.fn(\"CLI.plugin.writePlugins\")(function* (\n\tpath: string,\n\tsource: string,\n\tplugins: ReadonlyArray<unknown>,\n) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst nodePath = yield* Path.Path;\n\tconst edited = applyEdits(\n\t\tsource,\n\t\tmodify(source, [\"plugins\"], plugins, { formattingOptions: { tabSize: 2, insertSpaces: false } }),\n\t);\n\tconst directory = nodePath.dirname(path);\n\tyield* fs.makeDirectory(directory, { recursive: true });\n\tconst mode = (yield* fs.exists(path)) ? (yield* fs.stat(path)).mode & 0o777 : 0o600;\n\tconst temporary = yield* fs.makeTempFile({ directory, prefix: `.${nodePath.basename(path)}.`, suffix: \".tmp\" });\n\tyield* fs\n\t\t.writeFileString(temporary, edited.endsWith(\"\\n\") ? edited : `${edited}\\n`)\n\t\t.pipe(\n\t\t\tEffect.andThen(fs.chmod(temporary, mode)),\n\t\t\tEffect.andThen(fs.rename(temporary, path)),\n\t\t\tEffect.ensuring(fs.remove(temporary, { force: true }).pipe(Effect.ignore)),\n\t\t);\n});\n\n/**\n * Serialize one settings read-modify-rename across CLI processes.\n *\n * The install or inspection that precedes an edit stays outside this scope; only the local edit is\n * locked, so unrelated downloads do not wait behind one another.\n */\nexport const withPluginsLock = <A, E, R>(path: string, edit: Effect.Effect<A, E, R>) =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst nodePath = yield* Path.Path;\n\t\tyield* fs.makeDirectory(nodePath.dirname(path), { recursive: true });\n\t\tyield* Plugin.settingsLock(\n\t\t\t`${path}.lock`,\n\t\t\t() => new InvalidInputError({ message: `timed out waiting to edit ${path}` }),\n\t\t);\n\t\treturn yield* edit;\n\t}).pipe(Effect.scoped);\n\n/**\n * Which file the edit lands in.\n *\n * A plugin belongs to a project by default — it is part of how that repository is worked on, so\n * the entry belongs in a file the repository can commit. `--global` writes the user settings file\n * instead, the way `npm -g` installs outside a package: `<--home>/settings.jsonc`, or the\n * `--user-config-dir` one that replaces it.\n *\n * The project is found the way the harness finds it: the nearest ancestor holding a `.codework`\n * directory, so a command run from `packages/app` edits the repository's own file rather than\n * creating a second one beside it. When no ancestor has one, the project begins here -- the\n * directory is created and the caller is told, because that decision changes where every future\n * plugin entry lands, and a mistyped `cd` is the way it goes wrong.\n *\n * There is nothing to warn about between layers: plugin entries from every layer accumulate, so a\n * user-wide entry still applies inside a project that declares its own.\n */\nexport const resolveTarget = Effect.fn(\"CLI.plugin.resolveTarget\")(function* (\n\tshared: Shared,\n\tglobal: boolean,\n\t/**\n\t * Where to discover the project from, when it is not the shell's directory.\n\t *\n\t * A session's host directory is the only other honest answer: it is a declared host path. The\n\t * session's *space* is not, and neither is its project -- a `Project` is env-independent by\n\t * design, so it has no host directory to offer.\n\t */\n\tfrom?: string,\n\t/** Only `plugin add` may establish a project marker when no project exists yet. */\n\tcreate = true,\n) {\n\tconst fs = yield* FileSystem.FileSystem;\n\tconst nodePath = yield* Path.Path;\n\tconst hostCwd = nodePath.resolve(\".\");\n\t// The linked session's host directory, or -- with none -- the one the command runs in.\n\tconst hostDir = from ?? hostCwd;\n\tconst home = yield* Global.resolve(Option.isNone(shared.home) ? {} : { home: shared.home.value });\n\tconst root = global ? undefined : yield* Settings.projectRoot(hostDir, home.home);\n\t// `paths` is ordered lowest priority first: the user layer, then the project.\n\tconst groups = Settings.paths({\n\t\thome: home.home,\n\t\t...(root === undefined ? {} : { root }),\n\t\t...userLayer(shared, hostCwd),\n\t});\n\tconst chosen = global ? 0 : 1;\n\t// An empty group is the project layer saying there is no project above this directory. Then\n\t// this directory becomes one -- reported, not silent, because the marker shadows any outer\n\t// project from now on, so a `.codework/` created by a mistyped `cd` is worth spotting at once.\n\tconst found = groups[chosen] ?? [];\n\tif (found.length > 0) {\n\t\tconst existing = yield* Effect.findFirst(found, (candidate) => fs.exists(candidate));\n\t\treturn {\n\t\t\tpath: Option.getOrElse(existing, () => found[0]!),\n\t\t\t...(root === undefined ? {} : { root }),\n\t\t} satisfies Target;\n\t}\n\tconst marker = nodePath.join(hostDir, \".codework\");\n\t// `created` is reported either way: with `create` unset the marker is named, not made, so a\n\t// caller can say what its write is about to establish without establishing it early.\n\tif (!create)\n\t\treturn { path: nodePath.join(marker, \"settings.jsonc\"), created: marker, root: hostDir } satisfies Target;\n\tyield* fs.makeDirectory(marker, { recursive: true });\n\treturn { path: nodePath.join(marker, \"settings.jsonc\"), created: marker, root: hostDir } satisfies Target;\n});\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { i as Cmd } from "./runtime-B3dlWGfs.mjs";
2
- import { f as layer, n as OAuthError, t as InvalidInputError } from "./error-CxoEKg-4.mjs";
1
+ import { i as Cmd } from "./runtime-D4zyJPrh.mjs";
2
+ import { f as layer, n as OAuthError, t as InvalidInputError } from "./error-C9ACQhhu.mjs";
3
3
  import { Effect, Option, Path } from "effect";
4
- import { checkOAuthProvider, oauthProviderLabel, summarizeGitHubCopilot, summarizeOpenAICodex } from "@codeworksh/aikit/oauth/summary";
5
4
  import { Global } from "@codeworksh/harness/effect";
5
+ import { checkOAuthProvider, oauthProviderLabel, summarizeGitHubCopilot, summarizeOpenAICodex } from "@codeworksh/aikit/oauth/summary";
6
6
  import { GitHubCopilotOAuthClient, JsonGitHubCopilotAuthStorage } from "@codeworksh/aikit/oauth/github/copilot";
7
7
  import { JsonOpenAICodexAuthStorage, OpenAICodexOAuthClient } from "@codeworksh/aikit/oauth/openai/codex";
8
8
  import { openBrowser, promptLine } from "@codeworksh/aikit/oauth/interactive";
@@ -113,4 +113,4 @@ const withServer = (url, program) => program.pipe(Effect.provide(layer(url)), Ef
113
113
  //#endregion
114
114
  export { oauthProviderLabel as a, makeOps as i, attempt as n, selectProvider as o, localOps as r, withServer as s, assertServerScope as t };
115
115
 
116
- //# sourceMappingURL=shared-IycfDUnF.mjs.map
116
+ //# sourceMappingURL=shared-DFB2--6V.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-IycfDUnF.mjs","names":["Client.layer"],"sources":["../../src/cli/cmd/handlers/auth/shared.ts"],"sourcesContent":["/* @effect-diagnostics nodeBuiltinImport:off -- OAuth login opens the system browser. */\n/* @effect-diagnostics globalDate:off -- Stored expiry timestamps are rendered for the user. */\n/* oxlint-disable effecttsgo/async-function -- Aikit OAuth callbacks require Promise-returning functions. */\nimport {\n\tGitHubCopilotOAuthClient,\n\tJsonGitHubCopilotAuthStorage,\n\ttype GitHubCopilotAuthStorage,\n} from \"@codeworksh/aikit/oauth/github/copilot\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexAuthStorage,\n} from \"@codeworksh/aikit/oauth/openai/codex\";\nimport { openBrowser, promptLine } from \"@codeworksh/aikit/oauth/interactive\";\nimport {\n\tcheckOAuthProvider,\n\toauthProviderLabel,\n\tsummarizeGitHubCopilot,\n\tsummarizeOpenAICodex,\n\ttype OAuthSummary,\n} from \"@codeworksh/aikit/oauth/summary\";\nimport { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, Option, Path } from \"effect\";\nimport { Client } from \"../../../../server/client.ts\";\nimport type { Contract } from \"../../../../server/contract.ts\";\nimport { InvalidInputError, OAuthError } from \"../../../error.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport type Provider = Contract.OAuthProvider;\n\n// The wire shape and aikit's summary are the same record.\nexport type Summary = Contract.OAuthInfo & OAuthSummary;\n\nconst announce = (\n\tinfo: { url: string; userCode?: string | undefined; instructions?: string | undefined },\n\tbrowser: boolean,\n): void => {\n\tprocess.stderr.write(\n\t\t`${info.instructions ?? \"Complete authentication in your browser.\"}\\n${\n\t\t\tinfo.userCode === undefined ? \"\" : `Enter code: ${info.userCode}\\n`\n\t\t}${info.url}\\n`,\n\t);\n\tif (browser) {\n\t\tvoid openBrowser(info.url, (error) => void process.stderr.write(`Failed to open browser: ${error.message}\\n`));\n\t}\n};\n\nexport interface LoginOptions {\n\treadonly browser: boolean;\n\treadonly device: boolean;\n\treadonly enterprise: Option.Option<string>;\n\treadonly enableModels: boolean;\n}\n\nexport interface Ops {\n\treadonly path: string;\n\treadonly login: (options: LoginOptions) => Promise<{ wire: Contract.OAuthCredentials; summary: Summary }>;\n\treadonly stored: () => Promise<Summary | undefined>;\n\treadonly refreshed: () => Promise<Summary | undefined>;\n\treadonly logout: () => Promise<void>;\n}\n\n/** Holds nothing: a server's credentials live on the server, not on this disk. */\nconst transient: OpenAICodexAuthStorage & GitHubCopilotAuthStorage = {\n\tget: async () => undefined,\n\tset: async () => {},\n\tclear: async () => {},\n};\n\nconst codexOps = (storage: OpenAICodexAuthStorage, path: string): Ops => {\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\treturn {\n\t\tpath,\n\t\tlogin: async (options) => {\n\t\t\tconst credentials = await client.login({\n\t\t\t\tdevice: options.device,\n\t\t\t\tonAuth: (info) => announce(info, options.browser),\n\t\t\t\tonProgress: (message) => void process.stderr.write(`${message}\\n`),\n\t\t\t\tonPrompt: (prompt) => promptLine(prompt.message),\n\t\t\t});\n\t\t\treturn { wire: { provider: \"openai-codex\", ...credentials }, summary: summarizeOpenAICodex(credentials) };\n\t\t},\n\t\tstored: async () => {\n\t\t\tconst credentials = await storage.get();\n\t\t\treturn credentials && summarizeOpenAICodex(credentials);\n\t\t},\n\t\trefreshed: async () => {\n\t\t\tconst credentials = await client.getCredentials();\n\t\t\treturn credentials && summarizeOpenAICodex(credentials);\n\t\t},\n\t\tlogout: () => client.logout(),\n\t};\n};\n\nconst copilotOps = (storage: GitHubCopilotAuthStorage, path: string): Ops => {\n\tconst client = new GitHubCopilotOAuthClient({ storage });\n\tconst read = async () => {\n\t\tconst credentials = await storage.get();\n\t\treturn credentials && summarizeGitHubCopilot(credentials);\n\t};\n\treturn {\n\t\tpath,\n\t\tlogin: async (options) => {\n\t\t\tconst credentials = await client.login({\n\t\t\t\t...(Option.isSome(options.enterprise) && { enterpriseUrl: options.enterprise.value }),\n\t\t\t\tenableModels: options.enableModels,\n\t\t\t\tonAuth: (info) => announce(info, options.browser),\n\t\t\t\tonProgress: (message) => void process.stderr.write(`${message}\\n`),\n\t\t\t});\n\t\t\treturn { wire: { provider: \"github-copilot\", ...credentials }, summary: summarizeGitHubCopilot(credentials) };\n\t\t},\n\t\tstored: read,\n\t\t// GitHub OAuth tokens never expire, so there is nothing to refresh.\n\t\trefreshed: read,\n\t\tlogout: () => client.logout(),\n\t};\n};\n\nexport const makeOps = (provider: Provider, options: { path?: string | undefined; persist?: boolean } = {}): Ops => {\n\tconst file = options.path === undefined ? {} : { path: options.path };\n\tif (provider === \"openai-codex\") {\n\t\tconst storage = options.persist === false ? undefined : new JsonOpenAICodexAuthStorage(file);\n\t\treturn codexOps(storage ?? transient, storage?.path ?? \"\");\n\t}\n\tconst storage = options.persist === false ? undefined : new JsonGitHubCopilotAuthStorage(file);\n\treturn copilotOps(storage ?? transient, storage?.path ?? \"\");\n};\n\nexport const attempt = <A>(message: string, run: () => Promise<A>) =>\n\tEffect.tryPromise({ try: run, catch: (cause) => new OAuthError({ message, cause }) });\n\n/** The provider named by the two mutually exclusive flags. */\nexport const selectProvider = (flags: {\n\treadonly openaiCodex: boolean;\n\treadonly githubCopilot: boolean;\n}): Effect.Effect<Provider, InvalidInputError> => {\n\tconst checked = checkOAuthProvider(flags);\n\treturn checked.ok\n\t\t? Effect.succeed(checked.provider)\n\t\t: Effect.fail(new InvalidInputError({ message: checked.message }));\n};\n\n/** Reject the local-credential flags when the credentials live on a server. */\nexport const assertServerScope = (authFile: Option.Option<string>) =>\n\tEffect.gen(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\tif (Option.isSome(authFile) || Option.isSome(shared.home)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--auth-file and --home belong on codework serve when using --server\",\n\t\t\t});\n\t\t}\n\t});\n\n/** Credential operations against this machine's auth.json. */\nexport const localOps = (provider: Provider, authFile: Option.Option<string>) =>\n\tEffect.gen(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\tconst path = yield* Path.Path;\n\t\tconst file = Option.isSome(authFile)\n\t\t\t? authFile.value\n\t\t\t: Option.isSome(shared.home)\n\t\t\t\t? path.join((yield* Global.resolve({ home: shared.home.value })).home, \"aikit\", \"auth.json\")\n\t\t\t\t: undefined;\n\t\treturn makeOps(provider, file === undefined ? {} : { path: file });\n\t});\n\n/** Run an effect against the RPC server at `url`, discharging the client. */\nexport const withServer = <A, E, R>(url: string, program: Effect.Effect<A, E, R>) =>\n\tprogram.pipe(Effect.provide(Client.layer(url)), Effect.scoped);\n\nexport { Client, oauthProviderLabel };\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-DFB2--6V.mjs","names":["Client.layer"],"sources":["../../src/cli/cmd/handlers/auth/shared.ts"],"sourcesContent":["/* @effect-diagnostics nodeBuiltinImport:off -- OAuth login opens the system browser. */\n/* @effect-diagnostics globalDate:off -- Stored expiry timestamps are rendered for the user. */\n/* oxlint-disable effecttsgo/async-function -- Aikit OAuth callbacks require Promise-returning functions. */\nimport {\n\tGitHubCopilotOAuthClient,\n\tJsonGitHubCopilotAuthStorage,\n\ttype GitHubCopilotAuthStorage,\n} from \"@codeworksh/aikit/oauth/github/copilot\";\nimport {\n\tJsonOpenAICodexAuthStorage,\n\tOpenAICodexOAuthClient,\n\ttype OpenAICodexAuthStorage,\n} from \"@codeworksh/aikit/oauth/openai/codex\";\nimport { openBrowser, promptLine } from \"@codeworksh/aikit/oauth/interactive\";\nimport {\n\tcheckOAuthProvider,\n\toauthProviderLabel,\n\tsummarizeGitHubCopilot,\n\tsummarizeOpenAICodex,\n\ttype OAuthSummary,\n} from \"@codeworksh/aikit/oauth/summary\";\nimport { Global } from \"@codeworksh/harness/effect\";\nimport { Effect, Option, Path } from \"effect\";\nimport { Client } from \"../../../../server/client.ts\";\nimport type { Contract } from \"../../../../server/contract.ts\";\nimport { InvalidInputError, OAuthError } from \"../../../error.ts\";\nimport { Cmd } from \"../../cmd.ts\";\n\nexport type Provider = Contract.OAuthProvider;\n\n// The wire shape and aikit's summary are the same record.\nexport type Summary = Contract.OAuthInfo & OAuthSummary;\n\nconst announce = (\n\tinfo: { url: string; userCode?: string | undefined; instructions?: string | undefined },\n\tbrowser: boolean,\n): void => {\n\tprocess.stderr.write(\n\t\t`${info.instructions ?? \"Complete authentication in your browser.\"}\\n${\n\t\t\tinfo.userCode === undefined ? \"\" : `Enter code: ${info.userCode}\\n`\n\t\t}${info.url}\\n`,\n\t);\n\tif (browser) {\n\t\tvoid openBrowser(info.url, (error) => void process.stderr.write(`Failed to open browser: ${error.message}\\n`));\n\t}\n};\n\nexport interface LoginOptions {\n\treadonly browser: boolean;\n\treadonly device: boolean;\n\treadonly enterprise: Option.Option<string>;\n\treadonly enableModels: boolean;\n}\n\nexport interface Ops {\n\treadonly path: string;\n\treadonly login: (options: LoginOptions) => Promise<{ wire: Contract.OAuthCredentials; summary: Summary }>;\n\treadonly stored: () => Promise<Summary | undefined>;\n\treadonly refreshed: () => Promise<Summary | undefined>;\n\treadonly logout: () => Promise<void>;\n}\n\n/** Holds nothing: a server's credentials live on the server, not on this disk. */\nconst transient: OpenAICodexAuthStorage & GitHubCopilotAuthStorage = {\n\tget: async () => undefined,\n\tset: async () => {},\n\tclear: async () => {},\n};\n\nconst codexOps = (storage: OpenAICodexAuthStorage, path: string): Ops => {\n\tconst client = new OpenAICodexOAuthClient({ storage });\n\treturn {\n\t\tpath,\n\t\tlogin: async (options) => {\n\t\t\tconst credentials = await client.login({\n\t\t\t\tdevice: options.device,\n\t\t\t\tonAuth: (info) => announce(info, options.browser),\n\t\t\t\tonProgress: (message) => void process.stderr.write(`${message}\\n`),\n\t\t\t\tonPrompt: (prompt) => promptLine(prompt.message),\n\t\t\t});\n\t\t\treturn { wire: { provider: \"openai-codex\", ...credentials }, summary: summarizeOpenAICodex(credentials) };\n\t\t},\n\t\tstored: async () => {\n\t\t\tconst credentials = await storage.get();\n\t\t\treturn credentials && summarizeOpenAICodex(credentials);\n\t\t},\n\t\trefreshed: async () => {\n\t\t\tconst credentials = await client.getCredentials();\n\t\t\treturn credentials && summarizeOpenAICodex(credentials);\n\t\t},\n\t\tlogout: () => client.logout(),\n\t};\n};\n\nconst copilotOps = (storage: GitHubCopilotAuthStorage, path: string): Ops => {\n\tconst client = new GitHubCopilotOAuthClient({ storage });\n\tconst read = async () => {\n\t\tconst credentials = await storage.get();\n\t\treturn credentials && summarizeGitHubCopilot(credentials);\n\t};\n\treturn {\n\t\tpath,\n\t\tlogin: async (options) => {\n\t\t\tconst credentials = await client.login({\n\t\t\t\t...(Option.isSome(options.enterprise) && { enterpriseUrl: options.enterprise.value }),\n\t\t\t\tenableModels: options.enableModels,\n\t\t\t\tonAuth: (info) => announce(info, options.browser),\n\t\t\t\tonProgress: (message) => void process.stderr.write(`${message}\\n`),\n\t\t\t});\n\t\t\treturn { wire: { provider: \"github-copilot\", ...credentials }, summary: summarizeGitHubCopilot(credentials) };\n\t\t},\n\t\tstored: read,\n\t\t// GitHub OAuth tokens never expire, so there is nothing to refresh.\n\t\trefreshed: read,\n\t\tlogout: () => client.logout(),\n\t};\n};\n\nexport const makeOps = (provider: Provider, options: { path?: string | undefined; persist?: boolean } = {}): Ops => {\n\tconst file = options.path === undefined ? {} : { path: options.path };\n\tif (provider === \"openai-codex\") {\n\t\tconst storage = options.persist === false ? undefined : new JsonOpenAICodexAuthStorage(file);\n\t\treturn codexOps(storage ?? transient, storage?.path ?? \"\");\n\t}\n\tconst storage = options.persist === false ? undefined : new JsonGitHubCopilotAuthStorage(file);\n\treturn copilotOps(storage ?? transient, storage?.path ?? \"\");\n};\n\nexport const attempt = <A>(message: string, run: () => Promise<A>) =>\n\tEffect.tryPromise({ try: run, catch: (cause) => new OAuthError({ message, cause }) });\n\n/** The provider named by the two mutually exclusive flags. */\nexport const selectProvider = (flags: {\n\treadonly openaiCodex: boolean;\n\treadonly githubCopilot: boolean;\n}): Effect.Effect<Provider, InvalidInputError> => {\n\tconst checked = checkOAuthProvider(flags);\n\treturn checked.ok\n\t\t? Effect.succeed(checked.provider)\n\t\t: Effect.fail(new InvalidInputError({ message: checked.message }));\n};\n\n/** Reject the local-credential flags when the credentials live on a server. */\nexport const assertServerScope = (authFile: Option.Option<string>) =>\n\tEffect.gen(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\tif (Option.isSome(authFile) || Option.isSome(shared.home)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--auth-file and --home belong on codework serve when using --server\",\n\t\t\t});\n\t\t}\n\t});\n\n/** Credential operations against this machine's auth.json. */\nexport const localOps = (provider: Provider, authFile: Option.Option<string>) =>\n\tEffect.gen(function* () {\n\t\tconst shared = yield* Cmd.spec;\n\t\tconst path = yield* Path.Path;\n\t\tconst file = Option.isSome(authFile)\n\t\t\t? authFile.value\n\t\t\t: Option.isSome(shared.home)\n\t\t\t\t? path.join((yield* Global.resolve({ home: shared.home.value })).home, \"aikit\", \"auth.json\")\n\t\t\t\t: undefined;\n\t\treturn makeOps(provider, file === undefined ? {} : { path: file });\n\t});\n\n/** Run an effect against the RPC server at `url`, discharging the client. */\nexport const withServer = <A, E, R>(url: string, program: Effect.Effect<A, E, R>) =>\n\tprogram.pipe(Effect.provide(Client.layer(url)), Effect.scoped);\n\nexport { Client, oauthProviderLabel };\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { i as Cmd, t as handler } from "./runtime-B3dlWGfs.mjs";
2
- import { d as writeOut, i as reportFailure, n as OAuthError, p as make } from "./error-CxoEKg-4.mjs";
3
- import { a as oauthProviderLabel, n as attempt, o as selectProvider, r as localOps, s as withServer, t as assertServerScope } from "./shared-IycfDUnF.mjs";
1
+ import { i as Cmd, t as handler } from "./runtime-D4zyJPrh.mjs";
2
+ import { d as writeOut, i as reportFailure, n as OAuthError, p as make } from "./error-C9ACQhhu.mjs";
3
+ import { a as oauthProviderLabel, n as attempt, o as selectProvider, r as localOps, s as withServer, t as assertServerScope } from "./shared-DFB2--6V.mjs";
4
4
  import { Effect, Option } from "effect";
5
5
  import { formatOAuthSummary, oauthNotice } from "@codeworksh/aikit/oauth/summary";
6
6
  //#region src/cli/cmd/handlers/auth/status.ts
@@ -28,4 +28,4 @@ var status_default = handler(Cmd.commands.auth.commands.status, Effect.fn("CLI.a
28
28
  //#endregion
29
29
  export { status_default as default };
30
30
 
31
- //# sourceMappingURL=status-CCj71RVv.mjs.map
31
+ //# sourceMappingURL=status-BNc5JZ1C.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-CCj71RVv.mjs","names":["Runtime.handler","Client.make"],"sources":["../../src/cli/cmd/handlers/auth/status.ts"],"sourcesContent":["import { formatOAuthSummary, oauthNotice } from \"@codeworksh/aikit/oauth/summary\";\nimport { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { OAuthError, reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport {\n\tassertServerScope,\n\tattempt,\n\tClient,\n\tlocalOps,\n\toauthProviderLabel,\n\tselectProvider,\n\twithServer,\n} from \"./shared.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.auth.commands.status,\n\tEffect.fn(\"CLI.auth.status\")(function* ({ server, openaiCodex, githubCopilot, authFile, json }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst provider = yield* selectProvider({ openaiCodex, githubCopilot });\n\t\t\tconst name = oauthProviderLabel(provider);\n\n\t\t\tif (Option.isSome(server)) {\n\t\t\t\tyield* assertServerScope(authFile);\n\t\t\t\treturn yield* withServer(\n\t\t\t\t\tserver.value,\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst rpc = yield* Client.make;\n\t\t\t\t\t\tconst info = yield* rpc[\"auth.status\"]({ provider });\n\t\t\t\t\t\tif (info === null) {\n\t\t\t\t\t\t\treturn yield* new OAuthError({ message: oauthNotice(\"missing\", provider, \"the server\") });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield* writeOut(formatOAuthSummary(info, { json }));\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst ops = yield* localOps(provider, authFile);\n\t\t\tconst summary = yield* attempt(`failed to read ${name} credentials`, () => ops.stored());\n\t\t\tif (summary === undefined) {\n\t\t\t\treturn yield* new OAuthError({ message: oauthNotice(\"missing\", provider, ops.path) });\n\t\t\t}\n\t\t\tyield* writeOut(formatOAuthSummary(summary, { json }));\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;AAgBA,IAAA,iBAAeA,QACd,IAAI,SAAS,KAAK,SAAS,QAC3B,OAAO,GAAG,iBAAiB,CAAC,CAAC,WAAW,EAAE,QAAQ,aAAa,eAAe,UAAU,QAAQ;CA4B/F,OAAO,OA3BS,OAAO,IAAI,aAAa;EACvC,MAAM,WAAW,OAAO,eAAe;GAAE;GAAa;EAAc,CAAC;EACrE,MAAM,OAAO,mBAAmB,QAAQ;EAExC,IAAI,OAAO,OAAO,MAAM,GAAG;GAC1B,OAAO,kBAAkB,QAAQ;GACjC,OAAO,OAAO,WACb,OAAO,OACP,OAAO,IAAI,aAAa;IAEvB,MAAM,OAAO,QAAO,OADDC,KAAAA,CACK,cAAc,CAAC,EAAE,SAAS,CAAC;IACnD,IAAI,SAAS,MACZ,OAAO,OAAO,IAAI,WAAW,EAAE,SAAS,YAAY,WAAW,UAAU,YAAY,EAAE,CAAC;IAEzF,OAAO,SAAS,mBAAmB,MAAM,EAAE,KAAK,CAAC,CAAC;GACnD,CAAC,CACF;EACD;EAEA,MAAM,MAAM,OAAO,SAAS,UAAU,QAAQ;EAC9C,MAAM,UAAU,OAAO,QAAQ,kBAAkB,KAAK,qBAAqB,IAAI,OAAO,CAAC;EACvF,IAAI,YAAY,KAAA,GACf,OAAO,OAAO,IAAI,WAAW,EAAE,SAAS,YAAY,WAAW,UAAU,IAAI,IAAI,EAAE,CAAC;EAErF,OAAO,SAAS,mBAAmB,SAAS,EAAE,KAAK,CAAC,CAAC;CACtD,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
1
+ {"version":3,"file":"status-BNc5JZ1C.mjs","names":["Runtime.handler","Client.make"],"sources":["../../src/cli/cmd/handlers/auth/status.ts"],"sourcesContent":["import { formatOAuthSummary, oauthNotice } from \"@codeworksh/aikit/oauth/summary\";\nimport { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { OAuthError, reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport {\n\tassertServerScope,\n\tattempt,\n\tClient,\n\tlocalOps,\n\toauthProviderLabel,\n\tselectProvider,\n\twithServer,\n} from \"./shared.ts\";\n\nexport default Runtime.handler(\n\tCmd.commands.auth.commands.status,\n\tEffect.fn(\"CLI.auth.status\")(function* ({ server, openaiCodex, githubCopilot, authFile, json }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst provider = yield* selectProvider({ openaiCodex, githubCopilot });\n\t\t\tconst name = oauthProviderLabel(provider);\n\n\t\t\tif (Option.isSome(server)) {\n\t\t\t\tyield* assertServerScope(authFile);\n\t\t\t\treturn yield* withServer(\n\t\t\t\t\tserver.value,\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tconst rpc = yield* Client.make;\n\t\t\t\t\t\tconst info = yield* rpc[\"auth.status\"]({ provider });\n\t\t\t\t\t\tif (info === null) {\n\t\t\t\t\t\t\treturn yield* new OAuthError({ message: oauthNotice(\"missing\", provider, \"the server\") });\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield* writeOut(formatOAuthSummary(info, { json }));\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst ops = yield* localOps(provider, authFile);\n\t\t\tconst summary = yield* attempt(`failed to read ${name} credentials`, () => ops.stored());\n\t\t\tif (summary === undefined) {\n\t\t\t\treturn yield* new OAuthError({ message: oauthNotice(\"missing\", provider, ops.path) });\n\t\t\t}\n\t\t\tyield* writeOut(formatOAuthSummary(summary, { json }));\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;AAgBA,IAAA,iBAAeA,QACd,IAAI,SAAS,KAAK,SAAS,QAC3B,OAAO,GAAG,iBAAiB,CAAC,CAAC,WAAW,EAAE,QAAQ,aAAa,eAAe,UAAU,QAAQ;CA4B/F,OAAO,OA3BS,OAAO,IAAI,aAAa;EACvC,MAAM,WAAW,OAAO,eAAe;GAAE;GAAa;EAAc,CAAC;EACrE,MAAM,OAAO,mBAAmB,QAAQ;EAExC,IAAI,OAAO,OAAO,MAAM,GAAG;GAC1B,OAAO,kBAAkB,QAAQ;GACjC,OAAO,OAAO,WACb,OAAO,OACP,OAAO,IAAI,aAAa;IAEvB,MAAM,OAAO,QAAO,OADDC,KAAAA,CACK,cAAc,CAAC,EAAE,SAAS,CAAC;IACnD,IAAI,SAAS,MACZ,OAAO,OAAO,IAAI,WAAW,EAAE,SAAS,YAAY,WAAW,UAAU,YAAY,EAAE,CAAC;IAEzF,OAAO,SAAS,mBAAmB,MAAM,EAAE,KAAK,CAAC,CAAC;GACnD,CAAC,CACF;EACD;EAEA,MAAM,MAAM,OAAO,SAAS,UAAU,QAAQ;EAC9C,MAAM,UAAU,OAAO,QAAQ,kBAAkB,KAAK,qBAAqB,IAAI,OAAO,CAAC;EACvF,IAAI,YAAY,KAAA,GACf,OAAO,OAAO,IAAI,WAAW,EAAE,SAAS,YAAY,WAAW,UAAU,IAAI,IAAI,EAAE,CAAC;EAErF,OAAO,SAAS,mBAAmB,SAAS,EAAE,KAAK,CAAC,CAAC;CACtD,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
@@ -1,6 +1,6 @@
1
- import { i as Cmd, t as handler } from "./runtime-B3dlWGfs.mjs";
2
- import { d as writeOut, i as reportFailure } from "./error-CxoEKg-4.mjs";
3
- import { a as targeted, i as read, n as local, r as probe, t as fetchable } from "./entries-BXBULTVt.mjs";
1
+ import { i as Cmd, t as handler } from "./runtime-D4zyJPrh.mjs";
2
+ import { d as writeOut, i as reportFailure } from "./error-C9ACQhhu.mjs";
3
+ import { a as targeted, i as read, n as local, r as probe, t as fetchable } from "./entries-CzgqHfKQ.mjs";
4
4
  import { Effect, Option } from "effect";
5
5
  import { Plugin } from "@codeworksh/harness/effect";
6
6
  //#region src/cli/cmd/handlers/plugin/update.ts
@@ -48,4 +48,4 @@ var update_default = handler(Cmd.commands.plugin.commands.update, Effect.fn("CLI
48
48
  //#endregion
49
49
  export { update_default as default };
50
50
 
51
- //# sourceMappingURL=update-C-RdaEiC.mjs.map
51
+ //# sourceMappingURL=update-CaW7oDOl.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-C-RdaEiC.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/plugin/update.ts"],"sourcesContent":["import { Plugin } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { fetchable, local, probe, read, targeted } from \"./entries.ts\";\n\n/**\n * Take whatever `check` found.\n *\n * Only a plugin that is **already installed** is refreshed: \"not installed\" is not \"outdated\", and\n * `plugin install` is the verb for that. Each refresh publishes a new generation, which a running\n * session picks up at its next exchange -- so this command never has to reach into a server.\n */\nexport default Runtime.handler(\n\tCmd.commands.plugin.commands.update,\n\tEffect.fn(\"CLI.plugin.update\")(function* ({ spec }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst shared = yield* Cmd.spec;\n\t\t\tconst { entries, cache, hostDir } = yield* read(shared);\n\t\t\tconst selected = yield* targeted(entries, spec, hostDir);\n\t\t\tif (selected.length === 0 && Option.isSome(spec)) return;\n\n\t\t\tlet updated = 0;\n\t\t\tlet failed = 0;\n\t\t\tfor (const entry of selected) {\n\t\t\t\tconst target = fetchable(entry.target);\n\t\t\t\t// A local plugin has no revision to compare and is never copied into the store.\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\tyield* local(entry, spec);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst result = yield* Plugin.update(target, cache, {\n\t\t\t\t\tprobe: probe(cache, entry.from),\n\t\t\t\t\tfrom: entry.from,\n\t\t\t\t\t// Validated while staged, so a refresh that fetches something broken leaves\n\t\t\t\t\t// the generation already in use as the answer. Preserve the loader's reason:\n\t\t\t\t\t// an import failure or invalid definition is not a missing entrypoint.\n\t\t\t\t\tvalidate: (fetched) => Plugin.definition(fetched.entrypoint, entry.reference).pipe(Effect.asVoid),\n\t\t\t\t}).pipe(Effect.result);\n\n\t\t\t\tif (result._tag === \"Failure\") {\n\t\t\t\t\tfailed += 1;\n\t\t\t\t\tyield* writeOut(`${entry.reference} error[${result.failure.reason}]: ${result.failure.message}\\n`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (result.success._tag === \"updated\") {\n\t\t\t\t\tupdated += 1;\n\t\t\t\t\tyield* writeOut(`Updated ${entry.reference} to ${result.success.entry.revision ?? \"a new revision\"}\\n`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A spec that named only local plugins compared nothing, so there is nothing to sum up.\n\t\t\tif (Option.isSome(spec) && selected.every((entry) => fetchable(entry.target) === undefined)) return;\n\t\t\tyield* writeOut(updated === 0 ? \"Nothing to update.\\n\" : `${updated} updated.\\n`);\n\t\t\tif (failed > 0) process.exitCode = 1;\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAA,iBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,QAC7B,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,EAAE,QAAQ;CA2CnD,OAAO,OA1CS,OAAO,IAAI,aAAa;EACvC,MAAM,SAAS,OAAO,IAAI;EAC1B,MAAM,EAAE,SAAS,OAAO,YAAY,OAAO,KAAK,MAAM;EACtD,MAAM,WAAW,OAAO,SAAS,SAAS,MAAM,OAAO;EACvD,IAAI,SAAS,WAAW,KAAK,OAAO,OAAO,IAAI,GAAG;EAElD,IAAI,UAAU;EACd,IAAI,SAAS;EACb,KAAK,MAAM,SAAS,UAAU;GAC7B,MAAM,SAAS,UAAU,MAAM,MAAM;GAErC,IAAI,WAAW,KAAA,GAAW;IACzB,OAAO,MAAM,OAAO,IAAI;IACxB;GACD;GAEA,MAAM,SAAS,OAAO,OAAO,OAAO,QAAQ,OAAO;IAClD,OAAO,MAAM,OAAO,MAAM,IAAI;IAC9B,MAAM,MAAM;IAIZ,WAAW,YAAY,OAAO,WAAW,QAAQ,YAAY,MAAM,SAAS,CAAC,CAAC,KAAK,OAAO,MAAM;GACjG,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;GAErB,IAAI,OAAO,SAAS,WAAW;IAC9B,UAAU;IACV,OAAO,SAAS,GAAG,MAAM,UAAU,UAAU,OAAO,QAAQ,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;IAClG;GACD;GACA,IAAI,OAAO,QAAQ,SAAS,WAAW;IACtC,WAAW;IACX,OAAO,SAAS,WAAW,MAAM,UAAU,MAAM,OAAO,QAAQ,MAAM,YAAY,iBAAiB,GAAG;GACvG;EACD;EAGA,IAAI,OAAO,OAAO,IAAI,KAAK,SAAS,OAAO,UAAU,UAAU,MAAM,MAAM,MAAM,KAAA,CAAS,GAAG;EAC7F,OAAO,SAAS,YAAY,IAAI,yBAAyB,GAAG,QAAQ,YAAY;EAChF,IAAI,SAAS,GAAG,QAAQ,WAAW;CACpC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
1
+ {"version":3,"file":"update-CaW7oDOl.mjs","names":["Runtime.handler"],"sources":["../../src/cli/cmd/handlers/plugin/update.ts"],"sourcesContent":["import { Plugin } from \"@codeworksh/harness/effect\";\nimport { Effect, Option } from \"effect\";\nimport { Runtime } from \"../../../../framework/runtime.ts\";\nimport { reportFailure } from \"../../../error.ts\";\nimport { writeOut } from \"../../../output.ts\";\nimport { Cmd } from \"../../cmd.ts\";\nimport { fetchable, local, probe, read, targeted } from \"./entries.ts\";\n\n/**\n * Take whatever `check` found.\n *\n * Only a plugin that is **already installed** is refreshed: \"not installed\" is not \"outdated\", and\n * `plugin install` is the verb for that. Each refresh publishes a new generation, which a running\n * session picks up at its next exchange -- so this command never has to reach into a server.\n */\nexport default Runtime.handler(\n\tCmd.commands.plugin.commands.update,\n\tEffect.fn(\"CLI.plugin.update\")(function* ({ spec }) {\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst shared = yield* Cmd.spec;\n\t\t\tconst { entries, cache, hostDir } = yield* read(shared);\n\t\t\tconst selected = yield* targeted(entries, spec, hostDir);\n\t\t\tif (selected.length === 0 && Option.isSome(spec)) return;\n\n\t\t\tlet updated = 0;\n\t\t\tlet failed = 0;\n\t\t\tfor (const entry of selected) {\n\t\t\t\tconst target = fetchable(entry.target);\n\t\t\t\t// A local plugin has no revision to compare and is never copied into the store.\n\t\t\t\tif (target === undefined) {\n\t\t\t\t\tyield* local(entry, spec);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst result = yield* Plugin.update(target, cache, {\n\t\t\t\t\tprobe: probe(cache, entry.from),\n\t\t\t\t\tfrom: entry.from,\n\t\t\t\t\t// Validated while staged, so a refresh that fetches something broken leaves\n\t\t\t\t\t// the generation already in use as the answer. Preserve the loader's reason:\n\t\t\t\t\t// an import failure or invalid definition is not a missing entrypoint.\n\t\t\t\t\tvalidate: (fetched) => Plugin.definition(fetched.entrypoint, entry.reference).pipe(Effect.asVoid),\n\t\t\t\t}).pipe(Effect.result);\n\n\t\t\t\tif (result._tag === \"Failure\") {\n\t\t\t\t\tfailed += 1;\n\t\t\t\t\tyield* writeOut(`${entry.reference} error[${result.failure.reason}]: ${result.failure.message}\\n`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (result.success._tag === \"updated\") {\n\t\t\t\t\tupdated += 1;\n\t\t\t\t\tyield* writeOut(`Updated ${entry.reference} to ${result.success.entry.revision ?? \"a new revision\"}\\n`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// A spec that named only local plugins compared nothing, so there is nothing to sum up.\n\t\t\tif (Option.isSome(spec) && selected.every((entry) => fetchable(entry.target) === undefined)) return;\n\t\t\tyield* writeOut(updated === 0 ? \"Nothing to update.\\n\" : `${updated} updated.\\n`);\n\t\t\tif (failed > 0) process.exitCode = 1;\n\t\t});\n\n\t\treturn yield* program.pipe(Effect.catch(reportFailure));\n\t}),\n);\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAA,iBAAeA,QACd,IAAI,SAAS,OAAO,SAAS,QAC7B,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,EAAE,QAAQ;CA2CnD,OAAO,OA1CS,OAAO,IAAI,aAAa;EACvC,MAAM,SAAS,OAAO,IAAI;EAC1B,MAAM,EAAE,SAAS,OAAO,YAAY,OAAO,KAAK,MAAM;EACtD,MAAM,WAAW,OAAO,SAAS,SAAS,MAAM,OAAO;EACvD,IAAI,SAAS,WAAW,KAAK,OAAO,OAAO,IAAI,GAAG;EAElD,IAAI,UAAU;EACd,IAAI,SAAS;EACb,KAAK,MAAM,SAAS,UAAU;GAC7B,MAAM,SAAS,UAAU,MAAM,MAAM;GAErC,IAAI,WAAW,KAAA,GAAW;IACzB,OAAO,MAAM,OAAO,IAAI;IACxB;GACD;GAEA,MAAM,SAAS,OAAO,OAAO,OAAO,QAAQ,OAAO;IAClD,OAAO,MAAM,OAAO,MAAM,IAAI;IAC9B,MAAM,MAAM;IAIZ,WAAW,YAAY,OAAO,WAAW,QAAQ,YAAY,MAAM,SAAS,CAAC,CAAC,KAAK,OAAO,MAAM;GACjG,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;GAErB,IAAI,OAAO,SAAS,WAAW;IAC9B,UAAU;IACV,OAAO,SAAS,GAAG,MAAM,UAAU,UAAU,OAAO,QAAQ,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;IAClG;GACD;GACA,IAAI,OAAO,QAAQ,SAAS,WAAW;IACtC,WAAW;IACX,OAAO,SAAS,WAAW,MAAM,UAAU,MAAM,OAAO,QAAQ,MAAM,YAAY,iBAAiB,GAAG;GACvG;EACD;EAGA,IAAI,OAAO,OAAO,IAAI,KAAK,SAAS,OAAO,UAAU,UAAU,MAAM,MAAM,MAAM,KAAA,CAAS,GAAG;EAC7F,OAAO,SAAS,YAAY,IAAI,yBAAyB,GAAG,QAAQ,YAAY;EAChF,IAAI,SAAS,GAAG,QAAQ,WAAW;CACpC,CAEoB,CAAC,CAAC,KAAK,OAAO,MAAM,aAAa,CAAC;AACvD,CAAC,CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"error-CxoEKg-4.mjs","names":["OAuthError","Contract.Api","Envelope.decode","Client.ExecutionError"],"sources":["../../src/server/envelope.ts","../../src/server/contract.ts","../../src/server/client.ts","../../src/cli/output.ts","../../src/cli/error.ts"],"sourcesContent":["import { EventList, EventSchema, optional } from \"@codeworksh/harness/effect\";\nimport { Effect, Schema } from \"effect\";\n\n/**\n * The wire form of an `EventSchema.Payload`. `data` is carried in its encoded\n * form — decoded payloads are not wire-safe (`Schema.Duration`, aikit class\n * transforms) — so clients decode it lazily through their own copy of the\n * registry and can skip types they do not know.\n */\nexport const EventEnvelope = Schema.Struct({\n\tid: EventSchema.ID,\n\ttype: Schema.String,\n\tdurable: optional(Schema.Struct({ aggregateId: Schema.String, seq: Schema.Int, version: Schema.Int })),\n\tmetadata: optional(Schema.Record(Schema.String, Schema.String)),\n\tdata: Schema.Unknown,\n});\nexport type EventEnvelope = typeof EventEnvelope.Type;\n\nexport class UnknownEventTypeError extends Schema.TaggedError<UnknownEventTypeError>()(\"UnknownEventTypeError\", {\n\ttype: Schema.String,\n}) {}\n\n/** The transport's own readiness frame; it has no meaning inside the harness. */\nexport const Connected = EventSchema.define({ type: \"server.connected\", schema: {} });\n\n/** Resolves a published type to the definition that encodes it. */\nexport type Registry = (type: string) => EventSchema.Definition | undefined;\n\n/**\n * What a stock client can decode: the harness's public events plus the frames\n * the transport adds itself. A server may know more than this -- plugins\n * register their own types -- which is exactly why `data` crosses the wire\n * encoded and is decoded lazily, so an unknown type is skipped, not fatal.\n */\nconst core = EventSchema.latest([...EventList.PublicDefinitions, Connected]);\nexport const Core: Registry = (type) => core.get(type);\n\nexport class EncodingError extends Schema.TaggedError<EncodingError>()(\"EventEncodingError\", {\n\ttype: Schema.String,\n\tcause: Schema.Defect(),\n}) {}\n\nexport const encode = Effect.fn(\"Envelope.encode\")(function* (payload: EventSchema.Payload, registry: Registry = Core) {\n\tconst definition = registry(payload.type);\n\tif (definition === undefined) return yield* new UnknownEventTypeError({ type: payload.type });\n\tconst data = yield* Schema.encodeEffect(definition.data)(payload.data).pipe(\n\t\tEffect.mapError((cause) => new EncodingError({ type: payload.type, cause })),\n\t);\n\treturn {\n\t\tid: payload.id,\n\t\ttype: payload.type,\n\t\t...(payload.durable === undefined ? {} : { durable: payload.durable }),\n\t\t...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),\n\t\tdata,\n\t};\n});\n\nexport const decode = Effect.fn(\"Envelope.decode\")(function* (envelope: EventEnvelope, registry: Registry = Core) {\n\tconst definition = registry(envelope.type);\n\tif (definition === undefined) {\n\t\treturn yield* new UnknownEventTypeError({ type: envelope.type });\n\t}\n\tconst data = yield* Schema.decodeEffect(definition.data)(envelope.data);\n\treturn {\n\t\tid: envelope.id,\n\t\ttype: envelope.type,\n\t\t...(envelope.durable === undefined ? {} : { durable: envelope.durable }),\n\t\t...(envelope.metadata === undefined ? {} : { metadata: envelope.metadata }),\n\t\tdata,\n\t} as EventSchema.Payload;\n});\n\nexport * as Envelope from \"./envelope.ts\";\n","import { Model } from \"@codeworksh/aikit\";\nimport {\n\tControl,\n\tEvent,\n\tLocation,\n\toptional,\n\tPromptSchema,\n\tSandbox,\n\tSandboxError,\n\tSession,\n\tSessionStore,\n} from \"@codeworksh/harness/effect\";\nimport { Schema } from \"effect\";\nimport { Rpc, RpcGroup } from \"effect/unstable/rpc\";\nimport { EncodingError, EventEnvelope } from \"./envelope.ts\";\n\nexport const SandboxInfo = Schema.Struct({\n\tid: Sandbox.SandboxInstance.ID,\n\tdriver: Schema.String,\n\tkind: Sandbox.SandboxInstance.Kind,\n\tproviderResourceId: Schema.OptionFromNullOr(Schema.String),\n\townership: Sandbox.SandboxInstance.Ownership,\n\tstatus: Sandbox.SandboxInstance.Status,\n\tusage: Sandbox.SandboxInstance.Usage,\n\trefCount: Schema.Int,\n\tcreatedAt: Schema.DateFromString,\n\tupdatedAt: Schema.DateFromString,\n});\nexport type SandboxInfo = typeof SandboxInfo.Type;\n\nexport const SessionInfo = Schema.Struct({\n\tid: Session.SessionSchema.ID,\n\ttitle: Schema.String,\n\tdirectory: Session.AbsolutePath,\n\t/** The host directory this session is anchored to. Absent when it has none. */\n\thostDir: optional(Session.AbsolutePath),\n\tsandbox: optional(SandboxInfo),\n});\nexport type SessionInfo = typeof SessionInfo.Type;\n\nexport const RuntimeConfig = Schema.Struct({\n\tmodel: optional(Schema.Struct({ provider: Schema.String, id: Schema.String })),\n\tthinkingLevel: optional(Schema.Enum(Model.ThinkingLevelEnum)),\n});\nexport type RuntimeConfig = typeof RuntimeConfig.Type;\n\nexport const SandboxRef = Sandbox.Selection;\n\nexport class OAuthError extends Schema.TaggedError<OAuthError>()(\"Server.OAuthError\", {\n\tmessage: Schema.String,\n}) {}\n\n/** OAuth providers whose credentials this server stores. */\nexport const OAuthProvider = Schema.Literals([\"openai-codex\", \"github-copilot\"]);\nexport type OAuthProvider = typeof OAuthProvider.Type;\n\n/**\n * Credentials as the provider's aikit module persists them. The union is\n * discriminated by `provider` so one set of RPCs serves every login.\n */\nexport const OAuthCredentials = Schema.Union([\n\tSchema.Struct({\n\t\tprovider: Schema.Literal(\"openai-codex\"),\n\t\taccess: Schema.String,\n\t\trefresh: Schema.String,\n\t\texpires: Schema.Finite,\n\t\taccountId: Schema.String,\n\t}),\n\tSchema.Struct({\n\t\tprovider: Schema.Literal(\"github-copilot\"),\n\t\taccess: Schema.String,\n\t\trefresh: Schema.String,\n\t\texpires: Schema.Finite,\n\t\tenterpriseUrl: optional(Schema.String),\n\t\tapiEndpoint: optional(Schema.String),\n\t\tavailableModelIds: optional(Schema.Array(Schema.String)),\n\t}),\n]);\nexport type OAuthCredentials = typeof OAuthCredentials.Type;\n\n/** What a login looks like from the outside: never the tokens themselves. */\nexport const OAuthInfo = Schema.Struct({\n\tprovider: OAuthProvider,\n\t/** Epoch millis, or 0 for a credential that does not expire. */\n\texpires: Schema.Finite,\n\taccountId: optional(Schema.String),\n\tapiEndpoint: optional(Schema.String),\n\tenterpriseUrl: optional(Schema.String),\n\tavailableModels: optional(Schema.Int),\n});\nexport type OAuthInfo = typeof OAuthInfo.Type;\n\nconst SessionErrors = Schema.Union([\n\tSessionStore.SessionNotFoundError,\n\tSessionStore.SessionLinkedSpaceNotFoundError,\n\tSessionStore.RelinkError,\n]);\n\n// Every lifecycle error the sandbox control plane can raise; narrowing per\n// endpoint would misreport what `withMount` and `stop` actually fail with.\nconst SandboxErrors = Schema.Union([\n\tSandboxError.SandboxNotFoundError,\n\tSandboxError.SandboxDriverNotRegisteredError,\n\tSandboxError.SandboxDriverRegistrationError,\n\tSandboxError.SandboxUnsupportedError,\n\tSandboxError.SandboxProviderError,\n\tSandboxError.SandboxUnavailError,\n\tSandboxError.SandboxRemovedError,\n\tSandboxError.SandboxTransitionConflictError,\n\tSandboxError.SandboxBusyError,\n]);\n\nconst LocationErrors = Schema.Union([Location.DirectoryNotFoundError, Location.NotDirectoryError]);\n\nexport const Api = RpcGroup.make(\n\tRpc.make(\"auth.save\", {\n\t\tpayload: { credentials: OAuthCredentials },\n\t\tsuccess: OAuthInfo,\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.status\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.NullOr(OAuthInfo),\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.refresh\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.NullOr(OAuthInfo),\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"auth.logout\", {\n\t\tpayload: { provider: OAuthProvider },\n\t\tsuccess: Schema.Void,\n\t\terror: OAuthError,\n\t}),\n\tRpc.make(\"session.create\", {\n\t\tpayload: {\n\t\t\ttitle: optional(Schema.String),\n\t\t\tdirectory: optional(Schema.String),\n\t\t\t/**\n\t\t\t * The host directory this session is anchored to, usually the caller's project root.\n\t\t\t * Unrelated to `directory`, which names a place inside the session's space.\n\t\t\t *\n\t\t\t * It is an anchor and nothing more: whatever needs a host-side directory resolves from\n\t\t\t * here rather than from wherever the server happens to be running. What reads it is the\n\t\t\t * reader's business, not this field's.\n\t\t\t *\n\t\t\t * Optional and honoured as given. Omitting it is normal, not a failure.\n\t\t\t */\n\t\t\thostDir: optional(Session.AbsolutePath),\n\t\t\tsandbox: optional(SandboxRef),\n\t\t\truntime: optional(RuntimeConfig),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: Schema.Union([SessionErrors, SandboxErrors, LocationErrors]),\n\t}),\n\tRpc.make(\"session.list\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(SessionInfo),\n\t}),\n\tRpc.make(\"session.configure\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, runtime: RuntimeConfig },\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\tRpc.make(\"session.info\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Point an existing session at a host directory, or clear it with `null`.\n\t *\n\t * Not `session.relink`: that moves where the *work* happens, this changes which host directory\n\t * the session is *anchored to*. Conflating them would recreate exactly the `cwd`/`hostDir`\n\t * confusion the split exists to remove, which is why they sound alike and stay apart.\n\t */\n\tRpc.make(\"session.link\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\t/** Absent clears the anchor, leaving the session with no host directory. */\n\t\t\thostDir: optional(Session.AbsolutePath),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\tRpc.make(\"session.relink\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\tsandbox: optional(SandboxRef),\n\t\t\tdirectory: optional(Schema.String),\n\t\t},\n\t\tsuccess: SessionInfo,\n\t\terror: Schema.Union([SessionErrors, SandboxErrors, LocationErrors]),\n\t}),\n\tRpc.make(\"session.prompt\", {\n\t\tpayload: {\n\t\t\tsessionId: Session.SessionSchema.ID,\n\t\t\ttext: Schema.String,\n\t\t\tdelivery: optional(PromptSchema.Delivery),\n\t\t\tid: optional(Session.SessionMessageSchema.ID),\n\t\t},\n\t\tsuccess: Schema.Void,\n\t\terror: Schema.Union([SessionStore.SessionNotFoundError, Control.PromptConflictError]),\n\t}),\n\tRpc.make(\"session.interrupt\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Struct({ interrupted: Schema.Boolean }),\n\t}),\n\t/**\n\t * Whether a prompt materialized into the conversation. An admitted prompt\n\t * that is still queued has no entry yet, so this is the projection a client\n\t * reconciles against when the volatile stream left it unsure\n\t */\n\tRpc.make(\"session.message\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID, messageId: Session.SessionMessageSchema.ID },\n\t\tsuccess: Schema.Struct({ found: Schema.Boolean }),\n\t}),\n\tRpc.make(\"session.wait\", {\n\t\tpayload: { sessionId: Session.SessionSchema.ID },\n\t\tsuccess: Schema.Void,\n\t\terror: SessionStore.SessionNotFoundError,\n\t}),\n\t/**\n\t * Re-import every configured plugin, for the whole server.\n\t *\n\t * The one thing an exchange cannot notice on its own: a local plugin whose contents changed\n\t * while its path did not. A failure keeps the previous set and is reported here rather than\n\t * emptying a running server's tool registry.\n\t */\n\tRpc.make(\"plugin.reload\", {\n\t\tpayload: {},\n\t\t// No error channel: a reload that fails keeps the previous set and reports why, because a\n\t\t// server that empties its tool registry over a typo is worse than one that says so.\n\t\tsuccess: Schema.Struct({ plugins: Schema.Int, failure: optional(Schema.String) }),\n\t}),\n\tRpc.make(\"sandbox.drivers\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(Schema.Struct({ name: Schema.String, kind: Schema.String })),\n\t}),\n\tRpc.make(\"sandbox.list\", {\n\t\tpayload: {},\n\t\tsuccess: Schema.Array(SandboxInfo),\n\t}),\n\tRpc.make(\"sandbox.create\", {\n\t\tpayload: { driver: Schema.String },\n\t\tsuccess: SandboxInfo,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"sandbox.register\", {\n\t\tpayload: { driver: Schema.String, providerResourceId: Schema.String },\n\t\tsuccess: SandboxInfo,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"sandbox.stop\", {\n\t\tpayload: { sandboxId: Sandbox.SandboxInstance.ID },\n\t\tsuccess: Schema.Void,\n\t\terror: SandboxErrors,\n\t}),\n\tRpc.make(\"event.subscribe\", {\n\t\tpayload: {},\n\t\tsuccess: EventEnvelope,\n\t\terror: Schema.Union([Event.SubscriptionOverflowError, EncodingError]),\n\t\tstream: true,\n\t}),\n);\n\nexport * as Contract from \"./contract.ts\";\n","import { EventList, type EventSchema, optional, Session } from \"@codeworksh/harness/effect\";\nimport { NodeSocket } from \"@effect/platform-node\";\nimport { Deferred, Effect, Layer, Predicate, Schema, Stream } from \"effect\";\nimport { RpcClient, RpcSerialization } from \"effect/unstable/rpc\";\nimport { Contract } from \"./contract.ts\";\nimport { Envelope } from \"./envelope.ts\";\n\nexport const make = RpcClient.make(Contract.Api);\nexport type Client = Effect.Success<typeof make>;\n\nexport const layer = (url: string) =>\n\tRpcClient.layerProtocolSocket().pipe(\n\t\tLayer.provide(NodeSocket.layerWebSocket(url)),\n\t\tLayer.provide(RpcSerialization.layerNdjson),\n\t);\n\n/** A server-side failure as the client sees it: the category, not the cause. */\nexport class ExecutionError extends Schema.TaggedError<ExecutionError>()(\"Client.ExecutionError\", {\n\ttype: Schema.String,\n\tmessage: Schema.String,\n\tstatus: optional(Schema.Int),\n}) {}\n\n/**\n * Runs one prompt against a server and renders its output.\n *\n * Sessions are shared, so the stream carries other clients' work too and every\n * terminal event has to be attributed before it is believed. A terminal that\n * arrives before our own prompt is promoted belongs to somebody else's drain:\n * it is remembered rather than raised, and forgotten the moment our prompt is\n * promoted. It only becomes our outcome if the session reaches idle having\n * never promoted us -- at which point it is the best explanation available for\n * why our prompt never ran.\n */\nexport const run = Effect.fn(\"Client.run\")(function* <E, R>(\n\trpc: Client,\n\tinput: { sessionId: Session.SessionSchema.ID; text: string },\n\trender: (event: EventSchema.Payload) => Effect.Effect<void, E, R>,\n) {\n\tconst id = Session.SessionMessageSchema.ID.create();\n\tlet admitted = false;\n\tlet promoted = false;\n\tlet settled = false;\n\tlet unattributed: ExecutionError | undefined;\n\t// Raised once a busy period ends without our prompt in it: the session may be\n\t// about to go idle, and only idleness proves our prompt is never running.\n\tconst stalled = yield* Deferred.make<void>();\n\n\tconst terminal = (event: EventSchema.Payload): ExecutionError | undefined => {\n\t\tif (Schema.is(EventList.ExecutionInterrupted)(event))\n\t\t\treturn new ExecutionError({\n\t\t\t\ttype: \"aborted\",\n\t\t\t\tmessage: event.data.reason === \"shutdown\" ? \"Server stopped the session\" : \"Session interrupted\",\n\t\t\t});\n\t\tif (Schema.is(EventList.ExecutionFailed)(event))\n\t\t\treturn new ExecutionError({\n\t\t\t\ttype: event.data.error.type,\n\t\t\t\tmessage: event.data.error.message,\n\t\t\t\t...(event.data.error.status === undefined ? {} : { status: event.data.error.status }),\n\t\t\t});\n\t\treturn undefined;\n\t};\n\n\tconst consume = rpc[\"event.subscribe\"]({}).pipe(\n\t\tStream.mapEffect(\n\t\t\tEffect.fnUntraced(function* (envelope) {\n\t\t\t\tif (envelope.type === Envelope.Connected.type) {\n\t\t\t\t\tyield* rpc[\"session.prompt\"]({ ...input, id, delivery: \"followUp\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst event = yield* Envelope.decode(envelope).pipe(\n\t\t\t\t\tEffect.catchTag(\"UnknownEventTypeError\", () => Effect.void),\n\t\t\t\t);\n\t\t\t\tif (\n\t\t\t\t\tevent === undefined ||\n\t\t\t\t\t!Predicate.hasProperty(event.data, \"sessionId\") ||\n\t\t\t\t\tevent.data.sessionId !== input.sessionId\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\tif (Schema.is(EventList.PromptAdmitted)(event) && event.data.messageId === id) admitted = true;\n\t\t\t\tif (Schema.is(EventList.Prompted)(event) && event.data.messageId === id) {\n\t\t\t\t\tpromoted = true;\n\t\t\t\t\t// Our prompt is running after all; whatever ended before it was not ours.\n\t\t\t\t\tunattributed = undefined;\n\t\t\t\t}\n\t\t\t\tif (!admitted) return;\n\n\t\t\t\tconst ended = terminal(event);\n\t\t\t\tconst succeeded = Schema.is(EventList.ExecutionSucceeded)(event);\n\t\t\t\tif (!promoted) {\n\t\t\t\t\tif (ended !== undefined) unattributed = ended;\n\t\t\t\t\t// A busy period that ended without us: wait for idle to find out\n\t\t\t\t\t// whether a successor still picks our prompt up.\n\t\t\t\t\tif (ended !== undefined || succeeded) yield* Deferred.succeed(stalled, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (ended !== undefined) return yield* ended;\n\t\t\t\tif (succeeded) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tyield* render(event);\n\t\t\t}),\n\t\t),\n\t\tStream.takeUntil(() => settled),\n\t\tStream.runDrain,\n\t);\n\n\t// Idle is the cue to reconcile, not the verdict. `wait` follows successors, so\n\t// it resolves only once the session is quiet -- then the projection says\n\t// whether our prompt was ever part of it. A prompt that did run leaves its\n\t// terminal in flight on the same socket, so the consumer is left alone to\n\t// finish; only a prompt that never materialized ends the run early.\n\tlet abandoned = false;\n\tconst reconcile = Deferred.await(stalled).pipe(\n\t\tEffect.andThen(rpc[\"session.wait\"]({ sessionId: input.sessionId })),\n\t\tEffect.andThen(rpc[\"session.message\"]({ sessionId: input.sessionId, messageId: id })),\n\t\tEffect.andThen(({ found }) =>\n\t\t\tfound\n\t\t\t\t? Effect.never\n\t\t\t\t: Effect.sync(() => {\n\t\t\t\t\t\tabandoned = true;\n\t\t\t\t\t}),\n\t\t),\n\t);\n\n\tyield* Effect.raceFirst(consume, reconcile);\n\tif (settled) return;\n\tif (abandoned)\n\t\treturn yield* unattributed ?? new ExecutionError({ type: \"unknown\", message: \"Prompt was not promoted\" });\n\treturn yield* new ExecutionError({\n\t\ttype: \"transport.disconnected\",\n\t\tmessage: \"Event stream ended before the prompt finished; its output was not rendered\",\n\t});\n});\n\nexport * as Client from \"./client.ts\";\n","import type { Message } from \"@codeworksh/aikit\";\nimport { Effect } from \"effect\";\n\nexport interface UsageSummary {\n\treadonly turns: number;\n\treadonly provider?: string;\n\treadonly model?: string;\n\treadonly input: number;\n\treadonly output: number;\n\treadonly reasoning: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly totalTokens: number;\n\treadonly cost: number;\n}\n\nexport const emptyUsage: UsageSummary = {\n\tturns: 0,\n\tinput: 0,\n\toutput: 0,\n\treasoning: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: 0,\n};\n\nexport const addUsage = (summary: UsageSummary, message: Message.AssistantMessage): UsageSummary => ({\n\tturns: summary.turns + 1,\n\tprovider: message.provider.id,\n\tmodel: message.responseModel ?? message.model,\n\tinput: summary.input + message.usage.input,\n\toutput: summary.output + message.usage.output,\n\treasoning: summary.reasoning + (message.usage.reasoning ?? 0),\n\tcacheRead: summary.cacheRead + message.usage.cacheRead,\n\tcacheWrite: summary.cacheWrite + message.usage.cacheWrite,\n\ttotalTokens: summary.totalTokens + message.usage.totalTokens,\n\tcost: summary.cost + message.usage.cost.total,\n});\n\nconst number = new Intl.NumberFormat(\"en-US\");\nconst row = (label: string, value: string) => `${label.padEnd(9)}${value}\\n`;\n\nconst formatCost = (cost: number): string => `$${cost.toFixed(cost > 0 && cost < 0.01 ? 6 : 4)}`;\n\nexport const divider = (label: string, columns = 72): string => {\n\tconst width = Math.min(100, Math.max(32, columns));\n\tconst start = `── ${label} `;\n\treturn `${start}${\"─\".repeat(Math.max(2, width - start.length))}\\n`;\n};\n\nexport const header = (input: {\n\treadonly sessionId: string;\n\treadonly sandbox: string;\n\treadonly directory: string;\n\treadonly columns?: number;\n}): string =>\n\t`${row(\"session\", input.sessionId)}${row(\"sandbox\", `${input.sandbox} · ${input.directory}`)}\\n${divider(\n\t\t\"response\",\n\t\tinput.columns,\n\t)}`;\n\nexport const usage = (summary: UsageSummary, columns?: number): string => {\n\tconst turns = `${summary.turns} ${summary.turns === 1 ? \"turn\" : \"turns\"}`;\n\tconst model =\n\t\tsummary.provider === undefined || summary.model === undefined\n\t\t\t? \"unknown\"\n\t\t\t: `${summary.provider}/${summary.model}`;\n\tconst reasoning = summary.reasoning === 0 ? \"\" : ` · ${number.format(summary.reasoning)} reasoning`;\n\treturn `${divider(\"usage\", columns)}${row(\"model\", model)}${row(\n\t\t\"tokens\",\n\t\t`${number.format(summary.input)} input · ${number.format(summary.output)} output${reasoning} · ${number.format(\n\t\t\tsummary.totalTokens,\n\t\t)} total`,\n\t)}${row(\"cache\", `${number.format(summary.cacheRead)} read · ${number.format(summary.cacheWrite)} write`)}${row(\n\t\t\"cost\",\n\t\t`${formatCost(summary.cost)} · ${turns}`,\n\t)}`;\n};\n\nexport const writeOut = (value: string) => Effect.sync(() => void process.stdout.write(value));\nexport const writeError = (value: string) => Effect.sync(() => void process.stderr.write(value));\nexport const terminalColumns = () => (process.stderr.isTTY ? (process.stderr.columns ?? 72) : 72);\n","import { ModelCatalog, Plugin, Runner, SandboxError, SessionStore, Settings } from \"@codeworksh/harness/effect\";\nimport { SandboxProvider } from \"@codeworksh/harness/sandbox\";\nimport { Duration, Effect, Schema } from \"effect\";\nimport { Client } from \"../server/client.ts\";\nimport { writeError } from \"./output.ts\";\n\n/** Bad flag or argument combinations the parser cannot express on its own. */\nexport class InvalidInputError extends Schema.TaggedError<InvalidInputError>()(\"CLI.InvalidInputError\", {\n\tmessage: Schema.String,\n}) {}\n\nexport class OAuthError extends Schema.TaggedError<OAuthError>()(\"CLI.OAuthError\", {\n\tmessage: Schema.String,\n\tcause: Schema.optional(Schema.Defect()),\n}) {}\n\n/**\n * Every failure a command handler may surface to the runtime. Harness failures are\n * rendered inside the handler that owns them, so only the CLI's own errors reach\n * the top-level renderer.\n */\nexport type CommandError = InvalidInputError | OAuthError;\n\nconst isInvalidInputError = Schema.is(InvalidInputError);\nconst isOAuthError = Schema.is(OAuthError);\nconst isProviderError = Schema.is(Runner.ProviderError);\nconst isModelCatalogError = Schema.is(Runner.ModelCatalogError);\nconst isModelCatalogRefreshError = Schema.is(ModelCatalog.RefreshError);\nconst isModelNotFoundError = Schema.is(Runner.ModelNotFoundError);\nconst isLLMStreamError = Schema.is(Runner.LLMStreamError);\nconst isSandboxProviderError = Schema.is(SandboxProvider.SandboxProviderError);\nconst isPluginInstallError = Schema.is(Plugin.InstallError);\nconst isPluginSourceError = Schema.is(Plugin.SourceError);\nconst isPluginStoreError = Schema.is(Plugin.StoreError);\nconst isPluginLoadError = Schema.is(Plugin.LoadError);\nconst isSessionNotLinkedError = Schema.is(SessionStore.SessionNotLinkedError);\nconst isSettingsError = Schema.is(Settings.SettingsError);\nconst isSandboxDriverNotRegisteredError = Schema.is(SandboxError.SandboxDriverNotRegisteredError);\nconst isSandboxDriverRegistrationError = Schema.is(SandboxError.SandboxDriverRegistrationError);\nconst isExecutionError = Schema.is(Client.ExecutionError);\n\nconst credentialHint = (provider: string): string => {\n\tswitch (provider) {\n\t\tcase \"openrouter\":\n\t\t\treturn \"set OPENROUTER_API_KEY and retry\";\n\t\tcase \"openai\":\n\t\t\treturn \"set OPENAI_API_KEY and retry\";\n\t\tcase \"openai-codex\":\n\t\t\treturn \"run `codework auth login --openai-codex` and retry\";\n\t\tcase \"github-copilot\":\n\t\t\treturn \"run `codework auth login --github-copilot` and retry\";\n\t\tcase \"anthropic\":\n\t\t\treturn \"set ANTHROPIC_API_KEY and retry\";\n\t\tcase \"google\":\n\t\t\treturn \"set GOOGLE_GENERATIVE_AI_API_KEY and retry\";\n\t\tcase \"xai\":\n\t\t\treturn \"set XAI_API_KEY and retry\";\n\t\tdefault:\n\t\t\treturn `configure credentials for provider \"${provider}\" and retry`;\n\t}\n};\n\nconst providerHint = (error: Runner.ProviderError): string | undefined => {\n\tswitch (error.reason._tag) {\n\t\tcase \"Runner.ProviderAuthenticationError\":\n\t\t\treturn error.reason.authentication === \"missing\"\n\t\t\t\t? credentialHint(error.provider)\n\t\t\t\t: `check the credentials configured for provider \"${error.provider}\"`;\n\t\tcase \"Runner.ProviderAuthorizationError\":\n\t\t\treturn \"check that the credential can access this model and endpoint\";\n\t\tcase \"Runner.ProviderModelUnavailableError\":\n\t\t\treturn \"check the provider model ID and whether your account can access it\";\n\t\tcase \"Runner.ProviderRateLimitError\":\n\t\t\treturn error.reason.retryAfter === undefined\n\t\t\t\t? \"retry after the provider rate-limit window resets\"\n\t\t\t\t: `retry in about ${Math.ceil(Duration.toMillis(error.reason.retryAfter) / 1_000)} seconds`;\n\t\tcase \"Runner.ProviderQuotaError\":\n\t\t\treturn \"check the provider account quota or billing balance\";\n\t\tcase \"Runner.ProviderTimeoutError\":\n\t\tcase \"Runner.ProviderTransportError\":\n\t\tcase \"Runner.ProviderUnavailableError\":\n\t\t\treturn error.isRetryable ? \"this failure is retryable\" : undefined;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n};\n\nconst unknownMessage = (error: unknown): string => {\n\tif (error instanceof Error && error.message.trim().length > 0) return error.message;\n\tif (typeof error === \"string\" && error.trim().length > 0) return error;\n\tif (typeof error === \"object\" && error !== null && \"_tag\" in error) return String(error._tag);\n\treturn \"the command failed for an unknown reason\";\n};\n\n/**\n * What the reader can do about a reference that failed to prepare. A plugin list is\n * usually hand-written in a settings file, so the phase is worth translating.\n */\n/** One hint per reason. Lowercase, like everything else a plugin failure prints. */\nconst providerCategory = (reason: Runner.ProviderFailureReason): string => {\n\tswitch (reason._tag) {\n\t\tcase \"Runner.ProviderAuthenticationError\":\n\t\t\treturn \"provider-authentication-error\";\n\t\tcase \"Runner.ProviderConfigurationError\":\n\t\t\treturn \"provider-configuration-error\";\n\t\tcase \"Runner.ProviderAuthorizationError\":\n\t\t\treturn \"provider-authorization-error\";\n\t\tcase \"Runner.ProviderModelUnavailableError\":\n\t\t\treturn \"provider-model-unavailable-error\";\n\t\tcase \"Runner.ProviderRateLimitError\":\n\t\t\treturn \"provider-rate-limit-error\";\n\t\tcase \"Runner.ProviderQuotaError\":\n\t\t\treturn \"provider-quota-error\";\n\t\tcase \"Runner.ProviderInvalidRequestError\":\n\t\t\treturn \"provider-invalid-request-error\";\n\t\tcase \"Runner.ProviderContentPolicyError\":\n\t\t\treturn \"provider-content-filter-error\";\n\t\tcase \"Runner.ProviderTimeoutError\":\n\t\t\treturn \"provider-timeout-error\";\n\t\tcase \"Runner.ProviderTransportError\":\n\t\t\treturn \"provider-transport-error\";\n\t\tcase \"Runner.ProviderUnavailableError\":\n\t\t\treturn \"provider-unavailable-error\";\n\t\tcase \"Runner.ProviderInvalidResponseError\":\n\t\t\treturn \"provider-invalid-response-error\";\n\t\tcase \"Runner.ProviderUnknownError\":\n\t\t\treturn \"provider-unknown-error\";\n\t}\n};\n\nconst pluginReasonHint = (\n\treason:\n\t\t| Plugin.SourceError[\"reason\"]\n\t\t| Plugin.InstallError[\"reason\"]\n\t\t| Plugin.StoreError[\"reason\"]\n\t\t| Plugin.LoadError[\"reason\"],\n): string => {\n\tswitch (reason) {\n\t\tcase \"plugin-unsupported-source\":\n\t\t\treturn \"a path entry starts with `./`, `../`, `~/` or `/`; anything else is a package or a git spec, and a remote tarball is not supported\";\n\t\tcase \"plugin-not-found\":\n\t\t\treturn \"the path does not exist; check the spelling, remembering it anchors to the settings file that declares it\";\n\t\tcase \"plugin-escapes-root\":\n\t\t\treturn \"a plugin path must stay inside the project it is declared in\";\n\t\tcase \"plugin-resolve-failed\":\n\t\t\treturn \"check that the registry or git remote is reachable, and that your credentials are current\";\n\t\tcase \"plugin-fetch-failed\":\n\t\t\treturn \"check the package name and version, and that the registry is reachable\";\n\t\tcase \"plugin-no-commit\":\n\t\t\treturn \"the git source installed but no commit could be recovered; name a branch, tag or commit explicitly\";\n\t\tcase \"plugin-no-entrypoint\":\n\t\t\treturn \"the package installed but exports no module to import; check its `exports` and `main`\";\n\t\tcase \"plugin-not-installed\":\n\t\t\treturn \"run `codework plugin install` to fetch what the settings files name\";\n\t\tcase \"plugin-lock-timeout\":\n\t\t\treturn \"another install is holding this entry; wait for it to finish, or remove the stale `.lock` directory\";\n\t\tcase \"plugin-marker-invalid\":\n\t\tcase \"plugin-index-invalid\":\n\t\t\treturn \"the store entry is damaged; remove it and install again\";\n\t\tcase \"plugin-collect-failed\":\n\t\t\treturn \"the store could not be tidied; check the permissions on the plugin cache\";\n\t\tcase \"plugin-import-failed\":\n\t\t\treturn \"the module failed to load; import it directly to see its own error\";\n\t\tcase \"plugin-missing-dependency\":\n\t\t\treturn \"the plugin's own dependencies are missing; install them where the plugin lives\";\n\t\tcase \"plugin-not-compiled\":\n\t\t\treturn \"a plugin installed from git or npm must ship compiled javascript; build it and commit or publish the output\";\n\t\tcase \"plugin-invalid-definition\":\n\t\t\treturn \"a plugin module must default-export one object with a `setup` and a `vendor.domain.name` id\";\n\t}\n};\n\nconst settingsHint = (reason: Settings.SettingsError[\"reason\"]): string => {\n\tswitch (reason) {\n\t\tcase \"read\":\n\t\t\treturn \"the file exists but could not be read; check that it is a file and readable\";\n\t\tcase \"parse\":\n\t\t\treturn \"the file is not valid JSON; the location above is where parsing stopped\";\n\t\tcase \"decode\":\n\t\t\treturn \"the key above holds a value this setting does not accept\";\n\t}\n};\n\n/** Render typed SDK errors for humans without exposing Effect causes or provider payloads. */\nexport const renderError = (error: unknown): string => {\n\tif (isSandboxDriverNotRegisteredError(error)) {\n\t\treturn `error: sandbox driver \"${error.driver}\" is not registered (available: ${error.registered?.join(\", \") ?? \"none\"})\\n`;\n\t}\n\tif (isSandboxDriverRegistrationError(error)) {\n\t\treturn `error: ${error.reason}\\n`;\n\t}\n\tif (isInvalidInputError(error)) {\n\t\treturn `error: ${error.message}\\n`;\n\t}\n\tif (isOAuthError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[oauth-credential-error]: ${error.message}`,\n\t\t\t\t...(error.cause === undefined ? [] : [`detail: ${unknownMessage(error.cause)}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSandboxProviderError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error: SandboxProviderError - ${error.sanitized.message}`,\n\t\t\t\t`driver: ${error.driver}`,\n\t\t\t\t`operation: ${error.operation}`,\n\t\t\t\t...(error.sanitized.code === undefined ? [] : [`code: ${error.sanitized.code}`]),\n\t\t\t\t...(error.stack === undefined ? [] : [\"traceback:\", error.stack]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSessionNotLinkedError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${error.reason}]: ${error.message}`,\n\t\t\t\t`session: ${error.sessionId}`,\n\t\t\t\t\"hint: run `codework session link <session-id>` from the directory to anchor it to\",\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isSettingsError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[settings-${error.reason}-failed]: ${error.path}`,\n\t\t\t\t`detail: ${error.detail}`,\n\t\t\t\t`hint: ${settingsHint(error.reason)}`,\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\t// One shape for all three plugin domains: the reason is the slug, the message is the sentence,\n\t// and the reference is the string the person recognises from their settings file.\n\tif (\n\t\tisPluginSourceError(error) ||\n\t\tisPluginInstallError(error) ||\n\t\tisPluginStoreError(error) ||\n\t\tisPluginLoadError(error)\n\t) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${error.reason}]: ${error.message}`,\n\t\t\t\t...(error.reference === \"\" ? [] : [`reference: ${error.reference}`]),\n\t\t\t\t...(error.file === undefined ? [] : [`declared in: ${error.file}`]),\n\t\t\t\t...(isPluginLoadError(error) && error.id !== undefined ? [`id: ${error.id}`] : []),\n\t\t\t\t`hint: ${pluginReasonHint(error.reason)}`,\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isProviderError(error)) {\n\t\tconst hint = providerHint(error);\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[${providerCategory(error.reason)}]: ${error.message}`,\n\t\t\t\t`provider: ${error.provider}`,\n\t\t\t\t`model: ${error.model}`,\n\t\t\t\t...(error.reason.requestId === undefined ? [] : [`request: ${error.reason.requestId}`]),\n\t\t\t\t...(hint === undefined ? [] : [`hint: ${hint}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isModelCatalogError(error)) {\n\t\treturn (\n\t\t\t[`error[model-catalog-${error.reason}]: ${error.message}`, \"hint: run `codework models refresh`\"].join(\"\\n\") +\n\t\t\t\"\\n\"\n\t\t);\n\t}\n\tif (isModelCatalogRefreshError(error)) {\n\t\treturn (\n\t\t\t[`error[catalog-refresh-failed]: ${error.message}`, \"hint: check the network connection and retry\"].join(\n\t\t\t\t\"\\n\",\n\t\t\t) + \"\\n\"\n\t\t);\n\t}\n\tif (isModelNotFoundError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\t`error[model-not-found-error]: ${error.message}`,\n\t\t\t\t\"hint: check the provider/model IDs in models.gen.json or regenerate the catalog\",\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\tif (isLLMStreamError(error)) {\n\t\treturn `error[llm-stream-error]: ${error.message}\\n`;\n\t}\n\t// A remote run has only the category the server published; render it the same\n\t// way a local typed error is rendered, minus the detail that stayed server-side.\n\tif (isExecutionError(error)) {\n\t\treturn (\n\t\t\t[\n\t\t\t\terror.type === \"aborted\" ? `error: ${error.message}` : `error[${error.type}]: ${error.message}`,\n\t\t\t\t...(error.status === undefined ? [] : [`status: ${error.status}`]),\n\t\t\t].join(\"\\n\") + \"\\n\"\n\t\t);\n\t}\n\treturn `error: ${unknownMessage(error)}\\n`;\n};\n\nexport const reportFailure = (error: unknown) =>\n\twriteError(renderError(error)).pipe(\n\t\tEffect.andThen(\n\t\t\tEffect.sync(() => {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}),\n\t\t),\n\t);\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"run-D7h83L_m.mjs","names":["Runtime.handler","Client.make","Client.run","Client.layer"],"sources":["../../src/cli/cmd/handlers/run.ts"],"sourcesContent":["import { EventList, type EventSchema, Harness, Sandbox, Session } from \"@codeworksh/harness/effect\";\nimport { Effect, Exit, Fiber, Option, Queue, Ref, Schema, Stream } from \"effect\";\nimport { Runtime } from \"../../../framework/runtime.ts\";\nimport { Client } from \"../../../server/client.ts\";\nimport { InvalidInputError, renderError } from \"../../error.ts\";\nimport { harnessOptions } from \"../../harness.ts\";\nimport {\n\taddUsage,\n\temptyUsage,\n\theader,\n\tterminalColumns,\n\tusage,\n\ttype UsageSummary,\n\twriteError,\n\twriteOut,\n} from \"../../output.ts\";\nimport { Cmd } from \"../cmd.ts\";\n\ninterface RenderState {\n\treadonly usage: UsageSummary;\n\treadonly textSeen: boolean;\n\treadonly textEndsWithNewline: boolean;\n}\n\nconst initialRenderState: RenderState = {\n\tusage: emptyUsage,\n\ttextSeen: false,\n\ttextEndsWithNewline: false,\n};\n\nconst isTextDelta = Schema.is(EventList.LLMTextDelta);\nconst isLLMEnded = Schema.is(EventList.LLMEnded);\nconst isTurnEnded = Schema.is(EventList.TurnEnded);\n\nconst render = (state: Ref.Ref<RenderState>, ended?: Queue.Queue<string>) =>\n\tEffect.fn(\"CLI.render\")(function* (event: EventSchema.Payload) {\n\t\tif (isTextDelta(event)) {\n\t\t\tyield* writeOut(event.data.delta);\n\t\t\tif (event.data.delta.length > 0) {\n\t\t\t\tyield* Ref.update(state, (current) => ({\n\t\t\t\t\t...current,\n\t\t\t\t\ttextSeen: true,\n\t\t\t\t\ttextEndsWithNewline: event.data.delta.endsWith(\"\\n\"),\n\t\t\t\t}));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (isLLMEnded(event)) {\n\t\t\tyield* Ref.update(state, (current) => ({ ...current, usage: addUsage(current.usage, event.data.message) }));\n\t\t\treturn;\n\t\t}\n\t\tif (ended !== undefined && isTurnEnded(event)) {\n\t\t\tyield* Queue.offer(ended, event.data.messageId);\n\t\t}\n\t});\n\nconst finish = Effect.fn(\"CLI.finish\")(function* (state: Ref.Ref<RenderState>, columns: number) {\n\tconst rendered = yield* Ref.get(state);\n\tif (rendered.textSeen && !rendered.textEndsWithNewline) yield* writeOut(\"\\n\");\n\tyield* writeError(usage(rendered.usage, columns));\n});\n\nconst awaitMessage = Effect.fn(\"CLI.awaitMessage\")(function* (ended: Queue.Queue<string>, messageId: string) {\n\twhile ((yield* Queue.take(ended)) !== messageId) {\n\t\t// Earlier turns in the same drain are expected when a tool call continues.\n\t}\n});\n\nconst selectSandbox = Effect.fn(\"CLI.selectSandbox\")(function* (input: Sandbox.Selection) {\n\tconst selection = yield* Sandbox.resolve(input);\n\tif (selection.created && selection.info !== undefined) {\n\t\tconst id = selection.info.id;\n\t\tyield* Effect.addFinalizer(() => Effect.ignore(Sandbox.stop(id)));\n\t}\n\treturn selection.info;\n});\n\nexport default Runtime.handler(\n\tCmd.commands.run,\n\tEffect.fn(\"CLI.run\")(function* ({\n\t\tprompt,\n\t\tsession,\n\t\tcwd,\n\t\tsandboxDriver,\n\t\tsandboxProviderId,\n\t\tsandboxId,\n\t\tprovider,\n\t\tmodel,\n\t\tthinking,\n\t\tserver,\n\t}) {\n\t\tconst shared = yield* Cmd.spec;\n\t\tif (\n\t\t\tOption.isSome(session) &&\n\t\t\t(Option.isSome(cwd) ||\n\t\t\t\tOption.isSome(sandboxDriver) ||\n\t\t\t\tOption.isSome(sandboxProviderId) ||\n\t\t\t\tOption.isSome(sandboxId))\n\t\t) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage:\n\t\t\t\t\t\"--cwd, --sandbox-driver, --sandbox-id, and --sandbox-provider-id can only be used when creating a new session\",\n\t\t\t});\n\t\t}\n\t\tif (Option.isSome(provider) !== Option.isSome(model)) {\n\t\t\treturn yield* new InvalidInputError({ message: \"--provider and --model must be provided together\" });\n\t\t}\n\t\tif (Option.isSome(sandboxProviderId) && Option.isNone(sandboxDriver)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--sandbox-provider-id requires a remote --sandbox-driver\",\n\t\t\t});\n\t\t}\n\t\tif (Option.isSome(server) && [shared.home, shared.database, shared.userConfigDir].some(Option.isSome)) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--home, --database, and --user-config-dir belong on codework serve when using --server\",\n\t\t\t});\n\t\t}\n\n\t\tif (Option.isSome(sandboxId) && (Option.isSome(sandboxDriver) || Option.isSome(sandboxProviderId))) {\n\t\t\treturn yield* new InvalidInputError({\n\t\t\t\tmessage: \"--sandbox-id cannot be combined with --sandbox-driver or --sandbox-provider-id\",\n\t\t\t});\n\t\t}\n\t\tconst selection: Sandbox.Selection = Option.isSome(sandboxId)\n\t\t\t? { id: Sandbox.SandboxInstance.ID.make(sandboxId.value) }\n\t\t\t: {\n\t\t\t\t\tdriver: Option.getOrElse(sandboxDriver, () => \"local\"),\n\t\t\t\t\t...(Option.isNone(sandboxProviderId) ? {} : { providerResourceId: sandboxProviderId.value }),\n\t\t\t\t};\n\n\t\t// The session's host directory, with no flag to set it: a person running a command is always\n\t\t// somewhere, and that somewhere is what they mean by \"this project\". `--cwd` is a different\n\t\t// thing entirely -- where the work runs inside the session's space, which may be a sandbox\n\t\t// on another machine.\n\t\tconst hostDir = Session.AbsolutePath.make(process.cwd());\n\n\t\tconst runtime = {\n\t\t\t...(Option.isNone(provider) || Option.isNone(model)\n\t\t\t\t? {}\n\t\t\t\t: { model: { provider: provider.value, id: model.value } }),\n\t\t\t...(Option.isNone(thinking) ? {} : { thinkingLevel: thinking.value }),\n\t\t};\n\t\tconst remote = Effect.gen(function* () {\n\t\t\tconst rpc = yield* Client.make;\n\t\t\tconst info = Option.isSome(session)\n\t\t\t\t? yield* rpc[\"session.configure\"]({ sessionId: Session.SessionSchema.ID.make(session.value), runtime })\n\t\t\t\t: yield* rpc[\"session.create\"]({\n\t\t\t\t\t\ttitle: \"CLI\",\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\t...(Option.isNone(cwd) ? {} : { directory: cwd.value }),\n\t\t\t\t\t\thostDir,\n\t\t\t\t\t\tsandbox: selection,\n\t\t\t\t\t});\n\t\t\tconst state = yield* Ref.make(initialRenderState);\n\t\t\tconst columns = terminalColumns();\n\t\t\tyield* writeError(\n\t\t\t\theader({\n\t\t\t\t\tsessionId: info.id,\n\t\t\t\t\tsandbox: info.sandbox?.driver ?? \"local\",\n\t\t\t\t\tdirectory: info.directory,\n\t\t\t\t\tcolumns,\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (info.sandbox !== undefined) yield* writeError(`sandbox-id: ${info.sandbox.id}\\n`);\n\t\t\tyield* Client.run(rpc, { sessionId: info.id, text: prompt }, render(state)).pipe(\n\t\t\t\tEffect.onInterrupt(() =>\n\t\t\t\t\trpc[\"session.interrupt\"]({ sessionId: info.id }).pipe(Effect.timeout(\"5 seconds\"), Effect.ignore),\n\t\t\t\t),\n\t\t\t);\n\t\t\tyield* finish(state, columns);\n\t\t});\n\t\tconst program = Effect.gen(function* () {\n\t\t\tlet handle: Session.Handle;\n\t\t\tif (Option.isSome(session)) {\n\t\t\t\thandle = yield* Session.attach({ sessionId: Session.SessionSchema.ID.make(session.value), ...runtime });\n\t\t\t} else {\n\t\t\t\tconst selected = yield* selectSandbox(selection);\n\t\t\t\thandle = yield* Session.create({\n\t\t\t\t\ttitle: \"CLI\",\n\t\t\t\t\t...runtime,\n\t\t\t\t\t...(selected === undefined ? {} : { sandbox: selected }),\n\t\t\t\t\t...(Option.isNone(cwd) ? {} : { directory: cwd.value }),\n\t\t\t\t\thostDir,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst ended = yield* Queue.unbounded<string>();\n\t\t\tconst renderState = yield* Ref.make(initialRenderState);\n\t\t\tconst printer = yield* handle\n\t\t\t\t.events()\n\t\t\t\t.pipe(Stream.runForEach(render(renderState, ended)), Effect.forkScoped({ startImmediately: true }));\n\n\t\t\tconst info = yield* handle.info;\n\t\t\tconst columns = terminalColumns();\n\t\t\tyield* writeError(\n\t\t\t\theader({\n\t\t\t\t\tsessionId: handle.id,\n\t\t\t\t\tsandbox: info.sandbox?.driver ?? \"local\",\n\t\t\t\t\tdirectory: info.directory,\n\t\t\t\t\tcolumns,\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// The local command joins execution to retain typed error details.\n\t\t\tconst execution = yield* handle\n\t\t\t\t.prompt({ text: prompt, delivery: \"followUp\" })\n\t\t\t\t.pipe(Effect.andThen(handle.resume()), Effect.exit);\n\t\t\tyield* handle.wait();\n\t\t\tif (Exit.isFailure(execution)) return yield* Effect.failCause(execution.cause);\n\t\t\tconst path = yield* handle.path();\n\t\t\tconst leaf = path.at(-1);\n\t\t\tif (leaf !== undefined) yield* awaitMessage(ended, leaf.entry.id);\n\t\t\tyield* Fiber.interrupt(printer);\n\t\t\tyield* finish(renderState, columns);\n\t\t});\n\n\t\tconst execute = Effect.gen(function* () {\n\t\t\tif (Option.isSome(server)) return yield* remote.pipe(Effect.provide(Client.layer(server.value)));\n\t\t\treturn yield* program.pipe(Effect.provide(Harness.layer(harnessOptions(shared))));\n\t\t});\n\t\treturn yield* execute.pipe(\n\t\t\tEffect.scoped,\n\t\t\tEffect.catch((error) =>\n\t\t\t\twriteError(renderError(error)).pipe(\n\t\t\t\t\tEffect.andThen(\n\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t}),\n);\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-B3dlWGfs.mjs","names":["Spec.make"],"sources":["../../src/framework/spec.ts","../../src/cli/cmd/cmd.ts","../../src/framework/runtime.ts"],"sourcesContent":["import { Command } from \"effect/unstable/cli\";\n\n/**\n * A declarative command tree. Specs carry only the shape of a command -- its\n * name, parameters, description, and children -- so the whole CLI surface can\n * be read in one file. Handlers are attached separately by {@link Runtime}, which\n * keeps their imports (and the harness they pull in) off the startup path.\n */\n\nexport interface Example {\n\treadonly command: string;\n\treadonly description: string;\n}\n\ninterface Options<\n\tConfig extends Command.Command.Config,\n\tShared extends Command.Command.FlagConfig,\n\tCommands extends ReadonlyArray<Any>,\n> {\n\treadonly description?: string;\n\treadonly params?: Config;\n\t/** Flags declared here are also parsed by every descendant command. */\n\treadonly shared?: Shared;\n\treadonly examples?: ReadonlyArray<Example>;\n\treadonly commands?: Commands;\n}\n\nexport interface Node<\n\tName extends string,\n\t// The tree is heterogeneous, so a node has to accept any command shape here.\n\t// Concrete types are recovered per-command through `Runtime.Input`.\n\t// biome-ignore lint/suspicious/noExplicitAny: heterogeneous command tree\n\tSpec extends Command.Command<Name, any, any, any, any>,\n\tCommands extends Children,\n> {\n\treadonly name: Name;\n\treadonly spec: Spec;\n\treadonly commands: Commands;\n}\n\n// The command name is invariant on `Command`, so the erased node type has to\n// admit any name for concrete nodes to be assignable to it.\n// biome-ignore lint/suspicious/noExplicitAny: heterogeneous command tree\nexport type Any = Node<string, Command.Command<any, any, any, any, any>, Children>;\nexport type Children = Readonly<Record<string, Any>>;\n\ntype ChildrenOf<Commands extends ReadonlyArray<Any>> = {\n\treadonly [Node in Commands[number] as Node[\"name\"]]: Node;\n};\n\nexport function make<\n\tconst Name extends string,\n\tconst Config extends Command.Command.Config = {},\n\tconst Shared extends Command.Command.FlagConfig = {},\n\tconst Commands extends ReadonlyArray<Any> = [],\n>(name: Name, options: Options<Config, Shared, Commands> = {}) {\n\tlet spec = Command.make(name, options.params ?? ({} as Config)).pipe(\n\t\tCommand.withSharedFlags(options.shared ?? ({} as Shared)),\n\t);\n\tif (options.description !== undefined) spec = spec.pipe(Command.withDescription(options.description));\n\tif (options.examples !== undefined) spec = spec.pipe(Command.withExamples(options.examples));\n\treturn {\n\t\tname,\n\t\tspec,\n\t\tcommands: Object.fromEntries(\n\t\t\t(options.commands ?? []).map((command) => [command.name, command]),\n\t\t) as ChildrenOf<Commands>,\n\t};\n}\n\nexport * as Spec from \"./spec.ts\";\n","import { Schema } from \"effect\";\nimport { Model } from \"@codeworksh/aikit\";\nimport { Argument, Flag } from \"effect/unstable/cli\";\nimport { Spec } from \"../../framework/spec.ts\";\n\n/**\n * The full command surface of the `codework` CLI. Declarations only -- each\n * command's behaviour lives in `./handlers`, wired up in `src/index.ts`.\n */\n\nexport const thinkingLevels = Object.values(Model.ThinkingLevelEnum);\n\n/**\n * Every `auth` subcommand answers the same three questions: which provider,\n * whose credentials, and where they live. Only `login` needs anything more.\n */\nconst AuthParams = {\n\topenaiCodex: Flag.Boolean(\"openai-codex\").pipe(\n\t\tFlag.withDescription(\"Use OpenAI Codex OAuth\"),\n\t\tFlag.withDefault(false),\n\t),\n\tgithubCopilot: Flag.Boolean(\"github-copilot\").pipe(\n\t\tFlag.withDescription(\"Use GitHub Copilot OAuth (device flow)\"),\n\t\tFlag.withDefault(false),\n\t),\n\tserver: Flag.String(\"server\").pipe(Flag.withDescription(\"RPC server URL (ws://host:port/rpc)\"), Flag.optional),\n\tauthFile: Flag.String(\"auth-file\").pipe(\n\t\tFlag.withDescription(\"Credential file (defaults to <home>/aikit/auth.json)\"),\n\t\tFlag.optional,\n\t),\n};\n\nconst JsonFlag = Flag.Boolean(\"json\").pipe(\n\tFlag.withDescription(\"Print machine-readable output\"),\n\tFlag.withDefault(false),\n);\n\nexport const Cmd = Spec.make(\"codework\", {\n\tdescription: \"CodeWork Command Line Interface\",\n\tshared: {\n\t\tuserConfigDir: Flag.String(\"user-config-dir\").pipe(\n\t\t\tFlag.withDescription(\"Directory whose settings.jsonc replaces the user settings in --home\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\thome: Flag.String(\"home\").pipe(\n\t\t\tFlag.withDescription(\"CodeWork home: user settings, credentials, cache and data (default: ~/.codework)\"),\n\t\t\tFlag.optional,\n\t\t),\n\t\tdatabase: Flag.String(\"database\").pipe(Flag.withDescription(\"SQLite database path or :memory:\"), Flag.optional),\n\t},\n\tcommands: [\n\t\tSpec.make(\"auth\", {\n\t\t\tdescription: \"Manage OAuth credentials\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"login\", {\n\t\t\t\t\tdescription: \"Sign in to a provider\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\t...AuthParams,\n\t\t\t\t\t\tbrowser: Flag.Boolean(\"browser\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Open the authorization URL in the default browser\"),\n\t\t\t\t\t\t\tFlag.withDefault(true),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdevice: Flag.Boolean(\"device\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Use the device-code flow instead of a localhost browser callback\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tenterprise: Flag.String(\"enterprise\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"GitHub Enterprise domain for GitHub Copilot login\"),\n\t\t\t\t\t\t\tFlag.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tenableModels: Flag.Boolean(\"enable-models\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Enable unconfigured Copilot catalog models after login\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tjson: JsonFlag,\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework auth login --openai-codex\", description: \"Sign in with ChatGPT\" },\n\t\t\t\t\t\t{ command: \"codework auth login --github-copilot\", description: \"Sign in with GitHub Copilot\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework auth login --openai-codex --device\",\n\t\t\t\t\t\t\tdescription: \"Sign in with a device code, no local port\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework auth login --openai-codex --server ws://127.0.0.1:7433/rpc\",\n\t\t\t\t\t\t\tdescription: \"Sign in the running server\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"status\", {\n\t\t\t\t\tdescription: \"Show a stored login without refreshing it\",\n\t\t\t\t\tparams: { ...AuthParams, json: JsonFlag },\n\t\t\t\t\texamples: [{ command: \"codework auth status --openai-codex\", description: \"Show the stored login\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"refresh\", {\n\t\t\t\t\tdescription: \"Refresh a stored login if it has expired\",\n\t\t\t\t\tparams: { ...AuthParams, json: JsonFlag },\n\t\t\t\t\texamples: [{ command: \"codework auth refresh --openai-codex\", description: \"Renew an expired login\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"logout\", {\n\t\t\t\t\tdescription: \"Clear a stored login\",\n\t\t\t\t\tparams: AuthParams,\n\t\t\t\t\texamples: [{ command: \"codework auth logout --github-copilot\", description: \"Clear the stored login\" }],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"run\", {\n\t\t\tdescription: \"Start or continue an agent session\",\n\t\t\tparams: {\n\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\tFlag.withDescription(\"RPC server URL (ws://host:port/rpc)\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tprompt: Argument.String(\"prompt\").pipe(Argument.withDescription(\"Prompt for the agent\")),\n\t\t\t\tsession: Flag.String(\"session\").pipe(\n\t\t\t\t\tFlag.withAlias(\"s\"),\n\t\t\t\t\tFlag.withDescription(\"Continue an existing session\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tcwd: Flag.String(\"cwd\").pipe(\n\t\t\t\t\tFlag.withAlias(\"C\"),\n\t\t\t\t\tFlag.withDescription(\"Working directory for a new session\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxDriver: Flag.String(\"sandbox-driver\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Sandbox driver for a new session (default: local)\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxId: Flag.String(\"sandbox-id\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Reuse an existing sandbox instance\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tsandboxProviderId: Flag.String(\"sandbox-provider-id\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Provider ID of an existing remote sandbox\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t\tprovider: Flag.String(\"provider\").pipe(Flag.withDescription(\"Model catalog provider ID\"), Flag.optional),\n\t\t\t\tmodel: Flag.String(\"model\").pipe(Flag.withDescription(\"Model ID\"), Flag.optional),\n\t\t\t\tthinking: Flag.Literals(\"thinking\", thinkingLevels).pipe(\n\t\t\t\t\tFlag.withDescription(\"Reasoning effort the model uses before answering\"),\n\t\t\t\t\tFlag.optional,\n\t\t\t\t),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: 'codework run \"Inspect the failing tests\"', description: \"Create a session\" },\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --provider openai --model gpt-5.5 --thinking high \"Inspect the failing tests\"',\n\t\t\t\t\tdescription: \"Create a session with an explicit model\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --sandbox-driver daytona \"Inspect the repository\"',\n\t\t\t\t\tdescription: \"Create a Daytona sandbox and session\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --sandbox-driver daytona --sandbox-provider-id <id> \"Inspect the repository\"',\n\t\t\t\t\tdescription: \"Use an existing remote sandbox\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcommand: 'codework run --session <id> --provider openai --model gpt-5.6-luna \"Now fix them\"',\n\t\t\t\t\tdescription: \"Continue a session with explicit model bindings\",\n\t\t\t\t},\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"serve\", {\n\t\t\tdescription: \"Start the CodeWork RPC server\",\n\t\t\tparams: {\n\t\t\t\thost: Flag.String(\"host\").pipe(\n\t\t\t\t\tFlag.withDescription(\"Host interface to bind\"),\n\t\t\t\t\tFlag.withDefault(\"127.0.0.1\"),\n\t\t\t\t),\n\t\t\t\tport: Flag.Int(\"port\").pipe(\n\t\t\t\t\tFlag.withSchema(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 65535 }))),\n\t\t\t\t\tFlag.withDescription(\"Port to listen on (0 for an ephemeral port)\"),\n\t\t\t\t\tFlag.withDefault(7433),\n\t\t\t\t),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: \"codework serve\", description: \"Start the RPC server on 127.0.0.1:7433\" },\n\t\t\t\t{ command: \"codework serve --port 0\", description: \"Choose an available local port\" },\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"session\", {\n\t\t\tdescription: \"Manage sessions\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"link\", {\n\t\t\t\t\tdescription: \"Anchor a session to a host directory\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tsession: Argument.String(\"session-id\").pipe(Argument.withDescription(\"The session to link\")),\n\t\t\t\t\t\tpath: Argument.String(\"path\").pipe(\n\t\t\t\t\t\t\t// The anchor is not a configuration mechanism, but `.codework` is the landmark\n\t\t\t\t\t\t\t// a person recognises, so the help names it to make the directory concrete.\n\t\t\t\t\t\t\tArgument.withDescription(\n\t\t\t\t\t\t\t\t\"Host directory to anchor to — typically the directory holding your .codework configuration; defaults to the shell's\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tunlink: Flag.Boolean(\"unlink\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Clear the anchor, leaving the session with no host directory\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Base URL of the running codework server\"),\n\t\t\t\t\t\t\tFlag.withDefault(\"http://127.0.0.1:7433\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9\",\n\t\t\t\t\t\t\tdescription: \"Link it to the directory you are standing in\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9 ~/work/api\",\n\t\t\t\t\t\t\tdescription: \"Link it to a project elsewhere on this machine\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework session link ses_01h9 --unlink\",\n\t\t\t\t\t\t\tdescription: \"Clear the anchor\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"plugin\", {\n\t\t\tdescription: \"Manage plugins\",\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"add\", {\n\t\t\t\t\tdescription: \"Install a plugin and add it to a settings file\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tpackage: Argument.String(\"package\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Package spec, path, or file: URL\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tglobal: Flag.Boolean(\"global\").pipe(\n\t\t\t\t\t\t\tFlag.withAlias(\"g\"),\n\t\t\t\t\t\t\tFlag.withDescription(\"Write the user-wide settings file instead of this project's\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tsession: Flag.String(\"session\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Write the project a session is linked to, rather than this directory's\"),\n\t\t\t\t\t\t\tFlag.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc@1.2.0\",\n\t\t\t\t\t\t\tdescription: \"Install a published plugin into this project's settings\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc --session ses_01h9\",\n\t\t\t\t\t\t\tdescription: \"Write the project that session is linked to, from anywhere\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin add @acme/codework-tool-proc -g\",\n\t\t\t\t\t\t\tdescription: \"Install it for every project this user runs\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"install\", {\n\t\t\t\t\tdescription: \"Install every plugin the settings files name\",\n\t\t\t\t\tparams: {},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin install\",\n\t\t\t\t\t\t\tdescription: \"Materialise what a fresh checkout already declares\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"list\", {\n\t\t\t\t\tdescription: \"List configured plugins and what each one resolved to\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tverbose: Flag.Boolean(\"verbose\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Show the message behind a failure, not only its reason\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [{ command: \"codework plugin list\", description: \"Show every configured plugin\" }],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"check\", {\n\t\t\t\t\tdescription: \"Report which configured plugins have a newer revision available\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tspec: Argument.String(\"spec\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Only this configured plugin: a package name or spec, git spec, or path\"),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t\t// An answer is reused for an hour, which is right for a command someone may\n\t\t\t\t\t\t// run repeatedly and wrong for the minute after they pushed a plugin. Without\n\t\t\t\t\t\t// this there is no way to say \"ask again\", and `check` reports a moving branch\n\t\t\t\t\t\t// as current while `update` — which always refreshes — moves it.\n\t\t\t\t\t\trefresh: Flag.Boolean(\"refresh\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Ask the remote again instead of reusing a recent answer\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework plugin check\", description: \"Ask the registry what has moved\" },\n\t\t\t\t\t\t{ command: \"codework plugin check @acme/codework-tool-proc\", description: \"Ask about one plugin\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin check --refresh\",\n\t\t\t\t\t\t\tdescription: \"Ignore the cached answer, after pushing a plugin\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"update\", {\n\t\t\t\t\tdescription: \"Fetch a newer revision of every plugin that has one\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tspec: Argument.String(\"spec\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Only this configured plugin: a package name or spec, git spec, or path\"),\n\t\t\t\t\t\t\tArgument.optional,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework plugin update\", description: \"Take whatever `check` found\" },\n\t\t\t\t\t\t{ command: \"codework plugin update @acme/codework-tool-proc\", description: \"Update one plugin\" },\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"reload\", {\n\t\t\t\t\tdescription: \"Re-import configured plugins in a running server\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tserver: Flag.String(\"server\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Base URL of the running codework server\"),\n\t\t\t\t\t\t\tFlag.withDefault(\"http://127.0.0.1:7433\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin reload\",\n\t\t\t\t\t\t\tdescription: \"Pick up edits to a local plugin without restarting\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"remove\", {\n\t\t\t\t\tdescription: \"Remove a plugin from a settings file\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tpackage: Argument.String(\"package\").pipe(\n\t\t\t\t\t\t\tArgument.withDescription(\"Configured package spec, path, or plugin ID\"),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tglobal: Flag.Boolean(\"global\").pipe(\n\t\t\t\t\t\t\tFlag.withAlias(\"g\"),\n\t\t\t\t\t\t\tFlag.withDescription(\"Edit the user-wide settings file instead of this project's\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: \"codework plugin remove @acme/codework-tool-proc\",\n\t\t\t\t\t\t\tdescription: \"Drop a plugin and any configuration written against it\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tSpec.make(\"models\", {\n\t\t\tdescription: \"List or refresh the model catalog\",\n\t\t\tparams: {\n\t\t\t\tprovider: Flag.String(\"provider\").pipe(Flag.withDescription(\"Model catalog provider ID\"), Flag.optional),\n\t\t\t},\n\t\t\texamples: [\n\t\t\t\t{ command: \"codework models\", description: \"List all models from all providers\" },\n\t\t\t\t{\n\t\t\t\t\tcommand: \"codework models --provider openai\",\n\t\t\t\t\tdescription: \"List models for a specific provider\",\n\t\t\t\t},\n\t\t\t\t{ command: \"codework models providers\", description: \"List all available provider IDs\" },\n\t\t\t],\n\t\t\tcommands: [\n\t\t\t\tSpec.make(\"providers\", {\n\t\t\t\t\tdescription: \"List available model providers in the catalog\",\n\t\t\t\t}),\n\t\t\t\tSpec.make(\"refresh\", {\n\t\t\t\t\tdescription: \"Download the model catalog into the home if it is stale\",\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tforce: Flag.Boolean(\"force\").pipe(\n\t\t\t\t\t\t\tFlag.withDescription(\"Download it even if it is still fresh\"),\n\t\t\t\t\t\t\tFlag.withDefault(false),\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t{ command: \"codework models refresh\", description: \"Refresh a catalog older than 15 minutes\" },\n\t\t\t\t\t\t{ command: \"codework models refresh --force\", description: \"Download the catalog now\" },\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t],\n});\n","import { Effect } from \"effect\";\nimport { Command } from \"effect/unstable/cli\";\nimport type { CommandError } from \"../cli/error.ts\";\nimport { Spec } from \"./spec.ts\";\n\n/**\n * Binds handlers to a {@link Spec} tree. Handlers are loaded through dynamic\n * imports so that starting the process -- or printing `--help` -- never pulls in\n * the harness, its sandbox drivers, or the model catalog.\n */\n\n/** Recovers the parsed input type of a spec node, for typing its handler. */\nexport type Input<Value> =\n\tValue extends Spec.Node<infer _Name, infer Spec, infer _Commands>\n\t\t? Input<Spec>\n\t\t: Value extends Command.Command<infer _Name, infer Parsed, infer _Context, infer _Error, infer _Requirements>\n\t\t\t? Parsed\n\t\t\t: never;\n\n/**\n * A handler may yield an ancestor's spec to read its shared flags, which shows up\n * as a `CommandContext` requirement; `withSubcommands` discharges it when the tree\n * is assembled.\n */\ntype Requirements = Command.Environment | Command.CommandContext<string>;\ntype Run<Parsed> = (input: Parsed) => Effect.Effect<void, CommandError, Requirements>;\ntype Loader<Node extends Spec.Any> = () => Promise<{ readonly default: Run<Input<Node>> }>;\n\n/**\n * The handler registry for a spec tree: a loader per leaf, mirroring the shape of\n * the tree. A parent with children takes its own handler under `$`.\n */\nexport type Handlers<Node extends Spec.Any> = keyof Node[\"commands\"] extends never\n\t? Loader<Node>\n\t: { readonly $?: Loader<Node> } & { readonly [Key in keyof Node[\"commands\"]]: Handlers<Node[\"commands\"][Key]> };\n\ninterface LazyHandler {\n\treadonly spec: Command.Command.Any;\n\t// biome-ignore lint/suspicious/noExplicitAny: input is recovered per-command by `Input`\n\treadonly load: () => Promise<{ readonly default: Run<any> }>;\n}\n\ntype LazyHandlers = LazyHandler[\"load\"] | { readonly [key: string]: LazyHandlers | undefined };\n\ntype ProvidedCommand = Command.Command<string, unknown, unknown, CommandError, Command.Environment>;\n\n/** Type-checks a handler against the spec node it implements. */\nexport function handler<const Node extends Spec.Any>(_node: Node, run: Run<Input<Node>>) {\n\treturn run;\n}\n\nexport function handlers<const Root extends Spec.Any>(\n\troot: Root,\n\thandlers: Handlers<Root>,\n): ReadonlyArray<LazyHandler> {\n\tconst result: LazyHandler[] = [];\n\n\tfunction add(node: Spec.Any, value: LazyHandlers) {\n\t\tif (typeof value === \"function\") {\n\t\t\tresult.push({ spec: node.spec, load: value });\n\t\t\treturn;\n\t\t}\n\t\tif (value.$ !== undefined) result.push({ spec: node.spec, load: value.$ as LazyHandler[\"load\"] });\n\t\tfor (const [name, child] of Object.entries(node.commands)) {\n\t\t\tconst nested = value[name];\n\t\t\tif (nested !== undefined) add(child, nested);\n\t\t}\n\t}\n\n\tadd(root, handlers as LazyHandlers);\n\treturn result;\n}\n\nexport function run(root: Spec.Any, handlers: ReadonlyArray<LazyHandler>, options: { readonly version: string }) {\n\treturn Command.run(provide(root, handlers), options);\n}\n\nfunction provide(node: Spec.Any, handlers: ReadonlyArray<LazyHandler>): ProvidedCommand {\n\tconst found = handlers.find((entry) => entry.spec === node.spec);\n\tconst spec = found\n\t\t? node.spec.pipe(\n\t\t\t\tCommand.withHandler((input) =>\n\t\t\t\t\tEffect.promise(found.load).pipe(Effect.flatMap((module) => module.default(input))),\n\t\t\t\t),\n\t\t\t)\n\t\t: node.spec;\n\tconst children = Object.values(node.commands);\n\tif (children.length === 0) return spec as ProvidedCommand;\n\treturn spec.pipe(Command.withSubcommands(children.map((child) => provide(child, handlers)))) as ProvidedCommand;\n}\n\nexport * as Runtime from \"./runtime.ts\";\n"],"mappings":"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"}