@synergenius/flow-weaver-pack-weaver 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +204 -0
- package/README.md +167 -0
- package/dist/bot/agent-provider.d.ts +34 -0
- package/dist/bot/agent-provider.d.ts.map +1 -0
- package/dist/bot/agent-provider.js +218 -0
- package/dist/bot/agent-provider.js.map +1 -0
- package/dist/bot/ai-client.d.ts +15 -0
- package/dist/bot/ai-client.d.ts.map +1 -0
- package/dist/bot/ai-client.js +128 -0
- package/dist/bot/ai-client.js.map +1 -0
- package/dist/bot/approvals.d.ts +22 -0
- package/dist/bot/approvals.d.ts.map +1 -0
- package/dist/bot/approvals.js +187 -0
- package/dist/bot/approvals.js.map +1 -0
- package/dist/bot/audit-logger.d.ts +5 -0
- package/dist/bot/audit-logger.d.ts.map +1 -0
- package/dist/bot/audit-logger.js +42 -0
- package/dist/bot/audit-logger.js.map +1 -0
- package/dist/bot/audit-store.d.ts +13 -0
- package/dist/bot/audit-store.d.ts.map +1 -0
- package/dist/bot/audit-store.js +59 -0
- package/dist/bot/audit-store.js.map +1 -0
- package/dist/bot/bot-agent-channel.d.ts +46 -0
- package/dist/bot/bot-agent-channel.d.ts.map +1 -0
- package/dist/bot/bot-agent-channel.js +58 -0
- package/dist/bot/bot-agent-channel.js.map +1 -0
- package/dist/bot/cli-provider.d.ts +29 -0
- package/dist/bot/cli-provider.d.ts.map +1 -0
- package/dist/bot/cli-provider.js +132 -0
- package/dist/bot/cli-provider.js.map +1 -0
- package/dist/bot/cli-stream-parser.d.ts +11 -0
- package/dist/bot/cli-stream-parser.d.ts.map +1 -0
- package/dist/bot/cli-stream-parser.js +53 -0
- package/dist/bot/cli-stream-parser.js.map +1 -0
- package/dist/bot/cost-store.d.ts +18 -0
- package/dist/bot/cost-store.d.ts.map +1 -0
- package/dist/bot/cost-store.js +81 -0
- package/dist/bot/cost-store.js.map +1 -0
- package/dist/bot/cost-tracker.d.ts +18 -0
- package/dist/bot/cost-tracker.d.ts.map +1 -0
- package/dist/bot/cost-tracker.js +60 -0
- package/dist/bot/cost-tracker.js.map +1 -0
- package/dist/bot/cron-parser.d.ts +5 -0
- package/dist/bot/cron-parser.d.ts.map +1 -0
- package/dist/bot/cron-parser.js +141 -0
- package/dist/bot/cron-parser.js.map +1 -0
- package/dist/bot/cron-scheduler.d.ts +12 -0
- package/dist/bot/cron-scheduler.d.ts.map +1 -0
- package/dist/bot/cron-scheduler.js +43 -0
- package/dist/bot/cron-scheduler.js.map +1 -0
- package/dist/bot/dashboard.d.ts +34 -0
- package/dist/bot/dashboard.d.ts.map +1 -0
- package/dist/bot/dashboard.js +602 -0
- package/dist/bot/dashboard.js.map +1 -0
- package/dist/bot/design-checker.d.ts +24 -0
- package/dist/bot/design-checker.d.ts.map +1 -0
- package/dist/bot/design-checker.js +269 -0
- package/dist/bot/design-checker.js.map +1 -0
- package/dist/bot/file-lock.d.ts +7 -0
- package/dist/bot/file-lock.d.ts.map +1 -0
- package/dist/bot/file-lock.js +64 -0
- package/dist/bot/file-lock.js.map +1 -0
- package/dist/bot/file-validator.d.ts +10 -0
- package/dist/bot/file-validator.d.ts.map +1 -0
- package/dist/bot/file-validator.js +27 -0
- package/dist/bot/file-validator.js.map +1 -0
- package/dist/bot/file-watcher.d.ts +24 -0
- package/dist/bot/file-watcher.d.ts.map +1 -0
- package/dist/bot/file-watcher.js +98 -0
- package/dist/bot/file-watcher.js.map +1 -0
- package/dist/bot/fw-api.d.ts +8 -0
- package/dist/bot/fw-api.d.ts.map +1 -0
- package/dist/bot/fw-api.js +12 -0
- package/dist/bot/fw-api.js.map +1 -0
- package/dist/bot/genesis-prompt-context.d.ts +31 -0
- package/dist/bot/genesis-prompt-context.d.ts.map +1 -0
- package/dist/bot/genesis-prompt-context.js +121 -0
- package/dist/bot/genesis-prompt-context.js.map +1 -0
- package/dist/bot/genesis-store.d.ts +28 -0
- package/dist/bot/genesis-store.d.ts.map +1 -0
- package/dist/bot/genesis-store.js +154 -0
- package/dist/bot/genesis-store.js.map +1 -0
- package/dist/bot/index.d.ts +38 -0
- package/dist/bot/index.d.ts.map +1 -0
- package/dist/bot/index.js +37 -0
- package/dist/bot/index.js.map +1 -0
- package/dist/bot/notifications.d.ts +20 -0
- package/dist/bot/notifications.d.ts.map +1 -0
- package/dist/bot/notifications.js +215 -0
- package/dist/bot/notifications.js.map +1 -0
- package/dist/bot/pipeline-runner.d.ts +22 -0
- package/dist/bot/pipeline-runner.d.ts.map +1 -0
- package/dist/bot/pipeline-runner.js +263 -0
- package/dist/bot/pipeline-runner.js.map +1 -0
- package/dist/bot/provider-registry.d.ts +26 -0
- package/dist/bot/provider-registry.d.ts.map +1 -0
- package/dist/bot/provider-registry.js +175 -0
- package/dist/bot/provider-registry.js.map +1 -0
- package/dist/bot/run-store.d.ts +25 -0
- package/dist/bot/run-store.d.ts.map +1 -0
- package/dist/bot/run-store.js +156 -0
- package/dist/bot/run-store.js.map +1 -0
- package/dist/bot/runner.d.ts +13 -0
- package/dist/bot/runner.d.ts.map +1 -0
- package/dist/bot/runner.js +244 -0
- package/dist/bot/runner.js.map +1 -0
- package/dist/bot/session-state.d.ts +19 -0
- package/dist/bot/session-state.d.ts.map +1 -0
- package/dist/bot/session-state.js +65 -0
- package/dist/bot/session-state.js.map +1 -0
- package/dist/bot/steering.d.ts +13 -0
- package/dist/bot/steering.d.ts.map +1 -0
- package/dist/bot/steering.js +40 -0
- package/dist/bot/steering.js.map +1 -0
- package/dist/bot/step-executor.d.ts +10 -0
- package/dist/bot/step-executor.d.ts.map +1 -0
- package/dist/bot/step-executor.js +30 -0
- package/dist/bot/step-executor.js.map +1 -0
- package/dist/bot/system-prompt.d.ts +19 -0
- package/dist/bot/system-prompt.d.ts.map +1 -0
- package/dist/bot/system-prompt.js +222 -0
- package/dist/bot/system-prompt.js.map +1 -0
- package/dist/bot/task-queue.d.ts +26 -0
- package/dist/bot/task-queue.d.ts.map +1 -0
- package/dist/bot/task-queue.js +98 -0
- package/dist/bot/task-queue.js.map +1 -0
- package/dist/bot/types.d.ts +478 -0
- package/dist/bot/types.d.ts.map +1 -0
- package/dist/bot/types.js +2 -0
- package/dist/bot/types.js.map +1 -0
- package/dist/bot/utils.d.ts +2 -0
- package/dist/bot/utils.d.ts.map +1 -0
- package/dist/bot/utils.js +20 -0
- package/dist/bot/utils.js.map +1 -0
- package/dist/bot/watch-daemon.d.ts +19 -0
- package/dist/bot/watch-daemon.d.ts.map +1 -0
- package/dist/bot/watch-daemon.js +178 -0
- package/dist/bot/watch-daemon.js.map +1 -0
- package/dist/bot/web-approval.d.ts +19 -0
- package/dist/bot/web-approval.d.ts.map +1 -0
- package/dist/bot/web-approval.js +207 -0
- package/dist/bot/web-approval.js.map +1 -0
- package/dist/cli-bridge.d.ts +2 -0
- package/dist/cli-bridge.d.ts.map +1 -0
- package/dist/cli-bridge.js +30 -0
- package/dist/cli-bridge.js.map +1 -0
- package/dist/cli-handlers.d.ts +79 -0
- package/dist/cli-handlers.d.ts.map +1 -0
- package/dist/cli-handlers.js +1335 -0
- package/dist/cli-handlers.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +749 -0
- package/dist/cli.js.map +1 -0
- package/dist/docs/docs/weaver-config.md +135 -0
- package/dist/docs/weaver-config.md +141 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-tools.d.ts +13 -0
- package/dist/mcp-tools.d.ts.map +1 -0
- package/dist/mcp-tools.js +197 -0
- package/dist/mcp-tools.js.map +1 -0
- package/dist/node-types/abort-task.d.ts +15 -0
- package/dist/node-types/abort-task.d.ts.map +1 -0
- package/dist/node-types/abort-task.js +28 -0
- package/dist/node-types/abort-task.js.map +1 -0
- package/dist/node-types/approval-gate.d.ts +18 -0
- package/dist/node-types/approval-gate.d.ts.map +1 -0
- package/dist/node-types/approval-gate.js +80 -0
- package/dist/node-types/approval-gate.js.map +1 -0
- package/dist/node-types/bot-report.d.ts +20 -0
- package/dist/node-types/bot-report.d.ts.map +1 -0
- package/dist/node-types/bot-report.js +67 -0
- package/dist/node-types/bot-report.js.map +1 -0
- package/dist/node-types/build-context.d.ts +16 -0
- package/dist/node-types/build-context.d.ts.map +1 -0
- package/dist/node-types/build-context.js +64 -0
- package/dist/node-types/build-context.js.map +1 -0
- package/dist/node-types/detect-provider.d.ts +17 -0
- package/dist/node-types/detect-provider.d.ts.map +1 -0
- package/dist/node-types/detect-provider.js +71 -0
- package/dist/node-types/detect-provider.js.map +1 -0
- package/dist/node-types/exec-validate-retry.d.ts +17 -0
- package/dist/node-types/exec-validate-retry.d.ts.map +1 -0
- package/dist/node-types/exec-validate-retry.js +147 -0
- package/dist/node-types/exec-validate-retry.js.map +1 -0
- package/dist/node-types/execute-plan.d.ts +26 -0
- package/dist/node-types/execute-plan.d.ts.map +1 -0
- package/dist/node-types/execute-plan.js +120 -0
- package/dist/node-types/execute-plan.js.map +1 -0
- package/dist/node-types/execute-target.d.ts +16 -0
- package/dist/node-types/execute-target.d.ts.map +1 -0
- package/dist/node-types/execute-target.js +238 -0
- package/dist/node-types/execute-target.js.map +1 -0
- package/dist/node-types/fix-errors.d.ts +24 -0
- package/dist/node-types/fix-errors.d.ts.map +1 -0
- package/dist/node-types/fix-errors.js +49 -0
- package/dist/node-types/fix-errors.js.map +1 -0
- package/dist/node-types/genesis-apply-retry.d.ts +27 -0
- package/dist/node-types/genesis-apply-retry.d.ts.map +1 -0
- package/dist/node-types/genesis-apply-retry.js +97 -0
- package/dist/node-types/genesis-apply-retry.js.map +1 -0
- package/dist/node-types/genesis-apply.d.ts +29 -0
- package/dist/node-types/genesis-apply.d.ts.map +1 -0
- package/dist/node-types/genesis-apply.js +76 -0
- package/dist/node-types/genesis-apply.js.map +1 -0
- package/dist/node-types/genesis-approve.d.ts +19 -0
- package/dist/node-types/genesis-approve.d.ts.map +1 -0
- package/dist/node-types/genesis-approve.js +59 -0
- package/dist/node-types/genesis-approve.js.map +1 -0
- package/dist/node-types/genesis-check-stabilize.d.ts +16 -0
- package/dist/node-types/genesis-check-stabilize.d.ts.map +1 -0
- package/dist/node-types/genesis-check-stabilize.js +32 -0
- package/dist/node-types/genesis-check-stabilize.js.map +1 -0
- package/dist/node-types/genesis-check-threshold.d.ts +15 -0
- package/dist/node-types/genesis-check-threshold.d.ts.map +1 -0
- package/dist/node-types/genesis-check-threshold.js +29 -0
- package/dist/node-types/genesis-check-threshold.js.map +1 -0
- package/dist/node-types/genesis-commit.d.ts +17 -0
- package/dist/node-types/genesis-commit.d.ts.map +1 -0
- package/dist/node-types/genesis-commit.js +59 -0
- package/dist/node-types/genesis-commit.js.map +1 -0
- package/dist/node-types/genesis-compile-validate.d.ts +26 -0
- package/dist/node-types/genesis-compile-validate.d.ts.map +1 -0
- package/dist/node-types/genesis-compile-validate.js +60 -0
- package/dist/node-types/genesis-compile-validate.js.map +1 -0
- package/dist/node-types/genesis-diff-fingerprint.d.ts +15 -0
- package/dist/node-types/genesis-diff-fingerprint.d.ts.map +1 -0
- package/dist/node-types/genesis-diff-fingerprint.js +59 -0
- package/dist/node-types/genesis-diff-fingerprint.js.map +1 -0
- package/dist/node-types/genesis-diff-workflow.d.ts +15 -0
- package/dist/node-types/genesis-diff-workflow.d.ts.map +1 -0
- package/dist/node-types/genesis-diff-workflow.js +67 -0
- package/dist/node-types/genesis-diff-workflow.js.map +1 -0
- package/dist/node-types/genesis-escrow-grace.d.ts +15 -0
- package/dist/node-types/genesis-escrow-grace.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-grace.js +52 -0
- package/dist/node-types/genesis-escrow-grace.js.map +1 -0
- package/dist/node-types/genesis-escrow-migrate.d.ts +21 -0
- package/dist/node-types/genesis-escrow-migrate.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-migrate.js +116 -0
- package/dist/node-types/genesis-escrow-migrate.js.map +1 -0
- package/dist/node-types/genesis-escrow-recover.d.ts +15 -0
- package/dist/node-types/genesis-escrow-recover.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-recover.js +90 -0
- package/dist/node-types/genesis-escrow-recover.js.map +1 -0
- package/dist/node-types/genesis-escrow-stage.d.ts +17 -0
- package/dist/node-types/genesis-escrow-stage.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-stage.js +86 -0
- package/dist/node-types/genesis-escrow-stage.js.map +1 -0
- package/dist/node-types/genesis-escrow-validate.d.ts +17 -0
- package/dist/node-types/genesis-escrow-validate.d.ts.map +1 -0
- package/dist/node-types/genesis-escrow-validate.js +110 -0
- package/dist/node-types/genesis-escrow-validate.js.map +1 -0
- package/dist/node-types/genesis-load-config.d.ts +17 -0
- package/dist/node-types/genesis-load-config.d.ts.map +1 -0
- package/dist/node-types/genesis-load-config.js +36 -0
- package/dist/node-types/genesis-load-config.js.map +1 -0
- package/dist/node-types/genesis-observe.d.ts +18 -0
- package/dist/node-types/genesis-observe.d.ts.map +1 -0
- package/dist/node-types/genesis-observe.js +103 -0
- package/dist/node-types/genesis-observe.js.map +1 -0
- package/dist/node-types/genesis-propose.d.ts +17 -0
- package/dist/node-types/genesis-propose.d.ts.map +1 -0
- package/dist/node-types/genesis-propose.js +69 -0
- package/dist/node-types/genesis-propose.js.map +1 -0
- package/dist/node-types/genesis-report.d.ts +20 -0
- package/dist/node-types/genesis-report.d.ts.map +1 -0
- package/dist/node-types/genesis-report.js +87 -0
- package/dist/node-types/genesis-report.js.map +1 -0
- package/dist/node-types/genesis-snapshot.d.ts +15 -0
- package/dist/node-types/genesis-snapshot.d.ts.map +1 -0
- package/dist/node-types/genesis-snapshot.js +26 -0
- package/dist/node-types/genesis-snapshot.js.map +1 -0
- package/dist/node-types/genesis-try-apply.d.ts +18 -0
- package/dist/node-types/genesis-try-apply.d.ts.map +1 -0
- package/dist/node-types/genesis-try-apply.js +142 -0
- package/dist/node-types/genesis-try-apply.js.map +1 -0
- package/dist/node-types/genesis-update-history.d.ts +15 -0
- package/dist/node-types/genesis-update-history.d.ts.map +1 -0
- package/dist/node-types/genesis-update-history.js +70 -0
- package/dist/node-types/genesis-update-history.js.map +1 -0
- package/dist/node-types/genesis-validate-proposal.d.ts +16 -0
- package/dist/node-types/genesis-validate-proposal.d.ts.map +1 -0
- package/dist/node-types/genesis-validate-proposal.js +109 -0
- package/dist/node-types/genesis-validate-proposal.js.map +1 -0
- package/dist/node-types/git-ops.d.ts +15 -0
- package/dist/node-types/git-ops.d.ts.map +1 -0
- package/dist/node-types/git-ops.js +69 -0
- package/dist/node-types/git-ops.js.map +1 -0
- package/dist/node-types/index.d.ts +37 -0
- package/dist/node-types/index.d.ts.map +1 -0
- package/dist/node-types/index.js +37 -0
- package/dist/node-types/index.js.map +1 -0
- package/dist/node-types/load-config.d.ts +17 -0
- package/dist/node-types/load-config.d.ts.map +1 -0
- package/dist/node-types/load-config.js +27 -0
- package/dist/node-types/load-config.js.map +1 -0
- package/dist/node-types/plan-task.d.ts +17 -0
- package/dist/node-types/plan-task.d.ts.map +1 -0
- package/dist/node-types/plan-task.js +55 -0
- package/dist/node-types/plan-task.js.map +1 -0
- package/dist/node-types/read-workflow.d.ts +15 -0
- package/dist/node-types/read-workflow.d.ts.map +1 -0
- package/dist/node-types/read-workflow.js +60 -0
- package/dist/node-types/read-workflow.js.map +1 -0
- package/dist/node-types/receive-task.d.ts +20 -0
- package/dist/node-types/receive-task.d.ts.map +1 -0
- package/dist/node-types/receive-task.js +69 -0
- package/dist/node-types/receive-task.js.map +1 -0
- package/dist/node-types/report.d.ts +14 -0
- package/dist/node-types/report.d.ts.map +1 -0
- package/dist/node-types/report.js +25 -0
- package/dist/node-types/report.js.map +1 -0
- package/dist/node-types/resolve-target.d.ts +16 -0
- package/dist/node-types/resolve-target.d.ts.map +1 -0
- package/dist/node-types/resolve-target.js +67 -0
- package/dist/node-types/resolve-target.js.map +1 -0
- package/dist/node-types/route-task.d.ts +14 -0
- package/dist/node-types/route-task.d.ts.map +1 -0
- package/dist/node-types/route-task.js +22 -0
- package/dist/node-types/route-task.js.map +1 -0
- package/dist/node-types/send-notify.d.ts +14 -0
- package/dist/node-types/send-notify.d.ts.map +1 -0
- package/dist/node-types/send-notify.js +71 -0
- package/dist/node-types/send-notify.js.map +1 -0
- package/dist/node-types/validate-result.d.ts +24 -0
- package/dist/node-types/validate-result.d.ts.map +1 -0
- package/dist/node-types/validate-result.js +38 -0
- package/dist/node-types/validate-result.js.map +1 -0
- package/dist/templates/index.d.ts +5 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +4 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/weaver-bot-template.d.ts +11 -0
- package/dist/templates/weaver-bot-template.d.ts.map +1 -0
- package/dist/templates/weaver-bot-template.js +99 -0
- package/dist/templates/weaver-bot-template.js.map +1 -0
- package/dist/templates/weaver-template.d.ts +11 -0
- package/dist/templates/weaver-template.d.ts.map +1 -0
- package/dist/templates/weaver-template.js +53 -0
- package/dist/templates/weaver-template.js.map +1 -0
- package/dist/workflows/genesis-task.d.ts +62 -0
- package/dist/workflows/genesis-task.d.ts.map +1 -0
- package/dist/workflows/genesis-task.js +64 -0
- package/dist/workflows/genesis-task.js.map +1 -0
- package/dist/workflows/index.d.ts +4 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/index.js +4 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/weaver-bot-batch.d.ts +49 -0
- package/dist/workflows/weaver-bot-batch.d.ts.map +1 -0
- package/dist/workflows/weaver-bot-batch.js +49 -0
- package/dist/workflows/weaver-bot-batch.js.map +1 -0
- package/dist/workflows/weaver-bot-session.d.ts +65 -0
- package/dist/workflows/weaver-bot-session.d.ts.map +1 -0
- package/dist/workflows/weaver-bot-session.js +68 -0
- package/dist/workflows/weaver-bot-session.js.map +1 -0
- package/dist/workflows/weaver-bot.d.ts +61 -0
- package/dist/workflows/weaver-bot.d.ts.map +1 -0
- package/dist/workflows/weaver-bot.js +61 -0
- package/dist/workflows/weaver-bot.js.map +1 -0
- package/dist/workflows/weaver.d.ts +24 -0
- package/dist/workflows/weaver.d.ts.map +1 -0
- package/dist/workflows/weaver.js +28 -0
- package/dist/workflows/weaver.js.map +1 -0
- package/flowweaver.manifest.json +1001 -0
- package/package.json +78 -0
- package/src/bot/agent-provider.ts +273 -0
- package/src/bot/ai-client.ts +153 -0
- package/src/bot/approvals.ts +273 -0
- package/src/bot/audit-logger.ts +45 -0
- package/src/bot/audit-store.ts +69 -0
- package/src/bot/bot-agent-channel.ts +99 -0
- package/src/bot/cli-provider.ts +169 -0
- package/src/bot/cli-stream-parser.ts +59 -0
- package/src/bot/cost-store.ts +92 -0
- package/src/bot/cost-tracker.ts +72 -0
- package/src/bot/cron-parser.ts +153 -0
- package/src/bot/cron-scheduler.ts +48 -0
- package/src/bot/dashboard.ts +658 -0
- package/src/bot/design-checker.ts +327 -0
- package/src/bot/file-lock.ts +73 -0
- package/src/bot/file-validator.ts +41 -0
- package/src/bot/file-watcher.ts +103 -0
- package/src/bot/fw-api.ts +18 -0
- package/src/bot/genesis-prompt-context.ts +135 -0
- package/src/bot/genesis-store.ts +180 -0
- package/src/bot/index.ts +127 -0
- package/src/bot/notifications.ts +263 -0
- package/src/bot/pipeline-runner.ts +324 -0
- package/src/bot/provider-registry.ts +236 -0
- package/src/bot/run-store.ts +169 -0
- package/src/bot/runner.ts +311 -0
- package/src/bot/session-state.ts +73 -0
- package/src/bot/steering.ts +44 -0
- package/src/bot/step-executor.ts +34 -0
- package/src/bot/system-prompt.ts +280 -0
- package/src/bot/task-queue.ts +111 -0
- package/src/bot/types.ts +571 -0
- package/src/bot/utils.ts +17 -0
- package/src/bot/watch-daemon.ts +203 -0
- package/src/bot/web-approval.ts +240 -0
- package/src/cli-bridge.ts +41 -0
- package/src/cli-handlers.ts +1445 -0
- package/src/docs/weaver-config.md +135 -0
- package/src/index.ts +177 -0
- package/src/mcp-tools.ts +274 -0
- package/src/node-types/abort-task.ts +31 -0
- package/src/node-types/approval-gate.ts +95 -0
- package/src/node-types/bot-report.ts +82 -0
- package/src/node-types/build-context.ts +65 -0
- package/src/node-types/detect-provider.ts +77 -0
- package/src/node-types/exec-validate-retry.ts +170 -0
- package/src/node-types/execute-plan.ts +130 -0
- package/src/node-types/execute-target.ts +256 -0
- package/src/node-types/fix-errors.ts +63 -0
- package/src/node-types/genesis-apply-retry.ts +133 -0
- package/src/node-types/genesis-apply.ts +96 -0
- package/src/node-types/genesis-approve.ts +73 -0
- package/src/node-types/genesis-check-stabilize.ts +37 -0
- package/src/node-types/genesis-check-threshold.ts +34 -0
- package/src/node-types/genesis-commit.ts +71 -0
- package/src/node-types/genesis-compile-validate.ts +77 -0
- package/src/node-types/genesis-diff-fingerprint.ts +67 -0
- package/src/node-types/genesis-diff-workflow.ts +71 -0
- package/src/node-types/genesis-escrow-grace.ts +62 -0
- package/src/node-types/genesis-escrow-migrate.ts +138 -0
- package/src/node-types/genesis-escrow-recover.ts +99 -0
- package/src/node-types/genesis-escrow-stage.ts +104 -0
- package/src/node-types/genesis-escrow-validate.ts +120 -0
- package/src/node-types/genesis-load-config.ts +44 -0
- package/src/node-types/genesis-observe.ts +119 -0
- package/src/node-types/genesis-propose.ts +86 -0
- package/src/node-types/genesis-report.ts +95 -0
- package/src/node-types/genesis-snapshot.ts +30 -0
- package/src/node-types/genesis-try-apply.ts +165 -0
- package/src/node-types/genesis-update-history.ts +72 -0
- package/src/node-types/genesis-validate-proposal.ts +124 -0
- package/src/node-types/git-ops.ts +72 -0
- package/src/node-types/index.ts +36 -0
- package/src/node-types/load-config.ts +27 -0
- package/src/node-types/plan-task.ts +66 -0
- package/src/node-types/read-workflow.ts +68 -0
- package/src/node-types/receive-task.ts +92 -0
- package/src/node-types/report.ts +25 -0
- package/src/node-types/resolve-target.ts +64 -0
- package/src/node-types/route-task.ts +25 -0
- package/src/node-types/send-notify.ts +75 -0
- package/src/node-types/validate-result.ts +49 -0
- package/src/templates/index.ts +5 -0
- package/src/templates/weaver-bot-template.ts +106 -0
- package/src/workflows/genesis-task.ts +91 -0
- package/src/workflows/index.ts +3 -0
- package/src/workflows/weaver-bot-batch.ts +65 -0
- package/src/workflows/weaver-bot.ts +79 -0
- package/templates.js +1 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as crypto from 'node:crypto';
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
import type { RunRecord, RunFilter, RetentionPolicy } from './types.js';
|
|
6
|
+
|
|
7
|
+
export class RunStore {
|
|
8
|
+
private readonly dir: string;
|
|
9
|
+
private readonly filePath: string;
|
|
10
|
+
|
|
11
|
+
constructor(storeDir?: string) {
|
|
12
|
+
this.dir = storeDir ?? process.env.WEAVER_HISTORY_DIR ?? path.join(os.homedir(), '.weaver');
|
|
13
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
14
|
+
this.filePath = path.join(this.dir, 'history.ndjson');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static newId(): string {
|
|
18
|
+
return crypto.randomUUID();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
append(record: RunRecord): void {
|
|
22
|
+
fs.appendFileSync(this.filePath, JSON.stringify(record) + '\n', 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
list(filter?: RunFilter): RunRecord[] {
|
|
26
|
+
const all = this.readAll();
|
|
27
|
+
let filtered = all;
|
|
28
|
+
|
|
29
|
+
if (filter?.workflowFile) {
|
|
30
|
+
const wf = filter.workflowFile;
|
|
31
|
+
filtered = filtered.filter((r) => r.workflowFile === wf);
|
|
32
|
+
}
|
|
33
|
+
if (filter?.outcome) {
|
|
34
|
+
const out = filter.outcome;
|
|
35
|
+
filtered = filtered.filter((r) => r.outcome === out);
|
|
36
|
+
}
|
|
37
|
+
if (filter?.success !== undefined) {
|
|
38
|
+
const s = filter.success;
|
|
39
|
+
filtered = filtered.filter((r) => r.success === s);
|
|
40
|
+
}
|
|
41
|
+
if (filter?.since) {
|
|
42
|
+
const since = filter.since;
|
|
43
|
+
filtered = filtered.filter((r) => r.startedAt >= since);
|
|
44
|
+
}
|
|
45
|
+
if (filter?.before) {
|
|
46
|
+
const before = filter.before;
|
|
47
|
+
filtered = filtered.filter((r) => r.startedAt <= before);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
filtered.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
51
|
+
|
|
52
|
+
const limit = filter?.limit ?? 50;
|
|
53
|
+
return filtered.slice(0, limit);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get(idOrPrefix: string): RunRecord | null {
|
|
57
|
+
if (idOrPrefix.length < 4) {
|
|
58
|
+
throw new Error('ID prefix must be at least 4 characters');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const all = this.readAll();
|
|
62
|
+
const matches = all.filter((r) => r.id.startsWith(idOrPrefix));
|
|
63
|
+
|
|
64
|
+
if (matches.length === 0) return null;
|
|
65
|
+
if (matches.length === 1) return matches[0]!;
|
|
66
|
+
|
|
67
|
+
throw new Error(
|
|
68
|
+
`Ambiguous ID prefix "${idOrPrefix}" matches ${matches.length} runs: ` +
|
|
69
|
+
matches.map((r) => r.id).join(', '),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Mark a run as in-progress. Creates a small marker file that survives crashes. */
|
|
74
|
+
markRunning(runId: string, workflowFile: string): void {
|
|
75
|
+
const marker = path.join(this.dir, `running-${runId}.json`);
|
|
76
|
+
fs.writeFileSync(marker, JSON.stringify({ id: runId, workflowFile, startedAt: new Date().toISOString(), pid: process.pid }), 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Remove the in-progress marker after the run completes. */
|
|
80
|
+
clearRunning(runId: string): void {
|
|
81
|
+
const marker = path.join(this.dir, `running-${runId}.json`);
|
|
82
|
+
try { fs.unlinkSync(marker); } catch { /* already gone */ }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Check for orphaned in-progress markers (runs killed mid-execution). */
|
|
86
|
+
checkOrphans(): Array<{ id: string; workflowFile: string; startedAt: string; pid: number }> {
|
|
87
|
+
const orphans: Array<{ id: string; workflowFile: string; startedAt: string; pid: number }> = [];
|
|
88
|
+
try {
|
|
89
|
+
const files = fs.readdirSync(this.dir).filter((f) => f.startsWith('running-') && f.endsWith('.json'));
|
|
90
|
+
for (const file of files) {
|
|
91
|
+
try {
|
|
92
|
+
const data = JSON.parse(fs.readFileSync(path.join(this.dir, file), 'utf-8'));
|
|
93
|
+
// Check if the PID is still alive
|
|
94
|
+
let alive = false;
|
|
95
|
+
try { process.kill(data.pid, 0); alive = true; } catch { /* process gone */ }
|
|
96
|
+
if (!alive) {
|
|
97
|
+
orphans.push(data);
|
|
98
|
+
// Record the orphaned run as an error and clean up
|
|
99
|
+
this.append({
|
|
100
|
+
id: data.id,
|
|
101
|
+
workflowFile: data.workflowFile,
|
|
102
|
+
startedAt: data.startedAt,
|
|
103
|
+
finishedAt: new Date().toISOString(),
|
|
104
|
+
durationMs: Date.now() - new Date(data.startedAt).getTime(),
|
|
105
|
+
success: false,
|
|
106
|
+
outcome: 'error',
|
|
107
|
+
summary: 'Process killed during execution (recovered on next start)',
|
|
108
|
+
dryRun: false,
|
|
109
|
+
});
|
|
110
|
+
fs.unlinkSync(path.join(this.dir, file));
|
|
111
|
+
}
|
|
112
|
+
} catch { /* skip corrupt marker */ }
|
|
113
|
+
}
|
|
114
|
+
} catch { /* dir read failed */ }
|
|
115
|
+
return orphans;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
prune(policy: RetentionPolicy): number {
|
|
119
|
+
const all = this.readAll();
|
|
120
|
+
if (all.length === 0) return 0;
|
|
121
|
+
|
|
122
|
+
all.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
123
|
+
let kept = [...all];
|
|
124
|
+
|
|
125
|
+
if (policy.maxAgeDays !== undefined) {
|
|
126
|
+
const cutoff = new Date(Date.now() - policy.maxAgeDays * 86_400_000).toISOString();
|
|
127
|
+
kept = kept.filter((r) => r.startedAt >= cutoff);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (policy.maxRecords !== undefined) {
|
|
131
|
+
kept = kept.slice(0, policy.maxRecords);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const pruned = all.length - kept.length;
|
|
135
|
+
if (pruned === 0) return 0;
|
|
136
|
+
|
|
137
|
+
// Rewrite atomically: oldest first in file
|
|
138
|
+
kept.sort((a, b) => a.startedAt.localeCompare(b.startedAt));
|
|
139
|
+
const tmpPath = this.filePath + '.tmp';
|
|
140
|
+
fs.writeFileSync(tmpPath, kept.map((r) => JSON.stringify(r)).join('\n') + '\n', 'utf-8');
|
|
141
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
142
|
+
|
|
143
|
+
return pruned;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
clear(): boolean {
|
|
147
|
+
if (!fs.existsSync(this.filePath)) return false;
|
|
148
|
+
fs.unlinkSync(this.filePath);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private readAll(): RunRecord[] {
|
|
153
|
+
if (!fs.existsSync(this.filePath)) return [];
|
|
154
|
+
|
|
155
|
+
const content = fs.readFileSync(this.filePath, 'utf-8');
|
|
156
|
+
const lines = content.split('\n').filter((line) => line.trim().length > 0);
|
|
157
|
+
const records: RunRecord[] = [];
|
|
158
|
+
|
|
159
|
+
for (const line of lines) {
|
|
160
|
+
try {
|
|
161
|
+
records.push(JSON.parse(line) as RunRecord);
|
|
162
|
+
} catch {
|
|
163
|
+
console.error('[weaver] Skipping corrupt history line');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return records;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import type {
|
|
4
|
+
ApprovalMode,
|
|
5
|
+
AuditEventCallback,
|
|
6
|
+
BotConfig,
|
|
7
|
+
BotNotifyConfig,
|
|
8
|
+
ExecutionEvent,
|
|
9
|
+
RunOutcome,
|
|
10
|
+
WeaverConfig,
|
|
11
|
+
WorkflowResult,
|
|
12
|
+
} from './types.js';
|
|
13
|
+
import { initAuditLogger, auditEmit, teardownAuditLogger } from './audit-logger.js';
|
|
14
|
+
import {
|
|
15
|
+
createProvider,
|
|
16
|
+
resolveProviderConfig,
|
|
17
|
+
} from './agent-provider.js';
|
|
18
|
+
import { BotAgentChannel } from './bot-agent-channel.js';
|
|
19
|
+
import {
|
|
20
|
+
WebhookNotificationChannel,
|
|
21
|
+
createNotifier,
|
|
22
|
+
} from './notifications.js';
|
|
23
|
+
import type { NotificationErrorHandler } from './notifications.js';
|
|
24
|
+
import { RunStore } from './run-store.js';
|
|
25
|
+
import { CostTracker } from './cost-tracker.js';
|
|
26
|
+
import { CostStore } from './cost-store.js';
|
|
27
|
+
|
|
28
|
+
function resolveApproval(
|
|
29
|
+
approval: BotConfig['approval'],
|
|
30
|
+
): { mode: ApprovalMode; timeoutSeconds: number; webhookUrl?: string; webOpen?: boolean } {
|
|
31
|
+
if (!approval || approval === 'auto') {
|
|
32
|
+
return { mode: 'auto', timeoutSeconds: 300 };
|
|
33
|
+
}
|
|
34
|
+
if (typeof approval === 'string') {
|
|
35
|
+
return { mode: approval, timeoutSeconds: 300 };
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
mode: approval.mode,
|
|
39
|
+
timeoutSeconds: approval.timeoutSeconds ?? 300,
|
|
40
|
+
webhookUrl: approval.webhookUrl,
|
|
41
|
+
webOpen: approval.webOpen,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function resolveNotify(
|
|
46
|
+
notify: BotConfig['notify'],
|
|
47
|
+
): BotNotifyConfig[] {
|
|
48
|
+
if (!notify) return [];
|
|
49
|
+
return Array.isArray(notify) ? notify : [notify];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function resolveWeaverConfig(
|
|
53
|
+
filePath: string,
|
|
54
|
+
explicit?: WeaverConfig,
|
|
55
|
+
): WeaverConfig {
|
|
56
|
+
if (explicit) return explicit;
|
|
57
|
+
|
|
58
|
+
const dir = path.dirname(filePath);
|
|
59
|
+
const localConfig = path.join(dir, '.weaver.json');
|
|
60
|
+
if (fs.existsSync(localConfig)) {
|
|
61
|
+
return JSON.parse(fs.readFileSync(localConfig, 'utf-8'));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const cwdConfig = path.join(process.cwd(), '.weaver.json');
|
|
65
|
+
if (fs.existsSync(cwdConfig)) {
|
|
66
|
+
return JSON.parse(fs.readFileSync(cwdConfig, 'utf-8'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { provider: 'auto' };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function buildSummary(result: unknown): string {
|
|
73
|
+
if (!result || typeof result !== 'object') return String(result);
|
|
74
|
+
|
|
75
|
+
const r = result as Record<string, unknown>;
|
|
76
|
+
if (typeof r.summary === 'string') return r.summary;
|
|
77
|
+
|
|
78
|
+
// Build a meaningful summary from whatever the workflow returned
|
|
79
|
+
const parts: string[] = [];
|
|
80
|
+
for (const [key, value] of Object.entries(r)) {
|
|
81
|
+
if (key === 'onSuccess' || key === 'onFailure') continue;
|
|
82
|
+
if (value === null || value === undefined) continue;
|
|
83
|
+
const str = typeof value === 'string' ? value : JSON.stringify(value);
|
|
84
|
+
parts.push(`${key}: ${str.length > 100 ? str.slice(0, 100) + '...' : str}`);
|
|
85
|
+
}
|
|
86
|
+
return parts.length > 0 ? parts.join(', ') : 'completed';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function runWorkflow(
|
|
90
|
+
filePath: string,
|
|
91
|
+
options?: {
|
|
92
|
+
params?: Record<string, unknown>;
|
|
93
|
+
verbose?: boolean;
|
|
94
|
+
dryRun?: boolean;
|
|
95
|
+
config?: WeaverConfig;
|
|
96
|
+
onEvent?: (event: ExecutionEvent) => void;
|
|
97
|
+
onAuditEvent?: AuditEventCallback;
|
|
98
|
+
onNotificationError?: NotificationErrorHandler;
|
|
99
|
+
dashboardServer?: import('./dashboard.js').DashboardServer;
|
|
100
|
+
},
|
|
101
|
+
): Promise<WorkflowResult> {
|
|
102
|
+
const absPath = path.resolve(filePath);
|
|
103
|
+
const verbose = options?.verbose ?? false;
|
|
104
|
+
|
|
105
|
+
let store: RunStore | null = null;
|
|
106
|
+
try { store = new RunStore(); } catch { /* non-fatal */ }
|
|
107
|
+
const runId = RunStore.newId();
|
|
108
|
+
const startedAt = new Date().toISOString();
|
|
109
|
+
initAuditLogger(runId, options?.onAuditEvent);
|
|
110
|
+
|
|
111
|
+
// Mark run as in-progress so abrupt kills leave a trace
|
|
112
|
+
try { store?.markRunning(runId, absPath); } catch { /* non-fatal */ }
|
|
113
|
+
|
|
114
|
+
if (!fs.existsSync(absPath)) {
|
|
115
|
+
throw new Error(`Workflow file not found: ${absPath}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const config = resolveWeaverConfig(absPath, options?.config);
|
|
119
|
+
const providerConfig = resolveProviderConfig(config.provider);
|
|
120
|
+
const approvalConfig = resolveApproval(config.approval);
|
|
121
|
+
const notifyConfigs = resolveNotify(config.notify);
|
|
122
|
+
|
|
123
|
+
const provider = await createProvider(providerConfig);
|
|
124
|
+
|
|
125
|
+
const costTracker = new CostTracker(providerConfig.model ?? 'unknown', providerConfig.name);
|
|
126
|
+
provider.onUsage = (step, model, usage) => costTracker.track(step, model, usage);
|
|
127
|
+
const channels = notifyConfigs.map(
|
|
128
|
+
(c) => new WebhookNotificationChannel(c, options?.onNotificationError),
|
|
129
|
+
);
|
|
130
|
+
const notifier = createNotifier(channels);
|
|
131
|
+
|
|
132
|
+
const projectDir = path.dirname(absPath);
|
|
133
|
+
|
|
134
|
+
if (verbose) {
|
|
135
|
+
console.log(`[weaver] Workflow: ${absPath}`);
|
|
136
|
+
const providerLabel = providerConfig.model
|
|
137
|
+
? `${providerConfig.name} (${providerConfig.model})`
|
|
138
|
+
: providerConfig.name;
|
|
139
|
+
console.log(`[weaver] Provider: ${providerLabel}`);
|
|
140
|
+
console.log(`[weaver] Approval: ${approvalConfig.mode}`);
|
|
141
|
+
console.log(`[weaver] Notifications: ${channels.length} channel(s)`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
auditEmit('run-start', { workflowFile: absPath, provider: providerConfig.name, projectDir });
|
|
145
|
+
|
|
146
|
+
await notifier({
|
|
147
|
+
type: 'workflow-start',
|
|
148
|
+
workflowFile: absPath,
|
|
149
|
+
projectDir,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const botChannel = new BotAgentChannel(provider, {
|
|
153
|
+
approvalMode: approvalConfig.mode,
|
|
154
|
+
approvalTimeoutSeconds: approvalConfig.timeoutSeconds,
|
|
155
|
+
approvalWebhookUrl: approvalConfig.webhookUrl,
|
|
156
|
+
approvalWebOpen: approvalConfig.webOpen,
|
|
157
|
+
dashboardServer: options?.dashboardServer,
|
|
158
|
+
notifier,
|
|
159
|
+
context: { projectDir, workflowFile: absPath },
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
const mod = '@synergenius/flow-weaver/executor';
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
165
|
+
const { executeWorkflowFromFile } = await (import(mod) as Promise<any>);
|
|
166
|
+
|
|
167
|
+
if (options?.dryRun) {
|
|
168
|
+
if (verbose) console.log('[weaver] Dry run, skipping execution');
|
|
169
|
+
const dryResult: WorkflowResult = { success: true, summary: 'Dry run', outcome: 'skipped' };
|
|
170
|
+
recordRun(store, { id: runId, workflowFile: absPath, startedAt, success: true, outcome: 'skipped', summary: 'Dry run', dryRun: true, provider: providerConfig.name, params: options?.params }, verbose);
|
|
171
|
+
return dryResult;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Forward trace events as ExecutionEvents
|
|
175
|
+
const onTraceEvent = options?.onEvent
|
|
176
|
+
? (traceEvent: { type: string; timestamp: number; data?: Record<string, unknown> }) => {
|
|
177
|
+
if (traceEvent.type !== 'STATUS_CHANGED' || !traceEvent.data) return;
|
|
178
|
+
const nodeId = traceEvent.data.id as string | undefined;
|
|
179
|
+
const status = traceEvent.data.status as string | undefined;
|
|
180
|
+
if (!nodeId || !status) return;
|
|
181
|
+
|
|
182
|
+
let eventType: ExecutionEvent['type'] | null = null;
|
|
183
|
+
if (status === 'RUNNING') eventType = 'node-start';
|
|
184
|
+
else if (status === 'SUCCEEDED') eventType = 'node-complete';
|
|
185
|
+
else if (status === 'FAILED') eventType = 'node-error';
|
|
186
|
+
|
|
187
|
+
if (eventType) {
|
|
188
|
+
options.onEvent!({
|
|
189
|
+
type: eventType,
|
|
190
|
+
nodeId,
|
|
191
|
+
nodeType: traceEvent.data.nodeTypeName as string | undefined,
|
|
192
|
+
timestamp: traceEvent.timestamp,
|
|
193
|
+
error: traceEvent.data.error as string | undefined,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
: undefined;
|
|
198
|
+
|
|
199
|
+
const execResult = await executeWorkflowFromFile(
|
|
200
|
+
absPath,
|
|
201
|
+
options?.params ?? {},
|
|
202
|
+
{
|
|
203
|
+
agentChannel: botChannel,
|
|
204
|
+
includeTrace: !!onTraceEvent,
|
|
205
|
+
production: !onTraceEvent,
|
|
206
|
+
onEvent: onTraceEvent,
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const result = execResult.result as Record<string, unknown> | null;
|
|
211
|
+
const success = (result?.onSuccess as boolean) ?? false;
|
|
212
|
+
const summary = buildSummary(result);
|
|
213
|
+
const outcome = success ? 'completed' : 'failed';
|
|
214
|
+
|
|
215
|
+
await notifier({
|
|
216
|
+
type: 'workflow-complete',
|
|
217
|
+
workflowFile: absPath,
|
|
218
|
+
projectDir,
|
|
219
|
+
summary,
|
|
220
|
+
outcome,
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
const costSummary = costTracker.hasEntries() ? costTracker.getRunSummary() : undefined;
|
|
224
|
+
persistCost(costSummary, absPath, providerConfig.name, verbose);
|
|
225
|
+
recordRun(store, {
|
|
226
|
+
id: runId, workflowFile: absPath, startedAt, success, outcome: outcome as RunOutcome, summary,
|
|
227
|
+
functionName: execResult.functionName, executionTime: execResult.executionTime,
|
|
228
|
+
dryRun: false, provider: providerConfig.name, params: options?.params,
|
|
229
|
+
}, verbose);
|
|
230
|
+
|
|
231
|
+
auditEmit('run-complete', { success, outcome, summary });
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
success,
|
|
235
|
+
summary,
|
|
236
|
+
outcome,
|
|
237
|
+
functionName: execResult.functionName,
|
|
238
|
+
executionTime: execResult.executionTime,
|
|
239
|
+
cost: costSummary,
|
|
240
|
+
};
|
|
241
|
+
} catch (err: unknown) {
|
|
242
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
243
|
+
|
|
244
|
+
await notifier({
|
|
245
|
+
type: 'error',
|
|
246
|
+
workflowFile: absPath,
|
|
247
|
+
projectDir,
|
|
248
|
+
error: msg,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const costSummary = costTracker.hasEntries() ? costTracker.getRunSummary() : undefined;
|
|
252
|
+
persistCost(costSummary, absPath, providerConfig.name, verbose);
|
|
253
|
+
recordRun(store, {
|
|
254
|
+
id: runId, workflowFile: absPath, startedAt, success: false, outcome: 'error', summary: msg,
|
|
255
|
+
dryRun: options?.dryRun ?? false, provider: providerConfig.name, params: options?.params,
|
|
256
|
+
}, verbose);
|
|
257
|
+
|
|
258
|
+
auditEmit('run-complete', { success: false, error: msg });
|
|
259
|
+
|
|
260
|
+
return { success: false, summary: msg, outcome: 'error', cost: costSummary };
|
|
261
|
+
} finally {
|
|
262
|
+
teardownAuditLogger();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function recordRun(
|
|
267
|
+
store: RunStore | null,
|
|
268
|
+
data: {
|
|
269
|
+
id: string; workflowFile: string; startedAt: string; success: boolean;
|
|
270
|
+
outcome: RunOutcome; summary: string; functionName?: string;
|
|
271
|
+
executionTime?: number; dryRun: boolean; provider?: string;
|
|
272
|
+
params?: Record<string, unknown>;
|
|
273
|
+
},
|
|
274
|
+
verbose: boolean,
|
|
275
|
+
): void {
|
|
276
|
+
if (!store) return;
|
|
277
|
+
const finishedAt = new Date().toISOString();
|
|
278
|
+
try {
|
|
279
|
+
store.append({
|
|
280
|
+
...data,
|
|
281
|
+
finishedAt,
|
|
282
|
+
durationMs: new Date(finishedAt).getTime() - new Date(data.startedAt).getTime(),
|
|
283
|
+
});
|
|
284
|
+
store.clearRunning(data.id);
|
|
285
|
+
} catch (err) {
|
|
286
|
+
if (verbose) console.error(`[weaver] Failed to record run history: ${err}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function persistCost(
|
|
291
|
+
costSummary: import('./types.js').RunCostSummary | undefined,
|
|
292
|
+
workflowFile: string,
|
|
293
|
+
provider: string,
|
|
294
|
+
verbose: boolean,
|
|
295
|
+
): void {
|
|
296
|
+
if (!costSummary || costSummary.totalInputTokens === 0) return;
|
|
297
|
+
try {
|
|
298
|
+
new CostStore().append({
|
|
299
|
+
timestamp: Date.now(),
|
|
300
|
+
workflowFile,
|
|
301
|
+
provider,
|
|
302
|
+
model: costSummary.model,
|
|
303
|
+
inputTokens: costSummary.totalInputTokens,
|
|
304
|
+
outputTokens: costSummary.totalOutputTokens,
|
|
305
|
+
estimatedCost: costSummary.totalCost,
|
|
306
|
+
steps: costSummary.entries.length,
|
|
307
|
+
});
|
|
308
|
+
} catch (err) {
|
|
309
|
+
if (verbose) console.error(`[weaver] Failed to persist cost data: ${err}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import * as crypto from 'node:crypto';
|
|
5
|
+
import { withFileLock } from './file-lock.js';
|
|
6
|
+
|
|
7
|
+
export interface SessionState {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
status: 'idle' | 'planning' | 'executing' | 'validating' | 'waiting-approval' | 'paused' | 'fixing';
|
|
10
|
+
currentTask: string | null;
|
|
11
|
+
completedTasks: number;
|
|
12
|
+
totalCost: number;
|
|
13
|
+
startedAt: number;
|
|
14
|
+
lastActivity: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class SessionStore {
|
|
18
|
+
private filePath: string;
|
|
19
|
+
|
|
20
|
+
constructor(dir?: string) {
|
|
21
|
+
const base = dir ?? path.join(os.homedir(), '.weaver');
|
|
22
|
+
this.filePath = path.join(base, 'session.json');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async create(): Promise<SessionState> {
|
|
26
|
+
const state: SessionState = {
|
|
27
|
+
sessionId: crypto.randomUUID().slice(0, 8),
|
|
28
|
+
status: 'idle',
|
|
29
|
+
currentTask: null,
|
|
30
|
+
completedTasks: 0,
|
|
31
|
+
totalCost: 0,
|
|
32
|
+
startedAt: Date.now(),
|
|
33
|
+
lastActivity: Date.now(),
|
|
34
|
+
};
|
|
35
|
+
await this.save(state);
|
|
36
|
+
return state;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
load(): SessionState | null {
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.existsSync(this.filePath)) return null;
|
|
42
|
+
return JSON.parse(fs.readFileSync(this.filePath, 'utf-8')) as SessionState;
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async save(state: SessionState): Promise<void> {
|
|
49
|
+
return withFileLock(this.filePath, () => {
|
|
50
|
+
const dir = path.dirname(this.filePath);
|
|
51
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
52
|
+
state.lastActivity = Date.now();
|
|
53
|
+
fs.writeFileSync(this.filePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async update(patch: Partial<SessionState>): Promise<SessionState | null> {
|
|
58
|
+
return withFileLock(this.filePath, () => {
|
|
59
|
+
const state = this.load();
|
|
60
|
+
if (!state) return null;
|
|
61
|
+
Object.assign(state, patch);
|
|
62
|
+
const dir = path.dirname(this.filePath);
|
|
63
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
64
|
+
state.lastActivity = Date.now();
|
|
65
|
+
fs.writeFileSync(this.filePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
66
|
+
return state;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
clear(): void {
|
|
71
|
+
try { fs.unlinkSync(this.filePath); } catch { /* ignore */ }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import { withFileLock } from './file-lock.js';
|
|
5
|
+
|
|
6
|
+
export interface SteeringCommand {
|
|
7
|
+
command: 'pause' | 'resume' | 'cancel' | 'redirect' | 'queue';
|
|
8
|
+
payload?: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class SteeringController {
|
|
13
|
+
private controlPath: string;
|
|
14
|
+
|
|
15
|
+
constructor(controlDir?: string) {
|
|
16
|
+
const dir = controlDir ?? path.join(os.homedir(), '.weaver');
|
|
17
|
+
this.controlPath = path.join(dir, 'control.json');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async check(): Promise<SteeringCommand | null> {
|
|
21
|
+
return withFileLock(this.controlPath, () => {
|
|
22
|
+
try {
|
|
23
|
+
if (!fs.existsSync(this.controlPath)) return null;
|
|
24
|
+
const raw = fs.readFileSync(this.controlPath, 'utf-8');
|
|
25
|
+
fs.unlinkSync(this.controlPath);
|
|
26
|
+
return JSON.parse(raw) as SteeringCommand;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async write(command: SteeringCommand): Promise<void> {
|
|
34
|
+
return withFileLock(this.controlPath, () => {
|
|
35
|
+
const dir = path.dirname(this.controlPath);
|
|
36
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
37
|
+
fs.writeFileSync(this.controlPath, JSON.stringify(command, null, 2), 'utf-8');
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
clear(): void {
|
|
42
|
+
try { fs.unlinkSync(this.controlPath); } catch { /* ignore */ }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { runCommand } from '@synergenius/flow-weaver';
|
|
4
|
+
|
|
5
|
+
export async function executeStep(
|
|
6
|
+
step: { operation: string; args: Record<string, unknown> },
|
|
7
|
+
projectDir: string,
|
|
8
|
+
): Promise<{ file?: string; files?: string[]; created?: boolean; output?: string }> {
|
|
9
|
+
const args = step.args;
|
|
10
|
+
const file = args.file as string | undefined;
|
|
11
|
+
|
|
12
|
+
switch (step.operation) {
|
|
13
|
+
case 'write-file':
|
|
14
|
+
case 'create-workflow':
|
|
15
|
+
case 'modify-source':
|
|
16
|
+
case 'implement-node': {
|
|
17
|
+
const filePath = path.resolve(projectDir, file!);
|
|
18
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
19
|
+
const existed = fs.existsSync(filePath);
|
|
20
|
+
fs.writeFileSync(filePath, (args.content as string) ?? (args.body as string) ?? '', 'utf-8');
|
|
21
|
+
return { file: filePath, created: !existed };
|
|
22
|
+
}
|
|
23
|
+
case 'read-file':
|
|
24
|
+
return {};
|
|
25
|
+
default: {
|
|
26
|
+
const result = await runCommand(step.operation, { ...args, cwd: projectDir });
|
|
27
|
+
return {
|
|
28
|
+
file: result.files?.[0],
|
|
29
|
+
files: result.files,
|
|
30
|
+
output: result.output ?? (result.data ? JSON.stringify(result.data, null, 2) : undefined),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|