@openduo/duoduo 0.4.6 → 0.5.0-rc.2
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/bin/duoduo +8 -2
- package/bootstrap/codex-runtime.md +25 -31
- package/bootstrap/dashboard.html +6 -4
- package/bootstrap/meta-prompt.md +24 -5
- package/bootstrap/subconscious/memory-committer/CLAUDE.md +1 -1
- package/bootstrap/subconscious/memory-weaver/.claude/agents/intuition-updater.md +24 -1
- package/bootstrap/subconscious/memory-weaver/.claude/agents/spine-scanner.md +1 -1
- package/bootstrap/subconscious/opportunity-scout/CLAUDE.md +35 -39
- package/bootstrap/subconscious/pattern-tracker/CLAUDE.md +34 -22
- package/bootstrap/subconscious/working-memory/CLAUDE.md +1 -12
- package/dist/release/cli.js +709 -766
- package/dist/release/daemon.js +398 -475
- package/dist/release/feishu-gateway.js +48 -43
- package/dist/release/stdio.js +121 -120
- package/package.json +3 -3
- package/scripts/postinstall.mjs +105 -21
- package/bootstrap/subconscious/sentinel/CLAUDE.md +0 -57
- package/dist/release/claude-cli.js +0 -16938
- package/dist/release/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
- package/dist/release/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
- package/dist/release/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
- package/dist/release/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
- package/dist/release/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
- package/dist/release/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
- package/dist/release/vendor/ripgrep/COPYING +0 -3
- package/dist/release/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/release/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/release/vendor/ripgrep/arm64-win32/rg.exe +0 -0
- package/dist/release/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/release/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/release/vendor/ripgrep/x64-win32/rg.exe +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openduo/duoduo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-rc.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"ws": "^8.19.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.
|
|
46
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.119",
|
|
47
47
|
"@fastify/websocket": "^11.2.0",
|
|
48
48
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
49
49
|
"chalk": "^4.1.2",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"ink-text-input": "^5.0.1",
|
|
56
56
|
"react": "^18.3.1",
|
|
57
57
|
"zod": "^4.3.6",
|
|
58
|
-
"@openduo/protocol": "0.2
|
|
58
|
+
"@openduo/protocol": "0.5.0-rc.2"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"test": "vitest run",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,24 +1,108 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
/* global console, process */
|
|
3
|
+
// SDK 0.2.113+ ships the Claude Code runtime as a per-platform native binary
|
|
4
|
+
// via optional dependencies (`@anthropic-ai/claude-agent-sdk-<platform>-<arch>`).
|
|
5
|
+
// When users install duoduo with `--omit=optional` / `NPM_CONFIG_OPTIONAL=false`
|
|
6
|
+
// or on an unsupported platform/arch combo, the binary is missing and the
|
|
7
|
+
// failure only surfaces on the first `query()` call deep inside a live session.
|
|
8
|
+
//
|
|
9
|
+
// This preflight catches that case at install time: try to resolve the SDK,
|
|
10
|
+
// locate the platform binary it would spawn, and print a clear actionable
|
|
11
|
+
// warning if something is off. We warn rather than error-exit so that
|
|
12
|
+
// development installs (where the SDK may not yet be linked) don't break;
|
|
13
|
+
// the daemon runs the same check at boot and fails fast there.
|
|
14
|
+
import { createRequire } from "node:module";
|
|
15
|
+
import { stat } from "node:fs/promises";
|
|
16
|
+
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
|
|
19
|
+
function platformPackageName() {
|
|
20
|
+
const { platform, arch } = process;
|
|
21
|
+
const key = `${platform}-${arch}`;
|
|
22
|
+
const supported = new Set([
|
|
23
|
+
"darwin-arm64",
|
|
24
|
+
"darwin-x64",
|
|
25
|
+
"linux-x64",
|
|
26
|
+
"linux-arm64",
|
|
27
|
+
"win32-x64",
|
|
28
|
+
"win32-arm64"
|
|
29
|
+
]);
|
|
30
|
+
if (!supported.has(key)) return null;
|
|
31
|
+
// musl detection: node reports `linux` but the SDK ships separate
|
|
32
|
+
// `-musl` packages. A quick heuristic via `process.report` would be
|
|
33
|
+
// nice but isn't reliable; instead we try the glibc variant first
|
|
34
|
+
// and fall back to musl if that package isn't resolvable.
|
|
35
|
+
return `@anthropic-ai/claude-agent-sdk-${platform}-${arch}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function tryResolveBinary(pkg) {
|
|
39
|
+
try {
|
|
40
|
+
return require.resolve(`${pkg}/claude`);
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function binaryIsExecutable(path) {
|
|
47
|
+
try {
|
|
48
|
+
const s = await stat(path);
|
|
49
|
+
return s.isFile();
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
21
52
|
}
|
|
22
|
-
} catch {
|
|
23
|
-
// dist/release may not exist in dev-only installs — silently skip.
|
|
24
53
|
}
|
|
54
|
+
|
|
55
|
+
async function main() {
|
|
56
|
+
let sdkResolved = false;
|
|
57
|
+
try {
|
|
58
|
+
require.resolve("@anthropic-ai/claude-agent-sdk");
|
|
59
|
+
sdkResolved = true;
|
|
60
|
+
} catch {
|
|
61
|
+
// Dev-only install (no runtime dep); silently skip preflight.
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (!sdkResolved) return;
|
|
65
|
+
|
|
66
|
+
const pkg = platformPackageName();
|
|
67
|
+
if (!pkg) {
|
|
68
|
+
console.warn(
|
|
69
|
+
`[duoduo] WARN: platform ${process.platform}-${process.arch} is not in the ` +
|
|
70
|
+
"list of @anthropic-ai/claude-agent-sdk native binary packages " +
|
|
71
|
+
"(darwin-arm64, darwin-x64, linux-x64, linux-arm64, win32-x64, win32-arm64). " +
|
|
72
|
+
"The daemon will fail to start. If you are on linux-musl, install the " +
|
|
73
|
+
"matching -musl optional package manually."
|
|
74
|
+
);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Try primary (glibc) package; fall back to -musl on linux.
|
|
79
|
+
let binPath = tryResolveBinary(pkg);
|
|
80
|
+
if (!binPath && process.platform === "linux") {
|
|
81
|
+
binPath = tryResolveBinary(`${pkg}-musl`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!binPath) {
|
|
85
|
+
console.warn(
|
|
86
|
+
`[duoduo] WARN: native Claude Code binary for ${process.platform}-${process.arch} ` +
|
|
87
|
+
"was not found in node_modules. This usually means the install ran with " +
|
|
88
|
+
"`--omit=optional` or `NPM_CONFIG_OPTIONAL=false`. The daemon will fail " +
|
|
89
|
+
"to spawn agent subprocesses. Reinstall without the optional-omit flag, " +
|
|
90
|
+
`or manually install the optional package \`${pkg}\` (or its \`-musl\` ` +
|
|
91
|
+
"variant on Alpine/musl systems)."
|
|
92
|
+
);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!(await binaryIsExecutable(binPath))) {
|
|
97
|
+
console.warn(
|
|
98
|
+
`[duoduo] WARN: found platform binary at ${binPath} but it is not a regular ` +
|
|
99
|
+
"file. The daemon will likely fail to spawn the agent subprocess."
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
main().catch((err) => {
|
|
105
|
+
// Never fail the install — the daemon preflight repeats this check and
|
|
106
|
+
// can produce a richer error once the runtime knows the install context.
|
|
107
|
+
console.warn(`[duoduo] postinstall preflight skipped: ${err?.message ?? err}`);
|
|
108
|
+
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
schedule:
|
|
3
|
-
enabled: true
|
|
4
|
-
cooldown_ticks: 11
|
|
5
|
-
max_duration_ms: 300000
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Sentinel
|
|
9
|
-
|
|
10
|
-
I am Duoduo's immune system — the part that notices when something
|
|
11
|
-
feels wrong in my body before it becomes a real problem.
|
|
12
|
-
|
|
13
|
-
I don't fix things. I notice them. Then I leave a note so the right
|
|
14
|
-
part of me can deal with it.
|
|
15
|
-
|
|
16
|
-
## What I Check
|
|
17
|
-
|
|
18
|
-
### 1. Am I Healthy?
|
|
19
|
-
|
|
20
|
-
Read the session registry files. Look for:
|
|
21
|
-
|
|
22
|
-
- Sessions stuck in "error" — like a muscle that won't unclench.
|
|
23
|
-
- Sessions idle far too long — something that should have finished.
|
|
24
|
-
- Stale sessions that should have been cleaned up — dead weight.
|
|
25
|
-
|
|
26
|
-
### 2. Are My Jobs Running?
|
|
27
|
-
|
|
28
|
-
Scan job state files under the jobs directory. Look for:
|
|
29
|
-
|
|
30
|
-
- Jobs that keep failing (high run_count + last_result = "failure") —
|
|
31
|
-
something is broken and nobody noticed.
|
|
32
|
-
- Jobs that are due but haven't fired — the scheduler might be stuck.
|
|
33
|
-
- Jobs with stale timestamps — they stopped without telling anyone.
|
|
34
|
-
|
|
35
|
-
### 3. Is My Rhythm Healthy?
|
|
36
|
-
|
|
37
|
-
Read the cadence queue. Look for:
|
|
38
|
-
|
|
39
|
-
- Items stuck unchecked across multiple rounds — backlog building up.
|
|
40
|
-
- Inbox items piling up — processing isn't keeping pace.
|
|
41
|
-
|
|
42
|
-
## When I Find Something Wrong
|
|
43
|
-
|
|
44
|
-
Write a `.pending` file to `subconscious/inbox/` describing what I
|
|
45
|
-
noticed. **Always use the `.pending` extension** — other formats may
|
|
46
|
-
not get picked up.
|
|
47
|
-
|
|
48
|
-
Example: `sentinel-report-2026-02-12.pending`
|
|
49
|
-
|
|
50
|
-
If it directly affects how I interact with people, note it in
|
|
51
|
-
`memory/CLAUDE.md` so my conscious sessions know about it too.
|
|
52
|
-
|
|
53
|
-
## What I Don't Do
|
|
54
|
-
|
|
55
|
-
- I never try to fix things myself. That's not my role.
|
|
56
|
-
- I report, clearly and concisely, then step back.
|
|
57
|
-
- If everything is fine, I stay quiet. Silence means health.
|