@tiangong-ai/cli 0.0.43 → 0.0.45
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/AGENTS.md +3 -1
- package/README.md +76 -8
- package/dist/research/orchestration.js +192 -8
- package/dist/research/orchestration.js.map +1 -1
- package/dist/research/setup-command.js +13 -1
- package/dist/research/setup-command.js.map +1 -1
- package/dist/research/workspace/audit-bundle.js +1 -0
- package/dist/research/workspace/audit-bundle.js.map +1 -1
- package/dist/research/workspace/executor.d.ts +9 -0
- package/dist/research/workspace/executor.js +161 -4
- package/dist/research/workspace/executor.js.map +1 -1
- package/dist/research/workspace/inference.js +6 -2
- package/dist/research/workspace/inference.js.map +1 -1
- package/dist/research/workspace/preflight.d.ts +2 -0
- package/dist/research/workspace/preflight.js +11 -2
- package/dist/research/workspace/preflight.js.map +1 -1
- package/dist/research/workspace/projects.js +11 -1
- package/dist/research/workspace/projects.js.map +1 -1
- package/dist/research/workspace/publication-workflow.js +1 -1
- package/dist/research/workspace/publication-workflow.js.map +1 -1
- package/dist/research/workspace/review-executor.d.ts +50 -0
- package/dist/research/workspace/review-executor.js +854 -0
- package/dist/research/workspace/review-executor.js.map +1 -0
- package/dist/research/workspace/runtime.js +63 -15
- package/dist/research/workspace/runtime.js.map +1 -1
- package/dist/research/workspace/scientific-design.d.ts +5 -5
- package/dist/research/workspace/scientific-design.js +92 -16
- package/dist/research/workspace/scientific-design.js.map +1 -1
- package/dist/research/workspace/scientific-objects.d.ts +53 -0
- package/dist/research/workspace/scientific-objects.js +395 -0
- package/dist/research/workspace/scientific-objects.js.map +1 -0
- package/dist/research/workspace/scientific-review.d.ts +4 -0
- package/dist/research/workspace/scientific-review.js +87 -25
- package/dist/research/workspace/scientific-review.js.map +1 -1
- package/dist/research/workspace/setup-catalog.js +22 -2
- package/dist/research/workspace/setup-catalog.js.map +1 -1
- package/dist/research/workspace/setup-declarative.d.ts +4 -0
- package/dist/research/workspace/setup-declarative.js +16 -1
- package/dist/research/workspace/setup-declarative.js.map +1 -1
- package/dist/research/workspace/setup-wizard.js +46 -3
- package/dist/research/workspace/setup-wizard.js.map +1 -1
- package/dist/research/workspace/setup.d.ts +3 -1
- package/dist/research/workspace/setup.js +76 -18
- package/dist/research/workspace/setup.js.map +1 -1
- package/dist/research/workspace/storage.d.ts +1 -0
- package/dist/research/workspace/storage.js +7 -0
- package/dist/research/workspace/storage.js.map +1 -1
- package/dist/research/workspace/types.d.ts +43 -1
- package/dist/research/workspace/workspace.js +62 -5
- package/dist/research/workspace/workspace.js.map +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -18,7 +18,7 @@ checkPaths:
|
|
|
18
18
|
- docs/agents/**
|
|
19
19
|
- src/**
|
|
20
20
|
lastReviewedAt: 2026-08-19
|
|
21
|
-
lastReviewedCommit:
|
|
21
|
+
lastReviewedCommit: 6adf1ad32bdfaa74bc1449bc46c2e6591bae67a1
|
|
22
22
|
---
|
|
23
23
|
|
|
24
24
|
# Tiangong AI CLI Contract
|
|
@@ -51,7 +51,9 @@ This repository owns the Tiangong AI command-line interface.
|
|
|
51
51
|
- `tiangong-ai research setup`
|
|
52
52
|
- `tiangong-ai research policy`
|
|
53
53
|
- `tiangong-ai research publication`
|
|
54
|
+
- `tiangong-ai research scientific`
|
|
54
55
|
- `tiangong-ai research workspace`
|
|
56
|
+
- `tiangong-ai research reviewer`
|
|
55
57
|
- `tiangong-ai research capability`
|
|
56
58
|
- `tiangong-ai research project`
|
|
57
59
|
- `tiangong-ai research status`
|
package/README.md
CHANGED
|
@@ -376,7 +376,7 @@ binds the manifest and every document by SHA-256; edits, manifest tampering, or
|
|
|
376
376
|
expiry block preflight and all later stages until the Policy is reviewed and
|
|
377
377
|
approved again.
|
|
378
378
|
|
|
379
|
-
Before search, the current native Codex or
|
|
379
|
+
Before search, the current native Codex, Claude, WorkBuddy, or CodeBuddy host must author a
|
|
380
380
|
project-specific scientific design. The CLI owns the closed schema and rejects
|
|
381
381
|
designs that confuse model-to-model disagreement with observed truth, inflate
|
|
382
382
|
independent sample size through resampling, omit quantity/threshold semantics,
|
|
@@ -387,10 +387,39 @@ the design or launch a nested producer.
|
|
|
387
387
|
Hash binding alone does not make a model executable. Each model declares raw
|
|
388
388
|
implementation bytes, a retrievable safe locator and entrypoint, exact
|
|
389
389
|
environment-lock bytes, implementation/environment status, and a freeze gate.
|
|
390
|
+
Before authoring a design with frozen model objects, register each external
|
|
391
|
+
regular non-symlink file through the public content-addressed intake:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
tiangong-ai research scientific object register \
|
|
395
|
+
--kind model-implementation \
|
|
396
|
+
--path /absolute/path/to/model.py \
|
|
397
|
+
--media-type text/x-python \
|
|
398
|
+
--workspace /absolute/path/to/workspace --json
|
|
399
|
+
tiangong-ai research scientific object register \
|
|
400
|
+
--kind environment-lock \
|
|
401
|
+
--path /absolute/path/to/requirements.lock \
|
|
402
|
+
--media-type text/plain \
|
|
403
|
+
--workspace /absolute/path/to/workspace --json
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Use the returned `sha256` and `objectLocator` verbatim in the design. Registration
|
|
407
|
+
is workspace-scoped because it must happen before project admission. It hashes
|
|
408
|
+
raw bytes, atomically stores an immutable `lineage/objects/<sha256>/blob`, and
|
|
409
|
+
records only deterministic non-path metadata. It never accepts a source inside
|
|
410
|
+
`.tiangong-research`, a symlink as the selected file, an unsupported/binary
|
|
411
|
+
media type, or invalid UTF-8. Canonical parent-directory aliases are resolved
|
|
412
|
+
before containment checks, including macOS `/var` aliases and Windows
|
|
413
|
+
cross-volume paths. Re-registration is idempotent, and `research scientific object inspect`
|
|
414
|
+
revalidates the record and blob before returning it. Do not hand-copy files into
|
|
415
|
+
the control directory.
|
|
416
|
+
|
|
390
417
|
Source-derived uncertainty states also declare whether their values are frozen
|
|
391
418
|
or pending, and every joint state maps exact parameter-state IDs. Pending model,
|
|
392
419
|
environment, or uncertainty objects are allowed only when a planned Policy rule
|
|
393
|
-
owns the same due gate.
|
|
420
|
+
owns the same due gate. Pending implementations use `null` for implementation
|
|
421
|
+
SHA-256, locator, and entrypoint; pending environments use `null` for lock
|
|
422
|
+
SHA-256 and locator. They are exposed in every earlier review packet as
|
|
394
423
|
`futureGateObligations` and become blocking mechanical errors at that gate.
|
|
395
424
|
Freezing them requires a new authoritative generation; it never upgrades the
|
|
396
425
|
old object in place.
|
|
@@ -454,7 +483,10 @@ Policy, design, and fresh native producer session; it cannot inherit scientific
|
|
|
454
483
|
approval from a superseded generation.
|
|
455
484
|
|
|
456
485
|
Review packet `stageInputs` identify promoted portable objects by purpose,
|
|
457
|
-
owner, source locator,
|
|
486
|
+
owner, safe source locator, media type, object kind, registration-record hash,
|
|
487
|
+
and SHA-256 over raw file bytes. Registered model code and environment locks are
|
|
488
|
+
copied as exact project-local `blob` bytes; they are never parsed as JSON merely
|
|
489
|
+
because the packet is JSON. `packetSha256` is the
|
|
458
490
|
logical packet identity that excludes its own identity field; the portable
|
|
459
491
|
audit manifest separately records the raw stored packet-file digest. This keeps
|
|
460
492
|
packet identity and byte-level transfer verification explicit rather than
|
|
@@ -602,13 +634,19 @@ The workspace stores its current protocol state under `.tiangong-research/`.
|
|
|
602
634
|
Each project follows the evidence-first sequence: broad discovery, strict
|
|
603
635
|
admission, acquisition audit, immutable evidence freeze, analysis, synthesis,
|
|
604
636
|
independent review, and mechanical closure. Discover, acquire, analyze, and
|
|
605
|
-
synthesize run in the current interactive Codex
|
|
606
|
-
session. The CLI never launches a nested producer process. Independent review
|
|
637
|
+
synthesize run in the current interactive Codex, Claude Code, WorkBuddy, or
|
|
638
|
+
CodeBuddy session. The CLI never launches a nested producer process. Independent review
|
|
607
639
|
runs through the other configured agent family's CLI, and execution is blocked
|
|
608
640
|
when the two roles use the same family.
|
|
609
641
|
|
|
610
|
-
Independent reviewer execution requires `/usr/bin/sandbox-exec` on macOS
|
|
611
|
-
Bubblewrap (`bwrap`) on Linux.
|
|
642
|
+
Independent reviewer execution always requires `/usr/bin/sandbox-exec` on macOS
|
|
643
|
+
or Bubblewrap (`bwrap`) on Linux. `reviewerExecution.transport=native-direct`
|
|
644
|
+
creates that capsule in the current process. `sandbox-bridge` sends one
|
|
645
|
+
hash-bound request to an owner-started, exact-version sidecar outside an IDE
|
|
646
|
+
sandbox; the sidecar creates the same capsule and returns an Ed25519-signed
|
|
647
|
+
attestation bound to workspace/config/runtime/capsule/request/result/model and
|
|
648
|
+
policy hashes. The two transports are explicit and never fall back to each
|
|
649
|
+
other. Windows can inspect and configure workspaces but
|
|
612
650
|
does not launch reviewer packages; smoke-test setup reports a non-blocking
|
|
613
651
|
warning there, while production readiness fails closed. The current native producer remains governed
|
|
614
652
|
by its host application's own permissions; the CLI supplies a hash-bound packet
|
|
@@ -628,7 +666,7 @@ tiangong-ai research run --workspace /absolute/path/to/workspace \
|
|
|
628
666
|
--project gpu-resource-impact --progress-jsonl
|
|
629
667
|
# When stopReason is native-stage-required, perform the returned stage here:
|
|
630
668
|
tiangong-ai research project stage prepare gpu-resource-impact \
|
|
631
|
-
--stage discover --host-agent
|
|
669
|
+
--stage discover --host-agent workbuddy \
|
|
632
670
|
--workspace /absolute/path/to/workspace --json
|
|
633
671
|
tiangong-ai research project stage submit gpu-resource-impact \
|
|
634
672
|
--session SESSION_ID --output /absolute/path/to/discover.json \
|
|
@@ -637,6 +675,36 @@ tiangong-ai research project stage submit gpu-resource-impact \
|
|
|
637
675
|
tiangong-ai research status --workspace /absolute/path/to/workspace --json
|
|
638
676
|
```
|
|
639
677
|
|
|
678
|
+
For WorkBuddy/CodeBuddy, keep Default Permission and start the sidecar from a
|
|
679
|
+
separate native terminal with a private non-symlink state directory outside the
|
|
680
|
+
workspace:
|
|
681
|
+
|
|
682
|
+
```bash
|
|
683
|
+
tiangong-ai research reviewer serve \
|
|
684
|
+
--workspace /absolute/path/to/workspace \
|
|
685
|
+
--state-dir /absolute/private/reviewer-sidecar --json
|
|
686
|
+
|
|
687
|
+
# From the sandboxed IDE:
|
|
688
|
+
tiangong-ai research reviewer status --workspace /absolute/path/to/workspace --json
|
|
689
|
+
tiangong-ai research reviewer doctor --confirm-agent-smoke-cost \
|
|
690
|
+
--workspace /absolute/path/to/workspace --json
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
Sidecar readiness includes real filesystem negative probes and a fixed
|
|
694
|
+
`execute|fingerprint|status` protocol. It has no arbitrary-command endpoint;
|
|
695
|
+
reviewer shell, browser, web, undeclared MCP, and Skill tools remain disabled.
|
|
696
|
+
Do not use Full Access, sandbox-disable flags, unsandboxed-command exceptions,
|
|
697
|
+
or silent transport fallback.
|
|
698
|
+
|
|
699
|
+
WorkBuddy/CodeBuddy capsule teardown never requests recursive bulk deletion
|
|
700
|
+
inside the outer IDE. Native stages remove only the single active-session
|
|
701
|
+
binding, while completed, aborted, handed-off, and reviewer/work-package
|
|
702
|
+
capsules are retained. The journal records
|
|
703
|
+
`capsuleDisposition=retained-outer-sandbox` plus a non-sensitive capsule ID.
|
|
704
|
+
Native Codex/Claude hosts keep the existing automatic capsule deletion behavior.
|
|
705
|
+
No path silently falls back to Full Access, and retained capsules are never
|
|
706
|
+
reported as active sessions.
|
|
707
|
+
|
|
640
708
|
The discover packet derives a bounded multi-channel plan from reviewed evidence
|
|
641
709
|
requirements. Required channels run first; exact repeated requests reuse the
|
|
642
710
|
project cache without another provider call but still consume a bounded context
|
|
@@ -6,6 +6,7 @@ import { parseStrictArgs, strictBoolean, strictString } from "../strict-args.js"
|
|
|
6
6
|
import { researchSetupHelp, runResearchSetupCommand } from "./setup-command.js";
|
|
7
7
|
import { loadCapabilityDeclarations, lockCapabilities, verifyCapabilities, } from "./workspace/capabilities.js";
|
|
8
8
|
import { inspectResearchContext } from "./workspace/context.js";
|
|
9
|
+
import { packageVersion } from "./workspace/constants.js";
|
|
9
10
|
import { setCapabilityCredentialFromEnvironment } from "./workspace/credentials.js";
|
|
10
11
|
import { configureExternalSkillProfile, doctorExternalCapabilities, EXTERNAL_SKILL_CONTEXT_PROFILE, EXTERNAL_SKILL_MEDIA_PROFILE, EXTERNAL_SKILL_PROFILE, importExternalCapability, inspectExternalSkillCatalog, } from "./workspace/external-skills.js";
|
|
11
12
|
import { appendJournalEvent } from "./workspace/journal.js";
|
|
@@ -20,6 +21,7 @@ import { recordDiscoveryAssessmentBatch } from "./workspace/discovery.js";
|
|
|
20
21
|
import { bindEvidenceDownload } from "./workspace/downloads.js";
|
|
21
22
|
import { registerNativeDiscoveryCandidate } from "./workspace/evidence-ledger.js";
|
|
22
23
|
import { recordNativeResearchActivity } from "./workspace/native-activity.js";
|
|
24
|
+
import { inspectReviewerBridgeStatus, startReviewerBridgeSidecar, } from "./workspace/review-executor.js";
|
|
23
25
|
import { readAndVerifyProjectInputPlan } from "./workspace/input-plan.js";
|
|
24
26
|
import { loadCurrentClaimEvidenceGraph, loadCurrentInferenceSnapshot, } from "./workspace/inference.js";
|
|
25
27
|
import { addProjectInput, createProjectAddendum, initializeProject, forkProject, listProjects, loadProject, nextReadyPackage, normalizeEvidenceRequirements, refreshProject, retryProjectPackage, setProjectDisposition, } from "./workspace/projects.js";
|
|
@@ -30,9 +32,10 @@ import { resolveInstalledResearchPolicySource, runInteractiveResearchPolicyWizar
|
|
|
30
32
|
import { abortNativeResearchStage, inspectNativeResearchStage, prepareNativeResearchStage, requestResearchHandoff, resolveResearchHandoff, runResearchWorkspace, submitNativeResearchStage, } from "./workspace/runtime.js";
|
|
31
33
|
import { schemaForStage } from "./workspace/schemas.js";
|
|
32
34
|
import { readAndVerifyScientificDesign, scientificDesignSchema, } from "./workspace/scientific-design.js";
|
|
35
|
+
import { inspectScientificObject, parseScientificObjectKind, registerScientificObject, } from "./workspace/scientific-objects.js";
|
|
33
36
|
import { inspectScientificReviewStatus, prepareScientificReview, scientificGateAssessmentSchema, scientificReviewSchema, submitScientificReview, } from "./workspace/scientific-review.js";
|
|
34
37
|
import { isObject, pathExists, sha256Text, workspacePaths } from "./workspace/storage.js";
|
|
35
|
-
import { doctorResearchWorkspace, initializeResearchWorkspace, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
|
|
38
|
+
import { doctorResearchWorkspace, initializeResearchWorkspace, loadWorkspaceConfig, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
|
|
36
39
|
const COMMON_OPTIONS = { help: "boolean", json: "boolean" };
|
|
37
40
|
const WORKSPACE_OPTIONS = { ...COMMON_OPTIONS, workspace: "string" };
|
|
38
41
|
export async function runResearchOrchestrationCommand(subcommand, argv, io) {
|
|
@@ -42,12 +45,16 @@ export async function runResearchOrchestrationCommand(subcommand, argv, io) {
|
|
|
42
45
|
return runResearchSetupCommand(argv, io);
|
|
43
46
|
if (subcommand === "workspace")
|
|
44
47
|
return runWorkspace(argv, io);
|
|
48
|
+
if (subcommand === "reviewer")
|
|
49
|
+
return runReviewer(argv, io);
|
|
45
50
|
if (subcommand === "capability")
|
|
46
51
|
return runCapability(argv, io);
|
|
47
52
|
if (subcommand === "policy")
|
|
48
53
|
return runPolicy(argv, io);
|
|
49
54
|
if (subcommand === "publication")
|
|
50
55
|
return runPublication(argv, io);
|
|
56
|
+
if (subcommand === "scientific")
|
|
57
|
+
return runScientific(argv, io);
|
|
51
58
|
if (subcommand === "project")
|
|
52
59
|
return runProject(argv, io);
|
|
53
60
|
if (subcommand === "schema")
|
|
@@ -65,6 +72,9 @@ export function researchOrchestrationHelp() {
|
|
|
65
72
|
tiangong-ai research context inspect [--path <absolute-path>] [--json]
|
|
66
73
|
tiangong-ai research workspace init <absolute-path> [--name <name>] [--mode smoke-test|production-research] [--json]
|
|
67
74
|
tiangong-ai research workspace doctor [--workspace <absolute-path>] [--agent-smoke] [--capability-smoke] [--json]
|
|
75
|
+
tiangong-ai research reviewer serve --state-dir <absolute-private-directory> [--workspace <absolute-path>] [--json]
|
|
76
|
+
tiangong-ai research reviewer status [--workspace <absolute-path>] [--json]
|
|
77
|
+
tiangong-ai research reviewer doctor --confirm-agent-smoke-cost [--workspace <absolute-path>] [--json]
|
|
68
78
|
tiangong-ai research capability catalog [--path <absolute-path>] [--workspace <absolute-path>] [--skill-root <absolute-path>] [--json]
|
|
69
79
|
tiangong-ai research capability configure [--profile ${EXTERNAL_SKILL_PROFILE}|${EXTERNAL_SKILL_CONTEXT_PROFILE}|${EXTERNAL_SKILL_MEDIA_PROFILE}] [--skill-root <absolute-path>] [--workspace <absolute-path>] [--json]
|
|
70
80
|
tiangong-ai research capability import --definition <absolute-json> [--workspace <absolute-path>] [--json]
|
|
@@ -79,11 +89,13 @@ export function researchOrchestrationHelp() {
|
|
|
79
89
|
tiangong-ai research policy validate <project-id> [--workspace <path>] [--json]
|
|
80
90
|
tiangong-ai research policy approve <project-id> --confirm [--acknowledge-defaults] [--workspace <path>] [--json]
|
|
81
91
|
tiangong-ai research policy resolve <project-id> [--workspace <path>] [--json]
|
|
82
|
-
tiangong-ai research publication freeze <project-id> --manuscript <absolute-file> --assessment <absolute-json> --submission <absolute-json> --producer-agent codex|claude --producer-session <opaque-id> [--supplements <absolute-json-array>] [--workspace <path>] [--json]
|
|
92
|
+
tiangong-ai research publication freeze <project-id> --manuscript <absolute-file> --assessment <absolute-json> --submission <absolute-json> --producer-agent codex|claude|workbuddy|codebuddy --producer-session <opaque-id> [--supplements <absolute-json-array>] [--workspace <path>] [--json]
|
|
83
93
|
tiangong-ai research publication review prepare <project-id> --role evidence|methods-reproducibility|domain-novelty|journal-editor --reviewer-agent codex|claude --reviewer-session <opaque-id> [--workspace <path>] [--json]
|
|
84
94
|
tiangong-ai research publication review submit <project-id> --role evidence|methods-reproducibility|domain-novelty|journal-editor --review <absolute-json> [--workspace <path>] [--json]
|
|
85
95
|
tiangong-ai research publication status <project-id> [--workspace <path>] [--json]
|
|
86
96
|
tiangong-ai research publication close <project-id> [--workspace <path>] [--json]
|
|
97
|
+
tiangong-ai research scientific object register --kind model-implementation|environment-lock --path <absolute-file> [--media-type <type>] [--workspace <path>] [--json]
|
|
98
|
+
tiangong-ai research scientific object inspect --kind model-implementation|environment-lock --locator <control-relative-locator> [--workspace <path>] [--json]
|
|
87
99
|
tiangong-ai research project init <project-id> --question <question> [--goal evidence-report|top-journal] [--design <absolute-json> --design-producer-agent codex|claude --design-producer-session <opaque-id>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--confirm-budget] [--workspace <path>] [--json]
|
|
88
100
|
tiangong-ai research project preflight --question <question> [--goal evidence-report|top-journal] [--policy-project <project-id> --design <absolute-json>] [--requirements <absolute-json>] [--input-plan <absolute-json>] [--workspace <path>] [--json]
|
|
89
101
|
tiangong-ai research project input add <project-id> --path <absolute-file> [--role primary|reference|replication] [--trust-status verified-owner-input|unverified-owner-input|reference-only|replication-candidate] [--independently-reproduced] [--workspace <path>] [--json]
|
|
@@ -100,7 +112,7 @@ export function researchOrchestrationHelp() {
|
|
|
100
112
|
tiangong-ai research project scientific status <project-id> [--workspace <path>] [--json]
|
|
101
113
|
tiangong-ai research project audit export <project-id> --output <absolute-new-directory> [--workspace <path>] [--json]
|
|
102
114
|
tiangong-ai research project audit verify --bundle <absolute-directory> [--json]
|
|
103
|
-
tiangong-ai research project stage prepare <project-id> --stage discover|acquire|analyze|synthesize --host-agent codex|claude [--workspace <path>] [--json]
|
|
115
|
+
tiangong-ai research project stage prepare <project-id> --stage discover|acquire|analyze|synthesize --host-agent codex|claude|workbuddy|codebuddy [--workspace <path>] [--json]
|
|
104
116
|
tiangong-ai research project stage submit <project-id> --session <id> --output <absolute-json> [--confirm-model <id>] [--workspace <path>] [--json]
|
|
105
117
|
tiangong-ai research project stage abort <project-id> --session <id> [--workspace <path>] [--json]
|
|
106
118
|
tiangong-ai research project evidence fetch <project-id> --request <absolute-json> [--workspace <path>] [--json]
|
|
@@ -120,6 +132,158 @@ export function researchOrchestrationHelp() {
|
|
|
120
132
|
${researchSetupHelp()}
|
|
121
133
|
`;
|
|
122
134
|
}
|
|
135
|
+
async function runScientific(argv, io) {
|
|
136
|
+
const [action, ...rest] = argv;
|
|
137
|
+
if (!action || action === "--help" || action === "-h")
|
|
138
|
+
return writeHelp(io);
|
|
139
|
+
if (action !== "object")
|
|
140
|
+
throw unknownAction("research scientific", action);
|
|
141
|
+
const [objectAction, ...objectRest] = rest;
|
|
142
|
+
if (objectAction === "register") {
|
|
143
|
+
const args = parseStrictArgs(objectRest, { ...WORKSPACE_OPTIONS, kind: "string", path: "string", "media-type": "string" }, "research scientific object register");
|
|
144
|
+
if (strictBoolean(args, "help"))
|
|
145
|
+
return writeHelp(io);
|
|
146
|
+
rejectPositionals(args.positionals, "research scientific object register");
|
|
147
|
+
const sourcePath = strictString(args, "path");
|
|
148
|
+
if (!sourcePath) {
|
|
149
|
+
throw new CliError("Scientific object register requires --kind and --path.", {
|
|
150
|
+
code: "RESEARCH_SCIENTIFIC_OBJECT_INVALID",
|
|
151
|
+
exitCode: 2,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
const root = await workspaceFromArgs(args);
|
|
155
|
+
const objectKind = parseScientificObjectKind(strictString(args, "kind"));
|
|
156
|
+
const record = await withWorkspaceLock(root, "research.scientific-object.register", async () => {
|
|
157
|
+
const value = await registerScientificObject({
|
|
158
|
+
root,
|
|
159
|
+
objectKind,
|
|
160
|
+
path: sourcePath,
|
|
161
|
+
...(strictString(args, "media-type")
|
|
162
|
+
? { mediaType: strictString(args, "media-type") }
|
|
163
|
+
: {}),
|
|
164
|
+
});
|
|
165
|
+
await appendJournalEvent(workspacePaths(root).journal, "scientific-object.registered", "workspace", {
|
|
166
|
+
objectKind: value.objectKind,
|
|
167
|
+
sha256: value.sha256,
|
|
168
|
+
bytes: value.bytes,
|
|
169
|
+
mediaType: value.mediaType,
|
|
170
|
+
objectLocator: value.objectLocator,
|
|
171
|
+
recordLocator: value.recordLocator,
|
|
172
|
+
recordSha256: value.recordSha256,
|
|
173
|
+
});
|
|
174
|
+
return value;
|
|
175
|
+
});
|
|
176
|
+
writeJson(io, record, args);
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
if (objectAction === "inspect") {
|
|
180
|
+
const args = parseStrictArgs(objectRest, { ...WORKSPACE_OPTIONS, kind: "string", locator: "string" }, "research scientific object inspect");
|
|
181
|
+
if (strictBoolean(args, "help"))
|
|
182
|
+
return writeHelp(io);
|
|
183
|
+
rejectPositionals(args.positionals, "research scientific object inspect");
|
|
184
|
+
const objectLocator = strictString(args, "locator");
|
|
185
|
+
if (!objectLocator) {
|
|
186
|
+
throw new CliError("Scientific object inspect requires --kind and --locator.", {
|
|
187
|
+
code: "RESEARCH_SCIENTIFIC_OBJECT_INVALID",
|
|
188
|
+
exitCode: 2,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
const root = await workspaceFromArgs(args);
|
|
192
|
+
writeJson(io, await inspectScientificObject({
|
|
193
|
+
root,
|
|
194
|
+
objectKind: parseScientificObjectKind(strictString(args, "kind")),
|
|
195
|
+
objectLocator,
|
|
196
|
+
}), args);
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
throw unknownAction("research scientific object", objectAction ?? "");
|
|
200
|
+
}
|
|
201
|
+
async function runReviewer(argv, io) {
|
|
202
|
+
const [action, ...rest] = argv;
|
|
203
|
+
if (!action || action === "--help" || action === "-h")
|
|
204
|
+
return writeHelp(io);
|
|
205
|
+
if (action === "status") {
|
|
206
|
+
const args = parseStrictArgs(rest, WORKSPACE_OPTIONS, "research reviewer status");
|
|
207
|
+
if (strictBoolean(args, "help"))
|
|
208
|
+
return writeHelp(io);
|
|
209
|
+
if (args.positionals.length)
|
|
210
|
+
throw unknownAction("research reviewer status", args.positionals[0]);
|
|
211
|
+
const root = await workspaceFromArgs(args);
|
|
212
|
+
writeJson(io, await inspectReviewerBridgeStatus(root), args);
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
if (action === "doctor") {
|
|
216
|
+
const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS, "confirm-agent-smoke-cost": "boolean" }, "research reviewer doctor");
|
|
217
|
+
if (strictBoolean(args, "help"))
|
|
218
|
+
return writeHelp(io);
|
|
219
|
+
if (args.positionals.length)
|
|
220
|
+
throw unknownAction("research reviewer doctor", args.positionals[0]);
|
|
221
|
+
if (!strictBoolean(args, "confirm-agent-smoke-cost")) {
|
|
222
|
+
throw new CliError("Reviewer doctor requires explicit model-cost confirmation.", {
|
|
223
|
+
code: "RESEARCH_REVIEW_BRIDGE_CONFIRMATION_REQUIRED",
|
|
224
|
+
exitCode: 3,
|
|
225
|
+
details: {
|
|
226
|
+
minimumAction: "Rerun with --confirm-agent-smoke-cost after reviewing reviewer provider quota and cost.",
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
const root = await workspaceFromArgs(args);
|
|
231
|
+
const result = await doctorResearchWorkspace(root, {
|
|
232
|
+
agentSmoke: true,
|
|
233
|
+
environment: io.env,
|
|
234
|
+
});
|
|
235
|
+
writeJson(io, result, args);
|
|
236
|
+
return result.status === "ready" ? 0 : 3;
|
|
237
|
+
}
|
|
238
|
+
if (action === "serve") {
|
|
239
|
+
const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS, "state-dir": "string" }, "research reviewer serve");
|
|
240
|
+
if (strictBoolean(args, "help"))
|
|
241
|
+
return writeHelp(io);
|
|
242
|
+
if (args.positionals.length)
|
|
243
|
+
throw unknownAction("research reviewer serve", args.positionals[0]);
|
|
244
|
+
const stateDirectory = strictString(args, "state-dir");
|
|
245
|
+
if (!stateDirectory ||
|
|
246
|
+
!isAbsolute(stateDirectory) ||
|
|
247
|
+
resolve(stateDirectory) !== stateDirectory) {
|
|
248
|
+
throw new CliError("Reviewer sidecar --state-dir must be an explicit absolute directory.", {
|
|
249
|
+
code: "RESEARCH_REVIEW_BRIDGE_STATE_INVALID",
|
|
250
|
+
exitCode: 2,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const root = await workspaceFromArgs(args);
|
|
254
|
+
const sidecar = await startReviewerBridgeSidecar({
|
|
255
|
+
root,
|
|
256
|
+
stateDirectory,
|
|
257
|
+
environment: io.env,
|
|
258
|
+
});
|
|
259
|
+
writeJson(io, {
|
|
260
|
+
status: "ready",
|
|
261
|
+
workspaceId: sidecar.workspaceId,
|
|
262
|
+
packageVersion: packageVersion(),
|
|
263
|
+
keyFingerprint: sidecar.keyFingerprint,
|
|
264
|
+
supportedActions: ["execute", "fingerprint", "status"],
|
|
265
|
+
}, args);
|
|
266
|
+
try {
|
|
267
|
+
await waitForReviewerSidecarTermination();
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
await sidecar.close();
|
|
271
|
+
}
|
|
272
|
+
return 0;
|
|
273
|
+
}
|
|
274
|
+
throw unknownAction("research reviewer", action);
|
|
275
|
+
}
|
|
276
|
+
async function waitForReviewerSidecarTermination() {
|
|
277
|
+
await new Promise((resolvePromise) => {
|
|
278
|
+
const stop = () => {
|
|
279
|
+
process.off("SIGINT", stop);
|
|
280
|
+
process.off("SIGTERM", stop);
|
|
281
|
+
resolvePromise();
|
|
282
|
+
};
|
|
283
|
+
process.once("SIGINT", stop);
|
|
284
|
+
process.once("SIGTERM", stop);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
123
287
|
async function runPublication(argv, io) {
|
|
124
288
|
const [action, ...rest] = argv;
|
|
125
289
|
if (!action || action === "--help" || action === "-h")
|
|
@@ -1314,6 +1478,7 @@ async function runStatus(argv, io) {
|
|
|
1314
1478
|
return writeHelp(io);
|
|
1315
1479
|
rejectPositionals(args.positionals, "research status");
|
|
1316
1480
|
const root = await workspaceFromArgs(args);
|
|
1481
|
+
const config = await loadWorkspaceConfig(root);
|
|
1317
1482
|
const selectedProject = strictString(args, "project");
|
|
1318
1483
|
const workspaceProjects = await listProjects(root);
|
|
1319
1484
|
const allProjects = selectedProject
|
|
@@ -1329,6 +1494,20 @@ async function runStatus(argv, io) {
|
|
|
1329
1494
|
project.status !== "abandoned");
|
|
1330
1495
|
const result = {
|
|
1331
1496
|
workspace: root,
|
|
1497
|
+
execution: {
|
|
1498
|
+
producer: {
|
|
1499
|
+
host: config.producer.agent,
|
|
1500
|
+
model: config.producer.model,
|
|
1501
|
+
mode: config.producer.executionMode,
|
|
1502
|
+
},
|
|
1503
|
+
reviewer: {
|
|
1504
|
+
agent: config.reviewer.agent,
|
|
1505
|
+
model: config.reviewer.model,
|
|
1506
|
+
mode: config.reviewer.executionMode,
|
|
1507
|
+
transport: config.reviewerExecution.transport,
|
|
1508
|
+
isolationProvider: config.reviewerExecution.isolationProvider,
|
|
1509
|
+
},
|
|
1510
|
+
},
|
|
1332
1511
|
hiddenSupersededProjects: selectedProject || strictBoolean(args, "all")
|
|
1333
1512
|
? 0
|
|
1334
1513
|
: workspaceProjects.filter((project) => project.lineage.supersededBy !== null).length,
|
|
@@ -1610,7 +1789,7 @@ function projectRecommendedAction(root, project, readyPackage, nativeStage, scie
|
|
|
1610
1789
|
: "Inspect the blocking package and use explicit retry or fork recovery.";
|
|
1611
1790
|
}
|
|
1612
1791
|
if (readyPackage && ["discover", "acquire", "analyze", "synthesize"].includes(readyPackage)) {
|
|
1613
|
-
return `Prepare native ${readyPackage}: tiangong-ai research project stage prepare ${project.id} --stage ${readyPackage} --host-agent <codex|claude> --workspace ${root}`;
|
|
1792
|
+
return `Prepare native ${readyPackage}: tiangong-ai research project stage prepare ${project.id} --stage ${readyPackage} --host-agent <codex|claude|workbuddy|codebuddy> --workspace ${root}`;
|
|
1614
1793
|
}
|
|
1615
1794
|
return readyPackage === "review"
|
|
1616
1795
|
? `Run the independent reviewer package: tiangong-ai research run --project ${project.id} --workspace ${root}`
|
|
@@ -1731,9 +1910,10 @@ function nativeProducerStage(value) {
|
|
|
1731
1910
|
});
|
|
1732
1911
|
}
|
|
1733
1912
|
function nativeHostAgent(value) {
|
|
1734
|
-
if (value === "codex" || value === "claude")
|
|
1913
|
+
if (value === "codex" || value === "claude" || value === "workbuddy" || value === "codebuddy") {
|
|
1735
1914
|
return value;
|
|
1736
|
-
|
|
1915
|
+
}
|
|
1916
|
+
throw new CliError("--host-agent must be codex, claude, workbuddy, or codebuddy.", {
|
|
1737
1917
|
code: "RESEARCH_NATIVE_HOST_INVALID",
|
|
1738
1918
|
exitCode: 2,
|
|
1739
1919
|
});
|
|
@@ -1846,9 +2026,13 @@ function scientificReviewRole(value) {
|
|
|
1846
2026
|
});
|
|
1847
2027
|
}
|
|
1848
2028
|
function publicationAgent(value, label) {
|
|
1849
|
-
|
|
2029
|
+
const producer = label.includes("producer");
|
|
2030
|
+
if (value === "codex" ||
|
|
2031
|
+
value === "claude" ||
|
|
2032
|
+
(producer && (value === "workbuddy" || value === "codebuddy"))) {
|
|
1850
2033
|
return value;
|
|
1851
|
-
|
|
2034
|
+
}
|
|
2035
|
+
throw new CliError(`--${label}-agent must be ${producer ? "codex, claude, workbuddy, or codebuddy" : "codex or claude"}.`, {
|
|
1852
2036
|
code: "RESEARCH_PUBLICATION_AGENT_INVALID",
|
|
1853
2037
|
exitCode: 2,
|
|
1854
2038
|
});
|