@oh-my-pi/pi-coding-agent 16.2.3 → 16.2.5
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 +31 -0
- package/dist/cli.js +3449 -3438
- package/dist/types/cli/update-cli.d.ts +15 -0
- package/dist/types/collab/replication-shrink.d.ts +39 -0
- package/dist/types/config/provider-globals.d.ts +7 -0
- package/dist/types/memories/index.d.ts +20 -1
- package/dist/types/modes/components/status-line/component.d.ts +5 -0
- package/dist/types/modes/components/status-line/types.d.ts +10 -0
- package/dist/types/modes/controllers/command-controller.d.ts +3 -3
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +2 -1
- package/dist/types/session/agent-session.d.ts +7 -0
- package/dist/types/session/session-manager.d.ts +2 -3
- package/dist/types/task/provider-concurrency.d.ts +40 -0
- package/dist/types/utils/git.d.ts +11 -0
- package/package.json +12 -12
- package/src/autolearn/controller.ts +13 -22
- package/src/cli/update-cli.ts +254 -0
- package/src/cli/worktree-cli.ts +8 -5
- package/src/collab/host.ts +13 -8
- package/src/collab/replication-shrink.ts +111 -0
- package/src/config/model-discovery.ts +33 -13
- package/src/config/provider-globals.ts +25 -0
- package/src/config/settings-schema.ts +5 -2
- package/src/eval/__tests__/julia-prelude.test.ts +2 -2
- package/src/memories/index.ts +115 -9
- package/src/memory-backend/local-backend.ts +5 -3
- package/src/modes/components/status-line/component.ts +35 -2
- package/src/modes/components/status-line/segments.ts +22 -8
- package/src/modes/components/status-line/types.ts +7 -0
- package/src/modes/controllers/command-controller.ts +5 -35
- package/src/modes/controllers/event-controller.ts +7 -1
- package/src/modes/controllers/input-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +9 -20
- package/src/modes/theme/theme.ts +6 -0
- package/src/modes/types.ts +2 -1
- package/src/prompts/goals/goal-todo-context.md +12 -0
- package/src/sdk.ts +13 -5
- package/src/session/agent-session.ts +129 -14
- package/src/session/session-manager.ts +2 -3
- package/src/slash-commands/builtin-registry.ts +7 -21
- package/src/task/executor.ts +4 -62
- package/src/task/provider-concurrency.ts +100 -0
- package/src/task/worktree.ts +13 -4
- package/src/task/yield-assembly.ts +27 -39
- package/src/tools/read.ts +11 -1
- package/src/utils/git.ts +13 -0
- package/src/prompts/system/autolearn-nudge.md +0 -5
|
@@ -130,74 +130,62 @@ export function assembleYieldResult(
|
|
|
130
130
|
arrayLabels?: ReadonlySet<string>,
|
|
131
131
|
): AssembledYieldResult | undefined {
|
|
132
132
|
if (yieldItems.length === 0) return undefined;
|
|
133
|
+
|
|
134
|
+
// Terminal = the last non-incremental yield (untyped, or string-typed like
|
|
135
|
+
// `type: "result"`). Array-typed yields are incremental sections and never
|
|
136
|
+
// terminate on their own.
|
|
133
137
|
let terminalItem: YieldItem | undefined;
|
|
134
138
|
for (let index = yieldItems.length - 1; index >= 0; index--) {
|
|
135
139
|
const item = yieldItems[index];
|
|
136
|
-
if (!item)
|
|
137
|
-
if (!isIncrementalYieldType(item.type)) {
|
|
140
|
+
if (item && !isIncrementalYieldType(item.type)) {
|
|
138
141
|
terminalItem = item;
|
|
139
142
|
break;
|
|
140
143
|
}
|
|
141
144
|
}
|
|
142
|
-
let hasTypedSections = false;
|
|
143
|
-
for (const item of yieldItems) {
|
|
144
|
-
if (getYieldLabels(item.type).length > 0) {
|
|
145
|
-
hasTypedSections = true;
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (terminalItem && typeof terminalItem.type === "string" && terminalItem.data === undefined) {
|
|
150
|
-
const resolved = resolveYieldPayload(terminalItem, lastAssistantText, getYieldLabels(terminalItem.type));
|
|
151
|
-
return {
|
|
152
|
-
data: resolved.value,
|
|
153
|
-
schemaOverridden: terminalItem.schemaOverridden === true,
|
|
154
|
-
rawText: resolved.fromLastAssistantText && typeof resolved.value === "string",
|
|
155
|
-
missingData: resolved.missingData,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
if (!hasTypedSections && terminalItem) {
|
|
159
|
-
const resolved = resolveYieldPayload(terminalItem, lastAssistantText, []);
|
|
160
|
-
return {
|
|
161
|
-
data: resolved.value,
|
|
162
|
-
schemaOverridden: terminalItem.schemaOverridden === true,
|
|
163
|
-
rawText: resolved.fromLastAssistantText && typeof resolved.value === "string",
|
|
164
|
-
missingData: resolved.missingData,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
145
|
|
|
146
|
+
// Sections come ONLY from incremental (array-typed) yields. A string `type`
|
|
147
|
+
// is a terminal marker, never a section label: folding its data under the
|
|
148
|
+
// label is what nested a finalize payload (`type: "result"`, `data: {…}`) one
|
|
149
|
+
// level deep and made output-schema validation report every field missing.
|
|
168
150
|
const sections: Record<string, unknown> = {};
|
|
169
151
|
const sectionCounts = new Map<string, number>();
|
|
170
152
|
let schemaOverridden = false;
|
|
171
153
|
let missingData = false;
|
|
172
154
|
let hasSections = false;
|
|
173
|
-
|
|
174
155
|
for (const item of yieldItems) {
|
|
175
156
|
if (item.status === "aborted") continue;
|
|
157
|
+
if (!isIncrementalYieldType(item.type)) continue;
|
|
176
158
|
schemaOverridden ||= item.schemaOverridden === true;
|
|
177
159
|
const labels = getYieldLabels(item.type);
|
|
178
|
-
if (labels.length === 0) continue;
|
|
179
160
|
const resolved = resolveYieldPayload(item, lastAssistantText, labels);
|
|
180
161
|
missingData ||= resolved.missingData;
|
|
181
|
-
const incremental = isIncrementalYieldType(item.type);
|
|
182
162
|
for (const label of labels) {
|
|
183
|
-
appendYieldSection(
|
|
184
|
-
sections,
|
|
185
|
-
sectionCounts,
|
|
186
|
-
label,
|
|
187
|
-
resolved.value,
|
|
188
|
-
incremental && (arrayLabels?.has(label) ?? false),
|
|
189
|
-
);
|
|
163
|
+
appendYieldSection(sections, sectionCounts, label, resolved.value, arrayLabels?.has(label) ?? false);
|
|
190
164
|
hasSections = true;
|
|
191
165
|
}
|
|
192
|
-
if (!isIncrementalYieldType(item.type)) break;
|
|
193
166
|
}
|
|
194
167
|
|
|
168
|
+
// An explicit terminal payload wins: an untyped final result or a
|
|
169
|
+
// `type: "result"` finalize that carries `data` is the complete result, used
|
|
170
|
+
// verbatim — never wrapped in a section.
|
|
171
|
+
if (terminalItem && terminalItem.data !== undefined) {
|
|
172
|
+
const resolved = resolveYieldPayload(terminalItem, lastAssistantText, []);
|
|
173
|
+
return {
|
|
174
|
+
data: resolved.value,
|
|
175
|
+
schemaOverridden: terminalItem.schemaOverridden === true,
|
|
176
|
+
rawText: resolved.fromLastAssistantText && typeof resolved.value === "string",
|
|
177
|
+
missingData: resolved.missingData,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// A data-less terminal finalize keeps accumulated sections; only when none
|
|
182
|
+
// exist does the last assistant turn become the raw result.
|
|
195
183
|
if (hasSections) {
|
|
196
184
|
return { data: sections, schemaOverridden, rawText: false, missingData };
|
|
197
185
|
}
|
|
198
186
|
|
|
199
187
|
if (!terminalItem) return undefined;
|
|
200
|
-
const resolved = resolveYieldPayload(terminalItem, lastAssistantText,
|
|
188
|
+
const resolved = resolveYieldPayload(terminalItem, lastAssistantText, getYieldLabels(terminalItem.type));
|
|
201
189
|
return {
|
|
202
190
|
data: resolved.value,
|
|
203
191
|
schemaOverridden: terminalItem.schemaOverridden === true,
|
package/src/tools/read.ts
CHANGED
|
@@ -178,7 +178,17 @@ interface HashlineHeaderContext {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
function formatReadHashlineHeader(displayPath: string, tag: string): string {
|
|
181
|
-
|
|
181
|
+
// In-workspace reads collapse to the bare filename for brevity: the edit
|
|
182
|
+
// tool's snapshot-tag recovery rebinds a bare `[name#tag]` onto the in-tree
|
|
183
|
+
// file it uniquely names. Out-of-workspace reads can't lean on that —
|
|
184
|
+
// recovery refuses to redirect a write outside the cwd/sandbox
|
|
185
|
+
// (HashlineFilesystem.allowTagPathRecovery) — so an absolute displayPath
|
|
186
|
+
// must stay directly resolvable, otherwise the basename resolves against
|
|
187
|
+
// cwd, misses, and the edit fails with "File not found" (e.g. ~/.claude/*).
|
|
188
|
+
// `shortenPath` keeps `~/.claude/...` (round-trips through resolveToCwd's ~
|
|
189
|
+
// expansion) instead of leaking the full home path into the read output.
|
|
190
|
+
const anchor = path.isAbsolute(displayPath) ? shortenPath(displayPath) : path.basename(displayPath);
|
|
191
|
+
return formatHashlineHeader(anchor, tag);
|
|
182
192
|
}
|
|
183
193
|
|
|
184
194
|
function recordFullHashlineContext(
|
package/src/utils/git.ts
CHANGED
|
@@ -1712,6 +1712,19 @@ export const repo = {
|
|
|
1712
1712
|
return primaryRootFromRepositorySync(repository);
|
|
1713
1713
|
},
|
|
1714
1714
|
|
|
1715
|
+
/**
|
|
1716
|
+
* Linked-worktree metadata for `cwd`, or `null` when `cwd` is the primary
|
|
1717
|
+
* checkout (or outside a repository). `root` is the worktree's own checkout
|
|
1718
|
+
* root; `primaryRoot` is the shared main checkout that names the project.
|
|
1719
|
+
* Resolves purely via on-disk `.git`/`commondir` walking — no subprocess —
|
|
1720
|
+
* so the status line may call it on every render.
|
|
1721
|
+
*/
|
|
1722
|
+
linkedWorktreeSync(cwd: string): { root: string; primaryRoot: string } | null {
|
|
1723
|
+
const repository = resolveRepositorySync(cwd);
|
|
1724
|
+
if (!repository || !isLinkedWorktree(repository)) return null;
|
|
1725
|
+
return { root: repository.repoRoot, primaryRoot: primaryRootFromRepositorySync(repository) };
|
|
1726
|
+
},
|
|
1727
|
+
|
|
1715
1728
|
/** Full GitRepository metadata (sync). */
|
|
1716
1729
|
resolveSync(cwd: string): GitRepository | null {
|
|
1717
1730
|
return resolveRepositorySync(cwd);
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
Hidden auto-learn reminder (not a user request). If your previous turn produced anything reusable, capture it now with your learning tools — a repeatable procedure becomes a managed skill (`manage_skill`), and a durable fact, convention, or user preference is worth remembering (`learn`, when memory is enabled).
|
|
2
|
-
|
|
3
|
-
Only capture what will genuinely help next time. If nothing is worth keeping, do nothing.
|
|
4
|
-
|
|
5
|
-
This reminder is appended to the user's real message; answer that message normally — the capture is in addition to, not a replacement for, the work the user just asked for.
|