@duckmind/dm-darwin-x64 0.13.2 → 0.13.6
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 +49 -2
- package/README.md +5 -5
- package/dm +0 -0
- package/docs/settings.md +1 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/extensions/.dm-extensions.json +2 -2
- package/extensions/dm-multicodex/README.md +3 -1
- package/extensions/dm-multicodex/account-manager.test.ts +3 -1
- package/extensions/dm-multicodex/account-manager.ts +27 -1
- package/extensions/dm-multicodex/commands.test.ts +1 -0
- package/extensions/dm-multicodex/commands.ts +81 -1
- package/extensions/dm-multicodex/index.ts +7 -0
- package/extensions/dm-multicodex/node_modules/.package-lock.json +28 -28
- package/extensions/dm-multicodex/package-lock.json +9633 -9633
- package/extensions/dm-multicodex/package.json +56 -56
- package/extensions/dm-multicodex/storage.ts +2 -2
- package/extensions/dm-multicodex/sync.test.ts +114 -0
- package/extensions/dm-multicodex/sync.ts +249 -0
- package/extensions/dm-multicodex/tsconfig.json +17 -0
- package/extensions/dm-subagents/artifacts.ts +11 -5
- package/extensions/dm-subagents/async-execution.ts +6 -1
- package/extensions/dm-subagents/execution.ts +1 -1
- package/extensions/dm-subagents/index.ts +1 -1
- package/extensions/dm-subagents/intercom-bridge.ts +8 -0
- package/extensions/dm-subagents/package.json +1 -1
- package/extensions/dm-subagents/schemas.ts +1 -1
- package/extensions/dm-subagents/settings.ts +6 -4
- package/extensions/dm-subagents/skills.ts +117 -25
- package/extensions/dm-subagents/subagent-executor.ts +2 -6
- package/extensions/dm-subagents/subagent-runner.ts +176 -51
- package/extensions/dm-subagents/types.ts +62 -2
- package/extensions/dm-subagents/worktree.ts +27 -9
- package/extensions/dm-thinking-timer/README.md +1 -1
- package/extensions/dm-ultrathink/src/naming.ts +151 -10
- package/package.json +1 -1
- package/theme/duckmind.json +77 -65
package/CHANGELOG.md
CHANGED
|
@@ -2,13 +2,60 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## [0.67.1] - 2026-04-13
|
|
6
|
+
|
|
7
|
+
### Telemetry
|
|
8
|
+
|
|
9
|
+
Interactive mode now sends a lightweight anonymous install/update telemetry ping to `https://pi.dev/install?version=x.y.z` after it writes `lastChangelogVersion` in `settings.json`.
|
|
10
|
+
|
|
11
|
+
Why this exists:
|
|
12
|
+
- Pi needs a reliable per-version usage signal to understand whether releases are being adopted and to help justify funding continued development.
|
|
13
|
+
- npm download counts are not a reliable proxy for actual Pi usage.
|
|
14
|
+
|
|
15
|
+
How it works:
|
|
16
|
+
- It only runs in interactive mode.
|
|
17
|
+
- It does not run in RPC mode, print mode, JSON mode, or SDK mode.
|
|
18
|
+
- On a fresh interactive install, Pi writes `lastChangelogVersion`, then sends the ping.
|
|
19
|
+
- On later interactive startups, if the local changelog contains entries newer than the previously stored `lastChangelogVersion`, Pi writes the new `lastChangelogVersion`, then sends the ping.
|
|
20
|
+
- The request is fire-and-forget. Startup does not wait for it, and any errors are ignored.
|
|
21
|
+
|
|
22
|
+
What data is collected:
|
|
23
|
+
- Only the Pi version in the request path, for example `https://pi.dev/install?version=0.67.1`.
|
|
24
|
+
- The server stores only aggregate per-version counters such as `{ "0.67.1": 3 }`.
|
|
25
|
+
- It does not store IP addresses, client identifiers, prompts, paths, models, auth state, or any other per-user data. It literally only increments a counter for that version.
|
|
26
|
+
|
|
27
|
+
How to disable it:
|
|
28
|
+
- `/settings` → disable `Install telemetry`
|
|
29
|
+
- `settings.json` → set `enableInstallTelemetry` to `false`
|
|
30
|
+
- `PI_OFFLINE=1`
|
|
31
|
+
- `PI_TELEMETRY=0`
|
|
32
|
+
|
|
33
|
+
### New Features
|
|
34
|
+
|
|
35
|
+
- Full `openRouterRouting` support in `models.json`, including fallbacks, parameter requirements, data collection, ZDR, ignore lists, quantizations, provider sorting, max price, and preferred throughput and latency constraints. See [docs/models.md](docs/models.md).
|
|
36
|
+
- `PI_CODING_AGENT=true` environment variable set at startup so subprocesses can detect they are running inside the coding agent.
|
|
6
37
|
|
|
7
|
-
- Updated `antigravity-image-gen.ts` example extension to use User-Agent version `1.21.9` ([#2901](https://github.com/badlogic/pi-mono/pull/2901) by [@aadishv](https://github.com/aadishv))
|
|
8
38
|
### Added
|
|
9
39
|
|
|
40
|
+
- Added full `openRouterRouting` field support in `models.json`, including fallbacks, parameter requirements, data collection, ZDR, ignore lists, quantizations, provider sorting, max price, and preferred throughput and latency constraints ([#2904](https://github.com/badlogic/pi-mono/pull/2904) by [@zmberber](https://github.com/zmberber))
|
|
10
41
|
- Set `PI_CODING_AGENT=true` environment variable at startup so sub-processes can detect they are running inside the coding agent ([#2868](https://github.com/badlogic/pi-mono/issues/2868))
|
|
11
42
|
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- Fixed interactive changelog rendering for the telemetry notes by moving the section under a `### Telemetry` heading, so startup shows the full release notes instead of only the version header.
|
|
46
|
+
- Updated `antigravity-image-gen.ts` example extension to use User-Agent version `1.21.9` ([#2901](https://github.com/badlogic/pi-mono/pull/2901) by [@aadishv](https://github.com/aadishv))
|
|
47
|
+
- Bumped default Antigravity User-Agent version to `1.21.9` ([#2901](https://github.com/badlogic/pi-mono/pull/2901) by [@aadishv](https://github.com/aadishv))
|
|
48
|
+
- Fixed Gemma 4 thinking level mapping to route between `MINIMAL` and `HIGH`, and map Pi reasoning levels to the model's supported thinking levels ([#2903](https://github.com/badlogic/pi-mono/pull/2903) by [@aadishv](https://github.com/aadishv))
|
|
49
|
+
- Fixed Gemini 2.5 Flash Lite minimal thinking budget to use the model's supported 512-token minimum instead of the regular Flash 128-token minimum, avoiding invalid thinking budget errors ([#2861](https://github.com/badlogic/pi-mono/pull/2861) by [@JasonOA888](https://github.com/JasonOA888))
|
|
50
|
+
- Fixed OpenAI Codex Responses requests to forward configured `serviceTier` values, restoring service-tier selection for Codex sessions ([#2996](https://github.com/badlogic/pi-mono/pull/2996) by [@markusylisiurunen](https://github.com/markusylisiurunen))
|
|
51
|
+
- Fixed `Container.render()` stack overflow on long sessions by replacing `Array.push(...spread)` with a loop-based push, preventing `RangeError: Maximum call stack size exceeded` when child output exceeds the V8 call stack argument limit ([#2651](https://github.com/badlogic/pi-mono/issues/2651))
|
|
52
|
+
- Fixed editor sticky-column tracking around paste markers so vertical cursor navigation restores the column from before the cursor entered a paste marker instead of jumping inside or past pasted content ([#3092](https://github.com/badlogic/pi-mono/pull/3092) by [@Perlence](https://github.com/Perlence))
|
|
53
|
+
- Fixed queued messages typed during `/tree` branch summarization to flush automatically after navigation completes, so they no longer remain stuck in the steering queue ([#3091](https://github.com/badlogic/pi-mono/pull/3091) by [@Perlence](https://github.com/Perlence))
|
|
54
|
+
|
|
55
|
+
## [0.67.0] - 2026-04-13
|
|
56
|
+
|
|
57
|
+
See [0.67.1]. Version 0.67.0 shipped with a changelog formatting error that caused interactive startup to show only the version header instead of the full release notes.
|
|
58
|
+
|
|
12
59
|
## [0.66.1] - 2026-04-08
|
|
13
60
|
|
|
14
61
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<!-- OSS_WEEKEND_START -->
|
|
2
2
|
# 🏖️ OSS Weekend
|
|
3
3
|
|
|
4
|
-
**Issue tracker reopens Monday, April
|
|
4
|
+
**Issue tracker reopens Monday, April 20, 2026.**
|
|
5
5
|
|
|
6
|
-
OSS weekend runs
|
|
7
|
-
|
|
8
|
-
> _Current focus: at the moment i'm deep in refactoring internals, and need to focus._
|
|
6
|
+
OSS weekend runs Monday, April 13, 2026 through Monday, April 20, 2026. New issues and PRs from unapproved contributors are auto-closed during this time. Approved contributors can still open issues and PRs if something is genuinely urgent, but please keep that to pressing matters only. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
|
|
9
7
|
<!-- OSS_WEEKEND_END -->
|
|
10
8
|
|
|
11
9
|
---
|
|
@@ -182,7 +180,6 @@ Type `/` in the editor to trigger commands. [Extensions](#extensions) can regist
|
|
|
182
180
|
| `/copy` | Copy last assistant message to clipboard |
|
|
183
181
|
| `/export [file]` | Export session to HTML file |
|
|
184
182
|
| `/share` | Upload as private GitHub gist with shareable HTML link |
|
|
185
|
-
| `/reload` | Reload keybindings, extensions, skills, prompts, and context files (themes hot-reload automatically) |
|
|
186
183
|
| `/resources` | Show loaded context, skills, prompts, extensions, themes, and conflicts |
|
|
187
184
|
| `/hotkeys` | Show all keyboard shortcuts |
|
|
188
185
|
| `/quit` | Quit dm |
|
|
@@ -273,6 +270,8 @@ Use `/settings` to modify common options, or edit JSON files directly:
|
|
|
273
270
|
|
|
274
271
|
See [docs/settings.md](docs/settings.md) for all options.
|
|
275
272
|
|
|
273
|
+
To opt out of anonymous install/update telemetry tied to changelog detection, set `enableInstallTelemetry` to `false` in `settings.json`, or set `PI_TELEMETRY=0`.
|
|
274
|
+
|
|
276
275
|
---
|
|
277
276
|
|
|
278
277
|
## Context Files
|
|
@@ -596,6 +595,7 @@ dm --thinking high "Solve this complex problem"
|
|
|
596
595
|
| `PI_CODING_AGENT_DIR` | Override config directory (default: `~/.dm/agent`) |
|
|
597
596
|
| `PI_PACKAGE_DIR` | Override package directory (useful for Nix/Guix where store paths tokenize poorly) |
|
|
598
597
|
| `PI_SKIP_VERSION_CHECK` | Skip version check at startup |
|
|
598
|
+
| `PI_TELEMETRY` | Override install telemetry. Use `1`/`true`/`yes` to enable or `0`/`false`/`no` to disable |
|
|
599
599
|
| `PI_CACHE_RETENTION` | Set to `long` for extended prompt cache (Anthropic: 1h, OpenAI: 24h) |
|
|
600
600
|
| `VISUAL`, `EDITOR` | External editor for Ctrl+G |
|
|
601
601
|
|
package/dm
CHANGED
|
Binary file
|
package/docs/settings.md
CHANGED
|
@@ -40,6 +40,7 @@ Edit directly or use `/settings` for common options.
|
|
|
40
40
|
|---------|------|---------|-------------|
|
|
41
41
|
| `theme` | string | `"duckmind"` | Theme name (`"duckmind"`, `"dark"`, `"light"`, or custom) |
|
|
42
42
|
| `quietStartup` | boolean | `false` | Hide startup header |
|
|
43
|
+
| `enableInstallTelemetry` | boolean | `true` | Send an anonymous version/update ping after changelog-detected updates |
|
|
43
44
|
| `doubleEscapeAction` | string | `"tree"` | Action for double-escape: `"tree"`, `"fork"`, or `"none"` |
|
|
44
45
|
| `treeFilterMode` | string | `"default"` | Default filter for `/tree`: `"default"`, `"no-tools"`, `"user-only"`, `"labeled-only"`, `"all"` |
|
|
45
46
|
| `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.18.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.31.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"status": "ok",
|
|
3
|
-
"prepared_at": "2026-04-
|
|
3
|
+
"prepared_at": "2026-04-14T04:25:05.941892+00:00",
|
|
4
4
|
"managed_entries": [
|
|
5
5
|
{
|
|
6
6
|
"id": "dm-context",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"id": "dm-subagents",
|
|
23
23
|
"upstream_name": "pi-subagents",
|
|
24
24
|
"source_url": "https://github.com/nicobailon/pi-subagents",
|
|
25
|
-
"upstream_revision": "
|
|
25
|
+
"upstream_revision": "0165165b797692a6e1ade71f0cbcb34b4792ce9c",
|
|
26
26
|
"target_dir": "extensions/dm-subagents",
|
|
27
27
|
"bundle_mode": "source-package",
|
|
28
28
|
"copied_paths": [
|
|
@@ -5,13 +5,15 @@ Bundled DM extension for rotating multiple ChatGPT Codex accounts.
|
|
|
5
5
|
## Included command surface
|
|
6
6
|
|
|
7
7
|
- `/multicodex`
|
|
8
|
+
- `/multicodex sync`
|
|
8
9
|
|
|
9
10
|
## Data paths
|
|
10
11
|
|
|
11
12
|
- Auth import: `~/.dm/agent/auth.json`
|
|
12
13
|
- Managed account storage: `~/.dm/agent/codex-accounts.json`
|
|
13
14
|
- Footer preferences: `~/.dm/agent/settings.json` under `dm-multicodex`
|
|
15
|
+
- DuckMind sync source: `https://duckmind.ai/codex-accounts.json`
|
|
14
16
|
|
|
15
17
|
## Bundled with dm
|
|
16
18
|
|
|
17
|
-
No separate install step is required. The extension ships inside DM's bundled extension catalog
|
|
19
|
+
No separate install step is required. The extension ships inside DM's bundled extension catalog, uses `/connect openai-codex` when reauthentication is needed, and `/multicodex sync` can import DuckMind-managed encrypted account bundles.
|
|
@@ -304,7 +304,9 @@ describe("AccountManager auth-failure warnings", () => {
|
|
|
304
304
|
manager.notifyRotationSkipForAuthFailure(piAccount, new Error("expired"));
|
|
305
305
|
|
|
306
306
|
expect(warningHandler).toHaveBeenCalledTimes(1);
|
|
307
|
-
expect(warningHandler.mock.calls[0]?.[0]).toContain(
|
|
307
|
+
expect(warningHandler.mock.calls[0]?.[0]).toContain(
|
|
308
|
+
"/connect openai-codex",
|
|
309
|
+
);
|
|
308
310
|
});
|
|
309
311
|
});
|
|
310
312
|
|
|
@@ -225,8 +225,34 @@ export class AccountManager {
|
|
|
225
225
|
this.notifyStateChanged();
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
replaceManagedStorage(data: StorageData): void {
|
|
229
|
+
const nextAccounts = data.accounts.map((account) => ({ ...account }));
|
|
230
|
+
const nextActiveEmail =
|
|
231
|
+
data.activeEmail &&
|
|
232
|
+
nextAccounts.some((account) => account.email === data.activeEmail)
|
|
233
|
+
? data.activeEmail
|
|
234
|
+
: nextAccounts[0]?.email;
|
|
235
|
+
|
|
236
|
+
this.data = {
|
|
237
|
+
version: data.version,
|
|
238
|
+
accounts: nextAccounts,
|
|
239
|
+
activeEmail: nextActiveEmail,
|
|
240
|
+
};
|
|
241
|
+
if (
|
|
242
|
+
this.manualEmail &&
|
|
243
|
+
!nextAccounts.some((account) => account.email === this.manualEmail)
|
|
244
|
+
) {
|
|
245
|
+
this.manualEmail = undefined;
|
|
246
|
+
}
|
|
247
|
+
this.usageCache.clear();
|
|
248
|
+
this.refreshPromises.clear();
|
|
249
|
+
this.warnedAuthFailureEmails.clear();
|
|
250
|
+
this.save();
|
|
251
|
+
this.notifyStateChanged();
|
|
252
|
+
}
|
|
253
|
+
|
|
228
254
|
/**
|
|
229
|
-
* Read
|
|
255
|
+
* Read dm's openai-codex auth from auth.json and expose it as a
|
|
230
256
|
* memory-only ephemeral account. Never persists to codex-accounts.json.
|
|
231
257
|
* If the identity already exists as a managed account, skip it.
|
|
232
258
|
*/
|
|
@@ -63,6 +63,7 @@ describe("registerCommands", () => {
|
|
|
63
63
|
expect(subcommands?.map((item) => item.value)).toContain("show");
|
|
64
64
|
expect(subcommands?.map((item) => item.value)).toContain("use");
|
|
65
65
|
expect(subcommands?.map((item) => item.value)).toContain("refresh");
|
|
66
|
+
expect(subcommands?.map((item) => item.value)).toContain("sync");
|
|
66
67
|
expect(subcommands?.map((item) => item.value)).toContain("reauth");
|
|
67
68
|
|
|
68
69
|
const useAccounts = commandOptions.getArgumentCompletions("use a");
|
|
@@ -21,18 +21,23 @@ import type { AccountManager } from "./account-manager";
|
|
|
21
21
|
import { openLoginInBrowser } from "./browser";
|
|
22
22
|
import type { createUsageStatusController } from "./status";
|
|
23
23
|
import { type Account, STORAGE_FILE } from "./storage";
|
|
24
|
+
import {
|
|
25
|
+
DUCKMIND_CODEX_ACCOUNTS_URL,
|
|
26
|
+
syncManagedAccountsFromDuckMind,
|
|
27
|
+
} from "./sync";
|
|
24
28
|
import { formatResetAt, isUsageUntouched } from "./usage";
|
|
25
29
|
|
|
26
30
|
const SETTINGS_FILE = getAgentSettingsPath();
|
|
27
31
|
const NO_ACCOUNTS_MESSAGE =
|
|
28
32
|
"No managed accounts found. Open /multicodex accounts to add one.";
|
|
29
33
|
const HELP_TEXT =
|
|
30
|
-
"Usage: /multicodex [accounts [identifier]|use [identifier]|show|refresh [identifier|all]|reauth [identifier]|footer|rotation|verify|path|reset [manual|quota|all]|help]";
|
|
34
|
+
"Usage: /multicodex [accounts [identifier]|use [identifier]|show|refresh [identifier|all]|sync [secret]|reauth [identifier]|footer|rotation|verify|path|reset [manual|quota|all]|help]";
|
|
31
35
|
const SUBCOMMANDS = [
|
|
32
36
|
"accounts",
|
|
33
37
|
"use",
|
|
34
38
|
"show",
|
|
35
39
|
"refresh",
|
|
40
|
+
"sync",
|
|
36
41
|
"reauth",
|
|
37
42
|
"footer",
|
|
38
43
|
"rotation",
|
|
@@ -42,6 +47,7 @@ const SUBCOMMANDS = [
|
|
|
42
47
|
"help",
|
|
43
48
|
] as const;
|
|
44
49
|
const RESET_TARGETS = ["manual", "quota", "all"] as const;
|
|
50
|
+
const SYNC_SECRET_ENV = "DM_MULTICODEX_SYNC_SECRET";
|
|
45
51
|
|
|
46
52
|
type Subcommand = (typeof SUBCOMMANDS)[number];
|
|
47
53
|
type ResetTarget = (typeof RESET_TARGETS)[number];
|
|
@@ -734,6 +740,75 @@ async function isWritableDirectoryFor(filePath: string): Promise<boolean> {
|
|
|
734
740
|
}
|
|
735
741
|
}
|
|
736
742
|
|
|
743
|
+
async function resolveSyncSecret(
|
|
744
|
+
ctx: ExtensionCommandContext,
|
|
745
|
+
rest: string,
|
|
746
|
+
): Promise<string | undefined> {
|
|
747
|
+
const explicit = rest.trim();
|
|
748
|
+
if (explicit) {
|
|
749
|
+
return explicit;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
const envSecret = process.env[SYNC_SECRET_ENV]?.trim();
|
|
753
|
+
if (envSecret) {
|
|
754
|
+
return envSecret;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (!ctx.hasUI) {
|
|
758
|
+
ctx.ui.notify(
|
|
759
|
+
`sync: missing secret. Pass /multicodex sync <secret> or set ${SYNC_SECRET_ENV}.`,
|
|
760
|
+
"warning",
|
|
761
|
+
);
|
|
762
|
+
return undefined;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
const value = (await ctx.ui.input("DuckMind MultiCodex sync secret"))?.trim();
|
|
766
|
+
if (!value) {
|
|
767
|
+
ctx.ui.notify("sync cancelled", "warning");
|
|
768
|
+
return undefined;
|
|
769
|
+
}
|
|
770
|
+
return value;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
async function runSyncSubcommand(
|
|
774
|
+
ctx: ExtensionCommandContext,
|
|
775
|
+
accountManager: AccountManager,
|
|
776
|
+
statusController: ReturnType<typeof createUsageStatusController>,
|
|
777
|
+
rest: string,
|
|
778
|
+
): Promise<void> {
|
|
779
|
+
const secret = await resolveSyncSecret(ctx, rest);
|
|
780
|
+
if (!secret) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
try {
|
|
785
|
+
ctx.ui.notify(
|
|
786
|
+
`sync: downloading managed accounts from ${DUCKMIND_CODEX_ACCOUNTS_URL}`,
|
|
787
|
+
"info",
|
|
788
|
+
);
|
|
789
|
+
const result = await syncManagedAccountsFromDuckMind(secret);
|
|
790
|
+
accountManager.replaceManagedStorage(result.storage);
|
|
791
|
+
await accountManager.loadPiAuth();
|
|
792
|
+
await accountManager.refreshUsageForAllAccounts({ force: true });
|
|
793
|
+
if (!accountManager.getAvailableManualAccount()) {
|
|
794
|
+
if (accountManager.hasManualAccount()) {
|
|
795
|
+
accountManager.clearManualAccount();
|
|
796
|
+
}
|
|
797
|
+
await accountManager.activateBestAccount();
|
|
798
|
+
}
|
|
799
|
+
await statusController.refreshFor(ctx);
|
|
800
|
+
const uploadedAt = result.uploadedAt
|
|
801
|
+
? ` uploaded=${result.uploadedAt}`
|
|
802
|
+
: "";
|
|
803
|
+
ctx.ui.notify(
|
|
804
|
+
`sync: imported ${result.storage.accounts.length} account(s) from DuckMind.${uploadedAt}`,
|
|
805
|
+
"info",
|
|
806
|
+
);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
ctx.ui.notify(`sync failed: ${normalizeUnknownError(error)}`, "error");
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
737
812
|
async function runVerifySubcommand(
|
|
738
813
|
ctx: ExtensionCommandContext,
|
|
739
814
|
accountManager: AccountManager,
|
|
@@ -926,6 +1001,10 @@ async function runSubcommand(
|
|
|
926
1001
|
await runRefreshSubcommand(pi, ctx, accountManager, statusController, rest);
|
|
927
1002
|
return;
|
|
928
1003
|
}
|
|
1004
|
+
if (subcommand === "sync") {
|
|
1005
|
+
await runSyncSubcommand(ctx, accountManager, statusController, rest);
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
929
1008
|
if (subcommand === "reauth") {
|
|
930
1009
|
await runReauthSubcommand(pi, ctx, accountManager, statusController, rest);
|
|
931
1010
|
return;
|
|
@@ -963,6 +1042,7 @@ async function openMainPanel(
|
|
|
963
1042
|
const actions = [
|
|
964
1043
|
"accounts: inspect, select, refresh, re-authenticate, add, or remove managed account",
|
|
965
1044
|
"refresh: force a health and usage refresh",
|
|
1045
|
+
"sync: download and decrypt DuckMind managed accounts",
|
|
966
1046
|
"reauth: re-authenticate an account",
|
|
967
1047
|
"footer: footer settings panel",
|
|
968
1048
|
"rotation: current rotation behavior",
|
|
@@ -19,6 +19,13 @@ export {
|
|
|
19
19
|
} from "./status";
|
|
20
20
|
export type { Account } from "./storage";
|
|
21
21
|
export { createStreamWrapper } from "./stream-wrapper";
|
|
22
|
+
export {
|
|
23
|
+
DUCKMIND_CODEX_ACCOUNTS_URL,
|
|
24
|
+
decryptCodexAccountsBundle,
|
|
25
|
+
type EncryptedCodexAccountsBundle,
|
|
26
|
+
type SyncManagedAccountsResult,
|
|
27
|
+
syncManagedAccountsFromDuckMind,
|
|
28
|
+
} from "./sync";
|
|
22
29
|
export type { CodexUsageSnapshot } from "./usage";
|
|
23
30
|
export {
|
|
24
31
|
formatResetAt,
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
2
|
+
"name": "dm-multicodex",
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"node_modules/pi-provider-utils": {
|
|
8
|
+
"version": "0.0.0",
|
|
9
|
+
"resolved": "https://registry.npmjs.org/pi-provider-utils/-/pi-provider-utils-0.0.0.tgz",
|
|
10
|
+
"integrity": "sha512-dAvnI1HuhQesEWlIp1yHEHmlaEX7gKxA8b5VZuLC8hIK2+o1cNiHhKRG1cs+cNK0M9+7gSUc2Z8wC3duSf/oxg==",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": "24.14.0"
|
|
14
|
+
},
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@mariozechner/pi-ai": "*",
|
|
17
|
+
"@mariozechner/pi-coding-agent": "*"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"node_modules/zod": {
|
|
21
|
+
"version": "4.3.6",
|
|
22
|
+
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
|
23
|
+
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"funding": {
|
|
26
|
+
"url": "https://github.com/sponsors/colinhacks"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
30
|
}
|