@adhdev/daemon-core 0.9.82-rc.164 → 0.9.82-rc.165
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/dist/index.js +40 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -15
- package/dist/index.mjs.map +1 -1
- package/dist/providers/spec/cli-adapter.d.ts +9 -0
- package/package.json +1 -1
- package/src/providers/cli-provider-instance.ts +9 -1
- package/src/providers/provider-loader.ts +21 -11
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +4 -3
- package/src/providers/spec/cli-adapter.ts +9 -0
- package/src/providers/spec/native-history-executor.ts +13 -2
|
@@ -4,6 +4,15 @@ export declare class SpecCliAdapter implements CliAdapter {
|
|
|
4
4
|
readonly cliType: string;
|
|
5
5
|
readonly cliName: string;
|
|
6
6
|
readonly workingDir: string;
|
|
7
|
+
/**
|
|
8
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
9
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
10
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
11
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
12
|
+
* every turn until the 30s safety timeout because it expects the
|
|
13
|
+
* adapter to surface the final assistant message.
|
|
14
|
+
*/
|
|
15
|
+
readonly chatMessagesOwnedExternally: true;
|
|
7
16
|
private driver;
|
|
8
17
|
private spec;
|
|
9
18
|
private lastEvent;
|
package/package.json
CHANGED
|
@@ -966,7 +966,15 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
966
966
|
return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
|
|
967
967
|
}
|
|
968
968
|
if (parsed?.activeModal || parsed?.modal) return { reason: 'parsed_modal_active', terminal: true };
|
|
969
|
-
|
|
969
|
+
// SpecCliAdapter never populates parsed.messages — chat history flows
|
|
970
|
+
// through the daemon's native-history pipeline, not the status hook.
|
|
971
|
+
// Skipping the final-assistant gate avoids a 30s stall on every turn
|
|
972
|
+
// for spec-routed providers (agy / codex / claude / hermes).
|
|
973
|
+
const adapterOwnsMessagesElsewhere = (this.adapter as any)?.chatMessagesOwnedExternally === true;
|
|
974
|
+
if (!adapterOwnsMessagesElsewhere
|
|
975
|
+
&& !this.completionHasFinalAssistantMessage(parsed?.messages)) {
|
|
976
|
+
return { reason: 'missing_final_assistant' };
|
|
977
|
+
}
|
|
970
978
|
|
|
971
979
|
// Guard: if the screen still shows an approval/choice prompt as the last visible text,
|
|
972
980
|
// the turn is not complete even if the parsed status says idle and there is an assistant
|
|
@@ -948,18 +948,28 @@ export class ProviderLoader {
|
|
|
948
948
|
|
|
949
949
|
for (const entry of compat) {
|
|
950
950
|
if (this.matchesVersion(currentVersion, entry.ideVersion)) {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
if (
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
951
|
+
// entry.scriptDir is optional now — spec-driven providers (agy,
|
|
952
|
+
// codex on >=0.137, claude on >=2.1) only ship `spec` here, so
|
|
953
|
+
// there's nothing to load from the filesystem. SpecCliAdapter
|
|
954
|
+
// takes over via the `spec` path later in this method.
|
|
955
|
+
if (entry.scriptDir) {
|
|
956
|
+
const loaded = this.loadScriptsFromDir(type, entry.scriptDir);
|
|
957
|
+
if (loaded) {
|
|
958
|
+
resolved.scripts = loaded;
|
|
959
|
+
this.debugLog(` [compatibility] ${type} v${currentVersion} → ${entry.scriptDir}`);
|
|
960
|
+
resolved._resolvedScriptDir = entry.scriptDir;
|
|
961
|
+
resolved._resolvedScriptsSource = `compatibility:${entry.ideVersion}`;
|
|
962
|
+
if (providerDir) {
|
|
963
|
+
const fullDir = path.join(providerDir, entry.scriptDir);
|
|
964
|
+
resolved._resolvedScriptsPath = fs.existsSync(path.join(fullDir, 'scripts.js'))
|
|
965
|
+
? path.join(fullDir, 'scripts.js')
|
|
966
|
+
: fullDir;
|
|
967
|
+
}
|
|
968
|
+
matched = true;
|
|
962
969
|
}
|
|
970
|
+
} else {
|
|
971
|
+
// Spec-only entry — still counts as a match so the
|
|
972
|
+
// defaultScriptDir fallback below doesn't kick in.
|
|
963
973
|
matched = true;
|
|
964
974
|
}
|
|
965
975
|
break; // first match wins
|
|
@@ -237,14 +237,15 @@
|
|
|
237
237
|
"minItems": 1,
|
|
238
238
|
"items": {
|
|
239
239
|
"type": "object",
|
|
240
|
-
"required": ["
|
|
240
|
+
"required": ["ideVersion"],
|
|
241
241
|
"additionalProperties": false,
|
|
242
242
|
"properties": {
|
|
243
243
|
"ideVersion": { "type": "string", "description": "SemVer range." },
|
|
244
|
-
"scriptDir": { "type": "string", "pattern": "^scripts/[^/]+$" }
|
|
244
|
+
"scriptDir": { "type": "string", "pattern": "^scripts/[^/]+$" },
|
|
245
|
+
"spec": { "type": "string", "pattern": "^specs/[^/]+\\.json$", "description": "Path to declarative spec.json driving SpecCliAdapter for this version range." }
|
|
245
246
|
}
|
|
246
247
|
},
|
|
247
|
-
"description": "Maps installed agent versions to script subdirectories."
|
|
248
|
+
"description": "Maps installed agent versions to script subdirectories and/or declarative specs."
|
|
248
249
|
},
|
|
249
250
|
"defaultScriptDir": {
|
|
250
251
|
"type": "string",
|
|
@@ -30,6 +30,15 @@ export class SpecCliAdapter implements CliAdapter {
|
|
|
30
30
|
readonly cliType: string;
|
|
31
31
|
readonly cliName: string;
|
|
32
32
|
readonly workingDir: string;
|
|
33
|
+
/**
|
|
34
|
+
* Marker the daemon's finalization gate checks: `getStatus()` returns
|
|
35
|
+
* `messages: []` by design here (chat history lives in the daemon's
|
|
36
|
+
* native-history pipeline, not the adapter). Without this flag,
|
|
37
|
+
* cli-provider-instance's `missing_final_assistant` gate would stall
|
|
38
|
+
* every turn until the 30s safety timeout because it expects the
|
|
39
|
+
* adapter to surface the final assistant message.
|
|
40
|
+
*/
|
|
41
|
+
readonly chatMessagesOwnedExternally = true as const;
|
|
33
42
|
|
|
34
43
|
private driver: SpecDriver;
|
|
35
44
|
private spec: CliSpec;
|
|
@@ -256,9 +256,20 @@ function expandPath(template: string, input: NativeHistoryInput): string | null
|
|
|
256
256
|
// Re-expand ~ in case the fallback used it.
|
|
257
257
|
if (out.startsWith('~/')) out = path.join(os.homedir(), out.slice(2));
|
|
258
258
|
const now = new Date();
|
|
259
|
+
// claude (and a couple of other Anthropic-CLI–style providers) writes
|
|
260
|
+
// its per-cwd transcript under the *resolved* path
|
|
261
|
+
// (/private/tmp/foo, not /tmp/foo on macOS where /tmp -> /private/tmp).
|
|
262
|
+
// Without realpath, the spec template `~/.claude/projects/{cwd_dashed}/…`
|
|
263
|
+
// builds `-tmp-foo` and never finds the actual `-private-tmp-foo` dir.
|
|
264
|
+
const workspaceRaw = input.workspace ?? '';
|
|
265
|
+
let workspaceResolved = workspaceRaw;
|
|
266
|
+
if (workspaceRaw) {
|
|
267
|
+
try { workspaceResolved = fs.realpathSync(workspaceRaw); }
|
|
268
|
+
catch { /* path may not exist yet — keep the raw value */ }
|
|
269
|
+
}
|
|
259
270
|
const vars: Record<string, string> = {
|
|
260
|
-
cwd:
|
|
261
|
-
cwd_dashed:
|
|
271
|
+
cwd: workspaceResolved,
|
|
272
|
+
cwd_dashed: workspaceResolved.replace(/\//g, '-'),
|
|
262
273
|
session_id: input.providerSessionId || input.sessionId || input.historySessionId || '',
|
|
263
274
|
yyyy: String(now.getUTCFullYear()),
|
|
264
275
|
mm: String(now.getUTCMonth() + 1).padStart(2, '0'),
|