@a5c-ai/babysitter-sdk 0.0.184-staging.f2d9bb68 → 0.0.184
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/anycli/cache.d.ts +45 -0
- package/dist/anycli/cache.d.ts.map +1 -0
- package/dist/anycli/cache.js +118 -0
- package/dist/anycli/index.d.ts +10 -0
- package/dist/anycli/index.d.ts.map +1 -0
- package/dist/anycli/index.js +25 -0
- package/dist/anycli/types.d.ts +32 -0
- package/dist/anycli/types.d.ts.map +1 -0
- package/dist/anycli/types.js +9 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +72 -7
- package/dist/harness/invoker.d.ts.map +1 -1
- package/dist/harness/invoker.js +28 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/logging/runLogger.d.ts +2 -0
- package/dist/logging/runLogger.d.ts.map +1 -1
- package/dist/logging/runLogger.js +5 -2
- package/dist/prompts/commandTemplates.d.ts +1 -1
- package/dist/prompts/commandTemplates.d.ts.map +1 -1
- package/dist/prompts/templates/commands/anycli.md +205 -0
- package/dist/prompts/templates/commands/assimilate.md +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnyCLI Cache Management
|
|
3
|
+
*
|
|
4
|
+
* Simple filesystem-based cache for agent-generated service artifacts.
|
|
5
|
+
* One cache.json per service under ~/.a5c/anycli/cache/<service>/.
|
|
6
|
+
* The agent decides freshness, structure, and invalidation -- this module
|
|
7
|
+
* is just convenience I/O.
|
|
8
|
+
*/
|
|
9
|
+
import type { AnycliServiceCache } from "./types";
|
|
10
|
+
/**
|
|
11
|
+
* Returns the global cache directory for a service.
|
|
12
|
+
*
|
|
13
|
+
* @param service - Service identifier
|
|
14
|
+
* @returns Absolute path to `~/.a5c/anycli/cache/<service>/`
|
|
15
|
+
*/
|
|
16
|
+
export declare function getAnycliCacheDir(service: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Reads a cached service entry if one exists.
|
|
19
|
+
*
|
|
20
|
+
* Returns `null` if no cache entry exists or the entry is corrupt.
|
|
21
|
+
*
|
|
22
|
+
* @param service - Service identifier
|
|
23
|
+
* @returns The cached service entry, or null
|
|
24
|
+
*/
|
|
25
|
+
export declare function readServiceCache(service: string): Promise<AnycliServiceCache | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Writes a service cache entry atomically.
|
|
28
|
+
*
|
|
29
|
+
* @param service - Service identifier
|
|
30
|
+
* @param cache - The cache entry to write
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeServiceCache(service: string, cache: AnycliServiceCache): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Invalidates the cache for a service by removing its cache directory.
|
|
35
|
+
*
|
|
36
|
+
* @param service - Service identifier
|
|
37
|
+
*/
|
|
38
|
+
export declare function invalidateServiceCache(service: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Lists all cached service names.
|
|
41
|
+
*
|
|
42
|
+
* @returns Array of service identifier strings
|
|
43
|
+
*/
|
|
44
|
+
export declare function listCachedServices(): Promise<string[]>;
|
|
45
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/anycli/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAkBlD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAgB1F;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAc5D"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AnyCLI Cache Management
|
|
4
|
+
*
|
|
5
|
+
* Simple filesystem-based cache for agent-generated service artifacts.
|
|
6
|
+
* One cache.json per service under ~/.a5c/anycli/cache/<service>/.
|
|
7
|
+
* The agent decides freshness, structure, and invalidation -- this module
|
|
8
|
+
* is just convenience I/O.
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.getAnycliCacheDir = getAnycliCacheDir;
|
|
15
|
+
exports.readServiceCache = readServiceCache;
|
|
16
|
+
exports.writeServiceCache = writeServiceCache;
|
|
17
|
+
exports.invalidateServiceCache = invalidateServiceCache;
|
|
18
|
+
exports.listCachedServices = listCachedServices;
|
|
19
|
+
const fs_1 = require("fs");
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
const os_1 = require("os");
|
|
22
|
+
const atomic_js_1 = require("../storage/atomic.js");
|
|
23
|
+
/**
|
|
24
|
+
* Base directory name for babysitter state.
|
|
25
|
+
*/
|
|
26
|
+
const A5C_DIR = ".a5c";
|
|
27
|
+
/**
|
|
28
|
+
* Subdirectory for anycli cache within the global state dir.
|
|
29
|
+
*/
|
|
30
|
+
const ANYCLI_CACHE_SUBDIR = path_1.default.join("anycli", "cache");
|
|
31
|
+
/**
|
|
32
|
+
* Cache filename.
|
|
33
|
+
*/
|
|
34
|
+
const CACHE_FILE = "cache.json";
|
|
35
|
+
/**
|
|
36
|
+
* Returns the global cache directory for a service.
|
|
37
|
+
*
|
|
38
|
+
* @param service - Service identifier
|
|
39
|
+
* @returns Absolute path to `~/.a5c/anycli/cache/<service>/`
|
|
40
|
+
*/
|
|
41
|
+
function getAnycliCacheDir(service) {
|
|
42
|
+
return path_1.default.join((0, os_1.homedir)(), A5C_DIR, ANYCLI_CACHE_SUBDIR, service);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Reads a cached service entry if one exists.
|
|
46
|
+
*
|
|
47
|
+
* Returns `null` if no cache entry exists or the entry is corrupt.
|
|
48
|
+
*
|
|
49
|
+
* @param service - Service identifier
|
|
50
|
+
* @returns The cached service entry, or null
|
|
51
|
+
*/
|
|
52
|
+
async function readServiceCache(service) {
|
|
53
|
+
const cacheDir = getAnycliCacheDir(service);
|
|
54
|
+
const cachePath = path_1.default.join(cacheDir, CACHE_FILE);
|
|
55
|
+
try {
|
|
56
|
+
const raw = await fs_1.promises.readFile(cachePath, "utf8");
|
|
57
|
+
const entry = JSON.parse(raw);
|
|
58
|
+
return entry;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const err = error;
|
|
62
|
+
if (err.code === "ENOENT") {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
// Corrupt cache -- treat as miss
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Writes a service cache entry atomically.
|
|
71
|
+
*
|
|
72
|
+
* @param service - Service identifier
|
|
73
|
+
* @param cache - The cache entry to write
|
|
74
|
+
*/
|
|
75
|
+
async function writeServiceCache(service, cache) {
|
|
76
|
+
const cacheDir = getAnycliCacheDir(service);
|
|
77
|
+
await fs_1.promises.mkdir(cacheDir, { recursive: true });
|
|
78
|
+
const cachePath = path_1.default.join(cacheDir, CACHE_FILE);
|
|
79
|
+
await (0, atomic_js_1.writeFileAtomic)(cachePath, JSON.stringify(cache, null, 2) + "\n");
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Invalidates the cache for a service by removing its cache directory.
|
|
83
|
+
*
|
|
84
|
+
* @param service - Service identifier
|
|
85
|
+
*/
|
|
86
|
+
async function invalidateServiceCache(service) {
|
|
87
|
+
const cacheDir = getAnycliCacheDir(service);
|
|
88
|
+
try {
|
|
89
|
+
await fs_1.promises.rm(cacheDir, { recursive: true, force: true });
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
const err = error;
|
|
93
|
+
if (err.code !== "ENOENT") {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Lists all cached service names.
|
|
100
|
+
*
|
|
101
|
+
* @returns Array of service identifier strings
|
|
102
|
+
*/
|
|
103
|
+
async function listCachedServices() {
|
|
104
|
+
const baseDir = path_1.default.join((0, os_1.homedir)(), A5C_DIR, ANYCLI_CACHE_SUBDIR);
|
|
105
|
+
try {
|
|
106
|
+
const entries = await fs_1.promises.readdir(baseDir, { withFileTypes: true });
|
|
107
|
+
return entries
|
|
108
|
+
.filter((e) => e.isDirectory())
|
|
109
|
+
.map((e) => e.name);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const err = error;
|
|
113
|
+
if (err.code === "ENOENT") {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnyCLI Module
|
|
3
|
+
*
|
|
4
|
+
* Provides minimal cache infrastructure for agent-driven service integration.
|
|
5
|
+
* The agent handles all service discovery, auth resolution, and code generation
|
|
6
|
+
* at runtime -- these exports are just persistence utilities.
|
|
7
|
+
*/
|
|
8
|
+
export * from "./types";
|
|
9
|
+
export * from "./cache";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anycli/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AnyCLI Module
|
|
4
|
+
*
|
|
5
|
+
* Provides minimal cache infrastructure for agent-driven service integration.
|
|
6
|
+
* The agent handles all service discovery, auth resolution, and code generation
|
|
7
|
+
* at runtime -- these exports are just persistence utilities.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
__exportStar(require("./types"), exports);
|
|
25
|
+
__exportStar(require("./cache"), exports);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnyCLI Types
|
|
3
|
+
*
|
|
4
|
+
* Minimal type definitions for the AnyCLI service cache.
|
|
5
|
+
* The agent handles all service discovery, auth resolution, and code
|
|
6
|
+
* generation at runtime -- these types are just persistence infrastructure.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Transport type for MCP server communication.
|
|
10
|
+
*/
|
|
11
|
+
export type AnycliTransport = "stdio" | "http-sse";
|
|
12
|
+
/**
|
|
13
|
+
* Cache entry for a service's agent-generated artifacts.
|
|
14
|
+
*/
|
|
15
|
+
export interface AnycliServiceCache {
|
|
16
|
+
/** Service identifier (e.g. "github", "stripe") */
|
|
17
|
+
service: string;
|
|
18
|
+
/** Agent-defined service definition -- no rigid schema */
|
|
19
|
+
definition: Record<string, unknown>;
|
|
20
|
+
/** Generated module files: filename -> content */
|
|
21
|
+
modules: Record<string, string>;
|
|
22
|
+
/** Cache metadata */
|
|
23
|
+
metadata: {
|
|
24
|
+
/** ISO timestamp when the cache entry was created */
|
|
25
|
+
createdAt: string;
|
|
26
|
+
/** SDK version that generated this cache entry */
|
|
27
|
+
sdkVersion: string;
|
|
28
|
+
/** Hash of the definition for change detection */
|
|
29
|
+
definitionHash: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/anycli/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,UAAU,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,qBAAqB;IACrB,QAAQ,EAAE;QACR,qDAAqD;QACrD,SAAS,EAAE,MAAM,CAAC;QAClB,kDAAkD;QAClD,UAAU,EAAE,MAAM,CAAC;QACnB,kDAAkD;QAClD,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AnyCLI Types
|
|
4
|
+
*
|
|
5
|
+
* Minimal type definitions for the AnyCLI service cache.
|
|
6
|
+
* The agent handles all service discovery, auth resolution, and code
|
|
7
|
+
* generation at runtime -- these types are just persistence infrastructure.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,sBAAsB,IAAI,6BAA6B,EAAoB,MAAM,oBAAoB,CAAC;AAywB/G;;;;;;;;;GASG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BlE;AAOD,2EAA2E;AAC3E,QAAA,MAAM,sBAAsB,sCAAgC,CAAC;AAytD7D,OAAO,EAAE,aAAa,IAAI,cAAc,EAAE,sBAAsB,IAAI,uBAAuB,EAAE,CAAC;AAE9F,wBAAgB,mBAAmB;eAEf,MAAM,EAAE,GAA2B,OAAO,CAAC,MAAM,CAAC;kBA0pBpD,MAAM;EAIvB"}
|
package/dist/cli/main.js
CHANGED
|
@@ -137,6 +137,7 @@ Other commands (agents should never call these directly unless explicitly instru
|
|
|
137
137
|
babysitter harness:assimilate [--prompt <text>] [--harness <name>] [--workspace <dir>] [--model <model>] [--max-iterations <n>] [--runs-dir <dir>] [--json] [--verbose]
|
|
138
138
|
babysitter harness:doctor [--run-id <id>] [--runs-dir <dir>] [--json] [--verbose]
|
|
139
139
|
babysitter harness:contrib [--prompt <text>] [--harness <name>] [--workspace <dir>] [--model <model>] [--max-iterations <n>] [--runs-dir <dir>] [--json] [--verbose]
|
|
140
|
+
babysitter harness:anycli --service <name> [--scope <scopes>] [--mcp] [--auth-file <path>] [--transport <type>] [--prompt <text>] [--workspace <dir>] [--json] [--verbose]
|
|
140
141
|
babysitter harness:help [<topic>]
|
|
141
142
|
babysitter harness:observe [--workspace <dir>]
|
|
142
143
|
babysitter harness:user-install [--harness <name>] [--workspace <dir>] [--model <model>] [--runs-dir <dir>] [--json] [--verbose]
|
|
@@ -188,7 +189,7 @@ function parseArgs(argv) {
|
|
|
188
189
|
if (parsed.command === "--version" || parsed.command === "-v") {
|
|
189
190
|
parsed.command = "version";
|
|
190
191
|
}
|
|
191
|
-
|
|
192
|
+
let positionals = [];
|
|
192
193
|
for (let i = 0; i < rest.length; i += 1) {
|
|
193
194
|
const arg = rest[i];
|
|
194
195
|
if (arg === "--help" || arg === "-h") {
|
|
@@ -521,6 +522,27 @@ function parseArgs(argv) {
|
|
|
521
522
|
parsed.logSource = expectFlagValue(rest, ++i, "--source");
|
|
522
523
|
continue;
|
|
523
524
|
}
|
|
525
|
+
// harness:anycli flags
|
|
526
|
+
if (arg === "--service") {
|
|
527
|
+
parsed.anycliService = expectFlagValue(rest, ++i, "--service");
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
if (arg === "--scope") {
|
|
531
|
+
parsed.anycliScope = expectFlagValue(rest, ++i, "--scope");
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
if (arg === "--mcp") {
|
|
535
|
+
parsed.anycliMcp = true;
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (arg === "--auth-file") {
|
|
539
|
+
parsed.anycliAuthFile = expectFlagValue(rest, ++i, "--auth-file");
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (arg === "--transport") {
|
|
543
|
+
parsed.anycliTransport = expectFlagValue(rest, ++i, "--transport");
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
524
546
|
// harness:cleanup flags
|
|
525
547
|
if (arg === "--keep-days") {
|
|
526
548
|
const raw = expectFlagValue(rest, ++i, "--keep-days");
|
|
@@ -606,8 +628,17 @@ function parseArgs(argv) {
|
|
|
606
628
|
else if (parsed.command === "harness:cleanup" ||
|
|
607
629
|
parsed.command === "harness:assimilate" ||
|
|
608
630
|
parsed.command === "harness:contrib" ||
|
|
631
|
+
parsed.command === "harness:anycli" ||
|
|
609
632
|
parsed.command === "harness:user-install" ||
|
|
610
633
|
parsed.command === "harness:project-install") {
|
|
634
|
+
// For harness:anycli, first positional matching a service name pattern becomes the service
|
|
635
|
+
if (parsed.command === "harness:anycli" &&
|
|
636
|
+
!parsed.anycliService &&
|
|
637
|
+
positionals.length > 0 &&
|
|
638
|
+
/^[a-zA-Z0-9-]+$/.test(positionals[0])) {
|
|
639
|
+
parsed.anycliService = positionals[0];
|
|
640
|
+
positionals = positionals.slice(1);
|
|
641
|
+
}
|
|
611
642
|
// Positionals join as prompt text if no --prompt given
|
|
612
643
|
if (positionals.length > 0 && !parsed.prompt) {
|
|
613
644
|
parsed.prompt = positionals.join(" ");
|
|
@@ -999,10 +1030,9 @@ async function handleRunCreate(parsed) {
|
|
|
999
1030
|
});
|
|
1000
1031
|
const entrySpec = formatEntrypointSpecifier(result.metadata.entrypoint);
|
|
1001
1032
|
// --- Harness-specific session binding ---
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
1004
|
-
|
|
1005
|
-
const shouldBindSession = parsed.sessionId !== undefined;
|
|
1033
|
+
// Attempt session binding when --session-id is provided or --harness is
|
|
1034
|
+
// explicitly passed (the adapter resolves session IDs from env vars).
|
|
1035
|
+
const shouldBindSession = parsed.sessionId !== undefined || parsed.harness !== undefined;
|
|
1006
1036
|
const adapter = shouldBindSession
|
|
1007
1037
|
? (parsed.harness ? (0, harness_1.getAdapterByName)(parsed.harness) : (0, harness_1.getAdapter)())
|
|
1008
1038
|
: undefined;
|
|
@@ -1035,8 +1065,8 @@ async function handleRunCreate(parsed) {
|
|
|
1035
1065
|
json: parsed.json,
|
|
1036
1066
|
});
|
|
1037
1067
|
}
|
|
1038
|
-
else
|
|
1039
|
-
// --session-id was
|
|
1068
|
+
else {
|
|
1069
|
+
// --session-id or --harness was passed but the adapter could not resolve a session ID.
|
|
1040
1070
|
sessionBound = {
|
|
1041
1071
|
harness: parsed.harness ?? adapter.name,
|
|
1042
1072
|
sessionId: "",
|
|
@@ -1981,6 +2011,7 @@ const VALID_COMMANDS = [
|
|
|
1981
2011
|
"harness:assimilate",
|
|
1982
2012
|
"harness:doctor",
|
|
1983
2013
|
"harness:contrib",
|
|
2014
|
+
"harness:anycli",
|
|
1984
2015
|
"harness:help",
|
|
1985
2016
|
"harness:observe",
|
|
1986
2017
|
"harness:user-install",
|
|
@@ -2068,6 +2099,7 @@ ${bold}SECONDARY COMMANDS${reset}
|
|
|
2068
2099
|
${cyan}harness:cleanup${reset} [--keep-days <n>] Clean up old runs and orphaned processes
|
|
2069
2100
|
${cyan}harness:assimilate${reset} [--prompt <text>] Convert external methodology to babysitter processes
|
|
2070
2101
|
${cyan}harness:contrib${reset} [--prompt <text>] Submit feedback or contribute to babysitter
|
|
2102
|
+
${cyan}harness:anycli${reset} --service <name> Generate CLI/MCP tools for any service
|
|
2071
2103
|
${cyan}harness:user-install${reset} First-time user onboarding
|
|
2072
2104
|
${cyan}harness:project-install${reset} Onboard a project for babysitter
|
|
2073
2105
|
${cyan}harness:observe${reset} Launch real-time observer dashboard
|
|
@@ -2769,6 +2801,39 @@ function createBabysitterCli() {
|
|
|
2769
2801
|
interactive: parsed.interactive,
|
|
2770
2802
|
});
|
|
2771
2803
|
}
|
|
2804
|
+
if (parsed.command === "harness:anycli") {
|
|
2805
|
+
if (!parsed.anycliService) {
|
|
2806
|
+
console.error("--service is required for harness:anycli");
|
|
2807
|
+
console.error(USAGE);
|
|
2808
|
+
return 1;
|
|
2809
|
+
}
|
|
2810
|
+
if (parsed.anycliTransport === "websocket") {
|
|
2811
|
+
console.error("Error: WebSocket transport is not yet supported.\n" +
|
|
2812
|
+
"Use --transport stdio (default) or --transport http-sse instead.");
|
|
2813
|
+
return 1;
|
|
2814
|
+
}
|
|
2815
|
+
const { handleHarnessCreateRun } = await Promise.resolve().then(() => __importStar(require("./commands/harnessCreateRun")));
|
|
2816
|
+
const anycliPrompt = (0, prompts_1.renderCommandTemplate)("anycli", {
|
|
2817
|
+
serviceName: parsed.anycliService,
|
|
2818
|
+
scope: parsed.anycliScope ?? "*",
|
|
2819
|
+
mcpMode: parsed.anycliMcp ? "true" : "",
|
|
2820
|
+
authFile: parsed.anycliAuthFile ?? "",
|
|
2821
|
+
transport: parsed.anycliTransport ?? "stdio",
|
|
2822
|
+
userPrompt: parsed.prompt ?? "",
|
|
2823
|
+
});
|
|
2824
|
+
return await handleHarnessCreateRun({
|
|
2825
|
+
prompt: anycliPrompt,
|
|
2826
|
+
harness: parsed.harness,
|
|
2827
|
+
processPath: parsed.processPath,
|
|
2828
|
+
workspace: parsed.workspace,
|
|
2829
|
+
model: parsed.model,
|
|
2830
|
+
maxIterations: parsed.maxIterations,
|
|
2831
|
+
runsDir: parsed.runsDir,
|
|
2832
|
+
json: parsed.json,
|
|
2833
|
+
verbose: parsed.verbose,
|
|
2834
|
+
interactive: parsed.interactive,
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2772
2837
|
if (parsed.command === "harness:help") {
|
|
2773
2838
|
return handleHarnessHelp(parsed);
|
|
2774
2839
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoker.d.ts","sourceRoot":"","sources":["../../src/harness/invoker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"invoker.d.ts","sourceRoot":"","sources":["../../src/harness/invoker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AASzE,wDAAwD;AACxD,UAAU,cAAc;IACtB,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IACpC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAQD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAe3D,CAAC;AAuDX;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,MAAM,EAAE,CA+BV;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAqI9B"}
|
package/dist/harness/invoker.js
CHANGED
|
@@ -48,6 +48,7 @@ const node_fs_1 = require("node:fs");
|
|
|
48
48
|
const os = __importStar(require("node:os"));
|
|
49
49
|
const path = __importStar(require("node:path"));
|
|
50
50
|
const discovery_1 = require("./discovery");
|
|
51
|
+
const piWrapper_1 = require("./piWrapper");
|
|
51
52
|
const exceptions_1 = require("../runtime/exceptions");
|
|
52
53
|
/**
|
|
53
54
|
* Mapping from harness identifier to CLI command and flag details.
|
|
@@ -68,6 +69,11 @@ exports.HARNESS_CLI_MAP = {
|
|
|
68
69
|
cursor: { cli: "cursor", supportsModel: true, promptStyle: "positional", baseArgs: ["agent"], workspaceFlag: "--workspace" },
|
|
69
70
|
opencode: { cli: "opencode", supportsModel: false, promptStyle: "flag" },
|
|
70
71
|
};
|
|
72
|
+
const PROGRAMMATIC_ONLY_HARNESSES = ["internal"];
|
|
73
|
+
const SUPPORTED_HARNESS_NAMES = [
|
|
74
|
+
...PROGRAMMATIC_ONLY_HARNESSES,
|
|
75
|
+
...Object.keys(exports.HARNESS_CLI_MAP),
|
|
76
|
+
];
|
|
71
77
|
function quotePowerShellArg(value) {
|
|
72
78
|
return `'${value.replace(/'/g, "''")}'`;
|
|
73
79
|
}
|
|
@@ -114,9 +120,9 @@ function buildLaunchSpec(name, spec, cliPath, args, promptFilePath) {
|
|
|
114
120
|
function buildHarnessArgs(name, options) {
|
|
115
121
|
const spec = exports.HARNESS_CLI_MAP[name];
|
|
116
122
|
if (!spec) {
|
|
117
|
-
throw new exceptions_1.BabysitterRuntimeError("UnknownHarnessError", `Unknown harness: "${name}". Supported harnesses: ${
|
|
123
|
+
throw new exceptions_1.BabysitterRuntimeError("UnknownHarnessError", `Unknown harness: "${name}". Supported harnesses: ${SUPPORTED_HARNESS_NAMES.join(", ")}`, {
|
|
118
124
|
category: exceptions_1.ErrorCategory.Validation,
|
|
119
|
-
suggestions: [`Did you mean one of: ${
|
|
125
|
+
suggestions: [`Did you mean one of: ${SUPPORTED_HARNESS_NAMES.join(", ")}?`],
|
|
120
126
|
nextSteps: ["Use a supported harness name"],
|
|
121
127
|
});
|
|
122
128
|
}
|
|
@@ -156,11 +162,29 @@ const DEFAULT_TIMEOUT_MS = 900_000;
|
|
|
156
162
|
* not installed.
|
|
157
163
|
*/
|
|
158
164
|
async function invokeHarness(name, options) {
|
|
165
|
+
if (name === "internal") {
|
|
166
|
+
const session = (0, piWrapper_1.createPiSession)({
|
|
167
|
+
workspace: options.workspace,
|
|
168
|
+
model: options.model,
|
|
169
|
+
timeout: options.timeout,
|
|
170
|
+
ephemeral: true,
|
|
171
|
+
});
|
|
172
|
+
try {
|
|
173
|
+
const result = await session.prompt(options.prompt, options.timeout);
|
|
174
|
+
return {
|
|
175
|
+
...result,
|
|
176
|
+
harness: "internal",
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
session.dispose();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
159
183
|
const spec = exports.HARNESS_CLI_MAP[name];
|
|
160
184
|
if (!spec) {
|
|
161
|
-
throw new exceptions_1.BabysitterRuntimeError("UnknownHarnessError", `Unknown harness: "${name}". Supported harnesses: ${
|
|
185
|
+
throw new exceptions_1.BabysitterRuntimeError("UnknownHarnessError", `Unknown harness: "${name}". Supported harnesses: ${SUPPORTED_HARNESS_NAMES.join(", ")}`, {
|
|
162
186
|
category: exceptions_1.ErrorCategory.Validation,
|
|
163
|
-
suggestions: [`Did you mean one of: ${
|
|
187
|
+
suggestions: [`Did you mean one of: ${SUPPORTED_HARNESS_NAMES.join(", ")}?`],
|
|
164
188
|
nextSteps: ["Use a supported harness name"],
|
|
165
189
|
});
|
|
166
190
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,10 +10,33 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
13
18
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
20
|
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
16
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.anycli = void 0;
|
|
17
40
|
__exportStar(require("./runtime"), exports);
|
|
18
41
|
__exportStar(require("./runtime/types"), exports);
|
|
19
42
|
__exportStar(require("./storage"), exports);
|
|
@@ -29,3 +52,4 @@ __exportStar(require("./plugins"), exports);
|
|
|
29
52
|
__exportStar(require("./interaction"), exports);
|
|
30
53
|
__exportStar(require("./prompts"), exports);
|
|
31
54
|
__exportStar(require("./logging"), exports);
|
|
55
|
+
exports.anycli = __importStar(require("./anycli/index"));
|
|
@@ -79,5 +79,7 @@ export declare function createRunLogger(options: RunLoggerOptions): {
|
|
|
79
79
|
error: (label: string, message: string, context?: Record<string, unknown>) => void;
|
|
80
80
|
/** Raw write — lets callers specify the level explicitly. */
|
|
81
81
|
log: (level: RunLogLevel, label: string, message: string, context?: Record<string, unknown>) => void;
|
|
82
|
+
/** Returns a promise that resolves when all queued writes have completed. */
|
|
83
|
+
flush: () => Promise<void>;
|
|
82
84
|
};
|
|
83
85
|
//# sourceMappingURL=runLogger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runLogger.d.ts","sourceRoot":"","sources":["../../src/logging/runLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D,oDAAoD;AACpD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAQD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AASD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAMvF;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAexD;AAMD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,CAQjB;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"runLogger.d.ts","sourceRoot":"","sources":["../../src/logging/runLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D,oDAAoD;AACpD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,CAAC;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAQD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AASD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAMvF;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAexD;AAMD;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,CAQjB;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB;mBA2BtC,MAAM,WAAW,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;kBAE3D,MAAM,WAAW,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;kBAE1D,MAAM,WAAW,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;mBAEzD,MAAM,WAAW,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzE,6DAA6D;iBA9BzC,WAAW,SAAS,MAAM,WAAW,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAAI;IAgCzG,6EAA6E;;EAGhF"}
|
|
@@ -151,8 +151,9 @@ async function appendRunLog(entry, options) {
|
|
|
151
151
|
*/
|
|
152
152
|
function createRunLogger(options) {
|
|
153
153
|
const { runId, processId, logDir, source, type: defaultType } = options;
|
|
154
|
+
let pending = Promise.resolve();
|
|
154
155
|
function write(level, label, message, context) {
|
|
155
|
-
|
|
156
|
+
pending = pending.then(() => appendRunLog({
|
|
156
157
|
timestamp: new Date().toISOString(),
|
|
157
158
|
level,
|
|
158
159
|
type: defaultType,
|
|
@@ -162,7 +163,7 @@ function createRunLogger(options) {
|
|
|
162
163
|
processId,
|
|
163
164
|
source,
|
|
164
165
|
context,
|
|
165
|
-
}, { logDir }).catch(() => {
|
|
166
|
+
}, { logDir }).then(() => undefined)).catch(() => {
|
|
166
167
|
// Never let logging break orchestration.
|
|
167
168
|
});
|
|
168
169
|
}
|
|
@@ -173,5 +174,7 @@ function createRunLogger(options) {
|
|
|
173
174
|
error: (label, message, context) => write("error", label, message, context),
|
|
174
175
|
/** Raw write — lets callers specify the level explicitly. */
|
|
175
176
|
log: write,
|
|
177
|
+
/** Returns a promise that resolves when all queued writes have completed. */
|
|
178
|
+
flush: () => pending,
|
|
176
179
|
};
|
|
177
180
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CommandTemplateName = "assimilate" | "cleanup" | "contrib" | "doctor" | "forever" | "project-install" | "retrospect" | "user-install";
|
|
1
|
+
export type CommandTemplateName = "anycli" | "assimilate" | "cleanup" | "contrib" | "doctor" | "forever" | "project-install" | "retrospect" | "user-install";
|
|
2
2
|
export declare function resolveCommandTemplatePath(templateName: CommandTemplateName): string;
|
|
3
3
|
export declare function renderCommandTemplate(templateName: CommandTemplateName, extras?: Record<string, string>): string;
|
|
4
4
|
//# sourceMappingURL=commandTemplates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandTemplates.d.ts","sourceRoot":"","sources":["../../src/prompts/commandTemplates.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,GACT,iBAAiB,GACjB,YAAY,GACZ,cAAc,CAAC;AAsBnB,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,mBAAmB,GAAG,MAAM,CAEpF;AAED,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,mBAAmB,EACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAGR"}
|
|
1
|
+
{"version":3,"file":"commandTemplates.d.ts","sourceRoot":"","sources":["../../src/prompts/commandTemplates.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAC3B,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,SAAS,GACT,QAAQ,GACR,SAAS,GACT,iBAAiB,GACjB,YAAY,GACZ,cAAc,CAAC;AAsBnB,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,mBAAmB,GAAG,MAAM,CAEpF;AAED,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,mBAAmB,EACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAGR"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
[ANYCLI MODE] Dynamic service integration agent for any external service
|
|
2
|
+
|
|
3
|
+
Target service: {{serviceName}}
|
|
4
|
+
Scope: {{scope}}
|
|
5
|
+
{{#mcpMode}}MCP mode: enabled (transport: {{transport}}){{/mcpMode}}
|
|
6
|
+
{{^mcpMode}}Mode: ad-hoc execution{{/mcpMode}}
|
|
7
|
+
{{#authFile}}Auth file: {{authFile}}{{/authFile}}
|
|
8
|
+
{{#userPrompt}}User request: {{userPrompt}}{{/userPrompt}}
|
|
9
|
+
|
|
10
|
+
You are a service integration agent. You handle EVERYTHING dynamically: researching the service, figuring out authentication, writing code, and generating MCP servers. There are no pre-built templates or hardcoded patterns -- you discover and create everything at runtime based on what you learn about the service.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1: Service Discovery
|
|
15
|
+
|
|
16
|
+
**Goal:** Learn everything about **{{serviceName}}** and build a service definition.
|
|
17
|
+
|
|
18
|
+
### 1a. Check Cache
|
|
19
|
+
|
|
20
|
+
Check `~/.a5c/anycli/cache/{{serviceName}}/cache.json` for an existing cache entry.
|
|
21
|
+
|
|
22
|
+
If found, inspect `definition`, `modules`, and `metadata.createdAt`. You decide whether the cache is fresh enough to use. If the definition covers the requested scope (`{{scope}}`), skip to Phase 3 or 4.
|
|
23
|
+
|
|
24
|
+
### 1b. Research the Service
|
|
25
|
+
|
|
26
|
+
If no usable cache exists, research **{{serviceName}}** thoroughly:
|
|
27
|
+
|
|
28
|
+
1. **Web search** for official API documentation, OpenAPI/Swagger specs, developer guides.
|
|
29
|
+
2. **Identify**: base URL(s), API versioning scheme, authentication methods (specific to THIS service -- not generic patterns), rate limits, pagination style, error response format.
|
|
30
|
+
3. **Check** for existing CLI tools, SDKs (npm/pip/etc.), or MCP servers that already integrate with this service.
|
|
31
|
+
4. **Filter by scope**: `{{scope}}` -- if `*`, cover all major endpoint groups. If comma-separated, focus on those specific areas.
|
|
32
|
+
|
|
33
|
+
### 1c. Build the Definition
|
|
34
|
+
|
|
35
|
+
Construct a service definition object with whatever structure makes sense for **{{serviceName}}**. There is no rigid schema -- include the fields that are relevant:
|
|
36
|
+
|
|
37
|
+
- `name`, `apiBaseUrl`, `displayName`, `description`
|
|
38
|
+
- Authentication details specific to this service
|
|
39
|
+
- Endpoint groups filtered by scope
|
|
40
|
+
- Any service-specific metadata (rate limits, pagination, versioning, etc.)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Phase 2: Auth Resolution
|
|
45
|
+
|
|
46
|
+
**Goal:** Figure out what credentials **{{serviceName}}** needs and find them.
|
|
47
|
+
|
|
48
|
+
This is entirely service-specific. Do NOT use generic patterns like `SERVICE_API_KEY`. Instead:
|
|
49
|
+
|
|
50
|
+
1. **Read the service docs** to understand what auth method(s) it supports (API keys, OAuth2, bearer tokens, basic auth, etc.) and what the credentials look like.
|
|
51
|
+
{{#authFile}}
|
|
52
|
+
2. **Check the auth file** at `{{authFile}}` for credentials. Parse it as `.env` or JSON format.
|
|
53
|
+
{{/authFile}}
|
|
54
|
+
{{^authFile}}
|
|
55
|
+
2. **No auth file provided**, skip to next step.
|
|
56
|
+
{{/authFile}}
|
|
57
|
+
3. **Check environment variables** using the naming conventions that are standard for THIS specific service. For example: `GITHUB_TOKEN` for GitHub, `STRIPE_API_KEY` for Stripe, `OPENAI_API_KEY` for OpenAI -- whatever the service's own docs and ecosystem use.
|
|
58
|
+
4. **Check workspace `.env`** file for the same service-specific variable names.
|
|
59
|
+
5. **If credentials are missing**, report exactly what is needed, where to get it (with links to the service's credential/API key page if known), and what env var name to use.
|
|
60
|
+
|
|
61
|
+
**Security:** Never log or hardcode credentials. Generated code must read credentials from environment variables at runtime.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Phase 3: Code Generation
|
|
66
|
+
|
|
67
|
+
**Goal:** Write utility modules (`.mjs` files) based on what you learned about **{{serviceName}}**.
|
|
68
|
+
|
|
69
|
+
You decide the module structure, function signatures, and types based on the service's actual API. General guidelines:
|
|
70
|
+
|
|
71
|
+
- **HTTP client**: Use `fetch()` only -- zero external dependencies. Include auth headers, retries on 429/5xx, and the service's pagination pattern.
|
|
72
|
+
- **Scope modules**: One file per scope group with async functions for each endpoint. Full JSDoc.
|
|
73
|
+
- **Barrel export**: An `index.mjs` re-exporting everything.
|
|
74
|
+
- **No hardcoded credentials**: Read from env vars at runtime.
|
|
75
|
+
|
|
76
|
+
Write all modules to `~/.a5c/anycli/cache/{{serviceName}}/modules/`.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
{{#mcpMode}}
|
|
81
|
+
## Phase 4: MCP Server Generation
|
|
82
|
+
|
|
83
|
+
**Goal:** Write and start a complete MCP server for **{{serviceName}}**.
|
|
84
|
+
|
|
85
|
+
Write a self-contained `mcp-server.mjs` file from scratch using `@modelcontextprotocol/sdk` patterns:
|
|
86
|
+
|
|
87
|
+
- Import `McpServer` from `@modelcontextprotocol/sdk/server/mcp.js`
|
|
88
|
+
- Import the appropriate transport for `{{transport}}`:
|
|
89
|
+
- `stdio`: `StdioServerTransport` from `.../server/stdio.js`
|
|
90
|
+
- `http-sse`: `SSEServerTransport` from `.../server/sse.js`
|
|
91
|
+
- Register MCP tools based on the scope modules you generated
|
|
92
|
+
- Each tool: descriptive name (`{{serviceName}}_<action>`), JSON Schema input, handler that calls the scope module functions
|
|
93
|
+
- Graceful shutdown on SIGINT/SIGTERM
|
|
94
|
+
|
|
95
|
+
Save to `~/.a5c/anycli/cache/{{serviceName}}/mcp-server.mjs` and start it.
|
|
96
|
+
|
|
97
|
+
Output MCP client config for the user:
|
|
98
|
+
```json
|
|
99
|
+
{ "name": "{{serviceName}}-anycli", "transport": "{{transport}}",
|
|
100
|
+
"command": "node", "args": ["~/.a5c/anycli/cache/{{serviceName}}/mcp-server.mjs"] }
|
|
101
|
+
```
|
|
102
|
+
{{/mcpMode}}
|
|
103
|
+
|
|
104
|
+
{{^mcpMode}}
|
|
105
|
+
## Phase 4: Ad-hoc Execution
|
|
106
|
+
|
|
107
|
+
**Goal:** Fulfill the user's request using the generated modules.
|
|
108
|
+
|
|
109
|
+
{{#userPrompt}}
|
|
110
|
+
### Execute request:
|
|
111
|
+
> {{userPrompt}}
|
|
112
|
+
|
|
113
|
+
1. Determine which API calls are needed.
|
|
114
|
+
2. Import the generated modules from `~/.a5c/anycli/cache/{{serviceName}}/modules/`.
|
|
115
|
+
3. Execute operations in logical order, chaining multi-step calls as needed.
|
|
116
|
+
4. Present results clearly: tables for lists, formatted JSON for objects, summaries for aggregations.
|
|
117
|
+
{{/userPrompt}}
|
|
118
|
+
|
|
119
|
+
{{^userPrompt}}
|
|
120
|
+
### Interactive discovery:
|
|
121
|
+
No specific request provided. List the generated modules and their exported functions with descriptions and parameters. Suggest common use cases for **{{serviceName}}** and ask the user what they want to do.
|
|
122
|
+
{{/userPrompt}}
|
|
123
|
+
{{/mcpMode}}
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Phase 5: Caching
|
|
128
|
+
|
|
129
|
+
**Goal:** Save everything to `~/.a5c/anycli/cache/{{serviceName}}/cache.json` for reuse.
|
|
130
|
+
|
|
131
|
+
Write a single cache entry with this structure:
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"service": "{{serviceName}}",
|
|
135
|
+
"definition": { "...your service definition from Phase 1..." },
|
|
136
|
+
"modules": { "filename.mjs": "...file content..." },
|
|
137
|
+
"metadata": {
|
|
138
|
+
"createdAt": "<ISO timestamp>",
|
|
139
|
+
"sdkVersion": "<version>",
|
|
140
|
+
"definitionHash": "<hash of the definition>"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The SDK provides `readServiceCache`, `writeServiceCache`, `invalidateServiceCache`, and `listCachedServices` functions in `@a5c-ai/babysitter-sdk` (anycli module) for this purpose.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Phase 6: Verification
|
|
150
|
+
|
|
151
|
+
1. **Syntax check**: `node --check` on each generated `.mjs` file.
|
|
152
|
+
2. **Import check**: Dynamic import of `modules/index.mjs` to verify exports.
|
|
153
|
+
3. **Smoke test**: If auth is available, make one lightweight API call (health endpoint or list with limit=1).
|
|
154
|
+
{{#mcpMode}}
|
|
155
|
+
4. **MCP validation**: Verify the server module loads and tool count matches expectations.
|
|
156
|
+
{{/mcpMode}}
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Error Handling
|
|
161
|
+
|
|
162
|
+
- **Unknown service**: Report, suggest alternative names or provide a base URL. Stop.
|
|
163
|
+
- **Missing credentials**: Report what was tried, provide setup instructions with the correct env var names for this service. Stop.
|
|
164
|
+
- **Rate limiting**: Wait if reset < 60s, otherwise report partial results.
|
|
165
|
+
- **Network errors**: Report endpoint URL and error. Suggest checking connectivity.
|
|
166
|
+
- **Security invariant**: Never include credentials in output, errors, logs, or generated comments.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Output Format
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
==============================================
|
|
174
|
+
ANYCLI SERVICE INTEGRATION REPORT
|
|
175
|
+
Service: {{serviceName}} Scope: {{scope}}
|
|
176
|
+
==============================================
|
|
177
|
+
|
|
178
|
+
OVERALL STATUS: <READY | PARTIAL | FAILED>
|
|
179
|
+
|
|
180
|
+
| # | Phase | Status |
|
|
181
|
+
|----|--------------------|--------|
|
|
182
|
+
| 1 | Service Discovery | <s> |
|
|
183
|
+
| 2 | Auth Resolution | <s> |
|
|
184
|
+
| 3 | Code Generation | <s> |
|
|
185
|
+
| 4 | Execution | <s> |
|
|
186
|
+
| 5 | Caching | <s> |
|
|
187
|
+
| 6 | Verification | <s> |
|
|
188
|
+
|
|
189
|
+
Cache: ~/.a5c/anycli/cache/{{serviceName}}/
|
|
190
|
+
Modules: <list> Endpoints: <count> Auth: <method> (<source>)
|
|
191
|
+
{{#mcpMode}}
|
|
192
|
+
MCP server: ~/.a5c/anycli/cache/{{serviceName}}/mcp-server.mjs
|
|
193
|
+
Transport: {{transport}}
|
|
194
|
+
{{/mcpMode}}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Status:** READY = all phases passed. PARTIAL = warnings but no failures. FAILED = any phase failed.
|
|
198
|
+
{{#mcpMode}}
|
|
199
|
+
Include MCP connection instructions for the user's harness.
|
|
200
|
+
{{/mcpMode}}
|
|
201
|
+
{{^mcpMode}}
|
|
202
|
+
{{#userPrompt}}
|
|
203
|
+
Include execution results prominently before the phase summary.
|
|
204
|
+
{{/userPrompt}}
|
|
205
|
+
{{/mcpMode}}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
Resolve the active process library with `babysitter process-library:active --json` before selecting the workflow.
|
|
6
6
|
Read `binding.dir` from that JSON and treat it as the active process-library root. The assimilation process must be selected from that active library path, not guessed from some other repo-relative location.
|
|
7
7
|
Use the assimilation domain processes under the active library root. Available workflow paths relative to `binding.dir`:
|
|
8
|
-
- `specializations/
|
|
9
|
-
- `specializations/
|
|
8
|
+
- `specializations/meta/assimilation/workflows/methodology-assimilation` - Learn an external methodology from its repo/spec/source and convert it into babysitter processes, skills, and agents
|
|
9
|
+
- `specializations/meta/assimilation/harness/<name>` - Use the matching harness integration process for a specific harness target (for example `codex`, `opencode`, `gemini-cli`, `openclaw`, `antigravity`, or the generic fallback in the same directory)
|
|
10
10
|
Search the active assimilation subtree under `binding.dir` first and pick the concrete process from there before authoring anything.
|
|
11
11
|
If `Target to assimilate` is provided below, do not ask the user to restate the initial prompt or identify the target again. Only ask follow-up questions for genuinely missing constraints after inspecting the workspace and process-library context.
|
|
12
12
|
|
|
@@ -25,8 +25,8 @@ babysitter process-library:active --json
|
|
|
25
25
|
Run the process after formalizing it.
|
|
26
26
|
|
|
27
27
|
Available assimilation workflows:
|
|
28
|
-
- **methodology-assimilation** (`specializations/
|
|
29
|
-
- **harness integration** (`specializations/
|
|
28
|
+
- **methodology-assimilation** (`specializations/meta/assimilation/workflows/methodology-assimilation`) - Learns an external methodology from its repo and converts procedural instructions, commands, and manual flows into babysitter processes with refactored skills and agents. Supports output as methodology or specialization.
|
|
29
|
+
- **harness integration** (`specializations/meta/assimilation/harness/*`) - Integrates babysitter SDK with a specific AI coding harness (generic, codex, opencode, gemini-cli, openclaw, antigravity).
|
|
30
30
|
|
|
31
31
|
During the interview phase, determine which assimilation workflow to use based on the user's target:
|
|
32
32
|
- If the target is a **repo URL or methodology name** then use the methodology-assimilation workflow.
|
package/package.json
CHANGED