@tiangong-ai/cli 0.0.43 → 0.0.44

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.
Files changed (37) hide show
  1. package/AGENTS.md +1 -0
  2. package/README.md +42 -6
  3. package/dist/research/orchestration.js +121 -8
  4. package/dist/research/orchestration.js.map +1 -1
  5. package/dist/research/setup-command.js +13 -1
  6. package/dist/research/setup-command.js.map +1 -1
  7. package/dist/research/workspace/audit-bundle.js +1 -0
  8. package/dist/research/workspace/audit-bundle.js.map +1 -1
  9. package/dist/research/workspace/executor.d.ts +9 -0
  10. package/dist/research/workspace/executor.js +161 -4
  11. package/dist/research/workspace/executor.js.map +1 -1
  12. package/dist/research/workspace/preflight.d.ts +2 -0
  13. package/dist/research/workspace/preflight.js +6 -2
  14. package/dist/research/workspace/preflight.js.map +1 -1
  15. package/dist/research/workspace/projects.js +1 -1
  16. package/dist/research/workspace/projects.js.map +1 -1
  17. package/dist/research/workspace/publication-workflow.js +1 -1
  18. package/dist/research/workspace/publication-workflow.js.map +1 -1
  19. package/dist/research/workspace/review-executor.d.ts +50 -0
  20. package/dist/research/workspace/review-executor.js +854 -0
  21. package/dist/research/workspace/review-executor.js.map +1 -0
  22. package/dist/research/workspace/runtime.js +63 -15
  23. package/dist/research/workspace/runtime.js.map +1 -1
  24. package/dist/research/workspace/setup-catalog.js +22 -2
  25. package/dist/research/workspace/setup-catalog.js.map +1 -1
  26. package/dist/research/workspace/setup-declarative.d.ts +4 -0
  27. package/dist/research/workspace/setup-declarative.js +16 -1
  28. package/dist/research/workspace/setup-declarative.js.map +1 -1
  29. package/dist/research/workspace/setup-wizard.js +46 -3
  30. package/dist/research/workspace/setup-wizard.js.map +1 -1
  31. package/dist/research/workspace/setup.d.ts +3 -1
  32. package/dist/research/workspace/setup.js +76 -18
  33. package/dist/research/workspace/setup.js.map +1 -1
  34. package/dist/research/workspace/types.d.ts +43 -1
  35. package/dist/research/workspace/workspace.js +62 -5
  36. package/dist/research/workspace/workspace.js.map +1 -1
  37. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -52,6 +52,7 @@ This repository owns the Tiangong AI command-line interface.
52
52
  - `tiangong-ai research policy`
53
53
  - `tiangong-ai research publication`
54
54
  - `tiangong-ai research workspace`
55
+ - `tiangong-ai research reviewer`
55
56
  - `tiangong-ai research capability`
56
57
  - `tiangong-ai research project`
57
58
  - `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 Claude host must author a
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,
@@ -602,13 +602,19 @@ The workspace stores its current protocol state under `.tiangong-research/`.
602
602
  Each project follows the evidence-first sequence: broad discovery, strict
603
603
  admission, acquisition audit, immutable evidence freeze, analysis, synthesis,
604
604
  independent review, and mechanical closure. Discover, acquire, analyze, and
605
- synthesize run in the current interactive Codex app/session or Claude Code
606
- session. The CLI never launches a nested producer process. Independent review
605
+ synthesize run in the current interactive Codex, Claude Code, WorkBuddy, or
606
+ CodeBuddy session. The CLI never launches a nested producer process. Independent review
607
607
  runs through the other configured agent family's CLI, and execution is blocked
608
608
  when the two roles use the same family.
609
609
 
610
- Independent reviewer execution requires `/usr/bin/sandbox-exec` on macOS or
611
- Bubblewrap (`bwrap`) on Linux. Windows can inspect and configure workspaces but
610
+ Independent reviewer execution always requires `/usr/bin/sandbox-exec` on macOS
611
+ or Bubblewrap (`bwrap`) on Linux. `reviewerExecution.transport=native-direct`
612
+ creates that capsule in the current process. `sandbox-bridge` sends one
613
+ hash-bound request to an owner-started, exact-version sidecar outside an IDE
614
+ sandbox; the sidecar creates the same capsule and returns an Ed25519-signed
615
+ attestation bound to workspace/config/runtime/capsule/request/result/model and
616
+ policy hashes. The two transports are explicit and never fall back to each
617
+ other. Windows can inspect and configure workspaces but
612
618
  does not launch reviewer packages; smoke-test setup reports a non-blocking
613
619
  warning there, while production readiness fails closed. The current native producer remains governed
614
620
  by its host application's own permissions; the CLI supplies a hash-bound packet
@@ -628,7 +634,7 @@ tiangong-ai research run --workspace /absolute/path/to/workspace \
628
634
  --project gpu-resource-impact --progress-jsonl
629
635
  # When stopReason is native-stage-required, perform the returned stage here:
630
636
  tiangong-ai research project stage prepare gpu-resource-impact \
631
- --stage discover --host-agent codex \
637
+ --stage discover --host-agent workbuddy \
632
638
  --workspace /absolute/path/to/workspace --json
633
639
  tiangong-ai research project stage submit gpu-resource-impact \
634
640
  --session SESSION_ID --output /absolute/path/to/discover.json \
@@ -637,6 +643,36 @@ tiangong-ai research project stage submit gpu-resource-impact \
637
643
  tiangong-ai research status --workspace /absolute/path/to/workspace --json
638
644
  ```
639
645
 
646
+ For WorkBuddy/CodeBuddy, keep Default Permission and start the sidecar from a
647
+ separate native terminal with a private non-symlink state directory outside the
648
+ workspace:
649
+
650
+ ```bash
651
+ tiangong-ai research reviewer serve \
652
+ --workspace /absolute/path/to/workspace \
653
+ --state-dir /absolute/private/reviewer-sidecar --json
654
+
655
+ # From the sandboxed IDE:
656
+ tiangong-ai research reviewer status --workspace /absolute/path/to/workspace --json
657
+ tiangong-ai research reviewer doctor --confirm-agent-smoke-cost \
658
+ --workspace /absolute/path/to/workspace --json
659
+ ```
660
+
661
+ Sidecar readiness includes real filesystem negative probes and a fixed
662
+ `execute|fingerprint|status` protocol. It has no arbitrary-command endpoint;
663
+ reviewer shell, browser, web, undeclared MCP, and Skill tools remain disabled.
664
+ Do not use Full Access, sandbox-disable flags, unsandboxed-command exceptions,
665
+ or silent transport fallback.
666
+
667
+ WorkBuddy/CodeBuddy capsule teardown never requests recursive bulk deletion
668
+ inside the outer IDE. Native stages remove only the single active-session
669
+ binding, while completed, aborted, handed-off, and reviewer/work-package
670
+ capsules are retained. The journal records
671
+ `capsuleDisposition=retained-outer-sandbox` plus a non-sensitive capsule ID.
672
+ Native Codex/Claude hosts keep the existing automatic capsule deletion behavior.
673
+ No path silently falls back to Full Access, and retained capsules are never
674
+ reported as active sessions.
675
+
640
676
  The discover packet derives a bounded multi-channel plan from reviewed evidence
641
677
  requirements. Required channels run first; exact repeated requests reuse the
642
678
  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";
@@ -32,7 +34,7 @@ import { schemaForStage } from "./workspace/schemas.js";
32
34
  import { readAndVerifyScientificDesign, scientificDesignSchema, } from "./workspace/scientific-design.js";
33
35
  import { inspectScientificReviewStatus, prepareScientificReview, scientificGateAssessmentSchema, scientificReviewSchema, submitScientificReview, } from "./workspace/scientific-review.js";
34
36
  import { isObject, pathExists, sha256Text, workspacePaths } from "./workspace/storage.js";
35
- import { doctorResearchWorkspace, initializeResearchWorkspace, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
37
+ import { doctorResearchWorkspace, initializeResearchWorkspace, loadWorkspaceConfig, requireResearchWorkspace, withWorkspaceLock, } from "./workspace/workspace.js";
36
38
  const COMMON_OPTIONS = { help: "boolean", json: "boolean" };
37
39
  const WORKSPACE_OPTIONS = { ...COMMON_OPTIONS, workspace: "string" };
38
40
  export async function runResearchOrchestrationCommand(subcommand, argv, io) {
@@ -42,6 +44,8 @@ export async function runResearchOrchestrationCommand(subcommand, argv, io) {
42
44
  return runResearchSetupCommand(argv, io);
43
45
  if (subcommand === "workspace")
44
46
  return runWorkspace(argv, io);
47
+ if (subcommand === "reviewer")
48
+ return runReviewer(argv, io);
45
49
  if (subcommand === "capability")
46
50
  return runCapability(argv, io);
47
51
  if (subcommand === "policy")
@@ -65,6 +69,9 @@ export function researchOrchestrationHelp() {
65
69
  tiangong-ai research context inspect [--path <absolute-path>] [--json]
66
70
  tiangong-ai research workspace init <absolute-path> [--name <name>] [--mode smoke-test|production-research] [--json]
67
71
  tiangong-ai research workspace doctor [--workspace <absolute-path>] [--agent-smoke] [--capability-smoke] [--json]
72
+ tiangong-ai research reviewer serve --state-dir <absolute-private-directory> [--workspace <absolute-path>] [--json]
73
+ tiangong-ai research reviewer status [--workspace <absolute-path>] [--json]
74
+ tiangong-ai research reviewer doctor --confirm-agent-smoke-cost [--workspace <absolute-path>] [--json]
68
75
  tiangong-ai research capability catalog [--path <absolute-path>] [--workspace <absolute-path>] [--skill-root <absolute-path>] [--json]
69
76
  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
77
  tiangong-ai research capability import --definition <absolute-json> [--workspace <absolute-path>] [--json]
@@ -79,7 +86,7 @@ export function researchOrchestrationHelp() {
79
86
  tiangong-ai research policy validate <project-id> [--workspace <path>] [--json]
80
87
  tiangong-ai research policy approve <project-id> --confirm [--acknowledge-defaults] [--workspace <path>] [--json]
81
88
  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]
89
+ 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
90
  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
91
  tiangong-ai research publication review submit <project-id> --role evidence|methods-reproducibility|domain-novelty|journal-editor --review <absolute-json> [--workspace <path>] [--json]
85
92
  tiangong-ai research publication status <project-id> [--workspace <path>] [--json]
@@ -100,7 +107,7 @@ export function researchOrchestrationHelp() {
100
107
  tiangong-ai research project scientific status <project-id> [--workspace <path>] [--json]
101
108
  tiangong-ai research project audit export <project-id> --output <absolute-new-directory> [--workspace <path>] [--json]
102
109
  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]
110
+ tiangong-ai research project stage prepare <project-id> --stage discover|acquire|analyze|synthesize --host-agent codex|claude|workbuddy|codebuddy [--workspace <path>] [--json]
104
111
  tiangong-ai research project stage submit <project-id> --session <id> --output <absolute-json> [--confirm-model <id>] [--workspace <path>] [--json]
105
112
  tiangong-ai research project stage abort <project-id> --session <id> [--workspace <path>] [--json]
106
113
  tiangong-ai research project evidence fetch <project-id> --request <absolute-json> [--workspace <path>] [--json]
@@ -120,6 +127,92 @@ export function researchOrchestrationHelp() {
120
127
  ${researchSetupHelp()}
121
128
  `;
122
129
  }
130
+ async function runReviewer(argv, io) {
131
+ const [action, ...rest] = argv;
132
+ if (!action || action === "--help" || action === "-h")
133
+ return writeHelp(io);
134
+ if (action === "status") {
135
+ const args = parseStrictArgs(rest, WORKSPACE_OPTIONS, "research reviewer status");
136
+ if (strictBoolean(args, "help"))
137
+ return writeHelp(io);
138
+ if (args.positionals.length)
139
+ throw unknownAction("research reviewer status", args.positionals[0]);
140
+ const root = await workspaceFromArgs(args);
141
+ writeJson(io, await inspectReviewerBridgeStatus(root), args);
142
+ return 0;
143
+ }
144
+ if (action === "doctor") {
145
+ const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS, "confirm-agent-smoke-cost": "boolean" }, "research reviewer doctor");
146
+ if (strictBoolean(args, "help"))
147
+ return writeHelp(io);
148
+ if (args.positionals.length)
149
+ throw unknownAction("research reviewer doctor", args.positionals[0]);
150
+ if (!strictBoolean(args, "confirm-agent-smoke-cost")) {
151
+ throw new CliError("Reviewer doctor requires explicit model-cost confirmation.", {
152
+ code: "RESEARCH_REVIEW_BRIDGE_CONFIRMATION_REQUIRED",
153
+ exitCode: 3,
154
+ details: {
155
+ minimumAction: "Rerun with --confirm-agent-smoke-cost after reviewing reviewer provider quota and cost.",
156
+ },
157
+ });
158
+ }
159
+ const root = await workspaceFromArgs(args);
160
+ const result = await doctorResearchWorkspace(root, {
161
+ agentSmoke: true,
162
+ environment: io.env,
163
+ });
164
+ writeJson(io, result, args);
165
+ return result.status === "ready" ? 0 : 3;
166
+ }
167
+ if (action === "serve") {
168
+ const args = parseStrictArgs(rest, { ...WORKSPACE_OPTIONS, "state-dir": "string" }, "research reviewer serve");
169
+ if (strictBoolean(args, "help"))
170
+ return writeHelp(io);
171
+ if (args.positionals.length)
172
+ throw unknownAction("research reviewer serve", args.positionals[0]);
173
+ const stateDirectory = strictString(args, "state-dir");
174
+ if (!stateDirectory ||
175
+ !isAbsolute(stateDirectory) ||
176
+ resolve(stateDirectory) !== stateDirectory) {
177
+ throw new CliError("Reviewer sidecar --state-dir must be an explicit absolute directory.", {
178
+ code: "RESEARCH_REVIEW_BRIDGE_STATE_INVALID",
179
+ exitCode: 2,
180
+ });
181
+ }
182
+ const root = await workspaceFromArgs(args);
183
+ const sidecar = await startReviewerBridgeSidecar({
184
+ root,
185
+ stateDirectory,
186
+ environment: io.env,
187
+ });
188
+ writeJson(io, {
189
+ status: "ready",
190
+ workspaceId: sidecar.workspaceId,
191
+ packageVersion: packageVersion(),
192
+ keyFingerprint: sidecar.keyFingerprint,
193
+ supportedActions: ["execute", "fingerprint", "status"],
194
+ }, args);
195
+ try {
196
+ await waitForReviewerSidecarTermination();
197
+ }
198
+ finally {
199
+ await sidecar.close();
200
+ }
201
+ return 0;
202
+ }
203
+ throw unknownAction("research reviewer", action);
204
+ }
205
+ async function waitForReviewerSidecarTermination() {
206
+ await new Promise((resolvePromise) => {
207
+ const stop = () => {
208
+ process.off("SIGINT", stop);
209
+ process.off("SIGTERM", stop);
210
+ resolvePromise();
211
+ };
212
+ process.once("SIGINT", stop);
213
+ process.once("SIGTERM", stop);
214
+ });
215
+ }
123
216
  async function runPublication(argv, io) {
124
217
  const [action, ...rest] = argv;
125
218
  if (!action || action === "--help" || action === "-h")
@@ -1314,6 +1407,7 @@ async function runStatus(argv, io) {
1314
1407
  return writeHelp(io);
1315
1408
  rejectPositionals(args.positionals, "research status");
1316
1409
  const root = await workspaceFromArgs(args);
1410
+ const config = await loadWorkspaceConfig(root);
1317
1411
  const selectedProject = strictString(args, "project");
1318
1412
  const workspaceProjects = await listProjects(root);
1319
1413
  const allProjects = selectedProject
@@ -1329,6 +1423,20 @@ async function runStatus(argv, io) {
1329
1423
  project.status !== "abandoned");
1330
1424
  const result = {
1331
1425
  workspace: root,
1426
+ execution: {
1427
+ producer: {
1428
+ host: config.producer.agent,
1429
+ model: config.producer.model,
1430
+ mode: config.producer.executionMode,
1431
+ },
1432
+ reviewer: {
1433
+ agent: config.reviewer.agent,
1434
+ model: config.reviewer.model,
1435
+ mode: config.reviewer.executionMode,
1436
+ transport: config.reviewerExecution.transport,
1437
+ isolationProvider: config.reviewerExecution.isolationProvider,
1438
+ },
1439
+ },
1332
1440
  hiddenSupersededProjects: selectedProject || strictBoolean(args, "all")
1333
1441
  ? 0
1334
1442
  : workspaceProjects.filter((project) => project.lineage.supersededBy !== null).length,
@@ -1610,7 +1718,7 @@ function projectRecommendedAction(root, project, readyPackage, nativeStage, scie
1610
1718
  : "Inspect the blocking package and use explicit retry or fork recovery.";
1611
1719
  }
1612
1720
  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}`;
1721
+ return `Prepare native ${readyPackage}: tiangong-ai research project stage prepare ${project.id} --stage ${readyPackage} --host-agent <codex|claude|workbuddy|codebuddy> --workspace ${root}`;
1614
1722
  }
1615
1723
  return readyPackage === "review"
1616
1724
  ? `Run the independent reviewer package: tiangong-ai research run --project ${project.id} --workspace ${root}`
@@ -1731,9 +1839,10 @@ function nativeProducerStage(value) {
1731
1839
  });
1732
1840
  }
1733
1841
  function nativeHostAgent(value) {
1734
- if (value === "codex" || value === "claude")
1842
+ if (value === "codex" || value === "claude" || value === "workbuddy" || value === "codebuddy") {
1735
1843
  return value;
1736
- throw new CliError("--host-agent must be codex or claude.", {
1844
+ }
1845
+ throw new CliError("--host-agent must be codex, claude, workbuddy, or codebuddy.", {
1737
1846
  code: "RESEARCH_NATIVE_HOST_INVALID",
1738
1847
  exitCode: 2,
1739
1848
  });
@@ -1846,9 +1955,13 @@ function scientificReviewRole(value) {
1846
1955
  });
1847
1956
  }
1848
1957
  function publicationAgent(value, label) {
1849
- if (value === "codex" || value === "claude")
1958
+ const producer = label.includes("producer");
1959
+ if (value === "codex" ||
1960
+ value === "claude" ||
1961
+ (producer && (value === "workbuddy" || value === "codebuddy"))) {
1850
1962
  return value;
1851
- throw new CliError(`--${label}-agent must be codex or claude.`, {
1963
+ }
1964
+ throw new CliError(`--${label}-agent must be ${producer ? "codex, claude, workbuddy, or codebuddy" : "codex or claude"}.`, {
1852
1965
  code: "RESEARCH_PUBLICATION_AGENT_INVALID",
1853
1966
  exitCode: 2,
1854
1967
  });