@treeseed/sdk 0.6.8 → 0.6.10

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 (33) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +2 -0
  3. package/dist/managed-dependencies.d.ts +23 -0
  4. package/dist/managed-dependencies.js +133 -12
  5. package/dist/operations/providers/default.js +35 -0
  6. package/dist/operations/services/config-runtime.js +25 -6
  7. package/dist/operations/services/deploy.js +14 -1
  8. package/dist/operations/services/export-runtime.js +4 -0
  9. package/dist/operations/services/git-workflow.d.ts +2 -0
  10. package/dist/operations/services/git-workflow.js +39 -4
  11. package/dist/operations/services/github-api.d.ts +10 -0
  12. package/dist/operations/services/github-api.js +20 -1
  13. package/dist/operations/services/github-automation.d.ts +3 -0
  14. package/dist/operations/services/package-reference-policy.js +19 -3
  15. package/dist/operations/services/repository-save-orchestrator.js +10 -4
  16. package/dist/operations/services/workspace-dependency-mode.js +10 -18
  17. package/dist/operations-registry.js +1 -0
  18. package/dist/scripts/patch-starlight-content-path.js +2 -1
  19. package/dist/scripts/prepare.js +14 -0
  20. package/dist/verification.js +22 -1
  21. package/dist/workflow/operations.d.ts +259 -429
  22. package/dist/workflow/operations.js +662 -78
  23. package/dist/workflow/runs.d.ts +38 -0
  24. package/dist/workflow/runs.js +182 -15
  25. package/dist/workflow/worktrees.d.ts +39 -0
  26. package/dist/workflow/worktrees.js +224 -0
  27. package/dist/workflow-state.d.ts +13 -0
  28. package/dist/workflow-state.js +35 -2
  29. package/dist/workflow-support.d.ts +1 -1
  30. package/dist/workflow-support.js +2 -0
  31. package/dist/workflow.d.ts +14 -1
  32. package/package.json +2 -2
  33. package/templates/github/deploy.workflow.yml +135 -5
@@ -540,14 +540,14 @@ function applyPackageVersion(node, version) {
540
540
  function shouldSkipNetworkInstall() {
541
541
  return getGitHubAutomationMode() === "stub" || process.env.TREESEED_SAVE_NPM_INSTALL_MODE === "skip";
542
542
  }
543
- function shouldSkipGitDependencySmoke() {
544
- return shouldSkipNetworkInstall() || process.env.TREESEED_GIT_DEPENDENCY_SMOKE === "skip";
543
+ function shouldSkipGitDependencySmoke(options) {
544
+ return shouldSkipNetworkInstall() || process.env.TREESEED_GIT_DEPENDENCY_SMOKE === "skip" || options?.verifyMode === "skip";
545
545
  }
546
546
  function hasNpmLockfile(repoDir) {
547
547
  return existsSync(resolve(repoDir, "package-lock.json")) || existsSync(resolve(repoDir, "npm-shrinkwrap.json"));
548
548
  }
549
549
  async function runGitDependencySmoke(node, options, reference) {
550
- if (reference.mode !== "dev-git-tag" || shouldSkipGitDependencySmoke()) return;
550
+ if (reference.mode !== "dev-git-tag" || shouldSkipGitDependencySmoke(options)) return;
551
551
  const installSpec = reference.installSpec ?? reference.spec;
552
552
  const tempRoot = mkdtempSync(resolve(tmpdir(), "treeseed-git-dep-smoke-"));
553
553
  const npmCacheRoot = resolve(tempRoot, ".npm-cache");
@@ -593,7 +593,8 @@ async function runNpmInstallWithRetry(node, options, gitDependencyRefreshSpecs =
593
593
  let lastError = null;
594
594
  const packageJson = node.packageJson ?? (existsSync(resolve(node.path, "package.json")) ? readJson(resolve(node.path, "package.json")) : null);
595
595
  const rootWorkspaceInstall = node.path === options.root && Array.isArray(packageJson?.workspaces);
596
- const args = rootWorkspaceInstall ? gitDependencyRefreshSpecs.length > 0 ? ["install", ...gitDependencyRefreshSpecs, "--force"] : ["install"] : gitDependencyRefreshSpecs.length > 0 ? ["install", ...gitDependencyRefreshSpecs, "--force", "--workspaces=false"] : ["install", "--workspaces=false"];
596
+ const installFlags = ["--package-lock-only", "--ignore-scripts"];
597
+ const args = rootWorkspaceInstall ? gitDependencyRefreshSpecs.length > 0 ? ["install", ...gitDependencyRefreshSpecs, ...installFlags, "--force"] : ["install", ...installFlags] : gitDependencyRefreshSpecs.length > 0 ? ["install", ...gitDependencyRefreshSpecs, ...installFlags, "--force", "--workspaces=false"] : ["install", ...installFlags, "--workspaces=false"];
597
598
  for (let attempt = 1; attempt <= 5; attempt += 1) {
598
599
  emitProgress(options, node, "install", `npm ${args.join(" ")} attempt ${attempt}/5.`);
599
600
  try {
@@ -1230,6 +1231,11 @@ async function saveOneRepository(node, options, state) {
1230
1231
  report.install = await runNpmInstallWithRetry(node, options, gitDependencyRefreshSpecs);
1231
1232
  }
1232
1233
  if (hasNpmLockfile(node.path) && (node.kind === "project" || packageNeedsVersion || dependencyChanged || submodulesChanged)) {
1234
+ const lockfileIssues = collectDeploymentLockfileWorkspaceIssues(node.path);
1235
+ if (node.kind === "project" && lockfileIssues.length > 0 && !shouldSkipNetworkInstall()) {
1236
+ emitProgress(options, node, "lockfile", "Refreshing package-lock.json before validation.");
1237
+ report.install = await runNpmInstallWithRetry(node, options, gitDependencyRefreshSpecs);
1238
+ }
1233
1239
  report.lockfileValidation = await validateRepositoryLockfile(node, options);
1234
1240
  }
1235
1241
  const dirty = hasMeaningfulChanges(node.path);
@@ -1,5 +1,6 @@
1
1
  import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
2
2
  import { dirname, relative, resolve } from "node:path";
3
+ import { spawnSync } from "node:child_process";
3
4
  import { workspacePackages, workspaceRoot } from "./workspace-tools.js";
4
5
  const METADATA_VERSION = 1;
5
6
  const INTERNAL_DEPENDENCY_FIELDS = ["dependencies", "optionalDependencies", "peerDependencies", "devDependencies"];
@@ -64,24 +65,15 @@ function writeMetadata(root, links) {
64
65
  `, "utf8");
65
66
  }
66
67
  function gitInfoExcludePath(repoPath) {
67
- const gitPath = resolve(repoPath, ".git");
68
- const stat = safeLstat(gitPath);
69
- if (!stat) return null;
70
- if (stat.isDirectory()) {
71
- return resolve(gitPath, "info", "exclude");
72
- }
73
- if (stat.isFile()) {
74
- try {
75
- const content = readFileSync(gitPath, "utf8").trim();
76
- const match = /^gitdir:\s*(.+)$/iu.exec(content);
77
- if (!match) return null;
78
- const gitDir = resolve(repoPath, match[1]);
79
- return resolve(gitDir, "info", "exclude");
80
- } catch {
81
- return null;
82
- }
83
- }
84
- return null;
68
+ const result = spawnSync("git", ["rev-parse", "--git-common-dir"], {
69
+ cwd: repoPath,
70
+ stdio: "pipe",
71
+ encoding: "utf8"
72
+ });
73
+ if (result.status !== 0) return null;
74
+ const gitDir = result.stdout.trim();
75
+ if (!gitDir) return null;
76
+ return resolve(repoPath, gitDir, "info", "exclude");
85
77
  }
86
78
  function ensureGitInfoExcludes(root, links) {
87
79
  const patternsByRepo = /* @__PURE__ */ new Map();
@@ -17,6 +17,7 @@ const TRESEED_OPERATION_SPECS = [
17
17
  operation({ id: "deploy.rollback", name: "rollback", aliases: [], group: "Workflow", summary: "Roll back staging or production to a recorded deployment.", description: "Redeploy a previously recorded staging or production commit using a temporary checkout of that revision.", provider: "default", related: ["status", "release"] }),
18
18
  operation({ id: "workspace.doctor", name: "doctor", aliases: [], group: "Validation", summary: "Diagnose Treeseed tooling, auth, and workflow readiness.", description: "Collect doctor-style diagnostics for workspace readiness and optional safe repairs.", provider: "default", related: ["status", "config"] }),
19
19
  operation({ id: "workspace.install", name: "install", aliases: [], group: "Utilities", summary: "Install Treeseed-managed local dependencies.", description: "Install or repair Treeseed-managed CLI dependencies including GitHub CLI, Wrangler, Railway, Copilot, and optional gh-act support.", provider: "default", related: ["config", "doctor"] }),
20
+ operation({ id: "workspace.tools", name: "tools", aliases: [], group: "Utilities", summary: "Report Treeseed-managed executable locations.", description: "Inspect Treeseed-managed executable paths, invocation commands, cache roots, and GitHub CLI authentication state without installing or mutating tools.", provider: "default", related: ["install", "doctor"] }),
20
21
  operation({ id: "auth.login", name: "auth:login", aliases: [], group: "Validation", summary: "Authenticate against the configured Treeseed API.", description: "Start the device login flow against the active Treeseed API host and persist the returned session locally.", provider: "default", related: ["auth:check", "auth:whoami", "auth:logout"] }),
21
22
  operation({ id: "auth.logout", name: "auth:logout", aliases: [], group: "Validation", summary: "Clear locally stored Treeseed API credentials.", description: "Remove the persisted local device-flow session for the active Treeseed API host.", provider: "default", related: ["auth:login", "auth:whoami"] }),
22
23
  operation({ id: "auth.whoami", name: "auth:whoami", aliases: [], group: "Validation", summary: "Inspect the active Treeseed API identity.", description: "Use the persisted local remote session to query the active Treeseed API principal.", provider: "default", related: ["auth:login", "status"] }),
@@ -145,7 +145,8 @@ async function run() {
145
145
  }
146
146
  }
147
147
  if (existingFiles.length === 0) {
148
- throw new Error('Unable to find any Starlight collection helper files to patch.');
148
+ console.log('Starlight dependency tree not found; skipping knowledge-path patch.');
149
+ return;
149
150
  }
150
151
  let patchedAny = false;
151
152
  for (const collectionFile of existingFiles) {
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from 'node:child_process';
4
+
5
+ if (process.env.TREESEED_SKIP_PACKAGE_PREPARE === '1') {
6
+ process.exit(0);
7
+ }
8
+
9
+ const result = spawnSync('npm', ['run', 'build:dist'], {
10
+ stdio: 'inherit',
11
+ shell: process.platform === 'win32',
12
+ });
13
+
14
+ process.exit(result.status ?? 1);
@@ -51,6 +51,21 @@ function createActArgs(eventName, workflowPath) {
51
51
  }
52
52
  function createWorkspaceActWorkflow(options) {
53
53
  const relativePackageRoot = relative(options.workspaceRoot, options.packageRoot).replace(/\\/g, "/");
54
+ const siblingLinkCommands = options.localTreeseedSiblingDependencies.map((packageName) => {
55
+ const [, packageShortName] = packageName.split("/");
56
+ const packageDir = `packages/${packageShortName}`;
57
+ const packageScope = packageName.split("/")[0];
58
+ const linkParent = `node_modules/${packageScope}`;
59
+ const linkTarget = relative(
60
+ resolve(options.packageRoot, linkParent),
61
+ resolve(options.workspaceRoot, packageDir)
62
+ ).replace(/\\/g, "/");
63
+ return [
64
+ `mkdir -p ${linkParent}`,
65
+ `rm -rf ${linkParent}/${packageShortName}`,
66
+ `ln -s ${linkTarget} ${linkParent}/${packageShortName}`
67
+ ].join("\n");
68
+ }).join("\n");
54
69
  const siblingPreparationCommands = options.localTreeseedSiblingDependencies.map((packageName) => {
55
70
  const packageDir = `packages/${packageName.split("/")[1]}`;
56
71
  const manifest = readPackageManifest(resolve(options.workspaceRoot, packageDir, "package.json"));
@@ -111,13 +126,19 @@ ${siblingPreparationCommands.split("\n").map((line) => ` ${line}`).join
111
126
 
112
127
  ` : ""} - name: Install dependencies
113
128
  run: |
129
+ node -e "const fs = require('fs'); const p = JSON.parse(fs.readFileSync('package.json', 'utf8')); if (p.scripts) delete p.scripts.prepare; fs.writeFileSync('package.json', JSON.stringify(p, null, '\\t') + '\\n');"
114
130
  if test -f package-lock.json; then
115
131
  npm ci --workspaces=false
116
132
  else
117
133
  npm install --workspaces=false --no-audit --no-fund
118
134
  fi
135
+ git checkout -- package.json || true
119
136
 
120
- - name: Verify package
137
+ ${siblingLinkCommands ? ` - name: Link local Treeseed dependencies
138
+ run: |
139
+ ${siblingLinkCommands.split("\n").map((line) => ` ${line}`).join("\n")}
140
+
141
+ ` : ""} - name: Verify package
121
142
  run: npm run verify:direct
122
143
  `,
123
144
  "utf8"