@agimon-ai/doompi-loop 0.0.1-alpha.9 → 0.0.1-alpha.90

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 (87) hide show
  1. package/README.md +83 -21
  2. package/dist/apiContracts.cjs +17 -0
  3. package/dist/apiContracts.cjs.map +1 -0
  4. package/dist/apiContracts.d.mts +53 -0
  5. package/dist/apiContracts.d.mts.map +1 -0
  6. package/dist/apiContracts.mjs +13 -0
  7. package/dist/apiContracts.mjs.map +1 -0
  8. package/dist/extensions/pi.cjs +659 -1
  9. package/dist/extensions/pi.cjs.map +1 -1
  10. package/dist/extensions/pi.d.mts +5 -2
  11. package/dist/extensions/pi.d.mts.map +1 -0
  12. package/dist/extensions/pi.mjs +654 -1
  13. package/dist/extensions/pi.mjs.map +1 -1
  14. package/dist/extensions/server.cjs +369 -0
  15. package/dist/extensions/server.cjs.map +1 -0
  16. package/dist/extensions/server.d.mts +5 -0
  17. package/dist/extensions/server.d.mts.map +1 -0
  18. package/dist/extensions/server.mjs +364 -0
  19. package/dist/extensions/server.mjs.map +1 -0
  20. package/dist/extensions/web.mjs +331 -0
  21. package/dist/extensions/web.mjs.map +1 -0
  22. package/dist/index.cjs +0 -1
  23. package/dist/index.d.mts +2 -4
  24. package/dist/index.mjs +1 -1
  25. package/dist/loopLaunchers-Bciapxt0.d.mts +69 -0
  26. package/dist/loopLaunchers-Bciapxt0.d.mts.map +1 -0
  27. package/dist/loopLaunchers-BtcLH_xN.cjs +32 -0
  28. package/dist/loopLaunchers-BtcLH_xN.cjs.map +1 -0
  29. package/dist/loopLaunchers-cCniFbVA.mjs +15 -0
  30. package/dist/loopLaunchers-cCniFbVA.mjs.map +1 -0
  31. package/dist/loopLaunchers.cjs +5 -0
  32. package/dist/loopLaunchers.d.mts +2 -0
  33. package/dist/loopLaunchers.mjs +2 -0
  34. package/dist/loopView-BK4X_1UI.mjs +349 -0
  35. package/dist/loopView-BK4X_1UI.mjs.map +1 -0
  36. package/dist/loopView-C_OPuy8L.cjs +456 -0
  37. package/dist/loopView-C_OPuy8L.cjs.map +1 -0
  38. package/llms.txt +9 -0
  39. package/package.json +82 -14
  40. package/src/prompts/doompi-use-loop/SKILL.md +44 -0
  41. package/src/types/loopView.ts +73 -0
  42. package/dist/commands/loopCommand.cjs +0 -2
  43. package/dist/commands/loopCommand.cjs.map +0 -1
  44. package/dist/commands/loopCommand.mjs +0 -2
  45. package/dist/commands/loopCommand.mjs.map +0 -1
  46. package/dist/constants.cjs +0 -2
  47. package/dist/constants.cjs.map +0 -1
  48. package/dist/constants.mjs +0 -2
  49. package/dist/constants.mjs.map +0 -1
  50. package/dist/defaultLauncher.cjs +0 -2
  51. package/dist/defaultLauncher.cjs.map +0 -1
  52. package/dist/defaultLauncher.d.cts +0 -10
  53. package/dist/defaultLauncher.d.cts.map +0 -1
  54. package/dist/defaultLauncher.d.mts +0 -10
  55. package/dist/defaultLauncher.d.mts.map +0 -1
  56. package/dist/defaultLauncher.mjs +0 -2
  57. package/dist/defaultLauncher.mjs.map +0 -1
  58. package/dist/extension.cjs +0 -2
  59. package/dist/extension.cjs.map +0 -1
  60. package/dist/extension.d.cts +0 -6
  61. package/dist/extension.d.cts.map +0 -1
  62. package/dist/extension.d.mts +0 -6
  63. package/dist/extension.d.mts.map +0 -1
  64. package/dist/extension.mjs +0 -2
  65. package/dist/extension.mjs.map +0 -1
  66. package/dist/extensions/pi.d.cts +0 -2
  67. package/dist/index.d.cts +0 -4
  68. package/dist/launcher.cjs +0 -2
  69. package/dist/launcher.cjs.map +0 -1
  70. package/dist/launcher.d.cts +0 -47
  71. package/dist/launcher.d.cts.map +0 -1
  72. package/dist/launcher.d.mts +0 -47
  73. package/dist/launcher.d.mts.map +0 -1
  74. package/dist/launcher.mjs +0 -2
  75. package/dist/launcher.mjs.map +0 -1
  76. package/dist/leader.cjs +0 -2
  77. package/dist/leader.cjs.map +0 -1
  78. package/dist/leader.mjs +0 -2
  79. package/dist/leader.mjs.map +0 -1
  80. package/dist/tui/loopListOverlay.cjs +0 -2
  81. package/dist/tui/loopListOverlay.cjs.map +0 -1
  82. package/dist/tui/loopListOverlay.mjs +0 -2
  83. package/dist/tui/loopListOverlay.mjs.map +0 -1
  84. package/dist/tui/startLoopOverlay.cjs +0 -2
  85. package/dist/tui/startLoopOverlay.cjs.map +0 -1
  86. package/dist/tui/startLoopOverlay.mjs +0 -2
  87. package/dist/tui/startLoopOverlay.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pi.mjs","names":[],"sources":["../../src/extensions/pi.ts"],"sourcesContent":["import { registerLoopExtension } from '../extension.ts';\n\nexport default registerLoopExtension;\n"],"mappings":"yDAEA,IAAA,EAAe"}
1
+ {"version":3,"file":"pi.mjs","names":["EMPTY_MESSAGE","runtime","defineTool","defineTool","defineTool","rootSession","commandLoop","commandLoops","hookAgentSettled","resourceDoompiUseLoop","toolRestrictionLoop","toolLoopList","toolLoopStart","toolLoopStop"],"sources":["../../src/services/loopCommand/index.ts","../../src/services/defaultLoopLauncher/index.ts","../../src/tui/leader.ts","../../src/tui/loopListOverlay.ts","../../src/tui/startLoopOverlay.ts","../../src/tui/loopRuntime.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/runtime.cli.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/loop.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/loops.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool-restriction/loop.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-list.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-start.cli.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-stop.cli.ts","../../generated/pi.ts"],"sourcesContent":["import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';\n\nimport { START_COMMAND_DESCRIPTION, LIST_COMMAND_DESCRIPTION } from '../../constants/loop';\nimport { LIST_COMMAND_NAME, START_COMMAND_NAME } from '../../constants/loop';\nimport type { LoopCommandHandlers } from '../../types/loopCommand';\nexport function createLoopCommands(\n handlers: LoopCommandHandlers,\n): readonly (readonly [string, Parameters<ExtensionAPI['registerCommand']>[1]])[] {\n return [\n [\n START_COMMAND_NAME,\n {\n description: START_COMMAND_DESCRIPTION,\n handler: async (args, ctx) => handlers.start(ctx, args),\n },\n ],\n [\n LIST_COMMAND_NAME,\n {\n description: LIST_COMMAND_DESCRIPTION,\n handler: async (args, ctx) => handlers.list(ctx, args),\n },\n ],\n ];\n}\n","import type { ExtensionAPI, ExtensionContext, ExtensionUIContext } from '@earendil-works/pi-coding-agent';\nimport { Cron } from 'croner';\n\nimport { NOTIFY_WARNING_LEVEL, PACKAGE_SOURCE } from '../../constants/piLoop';\nimport type {\n DoomLoopLaunchersService,\n LoopLaunchRequest,\n LoopLauncherRegistration,\n} from '../../schemas/loopLaunchers';\nimport { CronLoopSchema, IntervalLoopSchema, parseCronLoop, parseIntervalLoop } from '../../schemas/loopTools';\n\nconst DEFAULT_INTERVAL_SECONDS = 300;\nconst MIN_INTERVAL_SECONDS = 30;\nconst MAX_INTERVAL_SECONDS = 3600;\nconst MILLISECONDS_PER_SECOND = 1000;\nconst PROMPT_PREVIEW_LENGTH = 80;\n\ninterface ActiveDefaultLoop {\n readonly prompt: string;\n readonly context: ExtensionContext;\n stopped: boolean;\n}\n\nexport interface DefaultLoopLauncher {\n onAgentSettled(this: void): void;\n register(ctx: ExtensionContext, launchers: DoomLoopLaunchersService): LoopLauncherRegistration;\n registerCron(ctx: ExtensionContext, launchers: DoomLoopLaunchersService): LoopLauncherRegistration;\n}\n\nasync function prepareLoop(ui: ExtensionUIContext, request: LoopLaunchRequest, cron: boolean) {\n if (request.input !== undefined) return cron ? parseCronLoop(request.input) : parseIntervalLoop(request.input);\n if (request.interactive === false) throw new Error('Loop configuration is required for agent launches.');\n const prompt = (await ui.editor('Loop prompt', ''))?.trim();\n if (!prompt || request.signal.aborted) return undefined;\n if (cron) {\n const expression = await ui.input('Cron expression (five fields)', '0 * * * *');\n if (expression === undefined || request.signal.aborted) return undefined;\n const timezone = await ui.input('Loop timezone', 'UTC');\n if (timezone === undefined || request.signal.aborted) return undefined;\n return parseCronLoop({ prompt, cron: expression, timezone: timezone.trim() || 'UTC' });\n }\n const raw = await ui.input('Loop interval in seconds', `Default: ${DEFAULT_INTERVAL_SECONDS}s`);\n if (raw === undefined || request.signal.aborted) return undefined;\n const intervalSeconds = Number(raw.trim() || DEFAULT_INTERVAL_SECONDS);\n if (\n !Number.isInteger(intervalSeconds) ||\n intervalSeconds < MIN_INTERVAL_SECONDS ||\n intervalSeconds > MAX_INTERVAL_SECONDS\n ) {\n ui.notify(\n `Interval must be between ${MIN_INTERVAL_SECONDS} and ${MAX_INTERVAL_SECONDS} seconds.`,\n NOTIFY_WARNING_LEVEL,\n );\n return undefined;\n }\n return parseIntervalLoop({ prompt, intervalSeconds });\n}\n\nfunction promptPreview(prompt: string): string {\n const oneLine = prompt.replaceAll(/\\s+/gu, ' ').trim();\n return oneLine.length > PROMPT_PREVIEW_LENGTH ? `${oneLine.slice(0, PROMPT_PREVIEW_LENGTH - 1)}…` : oneLine;\n}\n\nexport function createDefaultLoopLauncher(pi: Pick<ExtensionAPI, 'sendUserMessage'>): DefaultLoopLauncher {\n const pending = new Set<ActiveDefaultLoop>();\n const requestPass = (loop: ActiveDefaultLoop): void => {\n if (loop.stopped) return;\n if (!loop.context.isIdle()) {\n pending.add(loop);\n return;\n }\n pending.delete(loop);\n try {\n pi.sendUserMessage(loop.prompt);\n } catch (error) {\n loop.context.ui.notify(\n `Default loop pass could not start: ${error instanceof Error ? error.message : String(error)}`,\n NOTIFY_WARNING_LEVEL,\n );\n }\n };\n const register = (ctx: ExtensionContext, launchers: DoomLoopLaunchersService, cron: boolean) =>\n launchers.register({\n id: cron ? 'doompi.cron' : 'doompi.default',\n source: PACKAGE_SOURCE,\n label: cron ? 'Cron loop' : 'Default loop',\n description: cron\n ? 'Run a prompt on a five-field cron schedule.'\n : 'Run your own prompt in this session on an interval',\n inputSchema: { ...(cron ? CronLoopSchema : IntervalLoopSchema) },\n async launch(request) {\n const prepared = await prepareLoop(ctx.ui, request, cron);\n if (!prepared || request.signal.aborted) return undefined;\n const loop: ActiveDefaultLoop = { prompt: prepared.prompt, context: ctx, stopped: false };\n let stopTimer: () => void;\n let schedule: string;\n if ('cron' in prepared) {\n const job = new Cron(prepared.cron, { timezone: prepared.timezone, unref: true }, () => requestPass(loop));\n if (job.nextRun() === null) {\n job.stop();\n throw new Error('Cron expression has no future run.');\n }\n stopTimer = () => {\n job.stop();\n };\n schedule = `${prepared.cron} (${prepared.timezone})`;\n } else {\n const timer = setInterval(() => requestPass(loop), prepared.intervalSeconds * MILLISECONDS_PER_SECOND);\n timer.unref?.();\n stopTimer = () => clearInterval(timer);\n schedule = `every ${prepared.intervalSeconds}s`;\n requestPass(loop);\n }\n return {\n instanceId: request.instanceId,\n label: cron ? 'Cron loop' : 'Default loop',\n detail: `${schedule} · ${promptPreview(loop.prompt)}`,\n stop() {\n if (loop.stopped) return;\n loop.stopped = true;\n stopTimer();\n pending.delete(loop);\n },\n };\n },\n });\n return {\n onAgentSettled() {\n const next = pending.values().next().value;\n if (next) requestPass(next);\n },\n register: (ctx, launchers) => register(ctx, launchers, false),\n registerCron: (ctx, launchers) => register(ctx, launchers, true),\n };\n}\n","import type { DoomUiHubService } from '@agimon-ai/doompi-core/uiHub';\n\nimport { LIST_COMMAND_NAME, START_COMMAND_NAME } from '../constants/loop';\nimport { LOOPS_GROUP_ORDER, PACKAGE_SOURCE } from '../constants/piLoop';\n\nconst LOOPS_GROUP_SEGMENT = {\n key: 'l',\n label: 'loops',\n detail: 'recurring prompt loops',\n order: LOOPS_GROUP_ORDER,\n} as const;\n\nexport function registerLeaderContribution(hub: DoomUiHubService): () => void {\n const contribution = hub.registerLeader({\n source: PACKAGE_SOURCE,\n bindings: [\n {\n id: 'loop.start',\n path: [LOOPS_GROUP_SEGMENT, { key: 's', label: 'start', detail: 'begin a recurring loop' }],\n command: { name: START_COMMAND_NAME },\n },\n {\n id: 'loop.list',\n path: [LOOPS_GROUP_SEGMENT, { key: 'l', label: 'list', detail: 'loops in this session' }],\n command: { name: LIST_COMMAND_NAME },\n },\n ],\n });\n return () => contribution.dispose();\n}\n","import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/doomOverlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { DoomLoopLaunchersService, LoopInstanceSnapshot } from '../schemas/loopLaunchers';\n\nconst EMPTY_MESSAGE = 'No loop instances are active in this session.';\nconst STOP_SCOPE_MESSAGE = 'Stopping a loop does not cancel detached work already launched.';\nconst STOP_REASON = 'Stopped from the loop list.';\n\nexport class LoopListOverlay extends DoomOverlay {\n private readonly unsubscribe: () => void;\n private instances: readonly LoopInstanceSnapshot[];\n private selected = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly client: DoomLoopLaunchersService,\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.instances = client.listInstances();\n this.unsubscribe = client.subscribe(() => this.refresh());\n }\n\n dispose(): void {\n this.unsubscribe();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c') || data === 'q') {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.move(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.move(1);\n return;\n }\n if (data === 'x') {\n const instance = this.instances[this.selected];\n if (instance) void this.client.stop(instance.instanceId, STOP_REASON);\n }\n }\n\n protected getChrome(): DoomOverlayChrome {\n return {\n title: 'LOOPS',\n breadcrumb: 'SPC › l / loops › l / list',\n headerRight: `${this.instances.length} active`,\n footer: `${DOOM_NAVIGATION_KEYS.list} move · x stop · esc close · launched detached work continues`,\n footerHints: [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n ['x', 'stop scheduling'],\n ['esc', 'close'],\n ],\n accent: DOOM_OVERLAY_ACCENT,\n };\n }\n\n protected renderBody(width: number): string[] {\n const stopScope = this.theme.fg('dim', truncateToWidth(STOP_SCOPE_MESSAGE, width));\n if (!this.instances.length) return [this.theme.fg('dim', EMPTY_MESSAGE), '', stopScope];\n return [\n stopScope,\n '',\n ...this.instances.flatMap((instance, index) => {\n const marker = index === this.selected ? this.theme.fg('accent', '▸') : ' ';\n const name = instance.label ?? instance.launcherLabel;\n const state = this.theme.fg(instance.state === 'running' ? 'success' : 'warning', instance.state);\n const line = truncateToWidth(`${marker} ${name} · ${state}`, width);\n const detail = instance.detail ?? instance.instanceId;\n return [line, ` ${this.theme.fg('dim', truncateToWidth(detail, Math.max(0, width - 4)))}`];\n }),\n ];\n }\n\n private refresh(): void {\n this.instances = this.client.listInstances();\n this.selected = Math.min(this.selected, Math.max(0, this.instances.length - 1));\n this.invalidate();\n }\n\n private move(delta: number): void {\n if (!this.instances.length) return;\n this.selected = Math.max(0, Math.min(this.selected + delta, this.instances.length - 1));\n this.invalidate();\n }\n}\n\nexport async function openLoopListOverlay(ctx: ExtensionContext, client: DoomLoopLaunchersService): Promise<void> {\n if (ctx.mode !== 'tui') {\n const instances = client.listInstances();\n const labels = instances.map((instance) => `${instance.label ?? instance.launcherLabel} (${instance.instanceId})`);\n const selected = await ctx.ui.select('Stop loop scheduling', labels);\n const instance = instances[labels.indexOf(selected ?? '')];\n if (instance) await client.stop(instance.instanceId, STOP_REASON);\n return;\n }\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new LoopListOverlay(tui, theme, client, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n","import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/doomOverlay';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { matchesKey, truncateToWidth } from '@earendil-works/pi-tui';\n\nimport type { LoopLauncherSummary } from '../schemas/loopLaunchers';\n\nconst EMPTY_MESSAGE = 'No loop launchers are registered for this session.';\n\nexport class StartLoopOverlay extends DoomOverlay {\n private selected = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n private readonly launchers: readonly LoopLauncherSummary[],\n private readonly done: (result: string | undefined) => void,\n ) {\n super(tui, theme);\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c') || data === 'q') {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.move(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.move(1);\n return;\n }\n if (matchesKey(data, 'enter')) this.done(this.launchers[this.selected]?.id);\n }\n\n protected getChrome(): DoomOverlayChrome {\n return {\n title: 'START LOOP',\n breadcrumb: 'SPC › l / loops › s / start',\n footer: `${DOOM_NAVIGATION_KEYS.list} move · enter launch · esc close`,\n footerHints: [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n ['enter', 'launch'],\n ['esc', 'close'],\n ],\n accent: DOOM_OVERLAY_ACCENT,\n };\n }\n\n protected renderBody(width: number): string[] {\n if (!this.launchers.length) return [this.theme.fg('dim', EMPTY_MESSAGE)];\n return this.launchers.flatMap((launcher, index) => {\n const selected = index === this.selected;\n const marker = selected ? this.theme.fg('accent', '▸') : ' ';\n const label = selected ? this.theme.bold(launcher.label) : launcher.label;\n const lines = [`${marker} ${truncateToWidth(label, Math.max(0, width - 2))}`];\n if (launcher.description)\n lines.push(` ${this.theme.fg('dim', truncateToWidth(launcher.description, Math.max(0, width - 4)))}`);\n return lines;\n });\n }\n\n private move(delta: number): void {\n if (!this.launchers.length) return;\n this.selected = Math.max(0, Math.min(this.selected + delta, this.launchers.length - 1));\n this.invalidate();\n }\n}\n\nexport async function openStartLoopOverlay(\n ctx: ExtensionContext,\n launchers: readonly LoopLauncherSummary[],\n): Promise<string | undefined> {\n if (ctx.mode !== 'tui') {\n const labels = launchers.map((launcher) => launcher.label);\n const selected = await ctx.ui.select('Start loop', labels);\n return launchers[labels.indexOf(selected ?? '')]?.id;\n }\n return ctx.ui.custom<string | undefined>(\n (tui, theme, _keybindings, done) => new StartLoopOverlay(tui, theme, launchers, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n","import { DOOM_CORDIS_SESSION_SERVICE, type DoomCordisSessionService } from '@agimon-ai/doompi-core/cordisHost';\nimport type { DoomPluginTool, PiToolRestriction } from '@agimon-ai/doompi-core/piExtension';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/uiHub';\nimport { defineMinorMode, type MinorModeOwner, type MinorModeState } from '@agimon-ai/doompi-minor-mode';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport {\n ACTIVE_MODE_COLOR,\n LOOPS_GROUP_ORDER,\n MODE_STATUS_ID,\n NOTIFY_INFO_LEVEL,\n PACKAGE_SOURCE,\n STATUS_KEY,\n} from '../constants/piLoop';\nimport {\n DOOM_LOOP_LAUNCHERS_SERVICE,\n type DoomLoopLaunchersService,\n type LoopInstanceSnapshot,\n type LoopLauncherRegistration,\n} from '../schemas/loopLaunchers';\nimport { createDefaultLoopLauncher } from '../services/defaultLoopLauncher';\nimport { createDoomLoopLaunchersService } from '../services/loopLaunchers';\nimport { createLoopTools } from '../services/loopTools';\nimport { formatLoopStatusView, LOOP_VIEW_STATUS_KEY } from '../types/loopView';\nimport { registerLeaderContribution } from './leader';\nimport { openLoopListOverlay } from './loopListOverlay';\nimport { openStartLoopOverlay } from './startLoopOverlay';\n\nconst MODE_ACTION_ACTIVATE = 'activate';\nconst MODE_ACTION_DEACTIVATE = 'deactivate';\nconst SESSION_REPLACED_REASON = 'Pi session replaced.';\nconst SESSION_SHUTDOWN_REASON = 'Pi session shut down.';\n\ninterface ActiveLoopSession {\n readonly context: ExtensionContext;\n readonly hostSession: DoomCordisSessionService;\n readonly launchers: DoomLoopLaunchersService;\n}\n\nfunction loopModeState(enabled: boolean, instances: readonly LoopInstanceSnapshot[]): MinorModeState {\n return {\n activation: enabled ? 'active' : 'inactive',\n condition: 'ready',\n ...(enabled ? { detail: `${instances.length} loops`, color: ACTIVE_MODE_COLOR } : {}),\n actions: [\n {\n id: MODE_ACTION_ACTIVATE,\n enabled: !enabled,\n ...(enabled ? { disabledReason: 'Loop mode is already active.' } : {}),\n },\n { id: MODE_ACTION_DEACTIVATE, enabled, ...(enabled ? {} : { disabledReason: 'Loop mode is not active.' }) },\n ],\n };\n}\n\nimport type { LoopCommandHandlers } from '../types/loopCommand';\ninterface LoopPiRuntime {\n onAgentSettled(this: void): void;\n services: Array<(context: Context) => void>;\n handlers: LoopCommandHandlers;\n minorModes: MinorModeOwner[];\n loopTools: readonly DoomPluginTool[];\n toolRestrictions: readonly PiToolRestriction[];\n onDispose(): void;\n}\n/** Install Loop state and external resources into its host-owned Cordis plugin fiber. */\nexport function createLoopPiRuntime(pi: ExtensionAPI): LoopPiRuntime {\n let active = true;\n let activeSession: ActiveLoopSession | undefined;\n let mode: MinorModeOwner | undefined;\n let disposeLeader: (() => void) | undefined;\n const launchesInProgress = new WeakSet<ActiveLoopSession>();\n let modeEnabled = false;\n const toolListeners = new Set<() => void>();\n const loopTools = createLoopTools(\n () => {\n if (!activeSession) throw new Error('Loop launchers are unavailable for the active session.');\n return activeSession.launchers;\n },\n () => {\n if (!active || !modeEnabled) throw new Error('Enable Loop minor mode before using agent loop tools.');\n },\n );\n const toolNames = new Set(loopTools.map((tool) => tool.name));\n\n const currentSession = (context: ExtensionContext): ActiveLoopSession | undefined => {\n const binding = activeSession;\n if (\n !active ||\n !binding ||\n binding.context.sessionManager !== context.sessionManager ||\n binding.hostSession.sessionId !== context.sessionManager.getSessionId()\n ) {\n return undefined;\n }\n return binding;\n };\n\n const clearStatuses = (binding: ActiveLoopSession): void => {\n binding.context.ui?.setStatus(STATUS_KEY, undefined);\n if (binding.context.mode !== 'tui') binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, undefined);\n };\n const publishStatus = (binding: ActiveLoopSession): void => {\n if (!active || activeSession !== binding) return;\n const instances = binding.launchers.listInstances();\n binding.context.ui?.setStatus(STATUS_KEY, instances.length ? `loops: ${instances.length}` : undefined);\n if (binding.context.mode !== 'tui') {\n binding.context.ui?.setStatus(LOOP_VIEW_STATUS_KEY, formatLoopStatusView(instances));\n }\n mode?.publish();\n };\n\n const defaultLauncher = createDefaultLoopLauncher(pi);\n\n mode = defineMinorMode({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: MODE_STATUS_ID,\n label: 'Loop',\n description: 'Give the agent tools to create, inspect, and stop session loops.',\n order: LOOPS_GROUP_ORDER,\n actions: [\n {\n id: MODE_ACTION_ACTIVATE,\n label: 'Activate',\n description: 'Expose loop tools to the agent.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n {\n id: MODE_ACTION_DEACTIVATE,\n label: 'Deactivate',\n description: 'Hide agent loop tools. Existing loops and manual controls remain available.',\n contexts: ['tui', 'headless'],\n parameters: [],\n },\n ],\n },\n state: () => loopModeState(modeEnabled, activeSession?.launchers.listInstances() ?? []),\n async handleAction(_runtime, actionId, _arguments, { signal }) {\n signal.throwIfAborted();\n const binding = activeSession ? currentSession(activeSession.context) : undefined;\n if (!binding) throw new Error('Loop launchers are unavailable for the active session.');\n if (actionId !== MODE_ACTION_ACTIVATE && actionId !== MODE_ACTION_DEACTIVATE)\n throw new Error(`Unknown loop mode action: ${actionId}`);\n modeEnabled = actionId === MODE_ACTION_ACTIVATE;\n for (const listener of toolListeners) listener();\n publishStatus(binding);\n return {\n message: modeEnabled ? 'Loop tools activated.' : 'Loop tools deactivated. Existing loops are unchanged.',\n };\n },\n }).createOwner(undefined);\n return {\n onAgentSettled: defaultLauncher.onAgentSettled,\n loopTools,\n toolRestrictions: [\n {\n source: PACKAGE_SOURCE,\n restrict: (incoming) => (modeEnabled ? incoming : incoming.filter((name) => !toolNames.has(name))),\n subscribe(listener) {\n toolListeners.add(listener);\n return () => {\n toolListeners.delete(listener);\n };\n },\n },\n ],\n services: [\n (cordis: Context) => {\n cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n const dispose = registerLeaderContribution(requireDoomUiHub(uiContext));\n disposeLeader = dispose;\n return () => {\n dispose();\n if (disposeLeader === dispose) disposeLeader = undefined;\n };\n });\n\n cordis.inject([DOOM_CORDIS_SESSION_SERVICE], async (sessionContext) => {\n const hostSession = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n const launchers = createDoomLoopLaunchersService({\n generation: `${hostSession.generation}:loop-launchers`,\n createInstanceId: () => crypto.randomUUID(),\n timestamp: () => new Date().toISOString(),\n });\n const binding: ActiveLoopSession = { context: hostSession.context, hostSession, launchers };\n activeSession = binding;\n modeEnabled = false;\n for (const listener of toolListeners) listener();\n const provider = cordis.plugin((providerContext) => {\n providerContext.provide(DOOM_LOOP_LAUNCHERS_SERVICE, launchers);\n });\n\n let defaultRegistration: LoopLauncherRegistration;\n let cronRegistration: LoopLauncherRegistration;\n let unsubscribe: () => void;\n try {\n defaultRegistration = defaultLauncher.register(hostSession.context, launchers);\n cronRegistration = defaultLauncher.registerCron(hostSession.context, launchers);\n unsubscribe = launchers.subscribe(() => publishStatus(binding));\n publishStatus(binding);\n } catch (error) {\n if (activeSession === binding) activeSession = undefined;\n await launchers.dispose(SESSION_REPLACED_REASON);\n await provider.dispose();\n throw error;\n }\n\n return async () => {\n if (activeSession === binding) activeSession = undefined;\n modeEnabled = false;\n for (const listener of toolListeners) listener();\n unsubscribe();\n clearStatuses(binding);\n mode?.publish();\n const cleanupErrors: unknown[] = [];\n try {\n await Promise.all([\n defaultRegistration.dispose(SESSION_REPLACED_REASON),\n cronRegistration.dispose(SESSION_REPLACED_REASON),\n ]);\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n await launchers.dispose(SESSION_SHUTDOWN_REASON);\n } catch (error) {\n cleanupErrors.push(error);\n }\n try {\n await provider.dispose();\n } catch (error) {\n cleanupErrors.push(error);\n }\n if (cleanupErrors.length > 0) throw new AggregateError(cleanupErrors, 'Loop session cleanup failed.');\n };\n });\n },\n ],\n handlers: {\n async start(ctx, args) {\n const binding = currentSession(ctx);\n if (!binding) return;\n if (launchesInProgress.has(binding)) {\n ctx.ui.notify('A loop setup is already in progress.', NOTIFY_INFO_LEVEL);\n return;\n }\n launchesInProgress.add(binding);\n try {\n const launchers = binding.launchers.listLaunchers();\n if (!launchers.length) {\n ctx.ui.notify('No loop launchers are registered for this session.', NOTIFY_INFO_LEVEL);\n return;\n }\n\n const argument = args.trim();\n let launcherId: string | undefined;\n if (argument) {\n if (argument.split(/\\s+/u).length !== 1) {\n ctx.ui.notify('Usage: /loop [launcherId]', 'error');\n return;\n }\n if (!launchers.some((launcher) => launcher.id === argument)) {\n ctx.ui.notify(`Unknown loop launcher: ${argument}`, 'error');\n return;\n }\n launcherId = argument;\n } else {\n launcherId = await openStartLoopOverlay(ctx, launchers);\n if (activeSession !== binding || !launcherId) return;\n }\n\n const instance = await binding.launchers.launch(launcherId);\n if (activeSession !== binding) return;\n if (instance) ctx.ui.notify(`${instance.label ?? instance.launcherLabel} started.`, NOTIFY_INFO_LEVEL);\n } catch (error) {\n if (activeSession !== binding) return;\n ctx.ui.notify(`Loop could not start: ${error instanceof Error ? error.message : String(error)}`, 'error');\n } finally {\n launchesInProgress.delete(binding);\n }\n },\n async list(ctx, args = '') {\n const binding = currentSession(ctx);\n if (!binding) return;\n if (args.trim().startsWith('stop ')) {\n const stopped = await binding.launchers.stop(args.trim().slice(5).trim(), 'Stopped manually.');\n ctx.ui.notify(stopped ? 'Loop stopped.' : 'Loop instance was not active.', NOTIFY_INFO_LEVEL);\n return;\n }\n if (args.trim()) throw new Error('Usage: /loops [stop instanceId]');\n await openLoopListOverlay(ctx, binding.launchers);\n },\n },\n minorModes: [mode],\n onDispose() {\n active = false;\n const binding = activeSession;\n activeSession = undefined;\n modeEnabled = false;\n for (const listener of toolListeners) listener();\n toolListeners.clear();\n if (binding) clearStatuses(binding);\n mode?.publish();\n disposeLeader?.();\n disposeLeader = undefined;\n },\n };\n}\n","import type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { piMinorModes } from '@agimon-ai/doompi-minor-mode';\n\nimport { PACKAGE_SOURCE } from '../../../../../constants/piLoop';\nimport { createLoopCommands } from '../../../../../services/loopCommand';\nimport { createLoopPiRuntime } from '../../../../../tui/loopRuntime';\n\nexport default (({ pi }) => {\n const runtime = createLoopPiRuntime(pi);\n return {\n services: [...(runtime.services ?? []), piMinorModes(runtime.minorModes)],\n loopTools: runtime.loopTools,\n toolRestrictions: runtime.toolRestrictions,\n events: { agent_settled: runtime.onAgentSettled },\n commands: createLoopCommands(runtime.handlers),\n\n onDispose: () => runtime.onDispose(),\n resources: [\n {\n source: PACKAGE_SOURCE,\n moduleUrl: import.meta.url,\n skills: [\n {\n name: 'doompi-use-loop',\n description: 'Use Doom Pi Loop to start, inspect, and stop session-scoped recurring prompts safely.',\n },\n ],\n },\n ],\n };\n}) satisfies (context: PiPluginContext<undefined>) => PiPluginContributions<undefined>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport runtime from './_lib/runtime.cli';\n\nexport default defineRoot((context: PiPluginContext<undefined>) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n onDispose: value.onDispose,\n };\n});\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nexport default defineCliCommand(\n (context: WithRoot<PiPluginContext<undefined>, PiPluginContributions<undefined>>) => context.root.commands![0]!,\n);\n","import { defineCliCommand, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nexport default defineCliCommand(\n (context: WithRoot<PiPluginContext<undefined>, PiPluginContributions<undefined>>) => context.root.commands![1]!,\n);\n","import { defineCliHook, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nexport default defineCliHook(\n (context: WithRoot<PiPluginContext<undefined>, PiPluginContributions<undefined>>) =>\n context.root.events!['agent_settled']!,\n);\n","import { defineResource, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext, PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nexport default defineResource(\n (context: WithRoot<PiPluginContext<undefined>, PiPluginContributions<undefined>>) => context.root.resources![0]!,\n);\n","import { defineToolRestriction, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\n\nexport default defineToolRestriction(\n (context: WithRoot<unknown, PiPluginContributions<undefined>>) => context.root.toolRestrictions![0]!,\n);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[0]!);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[1]!);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, piToolContributions, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandLoop from '../src/extensions/workspaces/sessions/(backend)/command/loop.cli';\nimport commandLoops from '../src/extensions/workspaces/sessions/(backend)/command/loops.cli';\nimport hookAgentSettled from '../src/extensions/workspaces/sessions/(backend)/hook/agent-settled.cli';\nimport resourceDoompiUseLoop from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.cli';\nimport toolRestrictionLoop from '../src/extensions/workspaces/sessions/(backend)/tool-restriction/loop.cli';\nimport toolLoopList from '../src/extensions/workspaces/sessions/(backend)/tool/loop-list.cli';\nimport toolLoopStart from '../src/extensions/workspaces/sessions/(backend)/tool/loop-start.cli';\nimport toolLoopStop from '../src/extensions/workspaces/sessions/(backend)/tool/loop-stop.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandLoop> | OptionsOf<typeof commandLoops> | OptionsOf<typeof hookAgentSettled> | OptionsOf<typeof resourceDoompiUseLoop> | OptionsOf<typeof toolRestrictionLoop> | OptionsOf<typeof toolLoopList> | OptionsOf<typeof toolLoopStart> | OptionsOf<typeof toolLoopStop>, undefined>;\ntype Intersect<Union> =\n (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-loop', async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): PiPluginContributions['commands'] { return [at(commandLoop, contextSession), at(commandLoops, contextSession)]; },\n events: {\n agent_settled: at(hookAgentSettled, contextSession) as NonNullable<PiPluginContributions['events']>['agent_settled'],\n },\n get resources(): PiPluginContributions['resources'] { return [at(resourceDoompiUseLoop, contextSession)]; },\n get toolRestrictions(): PiPluginContributions['toolRestrictions'] { return [at(toolRestrictionLoop, contextSession)]; },\n ...piToolContributions('@agimon-ai/doompi-loop', [via({ name: 'loop_list' }, at(toolLoopList, contextSession)), via({ name: 'loop_start' }, at(toolLoopStart, contextSession)), via({ name: 'loop_stop' }, at(toolLoopStop, contextSession))]),\n services: [...(scopeSession.services ?? [])],\n };\n});\n\nexport default extension;\n"],"mappings":"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"}
@@ -0,0 +1,369 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_loopLaunchers = require("../loopLaunchers-BtcLH_xN.cjs");
6
+ const require_loopView = require("../loopView-C_OPuy8L.cjs");
7
+ let _agimon_ai_doompi_core_extensionFile = require("@agimon-ai/doompi-core/extensionFile");
8
+ let _agimon_ai_doompi_minor_mode = require("@agimon-ai/doompi-minor-mode");
9
+ let croner = require("croner");
10
+ let _agimon_ai_doompi_core_serverFacet = require("@agimon-ai/doompi-core/serverFacet");
11
+ //#region src/services/serverRuntime/index.ts
12
+ async function prepareLoop(execution, request, cron) {
13
+ if (request.input !== void 0) return cron ? require_loopView.parseCronLoop(request.input) : require_loopView.parseIntervalLoop(request.input);
14
+ if (request.interactive === false) throw new Error("Loop configuration is required for agent launches.");
15
+ const input = await execution.client.request({
16
+ kind: "input",
17
+ title: "Loop prompt",
18
+ multiline: true
19
+ }, request.signal);
20
+ const prompt = typeof input === "string" ? input.trim() : "";
21
+ if (!prompt || request.signal.aborted) return void 0;
22
+ if (cron) {
23
+ const expression = await execution.client.request({
24
+ kind: "input",
25
+ title: "Cron expression (five fields)",
26
+ initialValue: "0 * * * *"
27
+ }, request.signal);
28
+ if (typeof expression !== "string" || request.signal.aborted) return void 0;
29
+ const timezone = await execution.client.request({
30
+ kind: "input",
31
+ title: "Loop timezone",
32
+ initialValue: "UTC"
33
+ }, request.signal);
34
+ if (typeof timezone !== "string" || request.signal.aborted) return void 0;
35
+ return require_loopView.parseCronLoop({
36
+ prompt,
37
+ cron: expression,
38
+ timezone: timezone.trim() || "UTC"
39
+ });
40
+ }
41
+ const interval = await execution.client.request({
42
+ kind: "input",
43
+ title: "Loop interval in seconds",
44
+ initialValue: "300"
45
+ }, request.signal);
46
+ if (typeof interval !== "string" || request.signal.aborted) return void 0;
47
+ return require_loopView.parseIntervalLoop({
48
+ prompt,
49
+ intervalSeconds: Number(interval.trim() || "300")
50
+ });
51
+ }
52
+ function createSessionState(host) {
53
+ const launchers = require_loopView.createDoomLoopLaunchersService({
54
+ generation: `${host.context.sessionId}:loop-launchers`,
55
+ createInstanceId: () => crypto.randomUUID(),
56
+ timestamp: () => (/* @__PURE__ */ new Date()).toISOString()
57
+ });
58
+ let disposed = false;
59
+ const modeSelected = () => !disposed && (host.context.selection.state?.["minor-mode"] ?? []).includes("loop.active");
60
+ const publishView = () => host.context.client.setStatus(require_loopView.LOOP_VIEW_STATUS_KEY, require_loopView.formatLoopStatusView(launchers.listInstances()));
61
+ const modeOwner = (0, _agimon_ai_doompi_minor_mode.defineMinorMode)({
62
+ descriptor: {
63
+ source: require_loopView.PACKAGE_SOURCE,
64
+ id: require_loopView.MODE_STATUS_ID,
65
+ label: "Loop",
66
+ description: "Give the agent tools to create, inspect, and stop session loops.",
67
+ order: 60,
68
+ actions: [{
69
+ id: "activate",
70
+ label: "Activate",
71
+ description: "Expose loop tools to the agent.",
72
+ contexts: ["headless"],
73
+ parameters: []
74
+ }, {
75
+ id: "deactivate",
76
+ label: "Deactivate",
77
+ description: "Hide agent loop tools. Existing loops and manual controls remain available.",
78
+ contexts: ["headless"],
79
+ parameters: []
80
+ }]
81
+ },
82
+ state: () => ({
83
+ activation: modeSelected() ? "active" : "inactive",
84
+ condition: "ready",
85
+ ...modeSelected() ? {
86
+ detail: `${launchers.listInstances().length} loops`,
87
+ color: "accent"
88
+ } : {},
89
+ actions: [{
90
+ id: "activate",
91
+ enabled: !modeSelected(),
92
+ ...modeSelected() ? { disabledReason: "Loop mode is already active." } : {}
93
+ }, {
94
+ id: "deactivate",
95
+ enabled: modeSelected(),
96
+ ...modeSelected() ? {} : { disabledReason: "Loop mode is not active." }
97
+ }]
98
+ }),
99
+ async handleAction(_runtime, actionId, _arguments, { signal }) {
100
+ signal.throwIfAborted();
101
+ if (actionId !== "activate" && actionId !== "deactivate") throw new Error(`Unknown loop mode action: ${actionId}`);
102
+ const modes = (host.context.selection.state?.["minor-mode"] ?? []).filter((mode) => mode !== require_loopView.MODE_STATUS_ID);
103
+ await host.changeSelection({
104
+ axis: "state",
105
+ key: "minor-mode",
106
+ values: actionId === "activate" ? [...modes, require_loopView.MODE_STATUS_ID] : modes
107
+ });
108
+ modeOwner.publish();
109
+ return { message: actionId === "activate" ? "Loop tools activated." : "Loop tools deactivated. Existing loops are unchanged." };
110
+ }
111
+ }).createOwner(void 0);
112
+ const publish = () => {
113
+ if (disposed) return;
114
+ modeOwner.publish();
115
+ publishView();
116
+ };
117
+ const unsubscribe = launchers.subscribe(publish);
118
+ let submitting = false;
119
+ for (const cron of [false, true]) launchers.register({
120
+ id: cron ? "doompi.cron" : "doompi.default",
121
+ source: require_loopView.PACKAGE_SOURCE,
122
+ label: cron ? "Cron loop" : "Default loop",
123
+ description: cron ? "Run a prompt on a five-field cron schedule." : "Run a prompt in this session on an interval.",
124
+ inputSchema: { ...cron ? require_loopView.CronLoopSchema : require_loopView.IntervalLoopSchema },
125
+ async launch(request) {
126
+ const execution = host.context;
127
+ const prepared = await prepareLoop(execution, request, cron);
128
+ if (!prepared || request.signal.aborted) return void 0;
129
+ let stopped = false;
130
+ const tick = async () => {
131
+ if (stopped || request.signal.aborted || submitting) return;
132
+ submitting = true;
133
+ try {
134
+ const activity = await execution.session.activity();
135
+ if (stopped || request.signal.aborted || !activity.isIdle || activity.hasPendingMessages) return;
136
+ await execution.session.prompt(prepared.prompt);
137
+ } catch (error) {
138
+ await execution.client.notify({
139
+ body: `Loop pass failed: ${error instanceof Error ? error.message : String(error)}`,
140
+ level: "warning"
141
+ });
142
+ } finally {
143
+ submitting = false;
144
+ }
145
+ };
146
+ let stopTimer;
147
+ let detail;
148
+ if ("cron" in prepared) {
149
+ const job = new croner.Cron(prepared.cron, {
150
+ timezone: prepared.timezone,
151
+ unref: true
152
+ }, tick);
153
+ if (job.nextRun() === null) {
154
+ job.stop();
155
+ throw new Error("Cron expression has no future run.");
156
+ }
157
+ stopTimer = () => {
158
+ job.stop();
159
+ };
160
+ detail = `${prepared.cron} (${prepared.timezone})`;
161
+ } else {
162
+ const timer = setInterval(() => {
163
+ tick();
164
+ }, prepared.intervalSeconds * 1e3);
165
+ timer.unref?.();
166
+ stopTimer = () => clearInterval(timer);
167
+ detail = `every ${prepared.intervalSeconds}s`;
168
+ tick();
169
+ }
170
+ return {
171
+ instanceId: request.instanceId,
172
+ label: cron ? "Cron loop" : "Default loop",
173
+ detail,
174
+ stop() {
175
+ stopped = true;
176
+ stopTimer();
177
+ }
178
+ };
179
+ }
180
+ });
181
+ return {
182
+ loopTools: require_loopView.createLoopTools(() => launchers, () => {
183
+ if (!modeSelected()) throw new Error("Enable Loop minor mode before using agent loop tools.");
184
+ }).map((tool) => ({
185
+ ...tool,
186
+ when: {
187
+ state: { "minor-mode": require_loopView.MODE_STATUS_ID },
188
+ attribution: {
189
+ kind: "minor",
190
+ mode: require_loopView.MODE_STATUS_ID
191
+ }
192
+ }
193
+ })),
194
+ services: [(context) => {
195
+ context.plugin((provider) => {
196
+ provider.provide(require_loopLaunchers.DOOM_LOOP_LAUNCHERS_SERVICE, launchers);
197
+ });
198
+ context.effect(() => host.subscribeSelection(publish));
199
+ }, (0, _agimon_ai_doompi_minor_mode.serverMinorModes)([modeOwner])],
200
+ resources: [{
201
+ when: {
202
+ state: { "minor-mode": require_loopView.MODE_STATUS_ID },
203
+ attribution: {
204
+ kind: "minor",
205
+ mode: require_loopView.MODE_STATUS_ID
206
+ }
207
+ },
208
+ name: "doompi-use-loop",
209
+ kind: "skill",
210
+ read: () => (0, _agimon_ai_doompi_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/doompi-use-loop/SKILL.md")
211
+ }],
212
+ activities: [{
213
+ name: "doompi-loop",
214
+ async start() {
215
+ publish();
216
+ return async () => {
217
+ await launchers.stopAll("Session loop activity stopped.");
218
+ publish();
219
+ };
220
+ }
221
+ }],
222
+ commands: [{
223
+ name: require_loopView.START_COMMAND_NAME,
224
+ description: "Start a registered loop manually.",
225
+ async execute(args, execution) {
226
+ const available = launchers.listLaunchers();
227
+ const selected = args.trim() || await execution.client.request({
228
+ kind: "select",
229
+ title: "Choose a loop launcher",
230
+ options: available.map((entry) => ({
231
+ label: entry.label,
232
+ value: entry.id
233
+ }))
234
+ });
235
+ if (typeof selected !== "string" || !selected) return;
236
+ const instance = await launchers.launch(selected);
237
+ await execution.client.notify({
238
+ body: instance ? `Loop '${instance.instanceId}' started.` : "Loop launch was cancelled.",
239
+ level: "info"
240
+ });
241
+ }
242
+ }, {
243
+ name: require_loopView.LIST_COMMAND_NAME,
244
+ description: "List or stop session loops. Usage: /loops [stop instanceId].",
245
+ async execute(args, execution) {
246
+ const parts = args.trim().split(/\s+/u);
247
+ if (parts[0] === "stop" && parts.length === 2) {
248
+ const stopped = await launchers.stop(parts[1], "Stopped manually.");
249
+ await execution.client.notify({
250
+ body: stopped ? "Loop stopped." : "Loop instance was not active.",
251
+ level: "info"
252
+ });
253
+ return;
254
+ }
255
+ if (args.trim()) throw new Error("Usage: /loops [stop instanceId]");
256
+ const instances = launchers.listInstances();
257
+ await execution.client.notify({
258
+ body: instances.length === 0 ? "No loops are active." : JSON.stringify(instances, null, 2),
259
+ level: "info"
260
+ });
261
+ }
262
+ }],
263
+ hooks: [{
264
+ event: "session_start",
265
+ async handle() {
266
+ publish();
267
+ }
268
+ }, {
269
+ event: "session_shutdown",
270
+ async handle() {
271
+ await launchers.stopAll("Headless session shutdown.");
272
+ }
273
+ }],
274
+ onStart: publish,
275
+ async onDispose() {
276
+ if (disposed) return;
277
+ disposed = true;
278
+ unsubscribe();
279
+ await launchers.dispose("Headless loop facet disposed.");
280
+ }
281
+ };
282
+ }
283
+ //#endregion
284
+ //#region src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.ts
285
+ var runtime_server_default = (({ agent }) => agent ? createSessionState(agent) : { loopTools: [] });
286
+ //#endregion
287
+ //#region src/extensions/workspaces/sessions/(backend)/root.server.ts
288
+ var root_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoot)((context) => {
289
+ const value = runtime_server_default(context);
290
+ return {
291
+ value,
292
+ services: value.services,
293
+ activities: value.activities,
294
+ onStart: value.onStart,
295
+ onStop: value.onStop,
296
+ onDispose: value.onDispose
297
+ };
298
+ });
299
+ //#endregion
300
+ //#region src/extensions/workspaces/sessions/(backend)/command/loop.server.ts
301
+ var loop_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => context.root.commands?.[0], { cardinality: "optional" });
302
+ //#endregion
303
+ //#region src/extensions/workspaces/sessions/(backend)/command/loops.server.ts
304
+ var loops_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => context.root.commands?.[1], { cardinality: "optional" });
305
+ //#endregion
306
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts
307
+ var session_shutdown_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => context.root.hooks?.find((hook) => hook.event === "session_shutdown"), { cardinality: "optional" });
308
+ //#endregion
309
+ //#region src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts
310
+ var session_start_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => context.root.hooks?.find((hook) => hook.event === "session_start"), { cardinality: "optional" });
311
+ //#endregion
312
+ //#region src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.ts
313
+ var doompi_use_loop_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineRoutedContribution)((context) => context.root.resources?.[0], { cardinality: "optional" });
314
+ //#endregion
315
+ //#region src/extensions/workspaces/sessions/(backend)/tool/loop-list.server.ts
316
+ var loop_list_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineTool)((context) => context.root.loopTools[0]);
317
+ //#endregion
318
+ //#region src/extensions/workspaces/sessions/(backend)/tool/loop-start.server.ts
319
+ var loop_start_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineTool)((context) => context.root.loopTools[1]);
320
+ //#endregion
321
+ //#region src/extensions/workspaces/sessions/(backend)/tool/loop-stop.server.ts
322
+ var loop_stop_server_default = (0, _agimon_ai_doompi_core_extensionFile.defineTool)((context) => context.root.loopTools[2]);
323
+ //#endregion
324
+ //#region generated/server.ts
325
+ const at = (value, context) => typeof value === "function" ? value(context) : value;
326
+ /* v8 ignore next -- generated normalization branch */
327
+ const defined = (values) => values.filter((value) => value !== void 0);
328
+ const via = (identity, value) => value === void 0 ? void 0 : {
329
+ ...identity,
330
+ ...value
331
+ };
332
+ const facet = (0, _agimon_ai_doompi_core_serverFacet.defineServerPlugin)({
333
+ name: "@agimon-ai/doompi-loop",
334
+ session: async (context) => {
335
+ const scopeSession = await root_server_default(context);
336
+ const contextSession = {
337
+ ...context,
338
+ root: scopeSession.value
339
+ };
340
+ return {
341
+ ...(0, _agimon_ai_doompi_core_extensionFile.composeRootHooks)(scopeSession),
342
+ get commands() {
343
+ return defined([via({ name: "loop" }, at(loop_server_default, contextSession)), via({ name: "loops" }, at(loops_server_default, contextSession))]);
344
+ },
345
+ get hooks() {
346
+ return defined([via({ event: "session_shutdown" }, at(session_shutdown_server_default, contextSession)), via({ event: "session_start" }, at(session_start_server_default, contextSession))]);
347
+ },
348
+ get resources() {
349
+ return defined([at(doompi_use_loop_server_default, contextSession)]);
350
+ },
351
+ get tools() {
352
+ return [
353
+ via({ name: "loop_list" }, at(loop_list_server_default, contextSession)),
354
+ via({ name: "loop_start" }, at(loop_start_server_default, contextSession)),
355
+ via({ name: "loop_stop" }, at(loop_stop_server_default, contextSession))
356
+ ];
357
+ },
358
+ services: [...scopeSession.services ?? []],
359
+ get activities() {
360
+ return [...scopeSession.activities ?? []];
361
+ }
362
+ };
363
+ }
364
+ });
365
+ //#endregion
366
+ exports.default = facet;
367
+ exports.facet = facet;
368
+
369
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.cjs","names":["parseCronLoop","parseIntervalLoop","createDoomLoopLaunchersService","LOOP_VIEW_STATUS_KEY","formatLoopStatusView","defineMinorMode","PACKAGE_SOURCE","MODE_STATUS_ID","CronLoopSchema","IntervalLoopSchema","Cron","createLoopTools","DOOM_LOOP_LAUNCHERS_SERVICE","serverMinorModes","readPackageResource","START_COMMAND_NAME","LIST_COMMAND_NAME","defineRoot","runtime","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineTool","defineTool","defineTool","defineServerPlugin","rootSession","composeRootHooks","commandLoop","commandLoops","hookSessionShutdown","hookSessionStart","resourceDoompiUseLoop","toolLoopList","toolLoopStart","toolLoopStop"],"sources":["../../src/services/serverRuntime/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/runtime.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/loop.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/loops.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server.ts","../../src/extensions/workspaces/sessions/(backend)/hook/session-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-list.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-start.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/loop-stop.server.ts","../../generated/server.ts"],"sourcesContent":["import type { DoomHeadlessExecutionContext, DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport { readPackageResource, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { defineMinorMode, serverMinorModes } from '@agimon-ai/doompi-minor-mode';\nimport { Cron } from 'croner';\n\nimport { LIST_COMMAND_NAME, START_COMMAND_NAME } from '../../constants/loop';\nimport { MODE_STATUS_ID, PACKAGE_SOURCE } from '../../constants/piLoop';\nimport { DOOM_LOOP_LAUNCHERS_SERVICE, type LoopLaunchRequest } from '../../schemas/loopLaunchers';\nimport { CronLoopSchema, IntervalLoopSchema, parseCronLoop, parseIntervalLoop } from '../../schemas/loopTools';\nimport { formatLoopStatusView, LOOP_VIEW_STATUS_KEY } from '../../types/loopView';\nimport { createDoomLoopLaunchersService } from '../loopLaunchers';\nimport { createLoopTools } from '../loopTools';\nimport type { LoopToolsRoot } from '../loopTools/type';\n\nexport type LoopServerState = DoomServerSessionPlugin & LoopToolsRoot;\n\nasync function prepareLoop(execution: DoomHeadlessExecutionContext, request: LoopLaunchRequest, cron: boolean) {\n if (request.input !== undefined) return cron ? parseCronLoop(request.input) : parseIntervalLoop(request.input);\n if (request.interactive === false) throw new Error('Loop configuration is required for agent launches.');\n const input = await execution.client.request(\n { kind: 'input', title: 'Loop prompt', multiline: true },\n request.signal,\n );\n const prompt = typeof input === 'string' ? input.trim() : '';\n if (!prompt || request.signal.aborted) return undefined;\n if (cron) {\n const expression = await execution.client.request(\n { kind: 'input', title: 'Cron expression (five fields)', initialValue: '0 * * * *' },\n request.signal,\n );\n if (typeof expression !== 'string' || request.signal.aborted) return undefined;\n const timezone = await execution.client.request(\n { kind: 'input', title: 'Loop timezone', initialValue: 'UTC' },\n request.signal,\n );\n if (typeof timezone !== 'string' || request.signal.aborted) return undefined;\n return parseCronLoop({ prompt, cron: expression, timezone: timezone.trim() || 'UTC' });\n }\n const interval = await execution.client.request(\n { kind: 'input', title: 'Loop interval in seconds', initialValue: '300' },\n request.signal,\n );\n if (typeof interval !== 'string' || request.signal.aborted) return undefined;\n return parseIntervalLoop({ prompt, intervalSeconds: Number(interval.trim() || '300') });\n}\n\nexport function createSessionState(host: DoomHeadlessHostService): LoopServerState {\n const launchers = createDoomLoopLaunchersService({\n generation: `${host.context.sessionId}:loop-launchers`,\n createInstanceId: () => crypto.randomUUID(),\n timestamp: () => new Date().toISOString(),\n });\n let disposed = false;\n const modeSelected = (): boolean =>\n !disposed && (host.context.selection.state?.['minor-mode'] ?? []).includes(MODE_STATUS_ID);\n const publishView = (): void =>\n host.context.client.setStatus(LOOP_VIEW_STATUS_KEY, formatLoopStatusView(launchers.listInstances()));\n const modeOwner = defineMinorMode({\n descriptor: {\n source: PACKAGE_SOURCE,\n id: MODE_STATUS_ID,\n label: 'Loop',\n description: 'Give the agent tools to create, inspect, and stop session loops.',\n order: 60,\n actions: [\n {\n id: 'activate',\n label: 'Activate',\n description: 'Expose loop tools to the agent.',\n contexts: ['headless'],\n parameters: [],\n },\n {\n id: 'deactivate',\n label: 'Deactivate',\n description: 'Hide agent loop tools. Existing loops and manual controls remain available.',\n contexts: ['headless'],\n parameters: [],\n },\n ],\n },\n state: () => ({\n activation: modeSelected() ? 'active' : 'inactive',\n condition: 'ready',\n ...(modeSelected() ? { detail: `${launchers.listInstances().length} loops`, color: 'accent' } : {}),\n actions: [\n {\n id: 'activate',\n enabled: !modeSelected(),\n ...(modeSelected() ? { disabledReason: 'Loop mode is already active.' } : {}),\n },\n {\n id: 'deactivate',\n enabled: modeSelected(),\n ...(modeSelected() ? {} : { disabledReason: 'Loop mode is not active.' }),\n },\n ],\n }),\n async handleAction(_runtime, actionId, _arguments, { signal }) {\n signal.throwIfAborted();\n if (actionId !== 'activate' && actionId !== 'deactivate')\n throw new Error(`Unknown loop mode action: ${actionId}`);\n const modes = (host.context.selection.state?.['minor-mode'] ?? []).filter((mode) => mode !== MODE_STATUS_ID);\n await host.changeSelection({\n axis: 'state',\n key: 'minor-mode',\n values: actionId === 'activate' ? [...modes, MODE_STATUS_ID] : modes,\n });\n modeOwner.publish();\n return {\n message:\n actionId === 'activate' ? 'Loop tools activated.' : 'Loop tools deactivated. Existing loops are unchanged.',\n };\n },\n }).createOwner(undefined);\n const publish = (): void => {\n if (disposed) return;\n modeOwner.publish();\n publishView();\n };\n const unsubscribe = launchers.subscribe(publish);\n let submitting = false;\n for (const cron of [false, true]) {\n launchers.register({\n id: cron ? 'doompi.cron' : 'doompi.default',\n source: PACKAGE_SOURCE,\n label: cron ? 'Cron loop' : 'Default loop',\n description: cron\n ? 'Run a prompt on a five-field cron schedule.'\n : 'Run a prompt in this session on an interval.',\n inputSchema: { ...(cron ? CronLoopSchema : IntervalLoopSchema) },\n async launch(request) {\n const execution = host.context;\n const prepared = await prepareLoop(execution, request, cron);\n if (!prepared || request.signal.aborted) return undefined;\n let stopped = false;\n const tick = async (): Promise<void> => {\n if (stopped || request.signal.aborted || submitting) return;\n submitting = true;\n try {\n const activity = await execution.session.activity();\n if (stopped || request.signal.aborted || !activity.isIdle || activity.hasPendingMessages) return;\n await execution.session.prompt(prepared.prompt);\n } catch (error) {\n await execution.client.notify({\n body: `Loop pass failed: ${error instanceof Error ? error.message : String(error)}`,\n level: 'warning',\n });\n } finally {\n submitting = false;\n }\n };\n let stopTimer: () => void;\n let detail: string;\n if ('cron' in prepared) {\n const job = new Cron(prepared.cron, { timezone: prepared.timezone, unref: true }, tick);\n if (job.nextRun() === null) {\n job.stop();\n throw new Error('Cron expression has no future run.');\n }\n stopTimer = () => {\n job.stop();\n };\n detail = `${prepared.cron} (${prepared.timezone})`;\n } else {\n const timer = setInterval(() => {\n void tick();\n }, prepared.intervalSeconds * 1000);\n timer.unref?.();\n stopTimer = () => clearInterval(timer);\n detail = `every ${prepared.intervalSeconds}s`;\n void tick();\n }\n return {\n instanceId: request.instanceId,\n label: cron ? 'Cron loop' : 'Default loop',\n detail,\n stop() {\n stopped = true;\n stopTimer();\n },\n };\n },\n });\n }\n const loopTools = createLoopTools(\n () => launchers,\n () => {\n if (!modeSelected()) throw new Error('Enable Loop minor mode before using agent loop tools.');\n },\n ).map((tool) => ({\n ...tool,\n when: { state: { 'minor-mode': MODE_STATUS_ID }, attribution: { kind: 'minor' as const, mode: MODE_STATUS_ID } },\n }));\n return {\n loopTools,\n services: [\n (context) => {\n context.plugin((provider) => {\n provider.provide(DOOM_LOOP_LAUNCHERS_SERVICE, launchers);\n });\n context.effect(() => host.subscribeSelection(publish));\n },\n serverMinorModes([modeOwner]),\n ],\n resources: [\n {\n when: { state: { 'minor-mode': MODE_STATUS_ID }, attribution: { kind: 'minor', mode: MODE_STATUS_ID } },\n name: 'doompi-use-loop',\n kind: 'skill',\n read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-use-loop/SKILL.md'),\n },\n ],\n activities: [\n {\n name: 'doompi-loop',\n async start() {\n publish();\n return async () => {\n await launchers.stopAll('Session loop activity stopped.');\n publish();\n };\n },\n },\n ],\n commands: [\n {\n name: START_COMMAND_NAME,\n description: 'Start a registered loop manually.',\n async execute(args: string, execution: DoomHeadlessExecutionContext) {\n const available = launchers.listLaunchers();\n const selected =\n args.trim() ||\n (await execution.client.request({\n kind: 'select',\n title: 'Choose a loop launcher',\n options: available.map((entry) => ({ label: entry.label, value: entry.id })),\n }));\n if (typeof selected !== 'string' || !selected) return;\n const instance = await launchers.launch(selected);\n await execution.client.notify({\n body: instance ? `Loop '${instance.instanceId}' started.` : 'Loop launch was cancelled.',\n level: 'info',\n });\n },\n },\n {\n name: LIST_COMMAND_NAME,\n description: 'List or stop session loops. Usage: /loops [stop instanceId].',\n async execute(args: string, execution: DoomHeadlessExecutionContext) {\n const parts = args.trim().split(/\\s+/u);\n if (parts[0] === 'stop' && parts.length === 2) {\n const stopped = await launchers.stop(parts[1]!, 'Stopped manually.');\n await execution.client.notify({\n body: stopped ? 'Loop stopped.' : 'Loop instance was not active.',\n level: 'info',\n });\n return;\n }\n if (args.trim()) throw new Error('Usage: /loops [stop instanceId]');\n const instances = launchers.listInstances();\n await execution.client.notify({\n body: instances.length === 0 ? 'No loops are active.' : JSON.stringify(instances, null, 2),\n level: 'info',\n });\n },\n },\n ],\n hooks: [\n {\n event: 'session_start',\n async handle() {\n publish();\n },\n },\n {\n event: 'session_shutdown',\n async handle() {\n await launchers.stopAll('Headless session shutdown.');\n },\n },\n ],\n onStart: publish,\n async onDispose() {\n if (disposed) return;\n disposed = true;\n unsubscribe();\n await launchers.dispose('Headless loop facet disposed.');\n },\n };\n}\n","import type { DoomServerPluginDefinition } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { createSessionState, type LoopServerState } from '../../../../../services/serverRuntime';\n\nexport default (({ agent }): LoopServerState =>\n agent ? createSessionState(agent) : { loopTools: [] }) satisfies NonNullable<DoomServerPluginDefinition['session']>;\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport runtime from './_lib/runtime.server';\n\nexport default defineRoot((context: DoomServerPluginContext) => {\n const value = runtime(context);\n return {\n value,\n services: value.services,\n activities: value.activities,\n onStart: value.onStart,\n onStop: value.onStop,\n onDispose: value.onDispose,\n };\n});\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, Partial<DoomServerSessionPlugin>>) => context.root.commands?.[0],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, Partial<DoomServerSessionPlugin>>) => context.root.commands?.[1],\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, Partial<DoomServerSessionPlugin>>) =>\n context.root.hooks?.find((hook) => hook.event === 'session_shutdown'),\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, Partial<DoomServerSessionPlugin>>) =>\n context.root.hooks?.find((hook) => hook.event === 'session_start'),\n { cardinality: 'optional' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n (context: WithRoot<DoomServerPluginContext, Partial<DoomServerSessionPlugin>>) => context.root.resources?.[0],\n { cardinality: 'optional' },\n);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[0]!);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[1]!);\n","import { defineTool, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\n\nimport type { LoopToolsRoot } from '../../../../../services/loopTools/type';\n\nexport default defineTool((context: WithRoot<unknown, LoopToolsRoot>) => context.root.loopTools[2]!);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport commandLoop from '../src/extensions/workspaces/sessions/(backend)/command/loop.server';\nimport commandLoops from '../src/extensions/workspaces/sessions/(backend)/command/loops.server';\nimport hookSessionShutdown from '../src/extensions/workspaces/sessions/(backend)/hook/session-shutdown.server';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/session-start.server';\nimport resourceDoompiUseLoop from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-use-loop.server';\nimport toolLoopList from '../src/extensions/workspaces/sessions/(backend)/tool/loop-list.server';\nimport toolLoopStart from '../src/extensions/workspaces/sessions/(backend)/tool/loop-start.server';\nimport toolLoopStop from '../src/extensions/workspaces/sessions/(backend)/tool/loop-stop.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/doompi-loop',\n session: async (context) => {\n const scopeSession = await rootSession(context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get commands(): DoomServerSessionPlugin['commands'] { return defined([via({ name: 'loop' }, at(commandLoop, contextSession)), via({ name: 'loops' }, at(commandLoops, contextSession))]); },\n get hooks(): DoomServerSessionPlugin['hooks'] { return defined([via({ event: 'session_shutdown' }, at(hookSessionShutdown, contextSession)), via({ event: 'session_start' }, at(hookSessionStart, contextSession))]); },\n get resources(): DoomServerSessionPlugin['resources'] { return defined([at(resourceDoompiUseLoop, contextSession)]); },\n get tools(): DoomServerSessionPlugin['tools'] { return [via({ name: 'loop_list' }, at(toolLoopList, contextSession)), via({ name: 'loop_start' }, at(toolLoopStart, contextSession)), via({ name: 'loop_stop' }, at(toolLoopStop, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default facet;\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ //#region generated/server.d.ts
2
+ export declare const facet: import("@agimon-ai/doompi-core/serverFacet").DoomServerFacet;
3
+ //#endregion
4
+ export { facet as default };
5
+ //# sourceMappingURL=server.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAuBa,oDAAK"}