pi-ui-extend 1.0.40 → 1.0.42
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/README.md +10 -2
- package/dist/app/app.d.ts +3 -0
- package/dist/app/app.js +26 -0
- package/dist/app/commands/command-host.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +6 -1
- package/dist/app/commands/command-registry.js +3 -3
- package/dist/app/commands/command-session-actions.d.ts +0 -1
- package/dist/app/commands/command-session-actions.js +30 -15
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +59 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/icons.d.ts +14 -0
- package/dist/app/icons.js +33 -0
- package/dist/app/rendering/conversation-tool-renderer.js +2 -2
- package/dist/app/rendering/dcp-stats.d.ts +6 -1
- package/dist/app/rendering/dcp-stats.js +214 -46
- package/dist/app/rendering/editor-panels.js +17 -8
- package/dist/app/session/lazy-session-manager.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +1 -0
- package/dist/app/session/session-lifecycle-controller.js +6 -0
- package/dist/app/session/tabs-controller.d.ts +3 -5
- package/dist/app/session/tabs-controller.js +31 -22
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +15 -1
- package/dist/app/subagents/subagents-model.js +52 -17
- package/dist/app/types.d.ts +7 -0
- package/dist/bundled-extensions/session-title/config.js +1 -1
- package/dist/default-pix-config.js +10 -0
- package/dist/markdown-format.js +27 -9
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +106 -71
- package/dist/schemas/pi-tools-suite-schema.js +68 -88
- package/dist/schemas/pix-schema.d.ts +7 -0
- package/dist/schemas/pix-schema.js +14 -0
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +6 -0
- package/docs/desktop-mvp.md +12 -1
- package/docs/desktop-task-manager.md +93 -82
- package/external/pi-tools-suite/README.md +192 -72
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +50 -21
- package/external/pi-tools-suite/docs/context-gateway-p00-adr.md +216 -0
- package/external/pi-tools-suite/docs/context-gateway-p01n-gate-review.md +122 -0
- package/external/pi-tools-suite/docs/context-gateway-p01n-measurement.md +133 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-ra-evidence.md +111 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-rb-evidence.md +100 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-rc-evidence.md +69 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-rd-evidence.md +100 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-re-evidence.md +74 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-rf-evidence.md +153 -0
- package/external/pi-tools-suite/docs/context-gateway-p01r-rg-evidence.md +235 -0
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +40 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +120 -0
- package/external/pi-tools-suite/package.json +3 -0
- package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/scripts/browser-qa-runner.mjs +82 -1
- package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/SKILL.md → agents/browser-qa.md} +261 -12
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +20 -0
- package/external/pi-tools-suite/src/async-subagents/agents/oracle.md +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +20 -0
- package/external/pi-tools-suite/src/async-subagents/agents/verify.md +18 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +20 -72
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +42 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +13 -93
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +499 -0
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +9 -0
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +284 -417
- package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +54 -0
- package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +7 -6
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +65 -45
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +18 -6
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/index.ts +77 -3
- package/external/pi-tools-suite/src/async-subagents/lib.ts +12 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +54 -22
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +6 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +3 -0
- package/external/pi-tools-suite/src/config.ts +42 -2
- package/external/pi-tools-suite/src/context-gateway/accounting.ts +151 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +120 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +102 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +214 -0
- package/external/pi-tools-suite/src/context-gateway/metadata-normalization.ts +88 -0
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +89 -0
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +502 -0
- package/external/pi-tools-suite/src/context-gateway/test-output-parser.ts +326 -0
- package/external/pi-tools-suite/src/context-gateway/types.ts +158 -0
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +106 -0
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +892 -136
- package/external/pi-tools-suite/src/dcp/commands.ts +82 -139
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +533 -74
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +488 -94
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +122 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +70 -0
- package/external/pi-tools-suite/src/dcp/config.ts +86 -68
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +421 -0
- package/external/pi-tools-suite/src/dcp/debug-log.ts +7 -5
- package/external/pi-tools-suite/src/dcp/index.ts +617 -203
- package/external/pi-tools-suite/src/dcp/journal.ts +566 -0
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +244 -0
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -189
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/provider-tool-results.ts +189 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +299 -79
- package/external/pi-tools-suite/src/dcp/pruner-compression-blocks.ts +173 -281
- package/external/pi-tools-suite/src/dcp/pruner-emergency.ts +2 -4
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +23 -15
- package/external/pi-tools-suite/src/dcp/pruner-metadata.ts +11 -1
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +30 -82
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +28 -136
- package/external/pi-tools-suite/src/dcp/pruner.ts +18 -33
- package/external/pi-tools-suite/src/dcp/recovery.ts +129 -0
- package/external/pi-tools-suite/src/dcp/shadow-plan.ts +127 -0
- package/external/pi-tools-suite/src/dcp/state-transaction.ts +102 -0
- package/external/pi-tools-suite/src/dcp/state.ts +158 -580
- package/external/pi-tools-suite/src/dcp/ui.ts +1 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +36 -214
- package/external/pi-tools-suite/src/index.ts +16 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +76 -42
- package/external/pi-tools-suite/src/repo-discovery/index.ts +84 -18
- package/external/pi-tools-suite/src/repo-discovery/native-compact.ts +458 -0
- package/external/pi-tools-suite/src/resource-registry/index.ts +2290 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +189 -43
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/tool-descriptions.ts +41 -38
- package/external/pi-tools-suite/src/truncation-metadata-normalizer/index.ts +17 -0
- package/package.json +6 -3
- package/schemas/pi-tools-suite.json +540 -312
- package/schemas/pix.json +24 -0
- package/schemas/tasks.json +132 -0
- package/skills/spec-wiki/SKILL.md +55 -0
- package/skills/spec-wiki/evals/evals.json +132 -0
- package/skills/spec-wiki/evals/files/bootstrap/architecture/rfc-007.md +14 -0
- package/skills/spec-wiki/evals/files/bootstrap/docs/how-to-pay.md +4 -0
- package/skills/spec-wiki/evals/files/bootstrap/docs/overview.md +9 -0
- package/skills/spec-wiki/evals/files/bootstrap/requirements/payment-behavior.md +17 -0
- package/skills/spec-wiki/evals/files/bootstrap/src/payments.ts +12 -0
- package/skills/spec-wiki/evals/files/bootstrap/tests/payments.test.ts +11 -0
- package/skills/spec-wiki/evals/files/focused/src/session.ts +5 -0
- package/skills/spec-wiki/evals/files/focused/tests/session.test.ts +17 -0
- package/skills/spec-wiki/evals/files/maintenance/low-signal/incoming/capture.txt +2 -0
- package/skills/spec-wiki/evals/files/maintenance/low-signal/src/capture.ts +3 -0
- package/skills/spec-wiki/evals/files/maintenance/move/docs/old-job-contract.md +18 -0
- package/skills/spec-wiki/evals/files/maintenance/move/src/job.ts +5 -0
- package/skills/spec-wiki/evals/files/maintenance/new-relation/docs/session-refresh.md +24 -0
- package/skills/spec-wiki/evals/files/maintenance/new-relation/incoming/refresh-worker.ts +7 -0
- package/skills/spec-wiki/evals/files/maintenance/new-relation/src/session.ts +7 -0
- package/skills/spec-wiki/evals/files/maintenance/no-impact/docs/auth-contract.md +17 -0
- package/skills/spec-wiki/evals/files/maintenance/no-impact/incoming/telemetry-format.ts +3 -0
- package/skills/spec-wiki/evals/files/maintenance/no-impact/src/auth.ts +3 -0
- package/skills/spec-wiki/evals/files/query/docs/how-to-run-jobs.md +4 -0
- package/skills/spec-wiki/evals/files/query/docs/spec-overview.md +9 -0
- package/skills/spec-wiki/evals/files/query/features/jobs/cancellation-contract.md +15 -0
- package/skills/spec-wiki/evals/files/query/features/jobs/retry-spec.md +6 -0
- package/skills/spec-wiki/evals/maintenance_regression.py +311 -0
- package/skills/spec-wiki/evals/retrieval-eval.md +37 -0
- package/skills/spec-wiki/evals/retrieval-evals.json +37 -0
- package/skills/spec-wiki/evals/trigger-evals.json +94 -0
- package/skills/spec-wiki/references/bootstrap.md +100 -0
- package/skills/spec-wiki/references/focused-spec.md +117 -0
- package/skills/spec-wiki/references/index-schema.md +330 -0
- package/skills/spec-wiki/references/maintenance.md +134 -0
- package/skills/spec-wiki/references/query.md +74 -0
- package/skills/spec-wiki/scripts/spec_wiki.py +2076 -0
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -270
- package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/auth-scaffold-spec.md +0 -78
- package/external/pi-tools-suite/src/async-subagents/private-skills/browser-qa/references/qa-design.md +0 -223
- package/external/pi-tools-suite/src/dcp/state-persistence.ts +0 -195
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/{private-skills/browser-qa/references → agents/browser-qa/examples}/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/{private-skills → agents}/browser-qa/vendor/fflate.mjs +0 -0
|
@@ -39,7 +39,7 @@ const TerminalBellConfig = Type.Object({
|
|
|
39
39
|
// ---------------------------------------------------------------------------
|
|
40
40
|
const DcpManualModeConfig = Type.Object({
|
|
41
41
|
enabled: Type.Optional(Type.Boolean({ description: "Enable manual DCP mode." })),
|
|
42
|
-
automaticStrategies: Type.Optional(Type.
|
|
42
|
+
automaticStrategies: Type.Optional(Type.Never({ description: "Removed legacy key. Manual mode now has only the explicit enabled flag." })),
|
|
43
43
|
}, { description: "Manual mode configuration." });
|
|
44
44
|
const DcpAutoCandidatesConfig = Type.Object({
|
|
45
45
|
enabled: Type.Optional(Type.Boolean({ description: "Enable auto candidate selection for compression." })),
|
|
@@ -56,11 +56,17 @@ const DcpMessageModeConfig = Type.Object({
|
|
|
56
56
|
highTokens: Type.Optional(Type.Number({ description: "Token threshold for high-quality summary.", minimum: 0 })),
|
|
57
57
|
maxSuggestions: Type.Optional(Type.Number({ description: "Maximum compression suggestions.", minimum: 0 })),
|
|
58
58
|
}, { description: "Message-mode compression configuration." });
|
|
59
|
+
const DcpAutoCompressConfig = Type.Object({
|
|
60
|
+
enabled: Type.Optional(Type.Boolean({ description: "Allow autonomous compression after pressure/opportunity gates. Explicit compress calls can still use summarizerModel when summary is omitted." })),
|
|
61
|
+
patience: Type.Optional(Type.Number({ description: "Completed actionable opportunities allowed before automatic compression.", minimum: 0 })),
|
|
62
|
+
summarizerModel: Type.Optional(Type.Array(Type.String(), { description: "Ordered model refs used by auto-compress and explicit compress when summary is omitted; empty uses the deterministic extractive summary." })),
|
|
63
|
+
timeoutMs: Type.Optional(Type.Number({ description: "Per-summarizer deadline in milliseconds for automatic and explicit generated summaries.", minimum: 1 })),
|
|
64
|
+
}, { description: "Bounded automatic compression fallback." });
|
|
59
65
|
const DcpCompressConfig = Type.Object({
|
|
60
66
|
maxContextPercent: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: "Maximum context percent (0–1 or '80%') before compression triggers." })),
|
|
61
67
|
minContextPercent: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: "Target context percent after compression." })),
|
|
62
|
-
modelMaxContextPercent: Type.Optional(Type.Record(Type.String(), Type.Number(), { description: "Per-model max context percent
|
|
63
|
-
modelMinContextPercent: Type.Optional(Type.Record(Type.String(), Type.Number(), { description: "Per-model min context percent
|
|
68
|
+
modelMaxContextPercent: Type.Optional(Type.Record(Type.String(), Type.Union([Type.Number(), Type.String()]), { description: "Per-model max context overrides using the same fraction/token/percent formats." })),
|
|
69
|
+
modelMinContextPercent: Type.Optional(Type.Record(Type.String(), Type.Union([Type.Number(), Type.String()]), { description: "Per-model min context overrides using the same fraction/token/percent formats." })),
|
|
64
70
|
maxContextLimit: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: "Absolute max context tokens or '200k'." })),
|
|
65
71
|
minContextLimit: Type.Optional(Type.Union([Type.Number(), Type.String()], { description: "Absolute min context tokens." })),
|
|
66
72
|
modelMaxContextLimits: Type.Optional(Type.Record(Type.String(), Type.Union([Type.Number(), Type.String()]), { description: "Per-model max context limit overrides." })),
|
|
@@ -74,29 +80,37 @@ const DcpCompressConfig = Type.Object({
|
|
|
74
80
|
protectUserMessages: Type.Optional(Type.Boolean({ description: "Protect user messages from pruning." })),
|
|
75
81
|
autoCandidates: Type.Optional(DcpAutoCandidatesConfig),
|
|
76
82
|
messageMode: Type.Optional(DcpMessageModeConfig),
|
|
83
|
+
autoCompress: Type.Optional(DcpAutoCompressConfig),
|
|
77
84
|
}, { description: "Compression trigger and behavior configuration." });
|
|
78
|
-
const
|
|
79
|
-
enabled: Type.Optional(Type.Boolean({ description: "Enable
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
enabled: Type.Optional(Type.Boolean({ description: "Enable automatic tool output pruning." })),
|
|
89
|
-
maxOutputTokens: Type.Optional(Type.Number({ description: "Maximum output tokens before truncation.", minimum: 0 })),
|
|
90
|
-
keepRecentTurns: Type.Optional(Type.Number({ description: "Recent turns to keep.", minimum: 0 })),
|
|
91
|
-
readLikeTools: Type.Optional(Type.Array(Type.String(), { description: "Tools treated as read-like (aggressively pruned)." })),
|
|
92
|
-
readLikeTurns: Type.Optional(Type.Number({ description: "Turns threshold for read-like tool pruning.", minimum: 0 })),
|
|
93
|
-
protectedTools: Type.Optional(Type.Array(Type.String(), { description: "Tool outputs protected from auto-pruning." })),
|
|
94
|
-
}, { description: "Auto tool pruning strategy configuration." });
|
|
85
|
+
const DcpEmergencyCurrentTurnPruningConfig = Type.Object({
|
|
86
|
+
enabled: Type.Optional(Type.Boolean({ description: "Enable bounded same-turn emergency planning and last-resort output pruning." })),
|
|
87
|
+
hardContextPercent: Type.Optional(Type.Number({ description: "Context fraction that activates hard emergency pressure.", minimum: 0, maximum: 1 })),
|
|
88
|
+
targetContextPercent: Type.Optional(Type.Number({ description: "Context fraction the emergency path attempts to recover toward.", minimum: 0, maximum: 1 })),
|
|
89
|
+
patience: Type.Optional(Type.Number({ description: "Completed emergency opportunities allowed before last-resort pruning.", minimum: 0 })),
|
|
90
|
+
keepRecentToolPairs: Type.Optional(Type.Number({ description: "Newest complete tool-call/result pairs never selected by emergency cleanup.", minimum: 0 })),
|
|
91
|
+
minOutputTokens: Type.Optional(Type.Number({ description: "Minimum tool-result size eligible for emergency pruning.", minimum: 0 })),
|
|
92
|
+
maxSuggestions: Type.Optional(Type.Number({ description: "Maximum emergency message candidates shown in a reminder.", minimum: 0 })),
|
|
93
|
+
protectedTools: Type.Optional(Type.Array(Type.String(), { description: "Additional tools protected from emergency pruning and manual sweep." })),
|
|
94
|
+
}, { description: "Single bounded emergency cleanup strategy." });
|
|
95
95
|
const DcpStrategiesConfig = Type.Object({
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
emergencyCurrentTurnPruning: Type.Optional(DcpEmergencyCurrentTurnPruningConfig),
|
|
97
|
+
deduplication: Type.Optional(Type.Never({ description: "Removed legacy key; no automatic replacement policy maps to it." })),
|
|
98
|
+
purgeErrors: Type.Optional(Type.Never({ description: "Removed legacy key; no automatic replacement policy maps to it." })),
|
|
99
|
+
autoToolPruning: Type.Optional(Type.Never({ description: "Removed legacy key. Use explicit /dcp sweep or DCP compression/emergency policies instead." })),
|
|
100
|
+
}, { description: "Bounded DCP emergency strategy." });
|
|
101
|
+
const DcpConfigOverride = Type.Object({
|
|
102
|
+
enabled: Type.Optional(Type.Boolean()),
|
|
103
|
+
debug: Type.Optional(Type.Boolean()),
|
|
104
|
+
debugLog: Type.Optional(Type.Object({
|
|
105
|
+
maxBytes: Type.Optional(Type.Number({ minimum: 1024 })),
|
|
106
|
+
maxBackups: Type.Optional(Type.Number({ minimum: 1 })),
|
|
107
|
+
})),
|
|
108
|
+
manualMode: Type.Optional(DcpManualModeConfig),
|
|
109
|
+
compress: Type.Optional(DcpCompressConfig),
|
|
110
|
+
strategies: Type.Optional(DcpStrategiesConfig),
|
|
111
|
+
protectedFilePatterns: Type.Optional(Type.Array(Type.String())),
|
|
112
|
+
pruneNotification: Type.Optional(Type.Never({ description: "Removed legacy key; pruning notifications are no longer configurable." })),
|
|
113
|
+
}, { description: "Partial DCP override applied to a matching provider/model or bare-model key. Keys support * and ? wildcards." });
|
|
100
114
|
const DcpConfig = Type.Object({
|
|
101
115
|
enabled: Type.Optional(Type.Boolean({ description: "Enable DCP (Dynamic Context Pruning)." })),
|
|
102
116
|
debug: Type.Optional(Type.Boolean({ description: "Enable DCP debug logging." })),
|
|
@@ -108,71 +122,10 @@ const DcpConfig = Type.Object({
|
|
|
108
122
|
compress: Type.Optional(DcpCompressConfig),
|
|
109
123
|
strategies: Type.Optional(DcpStrategiesConfig),
|
|
110
124
|
protectedFilePatterns: Type.Optional(Type.Array(Type.String(), { description: "File path glob patterns whose content is protected from pruning." })),
|
|
111
|
-
|
|
125
|
+
modelOverrides: Type.Optional(Type.Record(Type.String(), DcpConfigOverride, { description: "Per-model partial DCP overrides. Exact keys take precedence over matching wildcards." })),
|
|
126
|
+
pruneNotification: Type.Optional(Type.Never({ description: "Removed legacy key; pruning notifications are no longer configurable." })),
|
|
112
127
|
}, { description: "DCP (Dynamic Context Pruning) configuration." });
|
|
113
128
|
// ---------------------------------------------------------------------------
|
|
114
|
-
// Async subagents
|
|
115
|
-
// ---------------------------------------------------------------------------
|
|
116
|
-
const RetryConfig = Type.Object({
|
|
117
|
-
maxRetries: Type.Optional(Type.Number({ description: "Maximum retry attempts.", minimum: 0 })),
|
|
118
|
-
backoffMs: Type.Optional(Type.Number({ description: "Base delay in ms before first retry.", minimum: 0 })),
|
|
119
|
-
retryableExitCodes: Type.Optional(Type.Array(Type.Number(), { description: "Exit codes eligible for retry. Empty array disables retry." })),
|
|
120
|
-
}, { description: "Retry configuration for sub-agents." });
|
|
121
|
-
const SubagentRoutingConfig = Type.Object({
|
|
122
|
-
enabled: Type.Optional(Type.Boolean({ description: "Enable LLM-based automatic role routing." })),
|
|
123
|
-
model: Type.Optional(Type.String({ description: "Router model in provider/model form." })),
|
|
124
|
-
fallbackModels: Type.Optional(Type.Array(Type.String(), { uniqueItems: true, description: "Ordered router model fallbacks tried when the primary routing model is unavailable or fails. The current parent model is always tried last." })),
|
|
125
|
-
maxTaskChars: Type.Optional(Type.Number({ description: "Max task/scope characters sent to router.", minimum: 100 })),
|
|
126
|
-
maxTokens: Type.Optional(Type.Number({ description: "Max router response tokens.", minimum: 8 })),
|
|
127
|
-
maxRetries: Type.Optional(Type.Number({ description: "Router request retries.", minimum: 0 })),
|
|
128
|
-
timeoutMs: Type.Optional(Type.Number({ description: "Router request timeout in ms.", minimum: 1000 })),
|
|
129
|
-
debug: Type.Optional(Type.Boolean({ description: "Show routing debug warnings." })),
|
|
130
|
-
}, { description: "LLM-based role routing configuration." });
|
|
131
|
-
const SubagentVisionConfig = Type.Object({
|
|
132
|
-
blindModelPatterns: Type.Optional(Type.Array(Type.String(), { description: "Glob-like model refs treated as unable to inspect images." })),
|
|
133
|
-
}, { description: "Vision capability overrides." });
|
|
134
|
-
const SubagentPresetTypeOverride = Type.Object({
|
|
135
|
-
model: Type.Optional(Type.String({ description: "Model override for this type within the preset." })),
|
|
136
|
-
fallbackModels: Type.Optional(Type.Array(Type.String(), { description: "Per-role fallback models." })),
|
|
137
|
-
thinking: Type.Optional(Type.String({ description: "Thinking level override." })),
|
|
138
|
-
extraArgs: Type.Optional(Type.Array(Type.String(), { description: "Extra CLI arguments." })),
|
|
139
|
-
timeoutMs: Type.Optional(Type.Number({ description: "Per-agent wall-clock timeout in ms.", minimum: 1 })),
|
|
140
|
-
}, { description: "Per-type override within a preset." });
|
|
141
|
-
const SubagentPreset = Type.Object({
|
|
142
|
-
description: Type.Optional(Type.String({ description: "Preset description." })),
|
|
143
|
-
model: Type.Optional(Type.String({ description: "Default model for this preset." })),
|
|
144
|
-
fallbackModels: Type.Optional(Type.Array(Type.String(), { description: "Global fallback models for this preset." })),
|
|
145
|
-
thinking: Type.Optional(Type.String({ description: "Default thinking level." })),
|
|
146
|
-
extraArgs: Type.Optional(Type.Array(Type.String(), { description: "Extra CLI arguments." })),
|
|
147
|
-
timeoutMs: Type.Optional(Type.Number({ description: "Per-agent wall-clock timeout in ms.", minimum: 1 })),
|
|
148
|
-
types: Type.Optional(Type.Record(Type.String(), SubagentPresetTypeOverride, { description: "Per-type overrides." })),
|
|
149
|
-
}, { description: "Named spawn preset." });
|
|
150
|
-
const SubagentTypeConfig = Type.Object({
|
|
151
|
-
description: Type.Optional(Type.String({ description: "Role description for routing." })),
|
|
152
|
-
model: Type.Optional(Type.String({ description: "Model for this sub-agent type." })),
|
|
153
|
-
fallbackModels: Type.Optional(Type.Array(Type.String(), { description: "Ordered model fallbacks." })),
|
|
154
|
-
thinking: Type.Optional(Type.String({ description: "Thinking level." })),
|
|
155
|
-
tools: Type.Optional(Type.Array(Type.String(), { description: "Enabled tools for this type." })),
|
|
156
|
-
isolatedSkills: Type.Optional(Type.Array(Type.String(), { description: "Explicit skill files loaded after disabling normal skill discovery for this type." })),
|
|
157
|
-
extraArgs: Type.Optional(Type.Array(Type.String(), { description: "Extra CLI arguments." })),
|
|
158
|
-
promptAppend: Type.Optional(Type.String({ description: "Extra prompt text appended after generated prompt." })),
|
|
159
|
-
promptOverride: Type.Optional(Type.String({ description: "Full prompt replacement." })),
|
|
160
|
-
retry: Type.Optional(RetryConfig),
|
|
161
|
-
maxResultBytes: Type.Optional(Type.Number({ description: "Max bytes in result summary.", minimum: 0 })),
|
|
162
|
-
timeoutMs: Type.Optional(Type.Number({ description: "Per-agent wall-clock timeout in ms.", minimum: 1 })),
|
|
163
|
-
}, { description: "Configuration for a sub-agent type/role." });
|
|
164
|
-
const AsyncSubagentsConfig = Type.Object({
|
|
165
|
-
defaultType: Type.Optional(Type.String({ description: "Default sub-agent type when not specified." })),
|
|
166
|
-
routing: Type.Optional(SubagentRoutingConfig),
|
|
167
|
-
vision: Type.Optional(SubagentVisionConfig),
|
|
168
|
-
presets: Type.Optional(Type.Record(Type.String(), SubagentPreset, { description: "Named spawn presets." })),
|
|
169
|
-
types: Type.Optional(Type.Record(Type.String(), SubagentTypeConfig, { description: "Sub-agent type definitions." })),
|
|
170
|
-
maxConcurrent: Type.Optional(Type.Number({ description: "Max concurrent agents per spawn batch (0 = unlimited).", minimum: 0 })),
|
|
171
|
-
retry: Type.Optional(RetryConfig),
|
|
172
|
-
maxResultBytes: Type.Optional(Type.Number({ description: "Global max bytes in result summary.", minimum: 0 })),
|
|
173
|
-
timeoutMs: Type.Optional(Type.Number({ description: "Global per-agent wall-clock timeout in ms.", minimum: 1 })),
|
|
174
|
-
}, { description: "Async sub-agent configuration." });
|
|
175
|
-
// ---------------------------------------------------------------------------
|
|
176
129
|
// Prompt commands
|
|
177
130
|
// ---------------------------------------------------------------------------
|
|
178
131
|
const PromptCommand = Type.Object({
|
|
@@ -186,6 +139,29 @@ const SecretFirewallConfig = Type.Object({
|
|
|
186
139
|
sessionHygiene: Type.Optional(Type.Boolean({ description: "Redact detected secret material from tool results and completed messages before it remains in session history." })),
|
|
187
140
|
notify: Type.Optional(Type.Boolean({ description: "Show a warning when one or more secrets are redacted. Secret values are never included in notifications." })),
|
|
188
141
|
}, { description: "Settings for the opt-in credential-firewall module." });
|
|
142
|
+
const CommentCheckerConfig = Type.Object({
|
|
143
|
+
enabled: Type.Optional(Type.Boolean({ description: "Enable or disable comment-checker without disabling the whole module." })),
|
|
144
|
+
strictness: Type.Optional(Type.Union([Type.Literal("conservative"), Type.Literal("balanced"), Type.Literal("aggressive")], { description: "Comment classification strictness. Defaults to balanced." })),
|
|
145
|
+
}, { description: "Settings for the comment-checker module." });
|
|
146
|
+
const ContextGatewayBudgetsConfig = Type.Object({
|
|
147
|
+
maxInlineBytes: Type.Optional(Type.Integer({ minimum: 1, maximum: 67108864, description: "Maximum inline size for a proven compact representation. Default 8192." })),
|
|
148
|
+
maxResultBytes: Type.Optional(Type.Integer({ minimum: 1, maximum: 67108864, description: "Budget for shell/other result classes. Selective enforce currently compacts only recognised complete simple test/build output. Default 8192." })),
|
|
149
|
+
maxExactReadBytes: Type.Optional(Type.Integer({ minimum: 1, maximum: 67108864, description: "Read-class observation budget. Reads remain passthrough because snapshot-safe recovery is not available. Default 32768." })),
|
|
150
|
+
maxSearchBytes: Type.Optional(Type.Integer({ minimum: 1, maximum: 67108864, description: "Repo-search/AST/structure observation budget. Gateway does not post-hoc truncate producer output. Default 8192." })),
|
|
151
|
+
maxSearchMatches: Type.Optional(Type.Integer({ minimum: 1, maximum: 1000, description: "Reserved search-match policy budget. Default 12." })),
|
|
152
|
+
}, { description: "Context Gateway class-specific observation and selective-enforcement budgets." });
|
|
153
|
+
const ContextGatewayConfig = Type.Object({
|
|
154
|
+
mode: Type.Optional(Type.Union([Type.Literal("off"), Type.Literal("observe"), Type.Literal("enforce")], { description: "Context Gateway mode. observe is passive; enforce only compacts proven complete simple test/build output and otherwise passes results through." })),
|
|
155
|
+
budgets: Type.Optional(ContextGatewayBudgetsConfig),
|
|
156
|
+
}, { description: "Context Gateway configuration. Default mode is off." });
|
|
157
|
+
const RepoDiscoveryConfig = Type.Object({
|
|
158
|
+
profile: Type.Optional(Type.Union([Type.Literal("baseline"), Type.Literal("native-compact")], { description: "repo_* runtime profile. baseline preserves historical argv/defaults; native-compact enables bounded native flags, cursors, validation, and an explicit per-call full override." })),
|
|
159
|
+
}, { description: "Repository discovery runtime policy. Default profile is baseline." });
|
|
160
|
+
const ResourceRegistryConfig = Type.Object({
|
|
161
|
+
remote: Type.Optional(Type.String({ description: "Git remote URL for the private registry. The repository contains reusable top-level skills/ and agents/ plus project-scoped state under projects/." })),
|
|
162
|
+
branch: Type.Optional(Type.String({ description: "Registry branch used for install/update/push/pull. Defaults to main." })),
|
|
163
|
+
projectKey: Type.Optional(Type.String({ description: "Optional explicit key for this project's projects/<key>/tasks.jsonc, plans/, and TODO.md state. Normally derived from the current Git origin." })),
|
|
164
|
+
}, { description: "Private Git-backed registry for reusable skills/agents and project-scoped tasks/plans state." });
|
|
189
165
|
// ---------------------------------------------------------------------------
|
|
190
166
|
// LSP
|
|
191
167
|
// ---------------------------------------------------------------------------
|
|
@@ -234,12 +210,16 @@ export const PiToolsSuiteConfigSchema = Type.Object({
|
|
|
234
210
|
]), { description: "Force per-todo thinking for matching provider/model or bare-model keys. Keys support * and ? wildcards; null removes an inherited override." })),
|
|
235
211
|
lookupModel: Type.Optional(Type.Union([Type.String(), Type.Null()], { description: "Vision-capable provider/model used by GLM's lookup tool; unset or null disables lookup." })),
|
|
236
212
|
terminalBell: Type.Optional(TerminalBellConfig),
|
|
213
|
+
commentChecker: Type.Optional(CommentCheckerConfig),
|
|
237
214
|
dcp: Type.Optional(DcpConfig),
|
|
238
|
-
asyncSubagents: Type.Optional(AsyncSubagentsConfig),
|
|
239
215
|
toolRenderer: Type.Optional(ToolRendererConfig),
|
|
240
216
|
promptCommands: Type.Optional(PromptCommandsConfig),
|
|
241
217
|
secretFirewall: Type.Optional(SecretFirewallConfig),
|
|
218
|
+
contextGateway: Type.Optional(ContextGatewayConfig),
|
|
219
|
+
repoDiscovery: Type.Optional(RepoDiscoveryConfig),
|
|
220
|
+
resourceRegistry: Type.Optional(ResourceRegistryConfig),
|
|
242
221
|
lsp: Type.Optional(LspConfig),
|
|
222
|
+
asyncSubagents: Type.Optional(Type.Never({ description: "Removed legacy key. Configure sub-agents in .pi/agents/*.md and model pools in .pi/agents/presets.jsonc." })),
|
|
243
223
|
}, {
|
|
244
224
|
$id: "https://unpkg.com/pi-ui-extend/schemas/pi-tools-suite.json",
|
|
245
225
|
$schema: "https://json-schema.org/draft-07/schema#",
|
|
@@ -64,5 +64,12 @@ export declare const PixConfigSchema: Type.TObject<{
|
|
|
64
64
|
label: Type.TString;
|
|
65
65
|
}>>>;
|
|
66
66
|
}>>;
|
|
67
|
+
desktop: Type.TOptional<Type.TObject<{
|
|
68
|
+
externalEditor: Type.TOptional<Type.TString>;
|
|
69
|
+
git: Type.TOptional<Type.TObject<{
|
|
70
|
+
reviewModelRef: Type.TOptional<Type.TString>;
|
|
71
|
+
commitMessageModelRef: Type.TOptional<Type.TString>;
|
|
72
|
+
}>>;
|
|
73
|
+
}>>;
|
|
67
74
|
}>;
|
|
68
75
|
export type PixConfigSchemaType = Static<typeof PixConfigSchema>;
|
|
@@ -69,6 +69,19 @@ const DictationConfig = Type.Object({
|
|
|
69
69
|
language: Type.Optional(Type.String({ description: "Selected language code, e.g. 'en' or 'ru'." })),
|
|
70
70
|
languages: Type.Optional(Type.Record(Type.String(), DictationLanguageModelConfig, { description: "Available language models keyed by language code." })),
|
|
71
71
|
}, { description: "Voice dictation (Vosk) configuration." });
|
|
72
|
+
const DesktopConfig = Type.Object({
|
|
73
|
+
externalEditor: Type.Optional(Type.String({
|
|
74
|
+
description: "External editor used by Pix Desktop project explorer. Known aliases include zed, code/vscode, cursor, subl/sublime, idea/intellij, and webstorm; an executable path/name is also accepted.",
|
|
75
|
+
})),
|
|
76
|
+
git: Type.Optional(Type.Object({
|
|
77
|
+
reviewModelRef: Type.Optional(Type.String({
|
|
78
|
+
description: "Model reference used by Pix Desktop for LLM review of Git diffs, optionally with a :thinking suffix.",
|
|
79
|
+
})),
|
|
80
|
+
commitMessageModelRef: Type.Optional(Type.String({
|
|
81
|
+
description: "Model reference used by Pix Desktop to generate Git commit messages, optionally with a :thinking suffix.",
|
|
82
|
+
})),
|
|
83
|
+
}, { description: "Pix Desktop Git/Source Control LLM preferences." })),
|
|
84
|
+
}, { description: "Pix Desktop-specific preferences." });
|
|
72
85
|
// ---------------------------------------------------------------------------
|
|
73
86
|
// Top-level schema
|
|
74
87
|
// ---------------------------------------------------------------------------
|
|
@@ -85,6 +98,7 @@ export const PixConfigSchema = Type.Object({
|
|
|
85
98
|
modelColors: Type.Optional(ModelColorsConfig),
|
|
86
99
|
iconTheme: Type.Optional(IconThemeConfig),
|
|
87
100
|
dictation: Type.Optional(DictationConfig),
|
|
101
|
+
desktop: Type.Optional(DesktopConfig),
|
|
88
102
|
}, {
|
|
89
103
|
$id: "https://unpkg.com/pi-ui-extend/schemas/pix.json",
|
|
90
104
|
$schema: "https://json-schema.org/draft-07/schema#",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** JSON Schema for project-scoped Desktop tasks stored in <cwd>/.pi/tasks.jsonc. */
|
|
2
|
+
import { Static, Type } from "typebox";
|
|
3
|
+
export declare const ProjectTasksSchema: Type.TObject<{
|
|
4
|
+
$schema: Type.TOptional<Type.TString>;
|
|
5
|
+
version: Type.TLiteral<1>;
|
|
6
|
+
tasks: Type.TArray<Type.TObject<{
|
|
7
|
+
id: Type.TString;
|
|
8
|
+
title: Type.TString;
|
|
9
|
+
description: Type.TOptional<Type.TString>;
|
|
10
|
+
type: Type.TUnion<[Type.TLiteral<"bug">, Type.TLiteral<"feature">, Type.TLiteral<"improvement">]>;
|
|
11
|
+
status: Type.TUnion<[Type.TLiteral<"backlog">, Type.TLiteral<"todo">, Type.TLiteral<"in-progress">, Type.TLiteral<"done">]>;
|
|
12
|
+
priority: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"urgent">]>;
|
|
13
|
+
sessionId: Type.TOptional<Type.TString>;
|
|
14
|
+
createdAt: Type.TString;
|
|
15
|
+
updatedAt: Type.TString;
|
|
16
|
+
}>>;
|
|
17
|
+
}>;
|
|
18
|
+
export type ProjectTasksSchemaType = Static<typeof ProjectTasksSchema>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** JSON Schema for project-scoped Desktop tasks stored in <cwd>/.pi/tasks.jsonc. */
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
const TaskType = Type.Union([
|
|
4
|
+
Type.Literal("bug"),
|
|
5
|
+
Type.Literal("feature"),
|
|
6
|
+
Type.Literal("improvement"),
|
|
7
|
+
]);
|
|
8
|
+
const TaskStatus = Type.Union([
|
|
9
|
+
Type.Literal("backlog"),
|
|
10
|
+
Type.Literal("todo"),
|
|
11
|
+
Type.Literal("in-progress"),
|
|
12
|
+
Type.Literal("done"),
|
|
13
|
+
]);
|
|
14
|
+
const TaskPriority = Type.Union([
|
|
15
|
+
Type.Literal("low"),
|
|
16
|
+
Type.Literal("medium"),
|
|
17
|
+
Type.Literal("high"),
|
|
18
|
+
Type.Literal("urgent"),
|
|
19
|
+
]);
|
|
20
|
+
const ProjectTask = Type.Object({
|
|
21
|
+
id: Type.String({ minLength: 1, maxLength: 128, description: "Stable unique task id." }),
|
|
22
|
+
title: Type.String({ minLength: 1, maxLength: 200, description: "Short task title." }),
|
|
23
|
+
description: Type.Optional(Type.String({ maxLength: 10_000, description: "Optional detailed task description." })),
|
|
24
|
+
type: TaskType,
|
|
25
|
+
status: TaskStatus,
|
|
26
|
+
priority: TaskPriority,
|
|
27
|
+
sessionId: Type.Optional(Type.String({ minLength: 1, maxLength: 512, description: "Optional Pi session associated with this task." })),
|
|
28
|
+
createdAt: Type.String({ format: "date-time", description: "RFC 3339 creation timestamp." }),
|
|
29
|
+
updatedAt: Type.String({ format: "date-time", description: "RFC 3339 last-update timestamp." }),
|
|
30
|
+
}, { additionalProperties: false });
|
|
31
|
+
export const ProjectTasksSchema = Type.Object({
|
|
32
|
+
$schema: Type.Optional(Type.String({ description: "JSON Schema URL used by editors for validation and autocomplete." })),
|
|
33
|
+
version: Type.Literal(1, { description: "Task document format version." }),
|
|
34
|
+
tasks: Type.Array(ProjectTask, { maxItems: 10_000, description: "Project tasks. Task ids must be unique." }),
|
|
35
|
+
}, {
|
|
36
|
+
$id: "https://unpkg.com/pi-ui-extend/schemas/tasks.json",
|
|
37
|
+
$schema: "https://json-schema.org/draft-07/schema#",
|
|
38
|
+
title: "Pix Project Tasks",
|
|
39
|
+
description: "Project-scoped task document stored in <cwd>/.pi/tasks.jsonc.",
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
});
|
package/docs/concurrency.md
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# Spec: Application concurrency and lifecycle safety
|
|
2
2
|
|
|
3
|
+
<!-- markdownlint-disable MD013 -->
|
|
4
|
+
|
|
3
5
|
## Type
|
|
4
6
|
|
|
5
7
|
Change
|
|
6
8
|
|
|
9
|
+
## Lifecycle
|
|
10
|
+
|
|
11
|
+
Active implemented contract.
|
|
12
|
+
|
|
7
13
|
## Goal
|
|
8
14
|
|
|
9
15
|
Keep tab, session, editor, extension UI, persistence, and shutdown work bound to
|
package/docs/desktop-mvp.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
Change
|
|
6
6
|
|
|
7
|
+
## Lifecycle
|
|
8
|
+
|
|
9
|
+
Historical baseline. This document records the first Desktop vertical slice and
|
|
10
|
+
still contains useful process-host/ACP transport contracts, but it is no longer
|
|
11
|
+
the current feature-scope inventory. Later implemented Desktop behavior is
|
|
12
|
+
specified by the `specs/desktop-*.md` family.
|
|
13
|
+
|
|
7
14
|
## Goal
|
|
8
15
|
|
|
9
16
|
Provide a lightweight desktop client for Pix using Tauri 2 and Svelte 5 +
|
|
@@ -21,7 +28,11 @@ updates, cancel a running turn, and answer extension elicitations.
|
|
|
21
28
|
elicitations.
|
|
22
29
|
- Development commands and a documented local setup path.
|
|
23
30
|
|
|
24
|
-
##
|
|
31
|
+
## MVP-era non-goals
|
|
32
|
+
|
|
33
|
+
The items below were intentionally out of scope for the first slice. Several
|
|
34
|
+
were implemented later and are governed by newer feature specs; they are not
|
|
35
|
+
current product non-goals.
|
|
25
36
|
|
|
26
37
|
- Feature parity with `PiUiExtendApp`.
|
|
27
38
|
- Voice input, an embedded terminal, custom widgets, image attachments,
|
|
@@ -2,123 +2,134 @@
|
|
|
2
2
|
|
|
3
3
|
## Type
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
As-is
|
|
6
|
+
|
|
7
|
+
## Lifecycle
|
|
8
|
+
|
|
9
|
+
Active current contract.
|
|
6
10
|
|
|
7
11
|
## Goal
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
Provide a project-scoped task list in Pix Desktop and let a saved task start or
|
|
14
|
+
reopen work in a Desktop session without conflating project tasks with the
|
|
15
|
+
agent's session-local todo list.
|
|
11
16
|
|
|
12
17
|
## Scope
|
|
13
18
|
|
|
14
19
|
- A collapsible, resizable left sidebar with `Tasks` and `Project` tabs.
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
- Task type (`bug`, `feature`, `improvement`)
|
|
18
|
-
`in-progress`, `done`)
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
20
|
+
- Create, edit, delete, manual status changes, drag reordering, and moving tasks
|
|
21
|
+
between type groups.
|
|
22
|
+
- Task type (`bug`, `feature`, `improvement`) and status (`backlog`, `todo`,
|
|
23
|
+
`in-progress`, `done`).
|
|
24
|
+
- Persisted priority (`low`, `medium`, `high`, `urgent`). New tasks currently
|
|
25
|
+
receive `medium`; priority is not exposed by the current task editor or rows.
|
|
26
|
+
- Project-local persistence in `.pi/tasks.jsonc` with a versioned schema.
|
|
27
|
+
- One-time migration from the legacy strict-JSON `.pi/tasks.json` file.
|
|
28
|
+
- Starting an unlinked task in a new ACP session and reopening an already-linked
|
|
29
|
+
session instead of creating a duplicate.
|
|
30
|
+
- Task descriptions can contain attachment markers; those attachments are
|
|
31
|
+
resolved when the task prompt is built.
|
|
23
32
|
|
|
24
33
|
## Non-goals
|
|
25
34
|
|
|
26
|
-
- Kanban
|
|
27
|
-
|
|
35
|
+
- Kanban columns, subtasks, dependencies, assignees, due dates, comments, or
|
|
36
|
+
task history.
|
|
37
|
+
- Task filtering controls in the current sidebar UI.
|
|
38
|
+
- Editing or displaying priority in the current sidebar UI.
|
|
28
39
|
- Automatic transition to `done` when an agent turn finishes.
|
|
29
|
-
- Synchronizing
|
|
40
|
+
- Synchronizing `.pi/tasks.jsonc` with the agent's session-local todo list.
|
|
30
41
|
- Concurrent multi-window file merging.
|
|
31
42
|
|
|
32
43
|
## Behavior
|
|
33
44
|
|
|
34
|
-
1. The sidebar
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
6.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
1. The sidebar starts on `Tasks`, remembers its width/collapsed state locally,
|
|
46
|
+
and keeps a compact tab rail available while collapsed.
|
|
47
|
+
2. Tasks are grouped by type. Dragging a task reorders it; dropping it into a
|
|
48
|
+
different group also changes its type and updates `updatedAt`.
|
|
49
|
+
3. Task rows show title, status, session/run action, edit, and delete controls.
|
|
50
|
+
Status uses icon, text, and color rather than color alone.
|
|
51
|
+
4. Creating a task requires a non-empty title, starts with status `todo` and
|
|
52
|
+
priority `medium`, and may include description text and attachments.
|
|
53
|
+
5. Editing changes title, description, and type. Status is changed separately.
|
|
54
|
+
Existing persisted priority is preserved.
|
|
55
|
+
6. `.pi/tasks.jsonc` is authoritative. Missing `.pi`/task storage produces an
|
|
56
|
+
empty version-1 document. JSONC comments and trailing commas are accepted.
|
|
57
|
+
7. If `.pi/tasks.jsonc` is absent and legacy `.pi/tasks.json` exists, Pix reads
|
|
58
|
+
and validates the legacy document, adds the schema reference when absent,
|
|
59
|
+
writes `.pi/tasks.jsonc`, deletes the legacy file, and returns the migrated
|
|
60
|
+
document. If JSONC already exists, it wins and the legacy file is ignored.
|
|
61
|
+
8. Starting an unlinked task creates/selects a new ACP session, persists its
|
|
62
|
+
session id, changes any non-`done` task to `in-progress`, preserves `done`,
|
|
63
|
+
appends the generated task prompt, and sends it immediately.
|
|
64
|
+
9. Starting a linked task opens that session. A stale/missing linked session is
|
|
65
|
+
a recoverable error and does not silently create another session.
|
|
66
|
+
10. Task completion remains manual.
|
|
50
67
|
|
|
51
68
|
## Contracts
|
|
52
69
|
|
|
53
|
-
- Project file: `.pi/tasks.
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
- Project file: `.pi/tasks.jsonc`.
|
|
71
|
+
- Document shape: optional `$schema`, `version: 1`, and `tasks`.
|
|
72
|
+
- Each task has a unique id, title, type, status, priority, `createdAt`, and
|
|
73
|
+
`updatedAt`; description and `sessionId` are optional.
|
|
74
|
+
- Unknown fields, duplicate ids, unsupported enum values, empty titles,
|
|
75
|
+
malformed timestamps, unsupported versions, and oversized documents are
|
|
76
|
+
rejected.
|
|
77
|
+
- The Tauri backend confines task paths to the active workspace, rejects escape
|
|
78
|
+
through `.pi` symlinks, and caps the document at 1 MB.
|
|
79
|
+
- Writes validate the complete document, write a same-directory temporary file,
|
|
80
|
+
and replace the target to avoid partial JSONC files.
|
|
60
81
|
|
|
61
82
|
## Invariants
|
|
62
83
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
persisted.
|
|
84
|
+
- Failed validation never replaces the task file.
|
|
85
|
+
- Failed persistence restores the previous in-memory task document.
|
|
86
|
+
- A task is linked to at most one session.
|
|
87
|
+
- Running/reordering/editing is disabled while conflicting task/session work is
|
|
88
|
+
active.
|
|
89
|
+
- Dragging between groups changes only ordering/type; other task fields survive.
|
|
70
90
|
|
|
71
91
|
## Edge cases
|
|
72
92
|
|
|
73
|
-
- Switching workspaces discards the previous
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
|
|
93
|
+
- Switching workspaces discards the previous in-memory task view and loads the
|
|
94
|
+
new project's task document.
|
|
95
|
+
- Missing storage means no tasks; malformed or empty JSON/JSONC is an error.
|
|
96
|
+
- A legacy task file is migrated at most once because successful migration
|
|
97
|
+
removes `.pi/tasks.json`.
|
|
98
|
+
- Save, session creation, attachment preparation, and prompt failures remain
|
|
99
|
+
visible and retryable.
|
|
80
100
|
|
|
81
101
|
## Related files
|
|
82
102
|
|
|
83
103
|
- `desktop/src/App.svelte`
|
|
84
|
-
- `desktop/src/components
|
|
85
|
-
- `desktop/src/lib
|
|
86
|
-
- `desktop/src/
|
|
104
|
+
- `desktop/src/components/WorkspaceSidebar.svelte`
|
|
105
|
+
- `desktop/src/lib/project-tasks.ts`
|
|
106
|
+
- `desktop/src/lib/project-tasks.test.ts`
|
|
87
107
|
- `desktop/src-tauri/src/lib.rs`
|
|
108
|
+
- `src/schemas/tasks-schema.ts`
|
|
88
109
|
|
|
89
110
|
## Verification
|
|
90
111
|
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
- Rust tests
|
|
94
|
-
|
|
95
|
-
- `npm --prefix desktop run check
|
|
96
|
-
|
|
97
|
-
- `cargo test --manifest-path desktop/src-tauri/Cargo.toml`
|
|
112
|
+
- `desktop/src/lib/project-tasks.test.ts` covers parsing, prompt generation, and
|
|
113
|
+
drag/reorder semantics.
|
|
114
|
+
- Rust tests in `desktop/src-tauri/src/lib.rs` cover missing/read/write/malformed
|
|
115
|
+
JSONC, validation, workspace confinement, and legacy JSON migration.
|
|
116
|
+
- Run `npm --prefix desktop test`, `npm --prefix desktop run check`, and
|
|
117
|
+
`cargo test --manifest-path desktop/src-tauri/Cargo.toml`.
|
|
98
118
|
|
|
99
119
|
## Risks / unknowns
|
|
100
120
|
|
|
101
|
-
- Whole-document writes assume one active
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
121
|
+
- Whole-document writes assume one active writer per project; multi-window merge
|
|
122
|
+
semantics remain out of scope.
|
|
123
|
+
- A linked session can be removed outside Pix Desktop and remains linked until
|
|
124
|
+
the user repairs or edits the task.
|
|
125
|
+
- Priority remains part of the persisted schema although the current UI does not
|
|
126
|
+
expose priority editing.
|
|
106
127
|
|
|
107
128
|
## Evidence
|
|
108
129
|
|
|
109
|
-
- Confirmed by code: desktop
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
- Confirmed by docs: `DESIGN.md` specifies a compact persistent sidebar,
|
|
116
|
-
semantic theme roles, Lucide icons, and non-color status cues.
|
|
117
|
-
- Implemented: `.pi/tasks.json` now has an explicit version-1 contract and
|
|
118
|
-
rejects unsupported versions rather than guessing a migration.
|
|
119
|
-
- Verified by tests: all 82 desktop Vitest tests and all 8 Rust tests pass;
|
|
120
|
-
Svelte/TypeScript checks report no errors or warnings.
|
|
121
|
-
- Verified visually: browser QA covered clean preference state, resize/collapse,
|
|
122
|
-
tabs, filters, and semantic colors in light/dark themes.
|
|
123
|
-
- Verified natively: actual Tauri UI/backend CRUD, Run, persisted linkage,
|
|
124
|
-
Open session without duplication, and delete cleanup all passed.
|
|
130
|
+
- Confirmed by code: `desktop/src/App.svelte`,
|
|
131
|
+
`desktop/src/components/WorkspaceSidebar.svelte`, and
|
|
132
|
+
`desktop/src/lib/project-tasks.ts` implement the current task lifecycle.
|
|
133
|
+
- Confirmed by code: `desktop/src-tauri/src/lib.rs` owns JSONC persistence,
|
|
134
|
+
validation, confinement, atomic replacement, and legacy migration.
|
|
135
|
+
- Confirmed by tests: project-task unit tests and Tauri task persistence tests.
|