@theokit/cli 3.0.2 → 4.0.1
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 +257 -0
- package/LICENSE +2 -2
- package/README.md +13 -0
- package/dist/bin/theokit.cjs +59 -28
- package/dist/bin/theokit.cjs.map +1 -1
- package/dist/bin/theokit.js +59 -28
- package/dist/bin/theokit.js.map +1 -1
- package/dist/index.cjs +59 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -10
- package/dist/index.d.ts +127 -10
- package/dist/index.js +59 -28
- package/dist/index.js.map +1 -1
- package/package.json +19 -16
- package/templates/chatbot/.env.example +14 -0
- package/templates/chatbot/README.md +34 -0
- package/templates/chatbot/package.json +20 -0
- package/templates/chatbot/src/index.ts +88 -0
- package/templates/chatbot/tsconfig.json +12 -0
- package/templates/minimal/README.md +1 -1
- package/templates/multi-agent/.env.example +14 -0
- package/templates/multi-agent/README.md +33 -0
- package/templates/multi-agent/package.json +20 -0
- package/templates/multi-agent/src/index.ts +90 -0
- package/templates/multi-agent/tsconfig.json +12 -0
- package/templates/rag-agent/.env.example +14 -0
- package/templates/rag-agent/README.md +34 -0
- package/templates/rag-agent/package.json +21 -0
- package/templates/rag-agent/src/index.ts +115 -0
- package/templates/rag-agent/tsconfig.json +12 -0
- package/templates/telegram-bot/README.md +4 -4
- package/templates/telegram-bot/package.json +2 -2
- package/templates/telegram-bot/src/index.ts +2 -2
- package/templates/workflow-automation/.env.example +14 -0
- package/templates/workflow-automation/README.md +33 -0
- package/templates/workflow-automation/package.json +20 -0
- package/templates/workflow-automation/src/index.ts +86 -0
- package/templates/workflow-automation/tsconfig.json +12 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,28 +1,145 @@
|
|
|
1
|
+
import { Agent } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The shape of `eval.config.{ts,mjs}`, consumed by `theokit eval` (T5.1, ADR D199).
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import type { EvalConfig } from "@theokit/cli";
|
|
8
|
+
*
|
|
9
|
+
* export default {
|
|
10
|
+
* agent: { model: "gpt-4o-mini" },
|
|
11
|
+
* dataset: [{ input: "2+2?", expected: "4" }],
|
|
12
|
+
* scorers: [{ name: "exact", score: (out, exp) => ({ score: out.trim() === exp ? 1 : 0 }) }],
|
|
13
|
+
* } satisfies EvalConfig;
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The runner now delegates to the SDK's `Eval.create().run()` (D212); this shape survived that swap
|
|
17
|
+
* unchanged, which is what D199 was for.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Outcome of a single scoring decision.
|
|
24
|
+
*
|
|
25
|
+
* Exported because `Scorer` — which IS public — returns it: a user writing a scorer could not name
|
|
26
|
+
* its return type. Same shape as the `MemoryProviderFactory` defect in #335, one level down.
|
|
27
|
+
*/
|
|
28
|
+
interface Score {
|
|
29
|
+
/** Numeric score in [0, 1]. Use 1.0 for "pass", 0.0 for "fail". */
|
|
30
|
+
readonly score: number;
|
|
31
|
+
/** Optional human-readable reason for the score (shown in the report). */
|
|
32
|
+
readonly reason?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Grades one agent output. May be sync or async (EC-K); both are awaited.
|
|
36
|
+
*
|
|
37
|
+
* `expected` is whatever the dataset entry carried, `unknown` because nothing constrains it — narrow
|
|
38
|
+
* it yourself. It is `undefined` for entries that declared no `expected`, so a scorer that assumes a
|
|
39
|
+
* string has to handle that.
|
|
40
|
+
*
|
|
41
|
+
* Scoring runs inside the SDK's eval engine, which reports per-ROW failures: a failed row carries an
|
|
42
|
+
* `error` and is counted in `errorRows` rather than aborting the suite.
|
|
43
|
+
*/
|
|
44
|
+
type Scorer = (output: string, expected?: unknown) => Score | Promise<Score>;
|
|
45
|
+
/**
|
|
46
|
+
* One evaluation case: the prompt sent to the agent, and an optional expected value handed to every
|
|
47
|
+
* scorer untouched (no comparison is performed for you).
|
|
48
|
+
*/
|
|
49
|
+
interface DatasetEntry {
|
|
50
|
+
readonly input: string;
|
|
51
|
+
readonly expected?: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The `Agent.create()` options object, inferred from the installed `@theokit/sdk` rather than
|
|
55
|
+
* re-declared. Whatever that version accepts — model, tools, plugins — is accepted here.
|
|
56
|
+
*/
|
|
57
|
+
type EvalAgentOptions = Parameters<typeof Agent.create>[0];
|
|
58
|
+
/**
|
|
59
|
+
* The DEFAULT export of `eval.config.{ts,mjs}`. A named export is not read.
|
|
60
|
+
*
|
|
61
|
+
* `theokit eval` checks only that `dataset` and `scorers` are arrays and `agent` is an object; every
|
|
62
|
+
* deeper mistake surfaces at run time, from the SDK, per row. An empty `dataset` is accepted and
|
|
63
|
+
* short-circuits to a zero-row report — the run costs nothing and proves nothing.
|
|
64
|
+
*
|
|
65
|
+
* Running it spends real money: each entry is one live agent turn against the configured provider.
|
|
66
|
+
*/
|
|
67
|
+
interface EvalConfig {
|
|
68
|
+
/** Cases to run, in order. Empty is legal and produces an empty report. */
|
|
69
|
+
readonly dataset: ReadonlyArray<DatasetEntry>;
|
|
70
|
+
/** Scorers applied to EVERY row. `name` is the column label in the markdown report. */
|
|
71
|
+
readonly scorers: ReadonlyArray<{
|
|
72
|
+
readonly name: string;
|
|
73
|
+
readonly score: Scorer;
|
|
74
|
+
}>;
|
|
75
|
+
/** Options for the agent under test — one agent config for the whole suite. */
|
|
76
|
+
readonly agent: EvalAgentOptions;
|
|
77
|
+
/**
|
|
78
|
+
* Rows evaluated in parallel. Omitted means the key is not forwarded at all, so the SDK's own
|
|
79
|
+
* default applies. Raise it and you raise your provider rate-limit exposure with it.
|
|
80
|
+
*/
|
|
81
|
+
readonly concurrency?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
1
84
|
/**
|
|
2
85
|
* Top-level CLI dispatcher via commander (ADR D194).
|
|
3
86
|
*
|
|
4
|
-
* Subcommands: `init`, `dev`, `inspect`, `eval`, `setup`, `
|
|
87
|
+
* Subcommands: `init`, `dev`, `inspect`, `eval`, `acp`, `setup`, `db`, `tasks`.
|
|
5
88
|
*
|
|
6
|
-
* Exit codes:
|
|
7
|
-
* - 0 → success
|
|
8
|
-
* - 1 → unknown error
|
|
9
|
-
* - 2 → user error (
|
|
89
|
+
* Exit codes at this layer:
|
|
90
|
+
* - 0 → success, and also `--help` / `--version`
|
|
91
|
+
* - 1 → unknown error (an exception that escaped a subcommand)
|
|
92
|
+
* - 2 → user error (unknown subcommand, unknown option, bad flag value)
|
|
93
|
+
*
|
|
94
|
+
* Subcommands are free to return codes of their own beyond these — `theokit tasks` uses 3 and 4,
|
|
95
|
+
* `theokit db check-schema-drift` uses 1 to mean "drift found", and `theokit dev` forwards the
|
|
96
|
+
* child process's exit code verbatim. Each command module documents its own.
|
|
10
97
|
*
|
|
11
98
|
* @internal
|
|
12
99
|
*/
|
|
100
|
+
/**
|
|
101
|
+
* Parse `argv` and run the matching subcommand, returning the process exit code instead of exiting.
|
|
102
|
+
*
|
|
103
|
+
* `argv` is commander-shaped, i.e. the full `process.argv`: `[execPath, scriptPath, ...args]`. The
|
|
104
|
+
* first two entries are skipped, so passing `["theokit", "init"]` silently drops `init` — pass
|
|
105
|
+
* `["node", "theokit", "init"]` when synthesising one.
|
|
106
|
+
*
|
|
107
|
+
* Never throws and never calls `process.exit`; the caller decides what to do with the code (the
|
|
108
|
+
* bundled `bin/theokit.ts` shim exits with it). Writes to `process.stdout` and `process.stderr`
|
|
109
|
+
* directly, so redirect the streams if you need to capture the output.
|
|
110
|
+
*
|
|
111
|
+
* Returns `0` for success and for `--help` / `--version`, `2` for a user error, `1` for anything
|
|
112
|
+
* that escaped a subcommand as an exception, and otherwise whatever the subcommand returned.
|
|
113
|
+
*/
|
|
13
114
|
declare function main(argv: ReadonlyArray<string>): Promise<number>;
|
|
14
115
|
|
|
15
116
|
/**
|
|
16
117
|
* Build-time version constants for @theokit/cli.
|
|
17
118
|
*
|
|
18
|
-
* `
|
|
19
|
-
* `
|
|
20
|
-
*
|
|
21
|
-
*
|
|
119
|
+
* Both are substituted by tsup `define` at BUILD time, so they are plain string literals in the
|
|
120
|
+
* shipped bundle. The `declare const` below only satisfies the type checker: evaluating this module
|
|
121
|
+
* from unbuilt source, without that substitution, throws a ReferenceError at import.
|
|
122
|
+
*
|
|
123
|
+
* `__SDK_VERSION__` is the sibling `@theokit/sdk` semver (NEVER `workspace:*`). Used by `init`
|
|
124
|
+
* templates to pin the SDK dep in scaffolded projects (EC-L fix from edge-case review).
|
|
22
125
|
*
|
|
23
126
|
* `__CLI_VERSION__` is this package's semver. Exposed via `--version`.
|
|
24
127
|
*/
|
|
128
|
+
/**
|
|
129
|
+
* The `@theokit/sdk` semver this CLI was BUILT against — a concrete version, never `workspace:*`.
|
|
130
|
+
*
|
|
131
|
+
* `theokit init` writes it into the scaffolded `package.json`, so it is what a new project pins. It
|
|
132
|
+
* is not a claim about the SDK the current process has loaded, which may be a different version
|
|
133
|
+
* entirely.
|
|
134
|
+
*/
|
|
25
135
|
declare const SDK_VERSION: string;
|
|
136
|
+
/**
|
|
137
|
+
* This package's semver, substituted at build time — what `theokit --version` prints.
|
|
138
|
+
*
|
|
139
|
+
* Distinct from {@link SDK_VERSION}, which is the `@theokit/sdk` version this CLI was built against
|
|
140
|
+
* and the one `theokit init` writes into a scaffolded `package.json`. They move independently, so a
|
|
141
|
+
* bug report should quote both.
|
|
142
|
+
*/
|
|
26
143
|
declare const CLI_VERSION: string;
|
|
27
144
|
|
|
28
|
-
export { CLI_VERSION, SDK_VERSION, main };
|
|
145
|
+
export { CLI_VERSION, type DatasetEntry, type EvalConfig, SDK_VERSION, type Score, type Scorer, main };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1,145 @@
|
|
|
1
|
+
import { Agent } from '@theokit/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The shape of `eval.config.{ts,mjs}`, consumed by `theokit eval` (T5.1, ADR D199).
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import type { EvalConfig } from "@theokit/cli";
|
|
8
|
+
*
|
|
9
|
+
* export default {
|
|
10
|
+
* agent: { model: "gpt-4o-mini" },
|
|
11
|
+
* dataset: [{ input: "2+2?", expected: "4" }],
|
|
12
|
+
* scorers: [{ name: "exact", score: (out, exp) => ({ score: out.trim() === exp ? 1 : 0 }) }],
|
|
13
|
+
* } satisfies EvalConfig;
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The runner now delegates to the SDK's `Eval.create().run()` (D212); this shape survived that swap
|
|
17
|
+
* unchanged, which is what D199 was for.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Outcome of a single scoring decision.
|
|
24
|
+
*
|
|
25
|
+
* Exported because `Scorer` — which IS public — returns it: a user writing a scorer could not name
|
|
26
|
+
* its return type. Same shape as the `MemoryProviderFactory` defect in #335, one level down.
|
|
27
|
+
*/
|
|
28
|
+
interface Score {
|
|
29
|
+
/** Numeric score in [0, 1]. Use 1.0 for "pass", 0.0 for "fail". */
|
|
30
|
+
readonly score: number;
|
|
31
|
+
/** Optional human-readable reason for the score (shown in the report). */
|
|
32
|
+
readonly reason?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Grades one agent output. May be sync or async (EC-K); both are awaited.
|
|
36
|
+
*
|
|
37
|
+
* `expected` is whatever the dataset entry carried, `unknown` because nothing constrains it — narrow
|
|
38
|
+
* it yourself. It is `undefined` for entries that declared no `expected`, so a scorer that assumes a
|
|
39
|
+
* string has to handle that.
|
|
40
|
+
*
|
|
41
|
+
* Scoring runs inside the SDK's eval engine, which reports per-ROW failures: a failed row carries an
|
|
42
|
+
* `error` and is counted in `errorRows` rather than aborting the suite.
|
|
43
|
+
*/
|
|
44
|
+
type Scorer = (output: string, expected?: unknown) => Score | Promise<Score>;
|
|
45
|
+
/**
|
|
46
|
+
* One evaluation case: the prompt sent to the agent, and an optional expected value handed to every
|
|
47
|
+
* scorer untouched (no comparison is performed for you).
|
|
48
|
+
*/
|
|
49
|
+
interface DatasetEntry {
|
|
50
|
+
readonly input: string;
|
|
51
|
+
readonly expected?: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The `Agent.create()` options object, inferred from the installed `@theokit/sdk` rather than
|
|
55
|
+
* re-declared. Whatever that version accepts — model, tools, plugins — is accepted here.
|
|
56
|
+
*/
|
|
57
|
+
type EvalAgentOptions = Parameters<typeof Agent.create>[0];
|
|
58
|
+
/**
|
|
59
|
+
* The DEFAULT export of `eval.config.{ts,mjs}`. A named export is not read.
|
|
60
|
+
*
|
|
61
|
+
* `theokit eval` checks only that `dataset` and `scorers` are arrays and `agent` is an object; every
|
|
62
|
+
* deeper mistake surfaces at run time, from the SDK, per row. An empty `dataset` is accepted and
|
|
63
|
+
* short-circuits to a zero-row report — the run costs nothing and proves nothing.
|
|
64
|
+
*
|
|
65
|
+
* Running it spends real money: each entry is one live agent turn against the configured provider.
|
|
66
|
+
*/
|
|
67
|
+
interface EvalConfig {
|
|
68
|
+
/** Cases to run, in order. Empty is legal and produces an empty report. */
|
|
69
|
+
readonly dataset: ReadonlyArray<DatasetEntry>;
|
|
70
|
+
/** Scorers applied to EVERY row. `name` is the column label in the markdown report. */
|
|
71
|
+
readonly scorers: ReadonlyArray<{
|
|
72
|
+
readonly name: string;
|
|
73
|
+
readonly score: Scorer;
|
|
74
|
+
}>;
|
|
75
|
+
/** Options for the agent under test — one agent config for the whole suite. */
|
|
76
|
+
readonly agent: EvalAgentOptions;
|
|
77
|
+
/**
|
|
78
|
+
* Rows evaluated in parallel. Omitted means the key is not forwarded at all, so the SDK's own
|
|
79
|
+
* default applies. Raise it and you raise your provider rate-limit exposure with it.
|
|
80
|
+
*/
|
|
81
|
+
readonly concurrency?: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
1
84
|
/**
|
|
2
85
|
* Top-level CLI dispatcher via commander (ADR D194).
|
|
3
86
|
*
|
|
4
|
-
* Subcommands: `init`, `dev`, `inspect`, `eval`, `setup`, `
|
|
87
|
+
* Subcommands: `init`, `dev`, `inspect`, `eval`, `acp`, `setup`, `db`, `tasks`.
|
|
5
88
|
*
|
|
6
|
-
* Exit codes:
|
|
7
|
-
* - 0 → success
|
|
8
|
-
* - 1 → unknown error
|
|
9
|
-
* - 2 → user error (
|
|
89
|
+
* Exit codes at this layer:
|
|
90
|
+
* - 0 → success, and also `--help` / `--version`
|
|
91
|
+
* - 1 → unknown error (an exception that escaped a subcommand)
|
|
92
|
+
* - 2 → user error (unknown subcommand, unknown option, bad flag value)
|
|
93
|
+
*
|
|
94
|
+
* Subcommands are free to return codes of their own beyond these — `theokit tasks` uses 3 and 4,
|
|
95
|
+
* `theokit db check-schema-drift` uses 1 to mean "drift found", and `theokit dev` forwards the
|
|
96
|
+
* child process's exit code verbatim. Each command module documents its own.
|
|
10
97
|
*
|
|
11
98
|
* @internal
|
|
12
99
|
*/
|
|
100
|
+
/**
|
|
101
|
+
* Parse `argv` and run the matching subcommand, returning the process exit code instead of exiting.
|
|
102
|
+
*
|
|
103
|
+
* `argv` is commander-shaped, i.e. the full `process.argv`: `[execPath, scriptPath, ...args]`. The
|
|
104
|
+
* first two entries are skipped, so passing `["theokit", "init"]` silently drops `init` — pass
|
|
105
|
+
* `["node", "theokit", "init"]` when synthesising one.
|
|
106
|
+
*
|
|
107
|
+
* Never throws and never calls `process.exit`; the caller decides what to do with the code (the
|
|
108
|
+
* bundled `bin/theokit.ts` shim exits with it). Writes to `process.stdout` and `process.stderr`
|
|
109
|
+
* directly, so redirect the streams if you need to capture the output.
|
|
110
|
+
*
|
|
111
|
+
* Returns `0` for success and for `--help` / `--version`, `2` for a user error, `1` for anything
|
|
112
|
+
* that escaped a subcommand as an exception, and otherwise whatever the subcommand returned.
|
|
113
|
+
*/
|
|
13
114
|
declare function main(argv: ReadonlyArray<string>): Promise<number>;
|
|
14
115
|
|
|
15
116
|
/**
|
|
16
117
|
* Build-time version constants for @theokit/cli.
|
|
17
118
|
*
|
|
18
|
-
* `
|
|
19
|
-
* `
|
|
20
|
-
*
|
|
21
|
-
*
|
|
119
|
+
* Both are substituted by tsup `define` at BUILD time, so they are plain string literals in the
|
|
120
|
+
* shipped bundle. The `declare const` below only satisfies the type checker: evaluating this module
|
|
121
|
+
* from unbuilt source, without that substitution, throws a ReferenceError at import.
|
|
122
|
+
*
|
|
123
|
+
* `__SDK_VERSION__` is the sibling `@theokit/sdk` semver (NEVER `workspace:*`). Used by `init`
|
|
124
|
+
* templates to pin the SDK dep in scaffolded projects (EC-L fix from edge-case review).
|
|
22
125
|
*
|
|
23
126
|
* `__CLI_VERSION__` is this package's semver. Exposed via `--version`.
|
|
24
127
|
*/
|
|
128
|
+
/**
|
|
129
|
+
* The `@theokit/sdk` semver this CLI was BUILT against — a concrete version, never `workspace:*`.
|
|
130
|
+
*
|
|
131
|
+
* `theokit init` writes it into the scaffolded `package.json`, so it is what a new project pins. It
|
|
132
|
+
* is not a claim about the SDK the current process has loaded, which may be a different version
|
|
133
|
+
* entirely.
|
|
134
|
+
*/
|
|
25
135
|
declare const SDK_VERSION: string;
|
|
136
|
+
/**
|
|
137
|
+
* This package's semver, substituted at build time — what `theokit --version` prints.
|
|
138
|
+
*
|
|
139
|
+
* Distinct from {@link SDK_VERSION}, which is the `@theokit/sdk` version this CLI was built against
|
|
140
|
+
* and the one `theokit init` writes into a scaffolded `package.json`. They move independently, so a
|
|
141
|
+
* bug report should quote both.
|
|
142
|
+
*/
|
|
26
143
|
declare const CLI_VERSION: string;
|
|
27
144
|
|
|
28
|
-
export { CLI_VERSION, SDK_VERSION, main };
|
|
145
|
+
export { CLI_VERSION, type DatasetEntry, type EvalConfig, SDK_VERSION, type Score, type Scorer, main };
|
package/dist/index.js
CHANGED
|
@@ -358,7 +358,7 @@ function startRunner(opts) {
|
|
|
358
358
|
args.push(opts.entry);
|
|
359
359
|
const child = spawn(process.execPath, [tsxBin, ...args], {
|
|
360
360
|
cwd: opts.cwd,
|
|
361
|
-
stdio: "inherit",
|
|
361
|
+
stdio: opts.stdio ?? "inherit",
|
|
362
362
|
env: process.env
|
|
363
363
|
});
|
|
364
364
|
const exited = new Promise((resolve6) => {
|
|
@@ -489,7 +489,13 @@ function formatReport(result) {
|
|
|
489
489
|
}
|
|
490
490
|
function truncate(s, max) {
|
|
491
491
|
if (s.length <= max) return s;
|
|
492
|
-
|
|
492
|
+
const budget = max - 1;
|
|
493
|
+
let out = "";
|
|
494
|
+
for (const ch of s) {
|
|
495
|
+
if (out.length + ch.length > budget) break;
|
|
496
|
+
out += ch;
|
|
497
|
+
}
|
|
498
|
+
return `${out}\u2026`;
|
|
493
499
|
}
|
|
494
500
|
function escapeMd(s) {
|
|
495
501
|
return s.replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
@@ -619,8 +625,8 @@ ${pc5.green("\u2713")} ${result.aggregate.totalRows} rows \xB7 mean score ${resu
|
|
|
619
625
|
}
|
|
620
626
|
|
|
621
627
|
// src/version.ts
|
|
622
|
-
var SDK_VERSION = "4.
|
|
623
|
-
var CLI_VERSION = "
|
|
628
|
+
var SDK_VERSION = "4.57.0";
|
|
629
|
+
var CLI_VERSION = "4.0.1";
|
|
624
630
|
|
|
625
631
|
// src/init/templates.ts
|
|
626
632
|
var TEMPLATES = [
|
|
@@ -634,6 +640,26 @@ var TEMPLATES = [
|
|
|
634
640
|
description: "100% local agent via Ollama (no remote API key required).",
|
|
635
641
|
hint: "Requires `ollama serve` + `ollama pull llama3.2:3b`."
|
|
636
642
|
},
|
|
643
|
+
{
|
|
644
|
+
name: "chatbot",
|
|
645
|
+
description: "Conversational agent that resumes its own thread across runs.",
|
|
646
|
+
hint: "SESSION_DIR=~/.claude writes sessions the Claude Code CLI can --continue."
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
name: "multi-agent",
|
|
650
|
+
description: "A classifier routes to specialists, all from one AgentFactory prefix.",
|
|
651
|
+
hint: 'Pass the input as an argument: `pnpm dev "Translate to French: hello"`.'
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: "rag-agent",
|
|
655
|
+
description: "Retrieval over your own files \u2014 Memory.openIndex behind a Tool.",
|
|
656
|
+
hint: "Put markdown under .theokit/memory/ first, or there is nothing to cite."
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
name: "workflow-automation",
|
|
660
|
+
description: "A committed Workflow (fn -> agentStep -> fn) handed to Cron.",
|
|
661
|
+
hint: "WORKFLOW_CRON overrides the schedule; default is every 5 minutes."
|
|
662
|
+
},
|
|
637
663
|
{
|
|
638
664
|
name: "telegram-bot",
|
|
639
665
|
description: "Telegram bot via @theokit/gateway + grammy.",
|
|
@@ -695,6 +721,13 @@ function resolveTemplatesRoot() {
|
|
|
695
721
|
`Could not locate bundled templates/ directory (searched up from ${here}). This usually means the published tarball was built without "files": ["templates"] (EC-C regression).`
|
|
696
722
|
);
|
|
697
723
|
}
|
|
724
|
+
var SCAFFOLD_USER_ERROR_CODES = [
|
|
725
|
+
"invalid_project_name",
|
|
726
|
+
"unknown_template",
|
|
727
|
+
"invalid_dest",
|
|
728
|
+
"dest_is_symlink",
|
|
729
|
+
"dest_not_empty"
|
|
730
|
+
];
|
|
698
731
|
function scaffoldError(code, message) {
|
|
699
732
|
const err = new Error(message);
|
|
700
733
|
err.code = code;
|
|
@@ -830,12 +863,7 @@ async function resolveTemplate(optsTemplate, skipPrompts) {
|
|
|
830
863
|
}
|
|
831
864
|
return template;
|
|
832
865
|
}
|
|
833
|
-
var USER_ERROR_CODES =
|
|
834
|
-
"invalid_project_name",
|
|
835
|
-
"dest_not_empty",
|
|
836
|
-
"invalid_dest",
|
|
837
|
-
"unknown_template"
|
|
838
|
-
]);
|
|
866
|
+
var USER_ERROR_CODES = new Set(SCAFFOLD_USER_ERROR_CODES);
|
|
839
867
|
async function runScaffold(name, template, force) {
|
|
840
868
|
try {
|
|
841
869
|
const result = await scaffold({
|
|
@@ -1189,14 +1217,6 @@ ${pc5.dim(" shape: Desktop OAuth client (installed block present)")}
|
|
|
1189
1217
|
}
|
|
1190
1218
|
const interactiveCode = await runInteractiveSetup();
|
|
1191
1219
|
if (interactiveCode !== 0) return interactiveCode;
|
|
1192
|
-
if (typeof opts.writable === "string" && opts.writable.length > 0) {
|
|
1193
|
-
process.stdout.write(
|
|
1194
|
-
`
|
|
1195
|
-
${pc5.yellow("note:")} you passed --writable=${opts.writable}. The upstream MCP server does not narrow scopes \u2014 all scopes are granted at consent.
|
|
1196
|
-
Write tools are gated at runtime by ${pc5.bold("googleWorkspace({ writable: true })")} in your code.
|
|
1197
|
-
`
|
|
1198
|
-
);
|
|
1199
|
-
}
|
|
1200
1220
|
process.stdout.write(
|
|
1201
1221
|
`
|
|
1202
1222
|
${pc5.green("\u2713")} gworkspace setup complete.
|
|
@@ -1243,7 +1263,6 @@ function spawnUpstream(args, timeoutMs) {
|
|
|
1243
1263
|
async function runSetup(domain, opts) {
|
|
1244
1264
|
if (domain === "gworkspace") {
|
|
1245
1265
|
const gworkspaceOpts = {
|
|
1246
|
-
writable: opts.writable,
|
|
1247
1266
|
probe: opts.probe === true,
|
|
1248
1267
|
nonInteractive: opts.nonInteractive === true,
|
|
1249
1268
|
...opts.credentialsPath !== void 0 ? { credentialsPath: opts.credentialsPath } : {}
|
|
@@ -1374,7 +1393,7 @@ async function runTasksInspect(id, opts) {
|
|
|
1374
1393
|
}
|
|
1375
1394
|
return 0;
|
|
1376
1395
|
}
|
|
1377
|
-
async function runTasksCancel(id,
|
|
1396
|
+
async function runTasksCancel(id, opts) {
|
|
1378
1397
|
if (!isValidTaskId(id)) {
|
|
1379
1398
|
process.stderr.write(`tasks: invalid id grammar: ${id}
|
|
1380
1399
|
`);
|
|
@@ -1399,12 +1418,21 @@ async function runTasksCancel(id, _opts) {
|
|
|
1399
1418
|
}
|
|
1400
1419
|
if (handle.state === "queued") {
|
|
1401
1420
|
const cancelledAt = Date.now();
|
|
1402
|
-
await store.update(id, (h) => ({
|
|
1421
|
+
await store.update(id, (h) => ({
|
|
1422
|
+
...h,
|
|
1423
|
+
state: "cancelled",
|
|
1424
|
+
cancelledAt,
|
|
1425
|
+
...opts.reason !== void 0 ? { cancelReason: opts.reason } : {}
|
|
1426
|
+
}));
|
|
1403
1427
|
process.stdout.write(`task ${id} cancelled (was queued)
|
|
1404
1428
|
`);
|
|
1405
1429
|
return 0;
|
|
1406
1430
|
}
|
|
1407
|
-
await store.update(id, (h) => ({
|
|
1431
|
+
await store.update(id, (h) => ({
|
|
1432
|
+
...h,
|
|
1433
|
+
cancelRequested: true,
|
|
1434
|
+
...opts.reason !== void 0 ? { cancelReason: opts.reason } : {}
|
|
1435
|
+
}));
|
|
1408
1436
|
process.stdout.write(
|
|
1409
1437
|
`cancel requested for task ${id}; the owning process will honor it at the next checkpoint
|
|
1410
1438
|
`
|
|
@@ -1414,7 +1442,13 @@ async function runTasksCancel(id, _opts) {
|
|
|
1414
1442
|
|
|
1415
1443
|
// src/main.ts
|
|
1416
1444
|
function registerSubcommands(program, setExit) {
|
|
1417
|
-
program.command("init [project-name]").description("Scaffold a new agent project from a bundled template.").option(
|
|
1445
|
+
program.command("init [project-name]").description("Scaffold a new agent project from a bundled template.").option(
|
|
1446
|
+
"-t, --template <name>",
|
|
1447
|
+
// Derived from the registry, not restated. This line named three templates while the
|
|
1448
|
+
// registry held seven — a help text that lists options is a second copy of the list, and
|
|
1449
|
+
// the copy is the one that goes stale.
|
|
1450
|
+
`Template name: ${TEMPLATES.map((t) => t.name).join(" | ")}`
|
|
1451
|
+
).option("-f, --force", "Overwrite a non-empty destination directory").option("-y, --yes", "Skip interactive prompts (CI mode)").action(async (projectName, opts) => {
|
|
1418
1452
|
setExit(await runInit(projectName, opts));
|
|
1419
1453
|
});
|
|
1420
1454
|
program.command("dev").description("Run the agent entry point under tsx --watch (hot-reload).").option("--entry <path>", "Entry file (default: src/index.ts or package.main)").option("--env <path>", "Env file to load (default: .env)").action(async (opts) => {
|
|
@@ -1430,15 +1464,12 @@ function registerSubcommands(program, setExit) {
|
|
|
1430
1464
|
setExit(await runEval(opts));
|
|
1431
1465
|
});
|
|
1432
1466
|
program.command("acp").description(
|
|
1433
|
-
"Launch a stdio Agent Client Protocol (ACP) server pointing at the entry file's default-exported agent. Used by
|
|
1467
|
+
"Launch a stdio Agent Client Protocol (ACP) server pointing at the entry file's default-exported agent. Used by ACP-compatible hosts. ADRs D349-D360."
|
|
1434
1468
|
).option("--entry <path>", "Entry file (default: src/index.ts or package.main)").option("--permission <mode>", "Tool permission mode: ask | auto | deny (default: ask)").option("--trusted-tools <list>", "Comma-separated tool names that bypass ask").option("--permission-timeout-ms <ms>", "Permission request timeout in ms (default: 60000)").action(async (opts) => {
|
|
1435
1469
|
setExit(await runAcp(opts));
|
|
1436
1470
|
});
|
|
1437
1471
|
program.command("setup <domain>").description(
|
|
1438
1472
|
"Stage credentials + connectivity probe for a third-party integration. Domains: gworkspace (Google Workspace)."
|
|
1439
|
-
).option(
|
|
1440
|
-
"--writable <products>",
|
|
1441
|
-
"Comma-separated products to grant write access (e.g., 'drive,calendar')"
|
|
1442
1473
|
).option("--probe", "Run upstream connectivity check after staging credentials").option(
|
|
1443
1474
|
"--credentials-path <path>",
|
|
1444
1475
|
"Override path to credentials.json (default: ~/.google-mcp/credentials.json)"
|
|
@@ -1476,7 +1507,7 @@ function registerSubcommands(program, setExit) {
|
|
|
1476
1507
|
setExit(await runTasksInspect(id, opts));
|
|
1477
1508
|
});
|
|
1478
1509
|
tasks.command("cancel <id>").description("Cancel a task (best-effort cross-process via cancelRequested flag)").option("--reason <reason>", "Cancellation reason recorded in the registry").action(async (id, opts) => {
|
|
1479
|
-
setExit(await runTasksCancel(id));
|
|
1510
|
+
setExit(await runTasksCancel(id, opts));
|
|
1480
1511
|
});
|
|
1481
1512
|
}
|
|
1482
1513
|
function mapCommanderExitCode(code, fallback) {
|