pi-crew 0.9.15 → 0.9.17
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/CHANGELOG.md +145 -0
- package/README.md +19 -0
- package/dist/build-meta.json +21790 -0
- package/dist/index.mjs +83070 -0
- package/dist/index.mjs.map +7 -0
- package/docs/A +358 -0
- package/docs/M-A +357 -0
- package/docs/REVIEW-FINDINGS-2026-06 +357 -0
- package/docs/Y +357 -0
- package/docs/a +357 -0
- package/docs/aA +358 -0
- package/docs/archive/README.md +91 -0
- package/docs/patterns/command-agent-skill.md +1 -1
- package/docs/skills/REFERENCE.md +0 -17
- package/docs//303/242mmaAAA/303/242 +357 -0
- package/index.bundle.ts +25 -0
- package/index.ts +95 -4
- package/package.json +15 -4
- package/skills/iterative-audit/SKILL.md +0 -1
- package/skills/widget-rendering/SKILL.md +17 -0
- package/src/adapters/claude-adapter.ts +1 -3
- package/src/adapters/export-util.ts +16 -16
- package/src/adapters/index.ts +5 -5
- package/src/agents/agent-config.ts +20 -14
- package/src/agents/agent-serializer.ts +1 -1
- package/src/agents/discover-agents.ts +83 -39
- package/src/benchmark/benchmark-runner.ts +51 -51
- package/src/benchmark/feedback-loop.ts +1 -1
- package/src/config/config.ts +166 -590
- package/src/config/defaults.ts +28 -2
- package/src/config/drift-detector.ts +11 -14
- package/src/config/markers.ts +201 -203
- package/src/config/resilient-parser.ts +14 -6
- package/src/config/role-tools.ts +3 -3
- package/src/config/suggestions.ts +5 -12
- package/src/config/types.ts +9 -25
- package/src/errors.ts +151 -157
- package/src/extension/action-suggestions.ts +54 -9
- package/src/extension/async-notifier.ts +43 -13
- package/src/extension/autonomous-policy.ts +77 -37
- package/src/extension/command-completions.ts +9 -8
- package/src/extension/context-status-injection.ts +14 -12
- package/src/extension/crew-autocomplete.ts +8 -16
- package/src/extension/crew-cleanup.ts +2 -1
- package/src/extension/crew-shortcuts.ts +9 -6
- package/src/extension/cross-extension-rpc.ts +136 -42
- package/src/extension/help.ts +1 -1
- package/src/extension/import-index.ts +10 -5
- package/src/extension/knowledge-injection.ts +88 -15
- package/src/extension/management.ts +89 -349
- package/src/extension/message-renderers.ts +3 -4
- package/src/extension/notification-router.ts +22 -5
- package/src/extension/notification-sink.ts +6 -3
- package/src/extension/pi-api.ts +17 -8
- package/src/extension/plan-orchestrate.ts +8 -27
- package/src/extension/project-init.ts +21 -6
- package/src/extension/register.ts +329 -975
- package/src/extension/registration/artifact-cleanup.ts +9 -4
- package/src/extension/registration/command-utils.ts +5 -1
- package/src/extension/registration/commands.ts +806 -314
- package/src/extension/registration/compaction-guard.ts +15 -15
- package/src/extension/registration/lifecycle.ts +259 -0
- package/src/extension/registration/observability.ts +293 -0
- package/src/extension/registration/subagent-helpers.ts +29 -7
- package/src/extension/registration/subagent-tools.ts +253 -44
- package/src/extension/registration/team-tool.ts +19 -84
- package/src/extension/registration/ui.ts +168 -0
- package/src/extension/registration/viewers.ts +64 -24
- package/src/extension/result-watcher.ts +18 -7
- package/src/extension/run-bundle-schema.ts +21 -6
- package/src/extension/run-export.ts +15 -6
- package/src/extension/run-import.ts +64 -29
- package/src/extension/run-index.ts +28 -9
- package/src/extension/run-maintenance.ts +32 -12
- package/src/extension/session-summary.ts +1 -1
- package/src/extension/team-manager-command.ts +64 -7
- package/src/extension/team-onboard.ts +151 -150
- package/src/extension/team-recommendation.ts +121 -21
- package/src/extension/team-tool/anchor.ts +31 -64
- package/src/extension/team-tool/api.ts +929 -141
- package/src/extension/team-tool/auto-summarize.ts +14 -26
- package/src/extension/team-tool/cache-control.ts +1 -5
- package/src/extension/team-tool/cancel.ts +138 -38
- package/src/extension/team-tool/chain-dispatch.ts +5 -13
- package/src/extension/team-tool/chain-executor.ts +29 -51
- package/src/extension/team-tool/config-patch.ts +1 -1
- package/src/extension/team-tool/context.ts +40 -20
- package/src/extension/team-tool/destructive-gate.ts +10 -5
- package/src/extension/team-tool/doctor.ts +170 -51
- package/src/extension/team-tool/explain.ts +228 -214
- package/src/extension/team-tool/failure-patterns.ts +3 -9
- package/src/extension/team-tool/goal-wrap.ts +71 -29
- package/src/extension/team-tool/goal.ts +185 -35
- package/src/extension/team-tool/handle-schedule.ts +34 -15
- package/src/extension/team-tool/handle-settings.ts +94 -56
- package/src/extension/team-tool/health-monitor.ts +27 -108
- package/src/extension/team-tool/inspect.ts +42 -9
- package/src/extension/team-tool/intent-policy.ts +4 -1
- package/src/extension/team-tool/lifecycle-actions.ts +244 -48
- package/src/extension/team-tool/orchestrate.ts +7 -18
- package/src/extension/team-tool/parallel-dispatch.ts +51 -29
- package/src/extension/team-tool/plan.ts +29 -5
- package/src/extension/team-tool/respond.ts +49 -16
- package/src/extension/team-tool/run-not-found.ts +3 -8
- package/src/extension/team-tool/run.ts +80 -317
- package/src/extension/team-tool/status.ts +135 -43
- package/src/extension/team-tool/workflow-manage.ts +92 -25
- package/src/extension/team-tool-types.ts +8 -1
- package/src/extension/team-tool.ts +142 -551
- package/src/extension/validate-resources.ts +39 -8
- package/src/hooks/registry.ts +66 -17
- package/src/hooks/types.ts +1 -1
- package/src/i18n.ts +25 -11
- package/src/observability/correlation.ts +17 -3
- package/src/observability/event-bus.ts +51 -56
- package/src/observability/event-to-metric.ts +117 -15
- package/src/observability/exporters/otlp-exporter.ts +56 -17
- package/src/observability/exporters/prometheus-exporter.ts +1 -1
- package/src/observability/metric-registry.ts +16 -4
- package/src/observability/metric-retention.ts +8 -2
- package/src/observability/metric-sink.ts +11 -3
- package/src/observability/metrics-primitives.ts +42 -9
- package/src/plugins/plugin-define.ts +2 -2
- package/src/plugins/plugin-registry.ts +25 -25
- package/src/plugins/plugins/index.ts +1 -1
- package/src/plugins/plugins/nextjs.ts +16 -16
- package/src/plugins/plugins/vite.ts +7 -11
- package/src/plugins/plugins/vitest.ts +6 -11
- package/src/runtime/adaptive-plan.ts +225 -40
- package/src/runtime/agent-control.ts +58 -15
- package/src/runtime/agent-memory.ts +15 -9
- package/src/runtime/agent-observability.ts +10 -2
- package/src/runtime/anchor-manager.ts +27 -25
- package/src/runtime/async-marker.ts +7 -1
- package/src/runtime/async-runner.ts +27 -23
- package/src/runtime/auto-summarize.ts +7 -13
- package/src/runtime/background-runner.ts +189 -251
- package/src/runtime/batch-barrier.ts +18 -16
- package/src/runtime/cancellation-token.ts +16 -6
- package/src/runtime/cancellation.ts +46 -8
- package/src/runtime/capability-inventory.ts +6 -4
- package/src/runtime/chain-parser.ts +44 -11
- package/src/runtime/chain-runner.ts +63 -69
- package/src/runtime/checkpoint.ts +12 -56
- package/src/runtime/child-pi.ts +343 -78
- package/src/runtime/coalesce-tasks.ts +268 -0
- package/src/runtime/code-summary.ts +71 -26
- package/src/runtime/compact-stages/index.ts +15 -5
- package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
- package/src/runtime/compact-stages/truncation-stage.ts +4 -1
- package/src/runtime/compaction-summary.ts +17 -10
- package/src/runtime/completion-guard.ts +33 -16
- package/src/runtime/crash-classification.ts +28 -7
- package/src/runtime/crash-recovery.ts +177 -37
- package/src/runtime/crew-agent-records.ts +193 -40
- package/src/runtime/crew-hooks.ts +9 -24
- package/src/runtime/cross-extension-rpc.ts +25 -23
- package/src/runtime/custom-tools/irc-tool.ts +43 -15
- package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
- package/src/runtime/delivery-coordinator.ts +34 -7
- package/src/runtime/delta-conflict.ts +9 -21
- package/src/runtime/deterministic-ast.ts +1 -1
- package/src/runtime/diagnostic-export.ts +53 -20
- package/src/runtime/direct-run.ts +12 -2
- package/src/runtime/dwf-state-store.ts +1 -1
- package/src/runtime/dynamic-workflow-context.ts +186 -58
- package/src/runtime/dynamic-workflow-runner.ts +42 -20
- package/src/runtime/effectiveness.ts +16 -8
- package/src/runtime/errors/crew-errors.ts +7 -11
- package/src/runtime/event-stream-bridge.ts +9 -3
- package/src/runtime/foreground-control.ts +54 -14
- package/src/runtime/foreground-watchdog.ts +9 -6
- package/src/runtime/goal-achievement.ts +27 -10
- package/src/runtime/goal-evaluator.ts +54 -19
- package/src/runtime/goal-loop-runner.ts +280 -99
- package/src/runtime/goal-state-store.ts +27 -17
- package/src/runtime/green-contract.ts +11 -2
- package/src/runtime/group-join.ts +64 -31
- package/src/runtime/handoff-manager.ts +37 -42
- package/src/runtime/heartbeat-gradient.ts +10 -2
- package/src/runtime/heartbeat-watcher.ts +32 -6
- package/src/runtime/hidden-handoff.ts +12 -30
- package/src/runtime/important-line-classifier.ts +12 -2
- package/src/runtime/iteration-hooks.ts +25 -15
- package/src/runtime/live-agent-control.ts +55 -7
- package/src/runtime/live-agent-manager.ts +130 -27
- package/src/runtime/live-control-realtime.ts +23 -3
- package/src/runtime/live-irc.ts +4 -1
- package/src/runtime/live-session-health.ts +12 -4
- package/src/runtime/live-session-runtime.ts +379 -117
- package/src/runtime/manifest-cache.ts +28 -12
- package/src/runtime/mcp-proxy.ts +8 -16
- package/src/runtime/metric-parser.ts +1 -5
- package/src/runtime/model-fallback.ts +55 -18
- package/src/runtime/model-resolver.ts +2 -6
- package/src/runtime/model-scope.ts +19 -3
- package/src/runtime/notebook-helpers.ts +60 -62
- package/src/runtime/orphan-worker-registry.ts +37 -26
- package/src/runtime/output-validator.ts +18 -3
- package/src/runtime/overflow-recovery.ts +5 -4
- package/src/runtime/parallel-research.ts +29 -5
- package/src/runtime/parallel-utils.ts +9 -11
- package/src/runtime/path-overlap.ts +150 -0
- package/src/runtime/peer-dep.ts +12 -17
- package/src/runtime/per-write-validator.ts +1 -3
- package/src/runtime/phase-tracker.ts +342 -330
- package/src/runtime/pi-args.ts +26 -8
- package/src/runtime/pi-json-output.ts +1 -1
- package/src/runtime/pi-spawn.ts +30 -19
- package/src/runtime/pipeline-runner.ts +56 -55
- package/src/runtime/plan-templates.ts +5 -6
- package/src/runtime/policy-engine.ts +43 -7
- package/src/runtime/post-checks.ts +12 -4
- package/src/runtime/post-exit-stdio-guard.ts +2 -2
- package/src/runtime/process-lifecycle.ts +20 -10
- package/src/runtime/process-status.ts +16 -5
- package/src/runtime/progress-event-coalescer.ts +2 -1
- package/src/runtime/progress-tracker.ts +103 -103
- package/src/runtime/prose-compressor.ts +9 -11
- package/src/runtime/recovery-recipes.ts +118 -24
- package/src/runtime/replace.ts +25 -10
- package/src/runtime/resilient-edit.ts +10 -25
- package/src/runtime/result-extractor.ts +1 -2
- package/src/runtime/retry-executor.ts +20 -4
- package/src/runtime/retry-runner.ts +26 -50
- package/src/runtime/role-permission.ts +6 -1
- package/src/runtime/run-coalesced-task-group.ts +256 -0
- package/src/runtime/run-drift.ts +14 -15
- package/src/runtime/run-tracker.ts +6 -28
- package/src/runtime/runtime-policy.ts +1 -6
- package/src/runtime/runtime-resolver.ts +80 -15
- package/src/runtime/scheduler.ts +47 -18
- package/src/runtime/semaphore.ts +5 -7
- package/src/runtime/sensitive-paths.ts +2 -1
- package/src/runtime/session-usage.ts +1 -1
- package/src/runtime/settings-store.ts +16 -12
- package/src/runtime/sidechain-output.ts +6 -2
- package/src/runtime/single-agent-compose.ts +1 -4
- package/src/runtime/skill-effectiveness.ts +29 -97
- package/src/runtime/skill-instructions.ts +40 -83
- package/src/runtime/stale-reconciler.ts +73 -197
- package/src/runtime/stream-preview.ts +1 -1
- package/src/runtime/streaming-output.ts +1 -1
- package/src/runtime/subagent-manager.ts +86 -169
- package/src/runtime/subprocess-tool-registry.ts +4 -1
- package/src/runtime/supervisor-contact.ts +10 -5
- package/src/runtime/task-display.ts +19 -5
- package/src/runtime/task-graph-scheduler.ts +95 -21
- package/src/runtime/task-graph.ts +5 -11
- package/src/runtime/task-health.ts +54 -47
- package/src/runtime/task-id.ts +11 -18
- package/src/runtime/task-output-context.ts +265 -81
- package/src/runtime/task-packet.ts +12 -20
- package/src/runtime/task-quality.ts +6 -14
- package/src/runtime/task-runner/context-retrieval.ts +4 -13
- package/src/runtime/task-runner/live-executor.ts +114 -36
- package/src/runtime/task-runner/output-splitter.ts +152 -0
- package/src/runtime/task-runner/progress.ts +50 -12
- package/src/runtime/task-runner/prompt-builder.ts +31 -7
- package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
- package/src/runtime/task-runner/result-utils.ts +3 -1
- package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
- package/src/runtime/task-runner/run-projection.ts +27 -8
- package/src/runtime/task-runner/state-helpers.ts +29 -8
- package/src/runtime/task-runner/tail-read.ts +2 -6
- package/src/runtime/task-runner.ts +180 -326
- package/src/runtime/team-runner-artifacts.ts +13 -0
- package/src/runtime/team-runner.ts +456 -974
- package/src/runtime/tool-output-pruner.ts +6 -9
- package/src/runtime/tool-progress.ts +11 -21
- package/src/runtime/verification-gates.ts +33 -24
- package/src/runtime/verification-integrity.ts +1 -4
- package/src/runtime/verification-worktree.ts +62 -12
- package/src/runtime/worker-heartbeat.ts +5 -1
- package/src/runtime/worker-startup.ts +29 -5
- package/src/runtime/workflow-state.ts +17 -9
- package/src/runtime/workspace-lock.ts +30 -35
- package/src/runtime/workspace-tree.ts +20 -32
- package/src/runtime/yield-handler.ts +43 -9
- package/src/runtime/zombie-scanner.ts +5 -4
- package/src/schema/config-schema.ts +266 -172
- package/src/schema/team-tool-schema.ts +29 -74
- package/src/schema/validation-types.ts +25 -17
- package/src/skills/discover-skills.ts +35 -10
- package/src/skills/skill-templates.ts +109 -27
- package/src/skills/validate.ts +26 -8
- package/src/state/active-run-registry.ts +87 -28
- package/src/state/artifact-store.ts +9 -5
- package/src/state/atomic-write-v2.ts +85 -63
- package/src/state/atomic-write.ts +105 -26
- package/src/state/blob-store.ts +47 -20
- package/src/state/contracts.ts +20 -5
- package/src/state/crew-init.ts +5 -22
- package/src/state/decision-ledger.ts +19 -73
- package/src/state/event-log-rotation.ts +41 -15
- package/src/state/event-log.ts +168 -53
- package/src/state/event-reconstructor.ts +11 -1
- package/src/state/gitignore-manager.ts +2 -8
- package/src/state/health-store.ts +57 -57
- package/src/state/hook-instinct-bridge.ts +1 -1
- package/src/state/hook-integrations.ts +1 -1
- package/src/state/instinct-store.ts +17 -5
- package/src/state/jsonl-writer.ts +1 -1
- package/src/state/locks.ts +23 -9
- package/src/state/mailbox.ts +151 -28
- package/src/state/observation-store.ts +20 -14
- package/src/state/run-cache.ts +142 -135
- package/src/state/run-graph.ts +6 -15
- package/src/state/run-metrics.ts +5 -18
- package/src/state/schedule.ts +15 -9
- package/src/state/state-store.ts +129 -45
- package/src/state/task-claims.ts +12 -2
- package/src/state/tiered-eval.ts +52 -43
- package/src/state/types-eval.ts +2 -2
- package/src/state/types.ts +24 -20
- package/src/state/usage.ts +20 -4
- package/src/state/worker-atomic-writer.ts +6 -3
- package/src/subagents/index.ts +2 -2
- package/src/teams/discover-teams.ts +21 -6
- package/src/tools/safe-bash-extension.ts +5 -6
- package/src/tools/safe-bash.ts +10 -11
- package/src/types/new-api-types.ts +6 -10
- package/src/ui/agent-management-overlay.ts +52 -40
- package/src/ui/card-colors.ts +13 -4
- package/src/ui/crew-footer.ts +8 -7
- package/src/ui/crew-select-list.ts +1 -1
- package/src/ui/dashboard-panes/agents-pane.ts +41 -25
- package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
- package/src/ui/dashboard-panes/capability-pane.ts +32 -15
- package/src/ui/dashboard-panes/health-pane.ts +2 -1
- package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
- package/src/ui/dashboard-panes/progress-pane.ts +12 -9
- package/src/ui/heartbeat-aggregator.ts +15 -4
- package/src/ui/keybinding-map.ts +40 -7
- package/src/ui/live-conversation-overlay.ts +36 -20
- package/src/ui/live-duration.ts +1 -4
- package/src/ui/live-run-sidebar.ts +88 -25
- package/src/ui/loaders.ts +2 -8
- package/src/ui/mascot.ts +20 -36
- package/src/ui/overlays/agent-picker-overlay.ts +11 -3
- package/src/ui/overlays/confirm-overlay.ts +4 -2
- package/src/ui/overlays/help-overlay.ts +25 -14
- package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
- package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
- package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
- package/src/ui/pi-ui-compat.ts +7 -7
- package/src/ui/powerbar-publisher.ts +120 -42
- package/src/ui/render-diff.ts +10 -3
- package/src/ui/render-scheduler.ts +12 -4
- package/src/ui/run-action-dispatcher.ts +81 -18
- package/src/ui/run-dashboard.ts +172 -76
- package/src/ui/run-event-bus.ts +59 -37
- package/src/ui/run-snapshot-cache.ts +276 -86
- package/src/ui/settings-overlay.ts +361 -74
- package/src/ui/status-colors.ts +12 -1
- package/src/ui/syntax-highlight.ts +1 -1
- package/src/ui/theme-adapter.ts +16 -14
- package/src/ui/theme-discovery.ts +13 -2
- package/src/ui/tool-progress-formatter.ts +7 -7
- package/src/ui/tool-render.ts +128 -56
- package/src/ui/tool-renderers/brief-mode.ts +45 -27
- package/src/ui/tool-renderers/index.ts +109 -43
- package/src/ui/transcript-cache.ts +32 -6
- package/src/ui/transcript-entries.ts +25 -23
- package/src/ui/transcript-viewer.ts +78 -29
- package/src/ui/widget/index.ts +99 -40
- package/src/ui/widget/widget-formatters.ts +13 -6
- package/src/ui/widget/widget-model.ts +19 -8
- package/src/ui/widget/widget-renderer.ts +23 -13
- package/src/ui/widget/widget-types.ts +1 -1
- package/src/utils/bm25-search.ts +199 -199
- package/src/utils/conflict-detect.ts +22 -21
- package/src/utils/env-filter.ts +14 -7
- package/src/utils/file-coalescer.ts +5 -1
- package/src/utils/fingerprint.ts +3 -6
- package/src/utils/frontmatter.ts +3 -1
- package/src/utils/fs-watch.ts +2 -6
- package/src/utils/gh-protocol.ts +119 -44
- package/src/utils/git.ts +13 -15
- package/src/utils/guards.ts +2 -5
- package/src/utils/ids.ts +9 -2
- package/src/utils/incremental-reader.ts +14 -3
- package/src/utils/internal-error.ts +2 -1
- package/src/utils/names.ts +12 -3
- package/src/utils/paths.ts +49 -5
- package/src/utils/project-detector.ts +2 -2
- package/src/utils/redaction.ts +29 -19
- package/src/utils/resolve-shell.ts +9 -7
- package/src/utils/run-watcher-registry.ts +19 -31
- package/src/utils/safe-paths.ts +45 -24
- package/src/utils/scan-cache.ts +9 -2
- package/src/utils/session-utils.ts +2 -4
- package/src/utils/sleep.ts +12 -5
- package/src/utils/sse-parser.ts +5 -17
- package/src/utils/visual.ts +52 -32
- package/src/workflows/discover-workflows.ts +41 -109
- package/src/workflows/intermediate-store.ts +5 -21
- package/src/workflows/preflight-validator.ts +6 -33
- package/src/workflows/topology-analyzer.ts +5 -21
- package/src/workflows/workflow-config.ts +7 -6
- package/src/worktree/branch-freshness.ts +66 -8
- package/src/worktree/cleanup.ts +130 -20
- package/src/worktree/worktree-manager.ts +212 -69
- package/skills/artifact-analysis-loop/SKILL.md +0 -303
- package/skills/detection-pipeline-design/SKILL.md +0 -286
- package/skills/hunting-investigation-loop/SKILL.md +0 -402
- package/skills/incident-playbook-construction/SKILL.md +0 -384
- package/skills/security-review/SKILL.md +0 -561
- package/skills/threat-hypothesis-framework/SKILL.md +0 -176
- package/skills/ui-render-performance/SKILL.md +0 -58
- /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
- /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
- /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
- /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
- /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
- /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
- /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
- /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
- /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
- /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
- /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
- /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
- /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
- /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
package/src/state/run-cache.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
1
2
|
import * as fs from "node:fs";
|
|
2
3
|
import * as path from "node:path";
|
|
3
|
-
import * as crypto from "node:crypto";
|
|
4
4
|
import { projectCrewRoot } from "../utils/paths.ts";
|
|
5
|
-
import type { TeamTaskState } from "./types.ts";
|
|
6
5
|
import { atomicWriteFile } from "./atomic-write.ts";
|
|
7
6
|
import { withFileLockSync } from "./locks.ts";
|
|
7
|
+
import type { TeamTaskState } from "./types.ts";
|
|
8
8
|
|
|
9
9
|
const DEFAULT_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
10
10
|
|
|
11
11
|
export interface CacheEntry {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
key: string;
|
|
13
|
+
runId: string;
|
|
14
|
+
status: string;
|
|
15
|
+
tasks: TeamTaskState[];
|
|
16
|
+
cachedAt: number;
|
|
17
|
+
expiresAt: number;
|
|
18
|
+
goal: string;
|
|
19
|
+
team: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface CacheIndex {
|
|
23
|
-
|
|
23
|
+
[cacheKey: string]: string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -28,21 +28,15 @@ interface CacheIndex {
|
|
|
28
28
|
* Uses SHA-256 hash of normalized goal + team + workflow.
|
|
29
29
|
*/
|
|
30
30
|
export function computeRunCacheKey(goal: string, team: string, workflow: string, _cwd: string): string {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.update(normalized)
|
|
34
|
-
.update(team)
|
|
35
|
-
.update(workflow)
|
|
36
|
-
.update(_cwd)
|
|
37
|
-
.digest("hex")
|
|
38
|
-
.slice(0, 16);
|
|
31
|
+
const normalized = goal.trim().toLowerCase().replace(/\s+/g, " ");
|
|
32
|
+
return crypto.createHash("sha256").update(normalized).update(team).update(workflow).update(_cwd).digest("hex").slice(0, 16);
|
|
39
33
|
}
|
|
40
34
|
|
|
41
35
|
/**
|
|
42
36
|
* Get the cache directory path.
|
|
43
37
|
*/
|
|
44
38
|
function cacheDir(cwd: string): string {
|
|
45
|
-
|
|
39
|
+
return path.join(projectCrewRoot(cwd), "cache");
|
|
46
40
|
}
|
|
47
41
|
|
|
48
42
|
/**
|
|
@@ -50,137 +44,150 @@ function cacheDir(cwd: string): string {
|
|
|
50
44
|
* Returns null if cache miss or expired.
|
|
51
45
|
*/
|
|
52
46
|
export function getCachedRun(cwd: string, cacheKey: string): CacheEntry | null {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
47
|
+
const dir = cacheDir(cwd);
|
|
48
|
+
const indexPath = path.join(dir, "index.json");
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(indexPath)) return null;
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
|
|
54
|
+
const entryPath = index[cacheKey];
|
|
55
|
+
|
|
56
|
+
if (!entryPath || !fs.existsSync(entryPath)) return null;
|
|
57
|
+
|
|
58
|
+
const entry = JSON.parse(fs.readFileSync(entryPath, "utf-8")) as CacheEntry;
|
|
59
|
+
|
|
60
|
+
if (Date.now() > entry.expiresAt) {
|
|
61
|
+
// Remove expired entry — use lock + atomic write to prevent index corruption
|
|
62
|
+
withFileLockSync(indexPath, () => {
|
|
63
|
+
try {
|
|
64
|
+
fs.unlinkSync(entryPath);
|
|
65
|
+
} catch {
|
|
66
|
+
/* ignore */
|
|
67
|
+
}
|
|
68
|
+
const updatedIndex = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
|
|
69
|
+
delete updatedIndex[cacheKey];
|
|
70
|
+
atomicWriteFile(indexPath, JSON.stringify(updatedIndex));
|
|
71
|
+
});
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return entry;
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
/**
|
|
86
82
|
* Save run result to cache.
|
|
87
83
|
*/
|
|
88
84
|
export function saveRunToCache(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
cwd: string,
|
|
86
|
+
cacheKey: string,
|
|
87
|
+
runId: string,
|
|
88
|
+
status: string,
|
|
89
|
+
tasks: TeamTaskState[],
|
|
90
|
+
goal: string,
|
|
91
|
+
team: string,
|
|
92
|
+
ttlMs: number = DEFAULT_CACHE_TTL_MS,
|
|
97
93
|
): void {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
fs.writeFileSync(tempPath, JSON.stringify(index), "utf-8");
|
|
129
|
-
fs.renameSync(tempPath, indexPath);
|
|
94
|
+
const dir = cacheDir(cwd);
|
|
95
|
+
|
|
96
|
+
if (!fs.existsSync(dir)) {
|
|
97
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const entry: CacheEntry = {
|
|
101
|
+
key: cacheKey,
|
|
102
|
+
runId,
|
|
103
|
+
status,
|
|
104
|
+
tasks,
|
|
105
|
+
cachedAt: Date.now(),
|
|
106
|
+
expiresAt: Date.now() + ttlMs,
|
|
107
|
+
goal,
|
|
108
|
+
team,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const entryPath = path.join(dir, `${cacheKey}.json`);
|
|
112
|
+
fs.writeFileSync(entryPath, JSON.stringify(entry), "utf-8");
|
|
113
|
+
|
|
114
|
+
// Update index with atomic write: write to temp file then rename
|
|
115
|
+
const indexPath = path.join(dir, "index.json");
|
|
116
|
+
const index: CacheIndex = fs.existsSync(indexPath) ? JSON.parse(fs.readFileSync(indexPath, "utf-8")) : {};
|
|
117
|
+
|
|
118
|
+
index[cacheKey] = entryPath;
|
|
119
|
+
|
|
120
|
+
// Atomic write: write to temp file first, then rename
|
|
121
|
+
const tempPath = path.join(dir, "index.json.tmp");
|
|
122
|
+
fs.writeFileSync(tempPath, JSON.stringify(index), "utf-8");
|
|
123
|
+
fs.renameSync(tempPath, indexPath);
|
|
130
124
|
}
|
|
131
125
|
|
|
132
126
|
/**
|
|
133
127
|
* Clear all cache entries.
|
|
134
128
|
*/
|
|
135
129
|
export function clearCache(cwd: string): void {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
130
|
+
const dir = cacheDir(cwd);
|
|
131
|
+
if (!fs.existsSync(dir)) return;
|
|
132
|
+
|
|
133
|
+
const indexPath = path.join(dir, "index.json");
|
|
134
|
+
if (fs.existsSync(indexPath)) {
|
|
135
|
+
try {
|
|
136
|
+
const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
|
|
137
|
+
for (const entryPath of Object.values(index)) {
|
|
138
|
+
try {
|
|
139
|
+
fs.unlinkSync(entryPath);
|
|
140
|
+
} catch {
|
|
141
|
+
/* ignore */
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
fs.unlinkSync(indexPath);
|
|
145
|
+
} catch {
|
|
146
|
+
/* ignore */
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Remove entry files not in index
|
|
151
|
+
const entries = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
try {
|
|
154
|
+
fs.unlinkSync(path.join(dir, entry));
|
|
155
|
+
} catch {
|
|
156
|
+
/* ignore */
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/**
|
|
162
162
|
* Get cache stats.
|
|
163
163
|
*/
|
|
164
|
-
export function getCacheStats(cwd: string): {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
164
|
+
export function getCacheStats(cwd: string): {
|
|
165
|
+
entries: number;
|
|
166
|
+
sizeBytes: number;
|
|
167
|
+
} {
|
|
168
|
+
const dir = cacheDir(cwd);
|
|
169
|
+
if (!fs.existsSync(dir)) return { entries: 0, sizeBytes: 0 };
|
|
170
|
+
|
|
171
|
+
let sizeBytes = 0;
|
|
172
|
+
let entries = 0;
|
|
173
|
+
const indexPath = path.join(dir, "index.json");
|
|
174
|
+
|
|
175
|
+
if (fs.existsSync(indexPath)) {
|
|
176
|
+
try {
|
|
177
|
+
const index = JSON.parse(fs.readFileSync(indexPath, "utf-8")) as CacheIndex;
|
|
178
|
+
entries = Object.keys(index).length;
|
|
179
|
+
for (const entryPath of Object.values(index)) {
|
|
180
|
+
try {
|
|
181
|
+
const stat = fs.statSync(entryPath);
|
|
182
|
+
sizeBytes += stat.size;
|
|
183
|
+
} catch {
|
|
184
|
+
/* ignore */
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} catch {
|
|
188
|
+
/* ignore */
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { entries, sizeBytes };
|
|
186
193
|
}
|
package/src/state/run-graph.ts
CHANGED
|
@@ -40,10 +40,7 @@ export interface RunGraph {
|
|
|
40
40
|
* Build a unified run graph from manifest + tasks.
|
|
41
41
|
* Consolidates state into a single graph JSON for dashboard/API use.
|
|
42
42
|
*/
|
|
43
|
-
export function buildRunGraph(
|
|
44
|
-
manifest: TeamRunManifest,
|
|
45
|
-
tasks: TeamTaskState[],
|
|
46
|
-
): RunGraph {
|
|
43
|
+
export function buildRunGraph(manifest: TeamRunManifest, tasks: TeamTaskState[]): RunGraph {
|
|
47
44
|
const nodes: RunGraphNode[] = [];
|
|
48
45
|
const edges: RunGraphEdge[] = [];
|
|
49
46
|
const nodeIds = new Set<string>();
|
|
@@ -106,12 +103,10 @@ export function buildRunGraph(
|
|
|
106
103
|
layerMap.get(layerName)!.push(`task:${task.id}`);
|
|
107
104
|
}
|
|
108
105
|
|
|
109
|
-
const layers: RunGraphLayer[] = [...layerMap.entries()].map(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}),
|
|
114
|
-
);
|
|
106
|
+
const layers: RunGraphLayer[] = [...layerMap.entries()].map(([name, nodeIdList]) => ({
|
|
107
|
+
name,
|
|
108
|
+
nodeIds: nodeIdList,
|
|
109
|
+
}));
|
|
115
110
|
|
|
116
111
|
return {
|
|
117
112
|
version: "1.0.0",
|
|
@@ -181,11 +176,7 @@ export function listRunGraphs(cwd: string): string[] {
|
|
|
181
176
|
/**
|
|
182
177
|
* Build and save run graph from manifest + tasks.
|
|
183
178
|
*/
|
|
184
|
-
export function buildAndSaveRunGraph(
|
|
185
|
-
manifest: TeamRunManifest,
|
|
186
|
-
tasks: TeamTaskState[],
|
|
187
|
-
cwd: string,
|
|
188
|
-
): string {
|
|
179
|
+
export function buildAndSaveRunGraph(manifest: TeamRunManifest, tasks: TeamTaskState[], cwd: string): string {
|
|
189
180
|
const graph = buildRunGraph(manifest, tasks);
|
|
190
181
|
return saveRunGraph(graph, cwd);
|
|
191
182
|
}
|
package/src/state/run-metrics.ts
CHANGED
|
@@ -37,10 +37,7 @@ function metricsFilePath(cwd: string, runId: string): string {
|
|
|
37
37
|
* Collect metrics for a run by reading its manifest, tasks, and event log.
|
|
38
38
|
* Returns undefined if the run cannot be loaded.
|
|
39
39
|
*/
|
|
40
|
-
export function collectRunMetrics(
|
|
41
|
-
cwd: string,
|
|
42
|
-
runId: string,
|
|
43
|
-
): RunMetrics | undefined {
|
|
40
|
+
export function collectRunMetrics(cwd: string, runId: string): RunMetrics | undefined {
|
|
44
41
|
assertSafePathId("runId", runId);
|
|
45
42
|
const result = loadRunManifestById(cwd, runId); // NOTE: no withRunLock - best-effort only; concurrent writes may cause inconsistency;
|
|
46
43
|
if (!result) return undefined;
|
|
@@ -69,17 +66,11 @@ export function collectRunMetrics(
|
|
|
69
66
|
// Duration: from run createdAt to updatedAt (manifest timestamps), or 0 if unavailable.
|
|
70
67
|
const createdAt = new Date(manifest.createdAt).getTime();
|
|
71
68
|
const updatedAt = new Date(manifest.updatedAt).getTime();
|
|
72
|
-
const durationMs =
|
|
73
|
-
isNaN(createdAt) || isNaN(updatedAt)
|
|
74
|
-
? 0
|
|
75
|
-
: Math.max(0, updatedAt - createdAt);
|
|
69
|
+
const durationMs = isNaN(createdAt) || isNaN(updatedAt) ? 0 : Math.max(0, updatedAt - createdAt);
|
|
76
70
|
|
|
77
71
|
// Consistency score: proportion of tasks that completed successfully among all non-skipped tasks.
|
|
78
72
|
const nonSkippedTasks = tasks.filter((t) => t.status !== "skipped");
|
|
79
|
-
const consistencyScore =
|
|
80
|
-
nonSkippedTasks.length > 0
|
|
81
|
-
? completedCount / nonSkippedTasks.length
|
|
82
|
-
: 1.0;
|
|
73
|
+
const consistencyScore = nonSkippedTasks.length > 0 ? completedCount / nonSkippedTasks.length : 1.0;
|
|
83
74
|
|
|
84
75
|
return {
|
|
85
76
|
runId,
|
|
@@ -108,10 +99,7 @@ export function saveRunMetrics(cwd: string, metrics: RunMetrics): void {
|
|
|
108
99
|
* Load a previously saved metrics snapshot.
|
|
109
100
|
* Returns undefined if the file does not exist or cannot be parsed.
|
|
110
101
|
*/
|
|
111
|
-
export function loadRunMetrics(
|
|
112
|
-
cwd: string,
|
|
113
|
-
runId: string,
|
|
114
|
-
): RunMetrics | undefined {
|
|
102
|
+
export function loadRunMetrics(cwd: string, runId: string): RunMetrics | undefined {
|
|
115
103
|
return readJsonFile<RunMetrics>(metricsFilePath(cwd, runId));
|
|
116
104
|
}
|
|
117
105
|
|
|
@@ -140,8 +128,7 @@ export function getRunMetricsSummary(cwd: string, limit = 25): RunMetrics[] {
|
|
|
140
128
|
|
|
141
129
|
// Sort newest first (by timestamp, then runId as tiebreaker).
|
|
142
130
|
metrics.sort((a, b) => {
|
|
143
|
-
const diff =
|
|
144
|
-
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
|
|
131
|
+
const diff = new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime();
|
|
145
132
|
if (diff !== 0) return diff;
|
|
146
133
|
return b.runId.localeCompare(a.runId);
|
|
147
134
|
});
|
package/src/state/schedule.ts
CHANGED
|
@@ -11,7 +11,7 @@ import * as fs from "node:fs";
|
|
|
11
11
|
import * as path from "node:path";
|
|
12
12
|
import { logInternalError } from "../utils/internal-error.ts";
|
|
13
13
|
|
|
14
|
-
import type {
|
|
14
|
+
import type { ScheduledTask, ScheduleStoreData } from "./types.ts";
|
|
15
15
|
|
|
16
16
|
export type DetectedSchedule =
|
|
17
17
|
| { type: "cron"; normalized: string }
|
|
@@ -34,7 +34,10 @@ export function parseInterval(s: string): number | null {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/** 6-field cron validation ("second minute hour dom month dow"). */
|
|
37
|
-
export function validateCronExpression(expr: string): {
|
|
37
|
+
export function validateCronExpression(expr: string): {
|
|
38
|
+
valid: boolean;
|
|
39
|
+
error?: string;
|
|
40
|
+
} {
|
|
38
41
|
const fields = expr.trim().split(/\s+/);
|
|
39
42
|
if (fields.length !== 6) {
|
|
40
43
|
return {
|
|
@@ -43,8 +46,11 @@ export function validateCronExpression(expr: string): { valid: boolean; error?:
|
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
// Basic format check: all fields must be non-empty
|
|
46
|
-
if (!fields.every(f => f.length > 0)) {
|
|
47
|
-
return {
|
|
49
|
+
if (!fields.every((f) => f.length > 0)) {
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
error: "Cron expression contains empty fields.",
|
|
53
|
+
};
|
|
48
54
|
}
|
|
49
55
|
// Accept any cron pattern — fail silently for malformed expressions
|
|
50
56
|
// (the croner library will reject at execution time)
|
|
@@ -122,11 +128,11 @@ export class ScheduleStore {
|
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
hasName(name: string): boolean {
|
|
125
|
-
return this.data.jobs.some(j => j.name === name);
|
|
131
|
+
return this.data.jobs.some((j) => j.name === name);
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
get(id: string): ScheduledTask | undefined {
|
|
129
|
-
return this.data.jobs.find(j => j.id === id);
|
|
135
|
+
return this.data.jobs.find((j) => j.id === id);
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
add(job: ScheduledTask): void {
|
|
@@ -135,7 +141,7 @@ export class ScheduleStore {
|
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
update(id: string, patch: Partial<ScheduledTask>): ScheduledTask | undefined {
|
|
138
|
-
const idx = this.data.jobs.findIndex(j => j.id === id);
|
|
144
|
+
const idx = this.data.jobs.findIndex((j) => j.id === id);
|
|
139
145
|
if (idx === -1) return undefined;
|
|
140
146
|
this.data.jobs[idx] = { ...this.data.jobs[idx], ...patch };
|
|
141
147
|
this.save();
|
|
@@ -144,11 +150,11 @@ export class ScheduleStore {
|
|
|
144
150
|
|
|
145
151
|
remove(id: string): boolean {
|
|
146
152
|
const before = this.data.jobs.length;
|
|
147
|
-
this.data.jobs = this.data.jobs.filter(j => j.id !== id);
|
|
153
|
+
this.data.jobs = this.data.jobs.filter((j) => j.id !== id);
|
|
148
154
|
if (this.data.jobs.length !== before) {
|
|
149
155
|
this.save();
|
|
150
156
|
return true;
|
|
151
157
|
}
|
|
152
158
|
return false;
|
|
153
159
|
}
|
|
154
|
-
}
|
|
160
|
+
}
|