@tiangong-ai/cli 0.0.32 → 0.0.33

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 (58) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +51 -17
  3. package/dist/research/orchestration.js +388 -31
  4. package/dist/research/orchestration.js.map +1 -1
  5. package/dist/research/workspace/acquisition.d.ts +71 -0
  6. package/dist/research/workspace/acquisition.js +593 -0
  7. package/dist/research/workspace/acquisition.js.map +1 -0
  8. package/dist/research/workspace/artifacts.d.ts +43 -0
  9. package/dist/research/workspace/artifacts.js +544 -0
  10. package/dist/research/workspace/artifacts.js.map +1 -0
  11. package/dist/research/workspace/broker.js +265 -56
  12. package/dist/research/workspace/broker.js.map +1 -1
  13. package/dist/research/workspace/discovery-planning.d.ts +25 -0
  14. package/dist/research/workspace/discovery-planning.js +106 -0
  15. package/dist/research/workspace/discovery-planning.js.map +1 -0
  16. package/dist/research/workspace/discovery-status.d.ts +46 -0
  17. package/dist/research/workspace/discovery-status.js +183 -0
  18. package/dist/research/workspace/discovery-status.js.map +1 -0
  19. package/dist/research/workspace/discovery.d.ts +25 -0
  20. package/dist/research/workspace/discovery.js +268 -0
  21. package/dist/research/workspace/discovery.js.map +1 -0
  22. package/dist/research/workspace/downloads.d.ts +76 -0
  23. package/dist/research/workspace/downloads.js +274 -0
  24. package/dist/research/workspace/downloads.js.map +1 -0
  25. package/dist/research/workspace/evidence-ledger.d.ts +52 -0
  26. package/dist/research/workspace/evidence-ledger.js +487 -0
  27. package/dist/research/workspace/evidence-ledger.js.map +1 -0
  28. package/dist/research/workspace/evidence.d.ts +1 -0
  29. package/dist/research/workspace/evidence.js +2 -0
  30. package/dist/research/workspace/evidence.js.map +1 -1
  31. package/dist/research/workspace/input-plan.js +4 -0
  32. package/dist/research/workspace/input-plan.js.map +1 -1
  33. package/dist/research/workspace/native-activity.d.ts +65 -0
  34. package/dist/research/workspace/native-activity.js +153 -0
  35. package/dist/research/workspace/native-activity.js.map +1 -0
  36. package/dist/research/workspace/preflight.d.ts +5 -0
  37. package/dist/research/workspace/preflight.js +37 -17
  38. package/dist/research/workspace/preflight.js.map +1 -1
  39. package/dist/research/workspace/projects.d.ts +3 -1
  40. package/dist/research/workspace/projects.js +346 -5
  41. package/dist/research/workspace/projects.js.map +1 -1
  42. package/dist/research/workspace/runtime.d.ts +106 -4
  43. package/dist/research/workspace/runtime.js +947 -80
  44. package/dist/research/workspace/runtime.js.map +1 -1
  45. package/dist/research/workspace/sanitization.js +28 -6
  46. package/dist/research/workspace/sanitization.js.map +1 -1
  47. package/dist/research/workspace/schemas.d.ts +3 -0
  48. package/dist/research/workspace/schemas.js +206 -33
  49. package/dist/research/workspace/schemas.js.map +1 -1
  50. package/dist/research/workspace/setup-wizard.js +10 -4
  51. package/dist/research/workspace/setup-wizard.js.map +1 -1
  52. package/dist/research/workspace/setup.d.ts +4 -1
  53. package/dist/research/workspace/setup.js +61 -11
  54. package/dist/research/workspace/setup.js.map +1 -1
  55. package/dist/research/workspace/types.d.ts +31 -3
  56. package/dist/research/workspace/workspace.js +45 -6
  57. package/dist/research/workspace/workspace.js.map +1 -1
  58. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { spawn } from "node:child_process";
3
- import { chmod, link, lstat, open, readFile, rm } from "node:fs/promises";
3
+ import { chmod, link, lstat, open, readFile, realpath, rm } from "node:fs/promises";
4
4
  import { hostname, homedir, platform } from "node:os";
5
5
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
6
6
  import { setTimeout as sleep } from "node:timers/promises";
@@ -30,8 +30,7 @@ const BRAVE_PROFILE_SKILLS = {
30
30
  const ADAPTER_ENV_KEY = "TIANGONG_RESEARCH_ADAPTER_CREDENTIALS_JSON";
31
31
  const MAX_COMMAND_OUTPUT_BYTES = 1024 * 1024;
32
32
  export async function createResearchSetupPlan(input) {
33
- const root = requireAbsoluteWorkspace(input.workspace);
34
- await assertWorkspaceDirectory(root);
33
+ const root = await resolveResearchSetupWorkspacePath(input.workspace);
35
34
  const scope = input.scope ?? "project";
36
35
  const agents = normalizeAgents(input.agents ?? ["codex"]);
37
36
  const agentRoutes = normalizeAgentRoutes(input.agentRoutes);
@@ -2311,6 +2310,12 @@ async function runAcademicPaperCompanion(input) {
2311
2310
  }
2312
2311
  const result = results[0];
2313
2312
  if (execution.exitCode !== 0 || result.success !== true) {
2313
+ const sourcesTried = Array.isArray(result.sources_tried)
2314
+ ? result.sources_tried
2315
+ .filter((source) => typeof source === "string")
2316
+ .map((source) => sanitizeResearchText(source).slice(0, 100))
2317
+ : [];
2318
+ const adapterError = sanitizeResearchRecord(isObject(result.error) ? result.error : {});
2314
2319
  if (result.success === false &&
2315
2320
  isObject(result.browser_handoff) &&
2316
2321
  result.file === null &&
@@ -2320,7 +2325,7 @@ async function runAcademicPaperCompanion(input) {
2320
2325
  skillId: input.skill.id,
2321
2326
  skillTreeSha256: input.skill.expectedTreeSha256,
2322
2327
  querySha256: sha256Text(doi ?? title),
2323
- sourcesTried: Array.isArray(result.sources_tried) ? result.sources_tried : [],
2328
+ sourcesTried,
2324
2329
  artifactCommitted: false,
2325
2330
  });
2326
2331
  return {
@@ -2331,20 +2336,32 @@ async function runAcademicPaperCompanion(input) {
2331
2336
  skillId: input.skill.id,
2332
2337
  role: input.skill.role,
2333
2338
  artifactCommitted: false,
2334
- sourcesTried: Array.isArray(result.sources_tried) ? result.sources_tried : [],
2335
- error: sanitizeResearchRecord(isObject(result.error) ? result.error : {}),
2339
+ sourcesTried,
2340
+ error: adapterError,
2336
2341
  provenance: companionProvenance(input.plan, input.skill),
2337
2342
  next: "Automatic legal OA sources were exhausted. Follow the installed academic-paper-download browser-handoff reference explicitly; no browser is launched or selected automatically.",
2338
2343
  };
2339
2344
  }
2345
+ const adapterCode = typeof adapterError.code === "string"
2346
+ ? sanitizeResearchText(adapterError.code).trim().slice(0, 100)
2347
+ : "unknown-adapter-error";
2348
+ const adapterMessage = typeof adapterError.message === "string"
2349
+ ? sanitizeResearchText(adapterError.message).trim().slice(0, 500)
2350
+ : "";
2340
2351
  throw setupError({
2341
2352
  code: "RESEARCH_SETUP_COMPANION_COMMAND_FAILED",
2342
2353
  step: "companion-paper-download",
2343
- reason: `The pinned paper adapter exited with status ${execution.exitCode}.`,
2344
- minimumAction: sanitizeResearchText(execution.stderr).trim().slice(0, 500) ||
2354
+ reason: `The pinned paper adapter failed (${adapterCode}; exit status ${execution.exitCode}).`,
2355
+ minimumAction: adapterMessage ||
2356
+ sanitizeResearchText(execution.stderr).trim().slice(0, 500) ||
2345
2357
  "Inspect the structured adapter error and verify its pinned Python dependencies.",
2346
2358
  retryCommand: `tiangong-ai research setup doctor --workspace ${input.root} --json`,
2347
2359
  exitCode: 3,
2360
+ diagnostics: {
2361
+ adapterError,
2362
+ sourcesTried,
2363
+ artifactCommitted: false,
2364
+ },
2348
2365
  });
2349
2366
  }
2350
2367
  const artifactPath = requireContainedArtifactPath(result.file, outputDirectory, "file");
@@ -2806,9 +2823,25 @@ function requireAbsoluteWorkspace(value) {
2806
2823
  }
2807
2824
  return resolve(value);
2808
2825
  }
2809
- async function assertWorkspaceDirectory(root) {
2826
+ export async function resolveResearchSetupWorkspacePath(value, options = {}) {
2827
+ const root = requireAbsoluteWorkspace(value);
2810
2828
  const info = await lstat(root).catch(() => undefined);
2811
- if (!info?.isDirectory() || info.isSymbolicLink()) {
2829
+ if (info) {
2830
+ if (!info.isDirectory() || info.isSymbolicLink()) {
2831
+ throw setupError({
2832
+ code: "RESEARCH_SETUP_WORKSPACE_INVALID",
2833
+ step: "workspace",
2834
+ reason: "Setup workspace must exist as a regular non-symlink directory.",
2835
+ minimumAction: `Create the directory explicitly, then retry with --workspace ${root}.`,
2836
+ retryCommand: "tiangong-ai research setup --help",
2837
+ exitCode: 2,
2838
+ });
2839
+ }
2840
+ const canonicalRoot = await realpath(root);
2841
+ await assertNoSymlinkedExistingPath(canonicalRoot);
2842
+ return canonicalRoot;
2843
+ }
2844
+ if (!options.allowMissingLeaf) {
2812
2845
  throw setupError({
2813
2846
  code: "RESEARCH_SETUP_WORKSPACE_INVALID",
2814
2847
  step: "workspace",
@@ -2818,7 +2851,24 @@ async function assertWorkspaceDirectory(root) {
2818
2851
  exitCode: 2,
2819
2852
  });
2820
2853
  }
2821
- await assertNoSymlinkedExistingPath(root);
2854
+ const requestedParent = dirname(root);
2855
+ const canonicalParent = await realpath(requestedParent).catch(() => undefined);
2856
+ const parentInfo = canonicalParent
2857
+ ? await lstat(canonicalParent).catch(() => undefined)
2858
+ : undefined;
2859
+ if (!canonicalParent || !parentInfo?.isDirectory() || parentInfo.isSymbolicLink()) {
2860
+ throw setupError({
2861
+ code: "RESEARCH_SETUP_WORKSPACE_INVALID",
2862
+ step: "workspace",
2863
+ reason: "The parent of a new setup workspace must exist as a regular directory.",
2864
+ minimumAction: `Create the parent directory explicitly, then retry with --workspace ${root}.`,
2865
+ retryCommand: "tiangong-ai research setup --help",
2866
+ exitCode: 2,
2867
+ });
2868
+ }
2869
+ const canonicalRoot = join(canonicalParent, basename(root));
2870
+ await assertNoSymlinkedExistingPath(canonicalRoot);
2871
+ return canonicalRoot;
2822
2872
  }
2823
2873
  function normalizedWorkspaceName(value) {
2824
2874
  const normalized = value.trim();