@aopslabs/aops 0.2.0
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 +19 -0
- package/NOTICE +7 -0
- package/README.md +203 -0
- package/assets/agent-assets/core/SKILL.md +49 -0
- package/assets/agent-assets/core/references/agentspace/SKILL.md +78 -0
- package/assets/agent-assets/core/references/aops-cli-core/SKILL.md +108 -0
- package/assets/agent-assets/core/references/chatv3/SKILL.md +48 -0
- package/assets/agent-assets/core/references/collaborative-work/SKILL.md +85 -0
- package/assets/agent-assets/core/references/discuss/SKILL.md +66 -0
- package/assets/agent-assets/core/references/docman/SKILL.md +69 -0
- package/assets/agent-assets/core/references/hosted-chat/SKILL.md +64 -0
- package/assets/agent-assets/core/references/mission/SKILL.md +54 -0
- package/assets/agent-assets/core/references/projectman/SKILL.md +86 -0
- package/assets/agent-assets/core/references/sys/SKILL.md +36 -0
- package/assets/agent-assets/core/references/view/SKILL.md +58 -0
- package/assets/agent-assets/core/references/working-disciplines/SKILL.md +69 -0
- package/assets/agent-assets/core/user-guides/agent-assets.md +81 -0
- package/assets/agent-assets/core/user-guides/agentspace.md +1098 -0
- package/assets/agent-assets/core/user-guides/aops-cli.md +1107 -0
- package/assets/agent-assets/core/user-guides/aops-system.md +63 -0
- package/assets/agent-assets/core/user-guides/chatv3.md +113 -0
- package/assets/agent-assets/core/user-guides/docman.md +162 -0
- package/assets/agent-assets/core/user-guides/projectman.md +212 -0
- package/assets/agent-assets/core/user-guides/sys.md +94 -0
- package/assets/agent-assets/core/user-guides/working-disciplines.md +588 -0
- package/assets/agent-assets/gateway/aops/SKILL.md +14 -0
- package/assets/r6-remote-session-baseline.json +19 -0
- package/assets/skills/aops-install/SKILL.md +231 -0
- package/assets/skills/aops-install/agents/openai.yaml +4 -0
- package/dist/commands/activity.js +352 -0
- package/dist/commands/agent-profile.js +653 -0
- package/dist/commands/agent.js +710 -0
- package/dist/commands/agents-md.js +125 -0
- package/dist/commands/api.js +84 -0
- package/dist/commands/archive.js +873 -0
- package/dist/commands/artifact.js +535 -0
- package/dist/commands/assets.js +1414 -0
- package/dist/commands/auth/device-login.js +1 -0
- package/dist/commands/auth/legacy-export.js +177 -0
- package/dist/commands/auth/login.js +426 -0
- package/dist/commands/chat.js +1363 -0
- package/dist/commands/chatv3.js +1684 -0
- package/dist/commands/checkpoint.js +549 -0
- package/dist/commands/commercial-artifact.js +475 -0
- package/dist/commands/commercial-license.js +594 -0
- package/dist/commands/community-auth.js +62 -0
- package/dist/commands/community-cockpit.js +185 -0
- package/dist/commands/community-console.js +109 -0
- package/dist/commands/community-doctor.js +335 -0
- package/dist/commands/community-server.js +2062 -0
- package/dist/commands/community-setup.js +284 -0
- package/dist/commands/discuss.js +1448 -0
- package/dist/commands/doc.js +5219 -0
- package/dist/commands/experience.js +922 -0
- package/dist/commands/host.js +1127 -0
- package/dist/commands/init.js +118 -0
- package/dist/commands/memory.js +3129 -0
- package/dist/commands/mission.js +562 -0
- package/dist/commands/official-catalog.js +134 -0
- package/dist/commands/plan.js +84 -0
- package/dist/commands/playbook.js +415 -0
- package/dist/commands/pm/context.js +6 -0
- package/dist/commands/pm/index.js +701 -0
- package/dist/commands/pm/projectman.js +6266 -0
- package/dist/commands/project.js +1080 -0
- package/dist/commands/prompt.js +1024 -0
- package/dist/commands/repo-sync.js +1907 -0
- package/dist/commands/resource.js +527 -0
- package/dist/commands/skill.js +1211 -0
- package/dist/commands/start-disciplines.js +510 -0
- package/dist/commands/start.js +1343 -0
- package/dist/commands/target.js +309 -0
- package/dist/commands/version.js +42 -0
- package/dist/commands/view.js +1852 -0
- package/dist/launchers/cockpit.js +28 -0
- package/dist/launchers/options.js +74 -0
- package/dist/launchers/server.js +41 -0
- package/dist/lib/agent-assets/envelope.js +83 -0
- package/dist/lib/agent-assets/gateway.js +15 -0
- package/dist/lib/agent-assets/guards.js +23 -0
- package/dist/lib/agent-assets/hosted-discovery.js +148 -0
- package/dist/lib/agent-assets/hosted-package-input.js +154 -0
- package/dist/lib/agent-assets/legacy-pointer-migration.js +677 -0
- package/dist/lib/agent-assets/native-fs.js +589 -0
- package/dist/lib/agent-assets/package-manifest.js +324 -0
- package/dist/lib/agent-assets/portable-path.js +67 -0
- package/dist/lib/agent-assets/release-input.js +177 -0
- package/dist/lib/agent-assets/roots.js +45 -0
- package/dist/lib/agent-assets/runtime-binding-reader.js +545 -0
- package/dist/lib/agent-assets/runtime-targets.js +50 -0
- package/dist/lib/agent-assets/store-reader.js +1212 -0
- package/dist/lib/agent-assets/store-types.js +1 -0
- package/dist/lib/agent-assets/store-writer.js +1484 -0
- package/dist/lib/agent-assets/types.js +1 -0
- package/dist/lib/agent-assets/unicode-case-folding-v15-1.generated.js +1548 -0
- package/dist/lib/commercial-final-readiness.js +504 -0
- package/dist/lib/commercial-lifecycle-smoke-isolation.js +236 -0
- package/dist/lib/commercial-managed-postgres-docker-adapter.js +274 -0
- package/dist/lib/commercial-setup-readiness-adapter.js +179 -0
- package/dist/lib/community-client-contract.js +164 -0
- package/dist/lib/community-cockpit-lifecycle.js +601 -0
- package/dist/lib/community-command-abort.js +59 -0
- package/dist/lib/community-diagnostic.js +237 -0
- package/dist/lib/community-docker-adapter.js +498 -0
- package/dist/lib/community-home.js +31 -0
- package/dist/lib/community-instance-contract.js +148 -0
- package/dist/lib/community-instance-layout.js +97 -0
- package/dist/lib/community-lifecycle.js +1631 -0
- package/dist/lib/community-migration-snapshot.js +770 -0
- package/dist/lib/community-native-application-recovery.js +425 -0
- package/dist/lib/community-native-child.js +240 -0
- package/dist/lib/community-native-database-recovery.js +456 -0
- package/dist/lib/community-native-lifecycle.js +2458 -0
- package/dist/lib/community-native-migration.js +339 -0
- package/dist/lib/community-native-postgres.js +596 -0
- package/dist/lib/community-operation-journal.js +773 -0
- package/dist/lib/community-operation-lock.js +596 -0
- package/dist/lib/community-release-resolver.js +291 -0
- package/dist/lib/community-release-verifier.js +475 -0
- package/dist/lib/community-repo-discovery.js +252 -0
- package/dist/lib/community-setup-server-env.js +203 -0
- package/dist/lib/external-url.js +110 -0
- package/dist/lib/official-catalog-gateway.js +108 -0
- package/dist/lib/official-catalog.js +364 -0
- package/dist/lib/server-bootstrap.js +240 -0
- package/dist/lib/setup-agent-assets-bridge.js +176 -0
- package/dist/lib/setup-agent-assets-release.js +52 -0
- package/dist/lib/setup-external-postgres.js +108 -0
- package/dist/lib/setup-init-orchestrator.js +990 -0
- package/dist/lib/setup-install-guide.js +52 -0
- package/dist/lib/setup-installer-release.js +47 -0
- package/dist/lib/setup-local-postgres.js +329 -0
- package/dist/lib/setup-official-catalog-bridge.js +148 -0
- package/dist/lib/setup-readiness.js +888 -0
- package/dist/lib/tui-launcher.js +59 -0
- package/dist/main.js +150 -0
- package/dist/seeds/agents-md.js +54 -0
- package/dist/utils/agent-gateway.js +275 -0
- package/dist/utils/agents-md.js +281 -0
- package/dist/utils/api.js +255 -0
- package/dist/utils/chatv3-session-store.js +185 -0
- package/dist/utils/command.js +67 -0
- package/dist/utils/community-host-runtime.js +376 -0
- package/dist/utils/config.js +1015 -0
- package/dist/utils/discussion-workspace.js +552 -0
- package/dist/utils/experience-workspace.js +326 -0
- package/dist/utils/guide-paths.js +67 -0
- package/dist/utils/hosted-sugar.js +56 -0
- package/dist/utils/hosted-workspace.js +229 -0
- package/dist/utils/memory-workspace.js +537 -0
- package/dist/utils/operator-runtime.js +199 -0
- package/dist/utils/password-crypto.js +39 -0
- package/dist/utils/playbook-workspace.js +479 -0
- package/dist/utils/project-context.js +255 -0
- package/dist/utils/prompts.js +70 -0
- package/dist/utils/refresh-race.js +28 -0
- package/dist/utils/repo-config.js +109 -0
- package/dist/utils/repo-first-projectman.js +194 -0
- package/dist/utils/repo-first-storage.js +13 -0
- package/dist/utils/repo-first-view.js +305 -0
- package/dist/utils/session-guidance.js +278 -0
- package/dist/utils/session-state.js +137 -0
- package/dist/utils/table.js +39 -0
- package/dist/utils/transient-fs.js +49 -0
- package/dist/utils/workspace-root.js +1 -0
- package/launchers/aops-cockpit.ps1 +15 -0
- package/launchers/aops-cockpit.sh +16 -0
- package/launchers/aops-server.ps1 +15 -0
- package/launchers/aops-server.sh +16 -0
- package/native/tui/win32-x64/aops-tui.exe +0 -0
- package/package.json +81 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
const SUPPORTED_TUI_TARGETS = new Set([
|
|
6
|
+
'darwin-arm64',
|
|
7
|
+
'darwin-x64',
|
|
8
|
+
'linux-arm64',
|
|
9
|
+
'linux-x64',
|
|
10
|
+
'win32-x64',
|
|
11
|
+
]);
|
|
12
|
+
function packageRootFromModule() {
|
|
13
|
+
return fileURLToPath(new URL('../../', import.meta.url));
|
|
14
|
+
}
|
|
15
|
+
export function shouldLaunchBundledTui(argv, inputIsTerminal = process.stdin.isTTY === true, outputIsTerminal = process.stdout.isTTY === true) {
|
|
16
|
+
return argv.length <= 2 && inputIsTerminal && outputIsTerminal;
|
|
17
|
+
}
|
|
18
|
+
export function buildBundledTuiLaunch(options = {}) {
|
|
19
|
+
const platform = options.platform ?? process.platform;
|
|
20
|
+
const arch = options.arch ?? process.arch;
|
|
21
|
+
const target = `${platform}-${arch}`;
|
|
22
|
+
if (!SUPPORTED_TUI_TARGETS.has(target)) {
|
|
23
|
+
throw new Error(`The bundled AOPS TUI does not support this platform (${target}). Use aops --help.`);
|
|
24
|
+
}
|
|
25
|
+
const packageRoot = path.resolve(options.packageRoot ?? packageRootFromModule());
|
|
26
|
+
const executableName = platform === 'win32' ? 'aops-tui.exe' : 'aops-tui';
|
|
27
|
+
const command = path.join(packageRoot, 'native', 'tui', target, executableName);
|
|
28
|
+
const cliEntrypoint = path.join(packageRoot, 'dist', 'main.js');
|
|
29
|
+
const env = {
|
|
30
|
+
...(options.environment ?? process.env),
|
|
31
|
+
AOPS_TUI_CLI_ENTRYPOINT: cliEntrypoint,
|
|
32
|
+
AOPS_TUI_NODE: options.nodeExecutable ?? process.execPath,
|
|
33
|
+
};
|
|
34
|
+
delete env.AOPS_TUI_CLI;
|
|
35
|
+
return Object.freeze({
|
|
36
|
+
command,
|
|
37
|
+
args: Object.freeze([]),
|
|
38
|
+
options: Object.freeze({ stdio: 'inherit', env }),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export async function launchBundledTui(options = {}) {
|
|
42
|
+
const invocation = buildBundledTuiLaunch(options);
|
|
43
|
+
const fileExists = options.fileExists ?? existsSync;
|
|
44
|
+
if (!fileExists(invocation.command)) {
|
|
45
|
+
throw new Error('The bundled AOPS TUI is missing. Reinstall @aopslabs/aops or use aops --help.');
|
|
46
|
+
}
|
|
47
|
+
const spawnProcess = options.spawnProcess ?? spawn;
|
|
48
|
+
const child = spawnProcess(invocation.command, [...invocation.args], invocation.options);
|
|
49
|
+
return await new Promise((resolve, reject) => {
|
|
50
|
+
child.once('error', reject);
|
|
51
|
+
child.once('exit', (code, signal) => {
|
|
52
|
+
if (signal) {
|
|
53
|
+
reject(new Error(`The AOPS TUI stopped after receiving ${signal}.`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
resolve(code ?? 1);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { logError } from '@aopslabs/xf-cli-ui';
|
|
4
|
+
import { resolveCommunityCliIdentity } from './lib/community-client-contract.js';
|
|
5
|
+
import { makeInitCommand } from './commands/init.js';
|
|
6
|
+
import { makeCommunitySetupCommand } from './commands/community-setup.js';
|
|
7
|
+
import { makeAssetsCommand } from './commands/assets.js';
|
|
8
|
+
import { makeStartCommand } from './commands/start.js';
|
|
9
|
+
import { makePlanCommand } from './commands/plan.js';
|
|
10
|
+
import { makeAgentsMdCommand } from './commands/agents-md.js';
|
|
11
|
+
import { makeAgentCommand } from './commands/agent.js';
|
|
12
|
+
import { makeSyncCommand } from './commands/repo-sync.js';
|
|
13
|
+
import { makeArchiveCommand } from './commands/archive.js';
|
|
14
|
+
import { makeViewCommand } from './commands/view.js';
|
|
15
|
+
import { makeHostCommand } from './commands/host.js';
|
|
16
|
+
import { makeApiCommand } from './commands/api.js';
|
|
17
|
+
import { guardCommunitySecretArgv, makeCommunityAuthCommand } from './commands/community-auth.js';
|
|
18
|
+
import { makeMemoryCommand } from './commands/memory.js';
|
|
19
|
+
import { makeCheckpointCommand } from './commands/checkpoint.js';
|
|
20
|
+
import { makeExperienceCommand } from './commands/experience.js';
|
|
21
|
+
import { makeDiscussCommand } from './commands/discuss.js';
|
|
22
|
+
import { makeChatCommand } from './commands/chat.js';
|
|
23
|
+
import { guardChatv3UnknownSubcommand, makeChatv3Command } from './commands/chatv3.js';
|
|
24
|
+
import { makeAgentProfileCommand } from './commands/agent-profile.js';
|
|
25
|
+
import { makePromptCommand } from './commands/prompt.js';
|
|
26
|
+
import { makeProjectCommand } from './commands/project.js';
|
|
27
|
+
import { makeMissionCommand } from './commands/mission.js';
|
|
28
|
+
import { makePlaybookCommand } from './commands/playbook.js';
|
|
29
|
+
import { makeResourceCommand } from './commands/resource.js';
|
|
30
|
+
import { makeArtifactCommand } from './commands/artifact.js';
|
|
31
|
+
import { makeCommercialLicenseCommand } from './commands/commercial-license.js';
|
|
32
|
+
import { makeActivityCommand } from './commands/activity.js';
|
|
33
|
+
import { makeSkillCommand } from './commands/skill.js';
|
|
34
|
+
import { makeDocCommand } from './commands/doc.js';
|
|
35
|
+
import { makePmCommand } from './commands/pm/index.js';
|
|
36
|
+
import { makeCommunityServerCommand } from './commands/community-server.js';
|
|
37
|
+
import { makeCommunityCockpitCommand } from './commands/community-cockpit.js';
|
|
38
|
+
import { makeCommunityDoctorCommand } from './commands/community-doctor.js';
|
|
39
|
+
import { makeCommunityConsoleCommand } from './commands/community-console.js';
|
|
40
|
+
import { makeTargetCommand } from './commands/target.js';
|
|
41
|
+
import { makeVersionCommand } from './commands/version.js';
|
|
42
|
+
import { launchBundledTui, shouldLaunchBundledTui } from './lib/tui-launcher.js';
|
|
43
|
+
import { CommunityDiagnosticError, formatCommunityDiagnostic, } from './lib/community-diagnostic.js';
|
|
44
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
45
|
+
stream.on('error', (error) => {
|
|
46
|
+
if (error?.code === 'EPIPE') {
|
|
47
|
+
process.exit(typeof process.exitCode === 'number' ? process.exitCode : 0);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function buildCommunityProgram() {
|
|
53
|
+
const program = new Command();
|
|
54
|
+
const version = resolveCommunityCliIdentity().version;
|
|
55
|
+
program
|
|
56
|
+
.name('aops')
|
|
57
|
+
.description('AOPS Community operator CLI for local-trusted, self-hosted workflows')
|
|
58
|
+
.enablePositionalOptions()
|
|
59
|
+
.version(version)
|
|
60
|
+
.version(version, '--cli-version', 'output the CLI version (legacy alias)');
|
|
61
|
+
program.addCommand(makeInitCommand());
|
|
62
|
+
program.addCommand(makeCommunitySetupCommand());
|
|
63
|
+
program.addCommand(makeAssetsCommand());
|
|
64
|
+
program.addCommand(makeStartCommand());
|
|
65
|
+
program.addCommand(makePlanCommand());
|
|
66
|
+
program.addCommand(makeAgentsMdCommand());
|
|
67
|
+
program.addCommand(makeAgentCommand());
|
|
68
|
+
program.addCommand(makeSyncCommand());
|
|
69
|
+
program.addCommand(makeArchiveCommand());
|
|
70
|
+
program.addCommand(makeViewCommand());
|
|
71
|
+
program.addCommand(makeHostCommand());
|
|
72
|
+
program.addCommand(makeApiCommand());
|
|
73
|
+
program.addCommand(makeCommunityAuthCommand());
|
|
74
|
+
program.addCommand(makeMemoryCommand());
|
|
75
|
+
program.addCommand(makeCheckpointCommand());
|
|
76
|
+
program.addCommand(makeExperienceCommand());
|
|
77
|
+
program.addCommand(makeDiscussCommand());
|
|
78
|
+
program.addCommand(makeChatCommand());
|
|
79
|
+
program.addCommand(makeChatv3Command());
|
|
80
|
+
program.addCommand(makeAgentProfileCommand());
|
|
81
|
+
program.addCommand(makePromptCommand());
|
|
82
|
+
program.addCommand(makeProjectCommand());
|
|
83
|
+
program.addCommand(makeMissionCommand());
|
|
84
|
+
program.addCommand(makePlaybookCommand());
|
|
85
|
+
program.addCommand(makeResourceCommand());
|
|
86
|
+
program.addCommand(makeArtifactCommand());
|
|
87
|
+
program.addCommand(makeCommercialLicenseCommand());
|
|
88
|
+
program.addCommand(makeActivityCommand());
|
|
89
|
+
program.addCommand(makeSkillCommand());
|
|
90
|
+
program.addCommand(makeDocCommand());
|
|
91
|
+
program.addCommand(makePmCommand());
|
|
92
|
+
program.addCommand(makeCommunityServerCommand());
|
|
93
|
+
program.addCommand(makeCommunityCockpitCommand());
|
|
94
|
+
program.addCommand(makeCommunityDoctorCommand());
|
|
95
|
+
program.addCommand(makeCommunityConsoleCommand());
|
|
96
|
+
program.addCommand(makeTargetCommand());
|
|
97
|
+
program.addCommand(makeVersionCommand());
|
|
98
|
+
program.addHelpText('after', `
|
|
99
|
+
AOPS Community is a single-user, self-hosted/local-trusted distribution.
|
|
100
|
+
Canonical writes go to the local AOPS server; .aops/** remains a read-only cache.
|
|
101
|
+
|
|
102
|
+
Quick checks:
|
|
103
|
+
aops setup ai
|
|
104
|
+
aops setup guide
|
|
105
|
+
aops host health
|
|
106
|
+
aops agent tools
|
|
107
|
+
aops view dashboard --style agent
|
|
108
|
+
`);
|
|
109
|
+
return program;
|
|
110
|
+
}
|
|
111
|
+
async function main() {
|
|
112
|
+
const program = buildCommunityProgram();
|
|
113
|
+
const jsonOutputRequested = process.argv.includes('--json');
|
|
114
|
+
try {
|
|
115
|
+
if (process.argv.length <= 2) {
|
|
116
|
+
if (shouldLaunchBundledTui(process.argv)) {
|
|
117
|
+
process.exitCode = await launchBundledTui();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
process.stdout.write('AOPS TUI requires an interactive terminal. Use aops --help or run an explicit aops command.\n');
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const argv = process.argv[2] === '--'
|
|
125
|
+
? [process.argv[0], process.argv[1], ...process.argv.slice(3)]
|
|
126
|
+
: process.argv;
|
|
127
|
+
guardChatv3UnknownSubcommand(argv);
|
|
128
|
+
guardCommunitySecretArgv(argv);
|
|
129
|
+
await program.parseAsync(argv);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
if (error instanceof CommunityDiagnosticError) {
|
|
133
|
+
if (jsonOutputRequested) {
|
|
134
|
+
process.stderr.write(`${JSON.stringify({
|
|
135
|
+
schemaVersion: 1,
|
|
136
|
+
ok: false,
|
|
137
|
+
error: error.diagnostic,
|
|
138
|
+
}, null, 2)}\n`);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
logError(formatCommunityDiagnostic(error.diagnostic));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
logError(String(error?.message ?? error));
|
|
146
|
+
}
|
|
147
|
+
process.exitCode = 1;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
void main();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const AOPS_AGENTS_MD_TEMPLATE_SEEDS = [
|
|
2
|
+
{
|
|
3
|
+
slug: 'aops-collaborative-startup',
|
|
4
|
+
title: 'AOPS Collaborative Startup',
|
|
5
|
+
description: 'Default solo-first session starter; boots the aops-collaborative-work skill (collaboration and chat are operator-opt-in).',
|
|
6
|
+
mirrorPath: '.aops/hosted/prompts/aops-collaborative-startup.md',
|
|
7
|
+
promptRef: 'prompt:aops-collaborative-startup',
|
|
8
|
+
tags: ['default', 'starter', 'solo-first', 'coordination-optional'],
|
|
9
|
+
snippet: [
|
|
10
|
+
'Boot the aops-collaborative-work skill and pick the mode once at kickoff: solo (default) | solo+async-review | chat-room.',
|
|
11
|
+
'Run the skill startup block with compact output; prefer aops-cli start --json --out <file> and follow result.promptRef.path instead of inline prompt JSON.',
|
|
12
|
+
'Read layered rules only as needed: repo AGENTS.md / ChatV3 room rules, selected working-discipline guardrails, accepted playbook briefs, and ranked experience briefs.',
|
|
13
|
+
'Use aops-cli mission resume --id <mission-id> --json or aops-cli start --resume <mission-id> --json when a mission exists; use aops-cli start --reminder --task "<current task>" --area <area> --json for mid-session refresh.',
|
|
14
|
+
'Pull detail through the skill detail ladder (sub-skill section, command --help, aops-cli agent schema).',
|
|
15
|
+
'Every task lands in PM before implementation; validate honestly; UI slices are verified live via Chrome MCP.',
|
|
16
|
+
'Solo modes may leave async PM review requests for a future session; chat-room mode posts the PM review-request ref into the hosted room as a wake.',
|
|
17
|
+
'Closeout (board/room) is operator-only; ordinary turn end writes status/handoff and keeps surfaces open.',
|
|
18
|
+
'When the operator asks for the bootstrapper/starter prompt, paste the prompt mirror body verbatim.',
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
slug: 'aops-task-execution-template',
|
|
23
|
+
title: 'AOPS Task Execution Template',
|
|
24
|
+
description: 'Operator-fillable, PM-backed generic execution checklist template.',
|
|
25
|
+
mirrorPath: '.aops/hosted/prompts/aops-task-execution-template.md',
|
|
26
|
+
promptRef: 'prompt:aops-task-execution-template',
|
|
27
|
+
tags: ['pm', 'closeout', 'template'],
|
|
28
|
+
snippet: [
|
|
29
|
+
'Use AOPS PM for substantive work: inspect or create the board/task/sprint window before implementation.',
|
|
30
|
+
'Build project context from AGENTS.md, repo memory, Projectman state, and relevant docs before changing files.',
|
|
31
|
+
'Track meaningful work as sprint microtasks; promote review findings or blockers to PM issues.',
|
|
32
|
+
'Validate, commit only scoped changes, then run the PM closeout sequence requested by the operator.',
|
|
33
|
+
'Write a short memory closeout for durable decisions, follow-ups, and resume context.',
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
slug: 'aops-cli-discuss',
|
|
38
|
+
title: 'AOPS Discuss / Decision Protocol',
|
|
39
|
+
description: 'Standalone discuss decision/consensus discipline; coordination via aops-cli-chat, review via aops-cli-projectman; canonical mechanics in the aops-cli-discuss hosted skill.',
|
|
40
|
+
mirrorPath: '.aops/hosted/skills/aops-cli-discuss.md',
|
|
41
|
+
promptRef: 'skill:aops-cli-discuss',
|
|
42
|
+
tags: ['discuss', 'decision', 'consensus'],
|
|
43
|
+
snippet: [
|
|
44
|
+
'Run a standalone discuss topic for material design decisions; give every peer enough independent context to research and form its own stance.',
|
|
45
|
+
'Drive at least four substantive non-final turns, then each agent files a kind=final-stance turn before concluding.',
|
|
46
|
+
'Confirm completeness from JSON (lifecycleState / missingTurnFinalStances), then conclude and finalize the outputs with no _TBD_ placeholders.',
|
|
47
|
+
'Surface decisions explicitly: there is no auto bridge — carry the discussion-topic ref into a PM review-request/issue and ping the hosted chat room.',
|
|
48
|
+
'Coordination/wake lives in aops-cli-chat; review + execution truth lives in aops-cli-projectman.',
|
|
49
|
+
'Conclude only after final stances are recorded; session/board closeout stays operator-only.',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
export const DEFAULT_AGENTS_MD_TEMPLATE_SLUG = 'aops-collaborative-startup';
|
|
54
|
+
export const DISCUSS_AGENTS_MD_TEMPLATE_SLUG = 'aops-cli-discuss';
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { logError } from '@aopslabs/xf-cli-ui';
|
|
2
|
+
import { buildHostedToolInvokeRequestBody, buildOperatorHeaders, } from './operator-runtime.js';
|
|
3
|
+
export { parseJsonInput } from './operator-runtime.js';
|
|
4
|
+
import { createCliApiClientFromOptions, isCliHostReachable, isCliAuthRequired, } from './api.js';
|
|
5
|
+
import { normalizeNonEmpty, } from './command.js';
|
|
6
|
+
import { hydrateProjectIdFromServerLookup, resolveProjectBindingContext, } from './project-context.js';
|
|
7
|
+
function normalizeScopeResolution(value) {
|
|
8
|
+
return value === 'explicit' || value === 'cascade' ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
export async function resolveAgentGatewayContext(options) {
|
|
11
|
+
const resolvedContext = await resolveProjectBindingContext(options, {
|
|
12
|
+
requireProject: false,
|
|
13
|
+
});
|
|
14
|
+
const projectName = normalizeNonEmpty(options.projectName) ?? normalizeNonEmpty(resolvedContext.projectName);
|
|
15
|
+
return {
|
|
16
|
+
tenantId: normalizeNonEmpty(options.tenantId),
|
|
17
|
+
locale: normalizeNonEmpty(options.locale),
|
|
18
|
+
fallbackLocale: normalizeNonEmpty(options.fallbackLocale),
|
|
19
|
+
scopeId: normalizeNonEmpty(options.scopeId) ?? normalizeNonEmpty(resolvedContext.scopeId),
|
|
20
|
+
projectId: normalizeNonEmpty(options.projectId) ?? resolvedContext.projectId,
|
|
21
|
+
projectName,
|
|
22
|
+
scopeResolution: normalizeScopeResolution(options.scopeResolution),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function buildProjectLookupDeps(apiState, options) {
|
|
26
|
+
return {
|
|
27
|
+
invokeHostedTool: ({ toolId, input }) => invokeHostedToolWithApiState(apiState, {
|
|
28
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
29
|
+
accessToken: options.accessToken,
|
|
30
|
+
refreshToken: options.refreshToken,
|
|
31
|
+
timeoutMs: options.timeoutMs,
|
|
32
|
+
tenantId: options.tenantId,
|
|
33
|
+
locale: options.locale,
|
|
34
|
+
fallbackLocale: options.fallbackLocale,
|
|
35
|
+
toolId,
|
|
36
|
+
input,
|
|
37
|
+
disableDurableActivityLog: true,
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function resolveProjectScopeOptionsWithApiState(apiState, options) {
|
|
42
|
+
if (normalizeNonEmpty(options.projectId) ?? normalizeNonEmpty(options.scopeId)) {
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
45
|
+
if (!normalizeNonEmpty(options.projectSlug) && !normalizeNonEmpty(options.projectName)) {
|
|
46
|
+
return options;
|
|
47
|
+
}
|
|
48
|
+
const baseContext = await resolveProjectBindingContext(options, {
|
|
49
|
+
requireProject: false,
|
|
50
|
+
});
|
|
51
|
+
if (!baseContext.pendingServerProjectLookup) {
|
|
52
|
+
return options;
|
|
53
|
+
}
|
|
54
|
+
const hydrated = await hydrateProjectIdFromServerLookup(baseContext, buildProjectLookupDeps(apiState, options));
|
|
55
|
+
const projectId = normalizeNonEmpty(hydrated.projectId);
|
|
56
|
+
if (!projectId)
|
|
57
|
+
return options;
|
|
58
|
+
return {
|
|
59
|
+
...options,
|
|
60
|
+
projectId,
|
|
61
|
+
scopeId: normalizeNonEmpty(options.scopeId) ?? normalizeNonEmpty(hydrated.scopeId) ?? projectId,
|
|
62
|
+
projectName: normalizeNonEmpty(hydrated.projectName) ?? normalizeNonEmpty(options.projectName),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export async function hydrateProjectContextWithApiState(apiState, options, context) {
|
|
66
|
+
if (normalizeNonEmpty(context.projectId) || !context.pendingServerProjectLookup) {
|
|
67
|
+
return context;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
return await hydrateProjectIdFromServerLookup(context, buildProjectLookupDeps(apiState, options));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return context;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export async function buildAgentContextHeaders(options) {
|
|
77
|
+
const resolved = await resolveAgentGatewayContext(options);
|
|
78
|
+
return buildOperatorHeaders({
|
|
79
|
+
tenantId: resolved.tenantId,
|
|
80
|
+
locale: resolved.locale,
|
|
81
|
+
fallbackLocale: resolved.fallbackLocale,
|
|
82
|
+
scopeId: resolved.scopeId,
|
|
83
|
+
projectId: resolved.projectId,
|
|
84
|
+
projectName: normalizeNonEmpty(options.projectName) ?? normalizeNonEmpty(resolved.projectName),
|
|
85
|
+
scopeResolution: resolved.scopeResolution,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export async function requireApiState(options) {
|
|
89
|
+
const apiState = await createCliApiClientFromOptions(options);
|
|
90
|
+
const accessToken = apiState.getAccessToken();
|
|
91
|
+
if (!accessToken) {
|
|
92
|
+
if ((await isCliAuthRequired(apiState, { timeoutMs: options.timeoutMs })) === false) {
|
|
93
|
+
return apiState;
|
|
94
|
+
}
|
|
95
|
+
if ((await isCliHostReachable(apiState, { timeoutMs: options.timeoutMs })) === false) {
|
|
96
|
+
logError(`Cannot reach the API host at ${apiState.baseUrl}. Start the target host or provide --api-base-url. Trusted-local auth can only be detected while the host is running.`);
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
logError('Missing access token. Run `aops-cli auth login` or provide --access-token / AOPS_API_ACCESS_TOKEN.');
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return apiState;
|
|
105
|
+
}
|
|
106
|
+
export async function invokeHostedToolWithApiState(apiState, options) {
|
|
107
|
+
const resolvedOptions = await resolveProjectScopeOptionsWithApiState(apiState, options);
|
|
108
|
+
const requestBody = buildHostedToolInvokeRequestBody(resolvedOptions);
|
|
109
|
+
const headers = await buildAgentContextHeaders(resolvedOptions);
|
|
110
|
+
if (resolvedOptions.disableDurableActivityLog !== true) {
|
|
111
|
+
headers['x-activity-source-kind'] = 'aops-cli';
|
|
112
|
+
}
|
|
113
|
+
return apiState.client.fetchJson(`/api/agent/tools/${encodeURIComponent(resolvedOptions.toolId)}/invoke`, {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
body: requestBody,
|
|
116
|
+
headers,
|
|
117
|
+
timeoutMs: resolvedOptions.timeoutMs,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
export function unwrapHostedToolResult(payload) {
|
|
121
|
+
if (Object.prototype.hasOwnProperty.call(payload, 'response')) {
|
|
122
|
+
return payload.response;
|
|
123
|
+
}
|
|
124
|
+
return payload;
|
|
125
|
+
}
|
|
126
|
+
function isRecord(value) {
|
|
127
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
128
|
+
}
|
|
129
|
+
function sanitizeActivityValue(value, depth = 0) {
|
|
130
|
+
if (depth > 3)
|
|
131
|
+
return '[truncated]';
|
|
132
|
+
if (typeof value === 'string') {
|
|
133
|
+
const normalized = value.trim();
|
|
134
|
+
if (normalized.length <= 400)
|
|
135
|
+
return normalized;
|
|
136
|
+
return `${normalized.slice(0, 397)}...`;
|
|
137
|
+
}
|
|
138
|
+
if (typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined) {
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(value)) {
|
|
142
|
+
return value.slice(0, 12).map((entry) => sanitizeActivityValue(entry, depth + 1));
|
|
143
|
+
}
|
|
144
|
+
if (!isRecord(value))
|
|
145
|
+
return String(value);
|
|
146
|
+
const next = {};
|
|
147
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
148
|
+
const lower = key.toLowerCase();
|
|
149
|
+
if (lower.includes('token') || lower.includes('secret') || lower.includes('password') || lower.includes('authorization')) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
next[key] = sanitizeActivityValue(entry, depth + 1);
|
|
153
|
+
}
|
|
154
|
+
return next;
|
|
155
|
+
}
|
|
156
|
+
function maybePushRef(target, type, id, label) {
|
|
157
|
+
const normalizedId = normalizeNonEmpty(id);
|
|
158
|
+
if (!normalizedId)
|
|
159
|
+
return;
|
|
160
|
+
if (target.some((entry) => entry.type === type && entry.id === normalizedId))
|
|
161
|
+
return;
|
|
162
|
+
target.push(label ? { type, id: normalizedId, label } : { type, id: normalizedId });
|
|
163
|
+
}
|
|
164
|
+
function collectRefsFromObject(value, refs) {
|
|
165
|
+
if (!isRecord(value))
|
|
166
|
+
return;
|
|
167
|
+
maybePushRef(refs, 'project', value.projectId);
|
|
168
|
+
maybePushRef(refs, 'scope', value.scopeId);
|
|
169
|
+
maybePushRef(refs, 'task', value.taskId);
|
|
170
|
+
maybePushRef(refs, 'sprint', value.sprintId);
|
|
171
|
+
maybePushRef(refs, 'microtask', value.microtaskId);
|
|
172
|
+
maybePushRef(refs, 'issue', value.issueId);
|
|
173
|
+
maybePushRef(refs, 'feedback', value.feedbackId);
|
|
174
|
+
maybePushRef(refs, 'prompt', value.promptId);
|
|
175
|
+
maybePushRef(refs, 'prompt-version', value.promptVersionId);
|
|
176
|
+
maybePushRef(refs, 'skill', value.skillId);
|
|
177
|
+
maybePushRef(refs, 'skill-version', value.skillVersionId);
|
|
178
|
+
maybePushRef(refs, 'resource', value.resourceId);
|
|
179
|
+
maybePushRef(refs, 'artifact', value.artifactId);
|
|
180
|
+
maybePushRef(refs, 'run', value.runId);
|
|
181
|
+
maybePushRef(refs, 'run-record', value.runRecordId);
|
|
182
|
+
maybePushRef(refs, 'workflow', value.workflowId ?? value.workflowInstanceId);
|
|
183
|
+
maybePushRef(refs, 'workflow-definition', value.workflowDefinitionId);
|
|
184
|
+
maybePushRef(refs, 'document', value.documentId);
|
|
185
|
+
maybePushRef(refs, 'document-version', value.documentVersionId);
|
|
186
|
+
maybePushRef(refs, 'page', value.pageId);
|
|
187
|
+
maybePushRef(refs, 'page-version', value.pageVersionId);
|
|
188
|
+
maybePushRef(refs, 'section', value.sectionId);
|
|
189
|
+
if (isRecord(value.data))
|
|
190
|
+
collectRefsFromObject(value.data, refs);
|
|
191
|
+
if (isRecord(value.input))
|
|
192
|
+
collectRefsFromObject(value.input, refs);
|
|
193
|
+
if (isRecord(value.result))
|
|
194
|
+
collectRefsFromObject(value.result, refs);
|
|
195
|
+
if (isRecord(value.response))
|
|
196
|
+
collectRefsFromObject(value.response, refs);
|
|
197
|
+
}
|
|
198
|
+
async function resolveProjectContextById(apiState, options, projectId) {
|
|
199
|
+
try {
|
|
200
|
+
const headers = await buildAgentContextHeaders(options);
|
|
201
|
+
const payload = await apiState.client.fetchJson(`/api/agentspace/projects/${encodeURIComponent(projectId)}`, {
|
|
202
|
+
method: 'GET',
|
|
203
|
+
headers,
|
|
204
|
+
timeoutMs: options.timeoutMs,
|
|
205
|
+
});
|
|
206
|
+
if (isRecord(payload)) {
|
|
207
|
+
const data = isRecord(payload.data) ? payload.data : payload;
|
|
208
|
+
return {
|
|
209
|
+
scopeId: normalizeNonEmpty(data.id) ?? normalizeNonEmpty(data.projectId) ?? projectId,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
}
|
|
215
|
+
return {};
|
|
216
|
+
}
|
|
217
|
+
async function resolveDurableActivityContext(apiState, options, resolved, payload) {
|
|
218
|
+
const scopeIdFromPayload = normalizeNonEmpty(isRecord(options.input) ? options.input.scopeId : undefined) ??
|
|
219
|
+
normalizeNonEmpty(isRecord(payload) ? payload.scopeId : undefined);
|
|
220
|
+
const projectId = normalizeNonEmpty(resolved.projectId) ??
|
|
221
|
+
normalizeNonEmpty(isRecord(options.input) ? options.input.projectId : undefined) ??
|
|
222
|
+
normalizeNonEmpty(isRecord(payload) ? payload.projectId : undefined);
|
|
223
|
+
let scopeId = normalizeNonEmpty(resolved.scopeId) ?? scopeIdFromPayload;
|
|
224
|
+
if (projectId && !scopeId) {
|
|
225
|
+
const projectContext = await resolveProjectContextById(apiState, options, projectId);
|
|
226
|
+
if (!scopeId)
|
|
227
|
+
scopeId = normalizeNonEmpty(projectContext.scopeId);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
scopeId,
|
|
231
|
+
projectId,
|
|
232
|
+
projectName: resolved.projectName,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
export async function appendCliDurableActivityLogBestEffort(params) {
|
|
236
|
+
const resolved = await resolveAgentGatewayContext(params.options);
|
|
237
|
+
const context = await resolveDurableActivityContext(params.apiState, { ...params.options, toolId: params.sourceId, apply: true }, resolved, isRecord(params.payload) ? params.payload : undefined);
|
|
238
|
+
const scopeId = context.scopeId;
|
|
239
|
+
const projectId = context.projectId;
|
|
240
|
+
if (!scopeId || !projectId)
|
|
241
|
+
return;
|
|
242
|
+
const refs = [];
|
|
243
|
+
maybePushRef(refs, 'scope', scopeId);
|
|
244
|
+
maybePushRef(refs, 'project', projectId);
|
|
245
|
+
params.refs?.forEach((entry) => maybePushRef(refs, entry.type, entry.id, entry.label));
|
|
246
|
+
collectRefsFromObject(params.payload, refs);
|
|
247
|
+
try {
|
|
248
|
+
const headers = await buildAgentContextHeaders({
|
|
249
|
+
...params.options,
|
|
250
|
+
scopeId,
|
|
251
|
+
projectId: context.projectId,
|
|
252
|
+
projectName: context.projectName,
|
|
253
|
+
});
|
|
254
|
+
await params.apiState.client.fetchJson('/api/agentspace/operations/activity-item/add-activity-item', {
|
|
255
|
+
method: 'POST',
|
|
256
|
+
headers,
|
|
257
|
+
body: {
|
|
258
|
+
data: {
|
|
259
|
+
scopeId,
|
|
260
|
+
projectId,
|
|
261
|
+
sourceKind: params.sourceKind ?? 'aops-cli',
|
|
262
|
+
sourceId: params.sourceId,
|
|
263
|
+
action: params.action,
|
|
264
|
+
status: params.status,
|
|
265
|
+
summary: params.summary,
|
|
266
|
+
refs,
|
|
267
|
+
payload: sanitizeActivityValue(params.payload),
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
timeoutMs: params.options.timeoutMs,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
}
|
|
275
|
+
}
|