@phyzess/pappra 0.0.0-stage → 0.1.0-beta.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/LICENSE +21 -0
- package/README.md +80 -2
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/assets/integrations/skills/pappra/SKILL.md +68 -0
- package/assets/integrations/skills/pappra/references/hosts.md +30 -0
- package/assets/integrations/skills/pappra/references/lifecycle.md +37 -0
- package/assets/integrations/skills/pappra/references/operations.md +14 -0
- package/assets/manifest.json +4 -0
- package/dist/app/collaboration.d.ts +170 -0
- package/dist/app/collaboration.js +1650 -0
- package/dist/app/doctor.d.ts +9 -0
- package/dist/app/doctor.js +1030 -0
- package/dist/app/init.d.ts +143 -0
- package/dist/app/init.js +1111 -0
- package/dist/cli/commands/code.d.ts +16 -0
- package/dist/cli/commands/code.js +127 -0
- package/dist/cli/commands/collaboration.d.ts +13 -0
- package/dist/cli/commands/collaboration.js +186 -0
- package/dist/cli/commands/continuity.d.ts +29 -0
- package/dist/cli/commands/continuity.js +133 -0
- package/dist/cli/commands/docs.d.ts +11 -0
- package/dist/cli/commands/docs.js +133 -0
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +57 -0
- package/dist/cli/commands/host.d.ts +13 -0
- package/dist/cli/commands/host.js +125 -0
- package/dist/cli/commands/init.d.ts +51 -0
- package/dist/cli/commands/init.js +668 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +10 -0
- package/dist/cli/output.d.ts +4 -0
- package/dist/cli/output.js +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.js +597 -0
- package/dist/code/budget.d.ts +14 -0
- package/dist/code/budget.js +39 -0
- package/dist/code/exec.d.ts +23 -0
- package/dist/code/exec.js +133 -0
- package/dist/code/identity.d.ts +13 -0
- package/dist/code/identity.js +214 -0
- package/dist/code/index.d.ts +6 -0
- package/dist/code/index.js +3 -0
- package/dist/code/providers/codegraph.d.ts +59 -0
- package/dist/code/providers/codegraph.js +567 -0
- package/dist/code/registration.d.ts +9 -0
- package/dist/code/registration.js +293 -0
- package/dist/code/service.d.ts +53 -0
- package/dist/code/service.js +633 -0
- package/dist/code/text.d.ts +3 -0
- package/dist/code/text.js +202 -0
- package/dist/collab/admission.d.ts +450 -0
- package/dist/collab/admission.js +797 -0
- package/dist/collab/canonical.d.ts +26 -0
- package/dist/collab/canonical.js +136 -0
- package/dist/collab/contracts.d.ts +73 -0
- package/dist/collab/contracts.js +76 -0
- package/dist/collab/envelope.d.ts +52 -0
- package/dist/collab/envelope.js +241 -0
- package/dist/collab/fingerprint.d.ts +7 -0
- package/dist/collab/fingerprint.js +58 -0
- package/dist/collab/handoff.d.ts +350 -0
- package/dist/collab/handoff.js +513 -0
- package/dist/collab/index.d.ts +9 -0
- package/dist/collab/index.js +8 -0
- package/dist/collab/lifecycle.d.ts +449 -0
- package/dist/collab/lifecycle.js +534 -0
- package/dist/collab/messages.d.ts +148 -0
- package/dist/collab/messages.js +583 -0
- package/dist/collab/notify.d.ts +47 -0
- package/dist/collab/notify.js +140 -0
- package/dist/collab/preflight.d.ts +31 -0
- package/dist/collab/preflight.js +271 -0
- package/dist/collab/resources.d.ts +119 -0
- package/dist/collab/resources.js +451 -0
- package/dist/collab/store.d.ts +143 -0
- package/dist/collab/store.js +606 -0
- package/dist/collab/types.d.ts +354 -0
- package/dist/collab/types.js +1 -0
- package/dist/collab/validation.d.ts +10 -0
- package/dist/collab/validation.js +303 -0
- package/dist/continuity/context.d.ts +24 -0
- package/dist/continuity/context.js +179 -0
- package/dist/continuity/index.d.ts +3 -0
- package/dist/continuity/index.js +1 -0
- package/dist/continuity/paths.d.ts +37 -0
- package/dist/continuity/paths.js +258 -0
- package/dist/continuity/service.d.ts +59 -0
- package/dist/continuity/service.js +1258 -0
- package/dist/hosts/claude/native.d.ts +79 -0
- package/dist/hosts/claude/native.js +853 -0
- package/dist/hosts/codex/native.d.ts +345 -0
- package/dist/hosts/codex/native.js +1528 -0
- package/dist/hosts/codex/protocol.d.ts +51 -0
- package/dist/hosts/codex/protocol.js +42 -0
- package/dist/hosts/detect.d.ts +28 -0
- package/dist/hosts/detect.js +73 -0
- package/dist/hosts/index.d.ts +10 -0
- package/dist/hosts/index.js +10 -0
- package/dist/hosts/integration/bundle.d.ts +16 -0
- package/dist/hosts/integration/bundle.js +81 -0
- package/dist/hosts/integration/hook-entry.d.ts +1 -0
- package/dist/hosts/integration/hook-entry.js +68 -0
- package/dist/hosts/integration/hook.d.ts +32 -0
- package/dist/hosts/integration/hook.js +781 -0
- package/dist/hosts/integration/pi-extension-runtime.d.ts +18 -0
- package/dist/hosts/integration/pi-extension-runtime.js +89 -0
- package/dist/hosts/integration/pi-template.d.ts +3 -0
- package/dist/hosts/integration/pi-template.js +5 -0
- package/dist/hosts/integration/service.d.ts +41 -0
- package/dist/hosts/integration/service.js +1381 -0
- package/dist/hosts/integration/support.d.ts +36 -0
- package/dist/hosts/integration/support.js +41 -0
- package/dist/hosts/integration/templates.d.ts +22 -0
- package/dist/hosts/integration/templates.js +70 -0
- package/dist/hosts/pi/protocol.d.ts +22 -0
- package/dist/hosts/pi/protocol.js +28 -0
- package/dist/hosts/pi/query-result.d.ts +22 -0
- package/dist/hosts/pi/query-result.js +710 -0
- package/dist/hosts/pi/rpc.d.ts +937 -0
- package/dist/hosts/pi/rpc.js +1621 -0
- package/dist/hosts/pilot.d.ts +485 -0
- package/dist/hosts/pilot.js +593 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/infra/fs.d.ts +27 -0
- package/dist/infra/fs.js +130 -0
- package/dist/infra/git.d.ts +60 -0
- package/dist/infra/git.js +358 -0
- package/dist/infra/owned-process-group.d.ts +173 -0
- package/dist/infra/owned-process-group.js +571 -0
- package/dist/install/apply.d.ts +65 -0
- package/dist/install/apply.js +663 -0
- package/dist/install/index.d.ts +5 -0
- package/dist/install/index.js +5 -0
- package/dist/install/ownership.d.ts +85 -0
- package/dist/install/ownership.js +430 -0
- package/dist/install/plan.d.ts +39 -0
- package/dist/install/plan.js +97 -0
- package/dist/install/rollback.d.ts +18 -0
- package/dist/install/rollback.js +544 -0
- package/dist/install/runtime.d.ts +76 -0
- package/dist/install/runtime.js +1145 -0
- package/dist/knowledge/catalog.d.ts +47 -0
- package/dist/knowledge/catalog.js +308 -0
- package/dist/knowledge/context.d.ts +28 -0
- package/dist/knowledge/context.js +61 -0
- package/dist/knowledge/index.d.ts +3 -0
- package/dist/knowledge/index.js +1 -0
- package/dist/knowledge/journal.d.ts +16 -0
- package/dist/knowledge/journal.js +109 -0
- package/dist/knowledge/lifecycle.d.ts +8 -0
- package/dist/knowledge/lifecycle.js +1001 -0
- package/dist/knowledge/paths.d.ts +37 -0
- package/dist/knowledge/paths.js +236 -0
- package/dist/knowledge/refs.d.ts +36 -0
- package/dist/knowledge/refs.js +267 -0
- package/dist/knowledge/service.d.ts +21 -0
- package/dist/knowledge/service.js +393 -0
- package/dist/knowledge/types.d.ts +171 -0
- package/dist/knowledge/types.js +1 -0
- package/dist/knowledge/write.d.ts +8 -0
- package/dist/knowledge/write.js +1223 -0
- package/dist/package-info.d.ts +6 -0
- package/dist/package-info.js +19 -0
- package/dist/schemas/code.d.ts +377 -0
- package/dist/schemas/code.js +145 -0
- package/dist/schemas/collaboration.d.ts +115 -0
- package/dist/schemas/collaboration.js +106 -0
- package/dist/schemas/continuity.d.ts +315 -0
- package/dist/schemas/continuity.js +199 -0
- package/dist/schemas/diagnostics.d.ts +28 -0
- package/dist/schemas/diagnostics.js +27 -0
- package/dist/schemas/doctor.d.ts +157 -0
- package/dist/schemas/doctor.js +75 -0
- package/dist/schemas/document.d.ts +644 -0
- package/dist/schemas/document.js +296 -0
- package/dist/schemas/errors.d.ts +177 -0
- package/dist/schemas/errors.js +176 -0
- package/dist/schemas/evidence.d.ts +24 -0
- package/dist/schemas/evidence.js +16 -0
- package/dist/schemas/host.d.ts +436 -0
- package/dist/schemas/host.js +201 -0
- package/dist/schemas/index.d.ts +15 -0
- package/dist/schemas/index.js +15 -0
- package/dist/schemas/init.d.ts +121 -0
- package/dist/schemas/init.js +94 -0
- package/dist/schemas/install.d.ts +213 -0
- package/dist/schemas/install.js +139 -0
- package/dist/schemas/machine.d.ts +43 -0
- package/dist/schemas/machine.js +96 -0
- package/dist/schemas/outcome.d.ts +23 -0
- package/dist/schemas/outcome.js +17 -0
- package/dist/schemas/paths.d.ts +19 -0
- package/dist/schemas/paths.js +63 -0
- package/dist/schemas/workspace.d.ts +120 -0
- package/dist/schemas/workspace.js +201 -0
- package/dist/workspace/config-file.d.ts +36 -0
- package/dist/workspace/config-file.js +237 -0
- package/dist/workspace/config.d.ts +28 -0
- package/dist/workspace/config.js +79 -0
- package/dist/workspace/discover.d.ts +34 -0
- package/dist/workspace/discover.js +195 -0
- package/dist/workspace/documents.d.ts +21 -0
- package/dist/workspace/documents.js +395 -0
- package/dist/workspace/ignore.d.ts +10 -0
- package/dist/workspace/ignore.js +48 -0
- package/dist/workspace/index.d.ts +7 -0
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/repositories.d.ts +24 -0
- package/dist/workspace/repositories.js +411 -0
- package/dist/workspace/resolve.d.ts +24 -0
- package/dist/workspace/resolve.js +268 -0
- package/dist/workspace/types.d.ts +71 -0
- package/dist/workspace/types.js +1 -0
- package/dist/workspace/validation.d.ts +18 -0
- package/dist/workspace/validation.js +197 -0
- package/package.json +105 -4
- package/skills/pappra/SKILL.md +68 -0
- package/skills/pappra/references/hosts.md +30 -0
- package/skills/pappra/references/lifecycle.md +37 -0
- package/skills/pappra/references/operations.md +14 -0
package/dist/cli/run.js
ADDED
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { getPackageInfo } from '../package-info.js';
|
|
3
|
+
import { initUsage, runInitCommand } from './commands/init.js';
|
|
4
|
+
import { doctorUsage, runDoctorCommand } from './commands/doctor.js';
|
|
5
|
+
import { docsUsage, runDocsCommand } from './commands/docs.js';
|
|
6
|
+
import { checkpointUsage, resumeUsage, runCheckpointCommand, runResumeCommand, } from './commands/continuity.js';
|
|
7
|
+
import { codeUsage, runCodeCommand } from './commands/code.js';
|
|
8
|
+
import { collaborationUsage, runCollaborationCommand, } from './commands/collaboration.js';
|
|
9
|
+
import { hostUsage, runHostCommand } from './commands/host.js';
|
|
10
|
+
import { hostNameSchema } from '../schemas/host.js';
|
|
11
|
+
function parseOptions(args) {
|
|
12
|
+
const { values, positionals } = parseArgs({
|
|
13
|
+
args: [...args],
|
|
14
|
+
options: {
|
|
15
|
+
help: { type: 'boolean', short: 'h' },
|
|
16
|
+
version: { type: 'boolean', short: 'v' },
|
|
17
|
+
json: { type: 'boolean' },
|
|
18
|
+
config: { type: 'string' },
|
|
19
|
+
apply: { type: 'boolean' },
|
|
20
|
+
'install-runtime': { type: 'boolean' },
|
|
21
|
+
'runtime-tarball': { type: 'string' },
|
|
22
|
+
'runtime-version': { type: 'string' },
|
|
23
|
+
root: { type: 'string' },
|
|
24
|
+
'include-private': { type: 'boolean' },
|
|
25
|
+
'include-archived': { type: 'boolean' },
|
|
26
|
+
task: { type: 'string' },
|
|
27
|
+
objective: { type: 'string' },
|
|
28
|
+
acceptance: { type: 'string', multiple: true },
|
|
29
|
+
constraint: { type: 'string', multiple: true },
|
|
30
|
+
decision: { type: 'string', multiple: true },
|
|
31
|
+
attempted: { type: 'string', multiple: true },
|
|
32
|
+
'next-action': { type: 'string', multiple: true },
|
|
33
|
+
limitation: { type: 'string', multiple: true },
|
|
34
|
+
artifact: { type: 'string', multiple: true },
|
|
35
|
+
'collaboration-record': { type: 'string' },
|
|
36
|
+
'context-completeness': { type: 'string' },
|
|
37
|
+
'author-session': { type: 'string' },
|
|
38
|
+
'native-harness': { type: 'string' },
|
|
39
|
+
'native-session': { type: 'string' },
|
|
40
|
+
session: { type: 'string' },
|
|
41
|
+
repo: { type: 'string' },
|
|
42
|
+
kind: { type: 'string' },
|
|
43
|
+
query: { type: 'string' },
|
|
44
|
+
limit: { type: 'string' },
|
|
45
|
+
'max-bytes': { type: 'string' },
|
|
46
|
+
rebuild: { type: 'boolean' },
|
|
47
|
+
host: { type: 'string' },
|
|
48
|
+
'host-root': { type: 'string' },
|
|
49
|
+
'host-version': { type: 'string' },
|
|
50
|
+
goal: { type: 'string' },
|
|
51
|
+
prepared: { type: 'string' },
|
|
52
|
+
capabilities: { type: 'string' },
|
|
53
|
+
controller: { type: 'string' },
|
|
54
|
+
'domain-root': { type: 'string' },
|
|
55
|
+
},
|
|
56
|
+
allowPositionals: true,
|
|
57
|
+
strict: true,
|
|
58
|
+
});
|
|
59
|
+
if (values.help && values.version) {
|
|
60
|
+
throw new Error('Use either --help or --version, not both.');
|
|
61
|
+
}
|
|
62
|
+
const command = positionals[0] ?? null;
|
|
63
|
+
if (command === 'docs') {
|
|
64
|
+
if (positionals.length > 3) {
|
|
65
|
+
throw new Error('Unknown command; docs accepts one action and one argument.');
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
values,
|
|
69
|
+
codeAction: null,
|
|
70
|
+
command,
|
|
71
|
+
docsAction: positionals[1] ?? null,
|
|
72
|
+
docsArgument: positionals[2] ?? null,
|
|
73
|
+
hostAction: null,
|
|
74
|
+
collaborationAction: null,
|
|
75
|
+
resumeTaskId: null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (command === 'resume') {
|
|
79
|
+
if (positionals.length > 2) {
|
|
80
|
+
throw new Error('resume accepts exactly one task id.');
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
values,
|
|
84
|
+
command,
|
|
85
|
+
docsAction: null,
|
|
86
|
+
docsArgument: null,
|
|
87
|
+
codeAction: null,
|
|
88
|
+
hostAction: null,
|
|
89
|
+
collaborationAction: null,
|
|
90
|
+
resumeTaskId: positionals[1] ?? null,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (command === 'code') {
|
|
94
|
+
if (positionals.length > 2) {
|
|
95
|
+
throw new Error('code accepts one action: status, prepare, or query.');
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
values,
|
|
99
|
+
command,
|
|
100
|
+
docsAction: null,
|
|
101
|
+
docsArgument: null,
|
|
102
|
+
codeAction: positionals[1] ?? null,
|
|
103
|
+
hostAction: null,
|
|
104
|
+
collaborationAction: null,
|
|
105
|
+
resumeTaskId: null,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (command === 'host') {
|
|
109
|
+
if (positionals.length > 2) {
|
|
110
|
+
throw new Error('host accepts one action: detect, describe, plan, install, or verify.');
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
values,
|
|
114
|
+
command,
|
|
115
|
+
docsAction: null,
|
|
116
|
+
docsArgument: null,
|
|
117
|
+
codeAction: null,
|
|
118
|
+
hostAction: positionals[1] ?? null,
|
|
119
|
+
collaborationAction: null,
|
|
120
|
+
resumeTaskId: null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (command === 'collab') {
|
|
124
|
+
if (positionals.length > 2) {
|
|
125
|
+
throw new Error('collab accepts one action: prepare, run, or query.');
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
values,
|
|
129
|
+
command,
|
|
130
|
+
docsAction: null,
|
|
131
|
+
docsArgument: null,
|
|
132
|
+
codeAction: null,
|
|
133
|
+
hostAction: null,
|
|
134
|
+
collaborationAction: positionals[1] ?? null,
|
|
135
|
+
resumeTaskId: null,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (positionals.length > 1) {
|
|
139
|
+
throw new Error('Only one command may be specified.');
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
values,
|
|
143
|
+
command,
|
|
144
|
+
docsAction: null,
|
|
145
|
+
docsArgument: null,
|
|
146
|
+
codeAction: null,
|
|
147
|
+
hostAction: null,
|
|
148
|
+
collaborationAction: null,
|
|
149
|
+
resumeTaskId: null,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function failure(output, json, code, error) {
|
|
153
|
+
const message = error instanceof Error ? error.message : 'Operation failed.';
|
|
154
|
+
if (json) {
|
|
155
|
+
output.stdout(`${JSON.stringify({ ok: false, code, message })}\n`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
output.stderr(`pappra: ${message}\n`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function hasContinuityOptions(values, includeSession = true) {
|
|
162
|
+
return (values.task !== undefined ||
|
|
163
|
+
values.objective !== undefined ||
|
|
164
|
+
values.acceptance !== undefined ||
|
|
165
|
+
values.constraint !== undefined ||
|
|
166
|
+
values.decision !== undefined ||
|
|
167
|
+
values.attempted !== undefined ||
|
|
168
|
+
values['next-action'] !== undefined ||
|
|
169
|
+
values.limitation !== undefined ||
|
|
170
|
+
values.artifact !== undefined ||
|
|
171
|
+
values['collaboration-record'] !== undefined ||
|
|
172
|
+
values['context-completeness'] !== undefined ||
|
|
173
|
+
values['author-session'] !== undefined ||
|
|
174
|
+
values['native-harness'] !== undefined ||
|
|
175
|
+
values['native-session'] !== undefined ||
|
|
176
|
+
(includeSession && values.session !== undefined));
|
|
177
|
+
}
|
|
178
|
+
const globalUsage = 'pappra [--help | --version] [--json]\n' +
|
|
179
|
+
'pappra init [--config <file>] [--apply] [--json]\n' +
|
|
180
|
+
' [--install-runtime (--runtime-tarball <file> | --runtime-version <version>)]\n' +
|
|
181
|
+
'pappra doctor [--root <path>] [--json]\n' +
|
|
182
|
+
'pappra docs <list|check|archive> [options]\n' +
|
|
183
|
+
'pappra checkpoint --task <id> [options] [--json]\n' +
|
|
184
|
+
'pappra resume <taskId> [--session <id>] [--json]\n' +
|
|
185
|
+
'pappra code <status|prepare|query> --repo <id> [options] [--json]\n' +
|
|
186
|
+
'pappra host <detect|describe|plan|install|verify> --host <name> [options] [--json]\n' +
|
|
187
|
+
'pappra collab <prepare|run|query> [options]';
|
|
188
|
+
export async function runCli(args, output) {
|
|
189
|
+
const jsonRequested = args.includes('--json');
|
|
190
|
+
let parsed;
|
|
191
|
+
try {
|
|
192
|
+
parsed = parseOptions(args);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
failure(output, jsonRequested, 'invalid_arguments', error);
|
|
196
|
+
return 2;
|
|
197
|
+
}
|
|
198
|
+
const { values, command, docsAction, docsArgument, codeAction, hostAction, collaborationAction, resumeTaskId, } = parsed;
|
|
199
|
+
const json = values.json === true;
|
|
200
|
+
let info;
|
|
201
|
+
try {
|
|
202
|
+
info = getPackageInfo();
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
failure(output, json, 'package_unavailable', error);
|
|
206
|
+
return 3;
|
|
207
|
+
}
|
|
208
|
+
if (values.version) {
|
|
209
|
+
if (command !== null) {
|
|
210
|
+
failure(output, json, 'invalid_arguments', '--version cannot be combined with a command.');
|
|
211
|
+
return 2;
|
|
212
|
+
}
|
|
213
|
+
output.stdout(json ? `${JSON.stringify(info)}\n` : `${info.version}\n`);
|
|
214
|
+
return 0;
|
|
215
|
+
}
|
|
216
|
+
if (command === 'collab') {
|
|
217
|
+
if (values.help) {
|
|
218
|
+
if (json) {
|
|
219
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['collab'], usage: collaborationUsage })}\n`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
output.stdout(collaborationUsage);
|
|
223
|
+
}
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
const action = collaborationAction === 'prepare' ||
|
|
227
|
+
collaborationAction === 'run' ||
|
|
228
|
+
collaborationAction === 'query'
|
|
229
|
+
? collaborationAction
|
|
230
|
+
: null;
|
|
231
|
+
if (action === null ||
|
|
232
|
+
values.version ||
|
|
233
|
+
values.config !== undefined ||
|
|
234
|
+
values.apply === true ||
|
|
235
|
+
values['install-runtime'] === true ||
|
|
236
|
+
values['runtime-tarball'] !== undefined ||
|
|
237
|
+
values['runtime-version'] !== undefined ||
|
|
238
|
+
values.root !== undefined ||
|
|
239
|
+
values['include-private'] === true ||
|
|
240
|
+
values['include-archived'] === true ||
|
|
241
|
+
hasContinuityOptions(values)) {
|
|
242
|
+
failure(output, json, 'invalid_arguments', 'collab requires prepare/run/query and only collab options.');
|
|
243
|
+
return 2;
|
|
244
|
+
}
|
|
245
|
+
return runCollaborationCommand({
|
|
246
|
+
cwd: process.cwd(),
|
|
247
|
+
action,
|
|
248
|
+
json,
|
|
249
|
+
goalFile: values.goal ?? null,
|
|
250
|
+
preparedFile: values.prepared ?? null,
|
|
251
|
+
capabilitiesFile: values.capabilities ?? null,
|
|
252
|
+
controller: values.controller ?? null,
|
|
253
|
+
domainRoot: values['domain-root'] ?? null,
|
|
254
|
+
}, output);
|
|
255
|
+
}
|
|
256
|
+
if (command === 'docs') {
|
|
257
|
+
if (values.version ||
|
|
258
|
+
values.config !== undefined ||
|
|
259
|
+
values.apply === true ||
|
|
260
|
+
values['install-runtime'] === true ||
|
|
261
|
+
values['runtime-tarball'] !== undefined ||
|
|
262
|
+
values['runtime-version'] !== undefined ||
|
|
263
|
+
values.root !== undefined ||
|
|
264
|
+
hasContinuityOptions(values)) {
|
|
265
|
+
failure(output, json, 'invalid_arguments', 'docs only accepts list/check/archive, --include-private, --include-archived, --help, and --json.');
|
|
266
|
+
return 2;
|
|
267
|
+
}
|
|
268
|
+
if (values.help) {
|
|
269
|
+
if (json) {
|
|
270
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['docs'], usage: docsUsage })}\n`);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
output.stdout(docsUsage);
|
|
274
|
+
}
|
|
275
|
+
return 0;
|
|
276
|
+
}
|
|
277
|
+
return runDocsCommand({
|
|
278
|
+
cwd: process.cwd(),
|
|
279
|
+
action: docsAction,
|
|
280
|
+
argument: docsArgument,
|
|
281
|
+
json,
|
|
282
|
+
includePrivate: values['include-private'] === true,
|
|
283
|
+
includeArchived: values['include-archived'] === true,
|
|
284
|
+
}, output);
|
|
285
|
+
}
|
|
286
|
+
if (command === 'doctor') {
|
|
287
|
+
if (values.help) {
|
|
288
|
+
if (json) {
|
|
289
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['init', 'doctor', 'docs'], usage: doctorUsage })}\n`);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
output.stdout(doctorUsage);
|
|
293
|
+
}
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
if (values.version ||
|
|
297
|
+
values.config !== undefined ||
|
|
298
|
+
values.apply === true ||
|
|
299
|
+
values['install-runtime'] === true ||
|
|
300
|
+
values['runtime-tarball'] !== undefined ||
|
|
301
|
+
values['runtime-version'] !== undefined ||
|
|
302
|
+
values['include-private'] === true ||
|
|
303
|
+
values['include-archived'] === true ||
|
|
304
|
+
hasContinuityOptions(values)) {
|
|
305
|
+
failure(output, json, 'invalid_arguments', 'doctor only accepts --root, --help, and --json.');
|
|
306
|
+
return 2;
|
|
307
|
+
}
|
|
308
|
+
return runDoctorCommand({
|
|
309
|
+
root: values.root ?? process.cwd(),
|
|
310
|
+
json,
|
|
311
|
+
}, output);
|
|
312
|
+
}
|
|
313
|
+
if (command === 'init') {
|
|
314
|
+
if (values.root !== undefined ||
|
|
315
|
+
values['include-private'] === true ||
|
|
316
|
+
values['include-archived'] === true ||
|
|
317
|
+
hasContinuityOptions(values)) {
|
|
318
|
+
failure(output, json, 'invalid_arguments', '--root, --include-private, and --include-archived are not valid for init; init uses the current directory.');
|
|
319
|
+
return 2;
|
|
320
|
+
}
|
|
321
|
+
if (values.help) {
|
|
322
|
+
if (json) {
|
|
323
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['init'], usage: initUsage })}\n`);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
output.stdout(initUsage);
|
|
327
|
+
}
|
|
328
|
+
return 0;
|
|
329
|
+
}
|
|
330
|
+
if (values.version) {
|
|
331
|
+
failure(output, json, 'invalid_arguments', '--version cannot be combined with init.');
|
|
332
|
+
return 2;
|
|
333
|
+
}
|
|
334
|
+
return runInitCommand({
|
|
335
|
+
cwd: process.cwd(),
|
|
336
|
+
configPath: values.config ?? null,
|
|
337
|
+
apply: values.apply === true,
|
|
338
|
+
json,
|
|
339
|
+
installRuntime: values['install-runtime'] === true,
|
|
340
|
+
runtimeTarball: values['runtime-tarball'] ?? null,
|
|
341
|
+
runtimeVersion: values['runtime-version'] ?? null,
|
|
342
|
+
}, output);
|
|
343
|
+
}
|
|
344
|
+
if (command === 'checkpoint') {
|
|
345
|
+
if (values.help) {
|
|
346
|
+
if (json) {
|
|
347
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['checkpoint', 'resume'], usage: checkpointUsage })}\n`);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
output.stdout(checkpointUsage);
|
|
351
|
+
}
|
|
352
|
+
return 0;
|
|
353
|
+
}
|
|
354
|
+
if (values.version ||
|
|
355
|
+
values.config !== undefined ||
|
|
356
|
+
values.apply === true ||
|
|
357
|
+
values['install-runtime'] === true ||
|
|
358
|
+
values['runtime-tarball'] !== undefined ||
|
|
359
|
+
values['runtime-version'] !== undefined ||
|
|
360
|
+
values.root !== undefined ||
|
|
361
|
+
values['include-private'] === true ||
|
|
362
|
+
values['include-archived'] === true ||
|
|
363
|
+
values.session !== undefined ||
|
|
364
|
+
values.task === undefined) {
|
|
365
|
+
failure(output, json, 'invalid_arguments', 'checkpoint requires --task and accepts only task/context options.');
|
|
366
|
+
return 2;
|
|
367
|
+
}
|
|
368
|
+
const completeness = values['context-completeness'];
|
|
369
|
+
if (completeness !== undefined &&
|
|
370
|
+
completeness !== 'complete' &&
|
|
371
|
+
completeness !== 'partial') {
|
|
372
|
+
failure(output, json, 'invalid_arguments', '--context-completeness must be complete or partial.');
|
|
373
|
+
return 2;
|
|
374
|
+
}
|
|
375
|
+
const nativeHarnessValue = values['native-harness'];
|
|
376
|
+
if (nativeHarnessValue !== undefined &&
|
|
377
|
+
!['pi', 'codex', 'claude', 'unknown'].includes(nativeHarnessValue)) {
|
|
378
|
+
failure(output, json, 'invalid_arguments', '--native-harness must be pi, codex, claude, or unknown.');
|
|
379
|
+
return 2;
|
|
380
|
+
}
|
|
381
|
+
const nativeHarness = nativeHarnessValue === 'pi' ||
|
|
382
|
+
nativeHarnessValue === 'codex' ||
|
|
383
|
+
nativeHarnessValue === 'claude' ||
|
|
384
|
+
nativeHarnessValue === 'unknown'
|
|
385
|
+
? nativeHarnessValue
|
|
386
|
+
: null;
|
|
387
|
+
return runCheckpointCommand({
|
|
388
|
+
cwd: process.cwd(),
|
|
389
|
+
json,
|
|
390
|
+
task: values.task,
|
|
391
|
+
objective: values.objective ?? null,
|
|
392
|
+
acceptance: values.acceptance ?? [],
|
|
393
|
+
constraints: values.constraint ?? [],
|
|
394
|
+
decisions: values.decision ?? [],
|
|
395
|
+
attempted: values.attempted ?? [],
|
|
396
|
+
nextActions: values['next-action'] ?? [],
|
|
397
|
+
limitations: values.limitation ?? [],
|
|
398
|
+
artifacts: values.artifact ?? [],
|
|
399
|
+
collaborationRecordRef: values['collaboration-record'] ?? null,
|
|
400
|
+
contextCompleteness: completeness ?? null,
|
|
401
|
+
authorSession: values['author-session'] ?? process.env.PI_SESSION_ID ?? null,
|
|
402
|
+
nativeHarness: nativeHarness ?? null,
|
|
403
|
+
nativeSession: values['native-session'] ?? null,
|
|
404
|
+
}, output);
|
|
405
|
+
}
|
|
406
|
+
if (command === 'resume') {
|
|
407
|
+
if (values.help) {
|
|
408
|
+
if (json) {
|
|
409
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['checkpoint', 'resume'], usage: resumeUsage })}\n`);
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
output.stdout(resumeUsage);
|
|
413
|
+
}
|
|
414
|
+
return 0;
|
|
415
|
+
}
|
|
416
|
+
if (values.version ||
|
|
417
|
+
values.config !== undefined ||
|
|
418
|
+
values.apply === true ||
|
|
419
|
+
values['install-runtime'] === true ||
|
|
420
|
+
values['runtime-tarball'] !== undefined ||
|
|
421
|
+
values['runtime-version'] !== undefined ||
|
|
422
|
+
values.root !== undefined ||
|
|
423
|
+
values['include-private'] === true ||
|
|
424
|
+
values['include-archived'] === true ||
|
|
425
|
+
hasContinuityOptions(values, false) ||
|
|
426
|
+
resumeTaskId === null) {
|
|
427
|
+
failure(output, json, 'invalid_arguments', 'resume requires one task id and accepts only --session.');
|
|
428
|
+
return 2;
|
|
429
|
+
}
|
|
430
|
+
return runResumeCommand({
|
|
431
|
+
cwd: process.cwd(),
|
|
432
|
+
json,
|
|
433
|
+
taskId: resumeTaskId,
|
|
434
|
+
currentSession: values.session ?? process.env.PI_SESSION_ID ?? null,
|
|
435
|
+
}, output);
|
|
436
|
+
}
|
|
437
|
+
if (command === 'code') {
|
|
438
|
+
if (values.help) {
|
|
439
|
+
if (json) {
|
|
440
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['code'], usage: codeUsage })}\n`);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
output.stdout(codeUsage);
|
|
444
|
+
}
|
|
445
|
+
return 0;
|
|
446
|
+
}
|
|
447
|
+
const allowedActions = ['status', 'prepare', 'query'];
|
|
448
|
+
const action = allowedActions.find((item) => item === codeAction) ?? null;
|
|
449
|
+
const kindValues = [
|
|
450
|
+
'explore',
|
|
451
|
+
'symbol',
|
|
452
|
+
'references',
|
|
453
|
+
'impact',
|
|
454
|
+
'text',
|
|
455
|
+
];
|
|
456
|
+
const kind = kindValues.find((item) => item === values.kind) ?? null;
|
|
457
|
+
const operationsInvalid = values.version ||
|
|
458
|
+
values.config !== undefined ||
|
|
459
|
+
values['install-runtime'] === true ||
|
|
460
|
+
values['runtime-tarball'] !== undefined ||
|
|
461
|
+
values['runtime-version'] !== undefined ||
|
|
462
|
+
values.root !== undefined ||
|
|
463
|
+
values['include-private'] === true ||
|
|
464
|
+
values['include-archived'] === true ||
|
|
465
|
+
hasContinuityOptions(values);
|
|
466
|
+
if (action === null ||
|
|
467
|
+
values.repo === undefined ||
|
|
468
|
+
operationsInvalid ||
|
|
469
|
+
(values.apply === true && action !== 'prepare') ||
|
|
470
|
+
(values.rebuild === true && action !== 'prepare') ||
|
|
471
|
+
(action !== 'query' &&
|
|
472
|
+
(values.kind !== undefined ||
|
|
473
|
+
values.query !== undefined ||
|
|
474
|
+
values.limit !== undefined ||
|
|
475
|
+
values['max-bytes'] !== undefined)) ||
|
|
476
|
+
(action !== 'prepare' && values.rebuild === true) ||
|
|
477
|
+
(action !== 'prepare' && values.apply === true)) {
|
|
478
|
+
failure(output, json, 'invalid_arguments', 'code requires status/prepare/query, --repo, and action-compatible options.');
|
|
479
|
+
return 2;
|
|
480
|
+
}
|
|
481
|
+
if (action === 'query' && (kind === null || values.query === undefined)) {
|
|
482
|
+
failure(output, json, 'invalid_arguments', 'code query requires --kind explore|symbol|references|impact|text and --query.');
|
|
483
|
+
return 2;
|
|
484
|
+
}
|
|
485
|
+
const numberOption = (raw, minimum, maximum) => {
|
|
486
|
+
if (raw === undefined)
|
|
487
|
+
return null;
|
|
488
|
+
const value = Number(raw);
|
|
489
|
+
return Number.isSafeInteger(value) && value >= minimum && value <= maximum
|
|
490
|
+
? value
|
|
491
|
+
: undefined;
|
|
492
|
+
};
|
|
493
|
+
const maxResults = numberOption(values.limit, 1, 100);
|
|
494
|
+
const maxBytes = numberOption(values['max-bytes'], 1, 16 * 1024 * 1024);
|
|
495
|
+
if (maxResults === undefined || maxBytes === undefined) {
|
|
496
|
+
failure(output, json, 'invalid_arguments', '--limit must be 1-100 and --max-bytes must be 1-16777216.');
|
|
497
|
+
return 2;
|
|
498
|
+
}
|
|
499
|
+
return runCodeCommand({
|
|
500
|
+
cwd: process.cwd(),
|
|
501
|
+
json,
|
|
502
|
+
action,
|
|
503
|
+
repositoryId: values.repo,
|
|
504
|
+
kind: action === 'query' ? kind : null,
|
|
505
|
+
query: action === 'query' ? (values.query ?? null) : null,
|
|
506
|
+
maxResults,
|
|
507
|
+
maxBytes,
|
|
508
|
+
apply: values.apply === true,
|
|
509
|
+
rebuild: values.rebuild === true,
|
|
510
|
+
}, output);
|
|
511
|
+
}
|
|
512
|
+
if (command === 'host') {
|
|
513
|
+
const allowedActions = [
|
|
514
|
+
'detect',
|
|
515
|
+
'describe',
|
|
516
|
+
'plan',
|
|
517
|
+
'install',
|
|
518
|
+
'verify',
|
|
519
|
+
];
|
|
520
|
+
const action = allowedActions.find((item) => item === hostAction) ?? null;
|
|
521
|
+
const parsedHost = hostNameSchema.safeParse(values.host);
|
|
522
|
+
const host = parsedHost.success ? parsedHost.data : null;
|
|
523
|
+
const invalid = values.version ||
|
|
524
|
+
values.config !== undefined ||
|
|
525
|
+
values['install-runtime'] === true ||
|
|
526
|
+
values['runtime-tarball'] !== undefined ||
|
|
527
|
+
values['runtime-version'] !== undefined ||
|
|
528
|
+
values.root !== undefined ||
|
|
529
|
+
values['include-private'] === true ||
|
|
530
|
+
values['include-archived'] === true ||
|
|
531
|
+
values.repo !== undefined ||
|
|
532
|
+
values.kind !== undefined ||
|
|
533
|
+
values.query !== undefined ||
|
|
534
|
+
values.limit !== undefined ||
|
|
535
|
+
values['max-bytes'] !== undefined ||
|
|
536
|
+
values.rebuild === true ||
|
|
537
|
+
hasContinuityOptions(values) ||
|
|
538
|
+
(values.apply === true && action !== 'install') ||
|
|
539
|
+
(values['host-root'] !== undefined && action === null) ||
|
|
540
|
+
(values['host-version'] !== undefined && action === null);
|
|
541
|
+
if (values.help) {
|
|
542
|
+
if (json) {
|
|
543
|
+
output.stdout(`${JSON.stringify({ ...info, commands: ['host'], usage: hostUsage })}\n`);
|
|
544
|
+
}
|
|
545
|
+
else {
|
|
546
|
+
output.stdout(hostUsage);
|
|
547
|
+
}
|
|
548
|
+
return 0;
|
|
549
|
+
}
|
|
550
|
+
if (action === null || host === null || invalid) {
|
|
551
|
+
failure(output, json, 'invalid_arguments', 'host requires detect/describe/plan/install/verify, --host, and action-compatible options.');
|
|
552
|
+
return 2;
|
|
553
|
+
}
|
|
554
|
+
return runHostCommand({
|
|
555
|
+
cwd: process.cwd(),
|
|
556
|
+
json,
|
|
557
|
+
action,
|
|
558
|
+
host,
|
|
559
|
+
hostRoot: values['host-root'] ?? null,
|
|
560
|
+
hostVersion: values['host-version'] ?? null,
|
|
561
|
+
apply: values.apply === true,
|
|
562
|
+
}, output);
|
|
563
|
+
}
|
|
564
|
+
if (command !== null) {
|
|
565
|
+
failure(output, json, 'invalid_arguments', `Unknown command: ${command}`);
|
|
566
|
+
return 2;
|
|
567
|
+
}
|
|
568
|
+
if (values.config !== undefined ||
|
|
569
|
+
values.apply === true ||
|
|
570
|
+
values['install-runtime'] === true ||
|
|
571
|
+
values['runtime-tarball'] !== undefined ||
|
|
572
|
+
values['runtime-version'] !== undefined ||
|
|
573
|
+
values.root !== undefined ||
|
|
574
|
+
values['include-private'] === true ||
|
|
575
|
+
values['include-archived'] === true ||
|
|
576
|
+
hasContinuityOptions(values)) {
|
|
577
|
+
failure(output, json, 'invalid_arguments', '--config/--apply/runtime flags require init; --root requires doctor.');
|
|
578
|
+
return 2;
|
|
579
|
+
}
|
|
580
|
+
if (values.help) {
|
|
581
|
+
if (json) {
|
|
582
|
+
output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'doctor', 'docs', 'checkpoint', 'resume', 'code', 'host', 'collab'] })}\n`);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
output.stdout(`${info.name} ${info.version}\n${info.description}\n\nUsage:\n ${globalUsage.replaceAll('\n', '\n ')}\n\nOptions:\n -h, --help Show help\n -v, --version Show version\n --json Output JSON\n\nCommands:\n init Plan workspace initialization\n doctor Read-only workspace and installation diagnostics\n docs List, check, and archive registered documents\n`);
|
|
586
|
+
output.stdout(' checkpoint Save a private task checkpoint\n resume Read a bounded recovery packet without starting an agent\n code Inspect or prepare selected code intelligence\n host Detect, plan, install, or verify a selected host integration\n collab Prepare, run, or query a bounded collaboration goal\n');
|
|
587
|
+
}
|
|
588
|
+
return 0;
|
|
589
|
+
}
|
|
590
|
+
if (json) {
|
|
591
|
+
output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'doctor', 'docs', 'checkpoint', 'resume', 'code', 'host', 'collab'] })}\n`);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
output.stdout(`${info.name} ${info.version}\n${info.description}\n\nUsage:\n ${globalUsage}\n\nRun pappra --help for all options.\n`);
|
|
595
|
+
}
|
|
596
|
+
return 0;
|
|
597
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CodeQueryItem } from '../schemas/code.js';
|
|
2
|
+
export interface BoundedCodeItems {
|
|
3
|
+
readonly items: CodeQueryItem[];
|
|
4
|
+
readonly bytes: number;
|
|
5
|
+
readonly truncated: boolean;
|
|
6
|
+
readonly reasons: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Bounds emitted item JSON, not source bytes scanned. `bytes` is the sum of
|
|
10
|
+
* item JSON bytes; the fixed result envelope (object keys and array brackets)
|
|
11
|
+
* is not counted. A budget below the first item leaves an empty, truncated
|
|
12
|
+
* result rather than silently exceeding the caller's byte ceiling.
|
|
13
|
+
*/
|
|
14
|
+
export declare function boundCodeItems(items: readonly CodeQueryItem[], maxBytes: number, maxResults: number, maxFiles: number): BoundedCodeItems;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function itemBytes(item) {
|
|
2
|
+
return Buffer.byteLength(JSON.stringify(item), 'utf8');
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Bounds emitted item JSON, not source bytes scanned. `bytes` is the sum of
|
|
6
|
+
* item JSON bytes; the fixed result envelope (object keys and array brackets)
|
|
7
|
+
* is not counted. A budget below the first item leaves an empty, truncated
|
|
8
|
+
* result rather than silently exceeding the caller's byte ceiling.
|
|
9
|
+
*/
|
|
10
|
+
export function boundCodeItems(items, maxBytes, maxResults, maxFiles) {
|
|
11
|
+
const selected = [];
|
|
12
|
+
const paths = new Set();
|
|
13
|
+
const reasons = [];
|
|
14
|
+
let bytes = 0;
|
|
15
|
+
for (const item of items) {
|
|
16
|
+
if (selected.length >= maxResults) {
|
|
17
|
+
reasons.push('result_limit');
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
if (!paths.has(item.path) && paths.size >= maxFiles) {
|
|
21
|
+
reasons.push('file_limit');
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
const size = itemBytes(item);
|
|
25
|
+
if (bytes + size > maxBytes) {
|
|
26
|
+
reasons.push('output_budget');
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
selected.push(item);
|
|
30
|
+
paths.add(item.path);
|
|
31
|
+
bytes += size;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
items: selected,
|
|
35
|
+
bytes,
|
|
36
|
+
truncated: selected.length < items.length || reasons.length > 0,
|
|
37
|
+
reasons: [...new Set(reasons)].slice(0, 16),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Outcome } from '../schemas/outcome.js';
|
|
2
|
+
export interface CommandOptions {
|
|
3
|
+
readonly command: string;
|
|
4
|
+
readonly args: readonly string[];
|
|
5
|
+
readonly cwd: string;
|
|
6
|
+
readonly timeoutMs?: number;
|
|
7
|
+
readonly maxOutputBytes?: number;
|
|
8
|
+
readonly signal?: AbortSignal;
|
|
9
|
+
}
|
|
10
|
+
export interface CommandResult {
|
|
11
|
+
readonly command: string;
|
|
12
|
+
readonly args: readonly string[];
|
|
13
|
+
readonly stdout: string;
|
|
14
|
+
readonly stderr: string;
|
|
15
|
+
readonly exitCode: number;
|
|
16
|
+
readonly bytes: number;
|
|
17
|
+
readonly durationMs: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Executes one argv-delimited local command without a shell. Output and time
|
|
21
|
+
* are bounded; a failure never becomes an empty successful result.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runCommand(options: CommandOptions): Promise<Outcome<CommandResult>>;
|