tines 0.0.155 → 0.0.157

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 (2) hide show
  1. package/dist/index.js +40 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3754,8 +3754,27 @@ function attachFlag(type, slot, contentType) {
3754
3754
  }
3755
3755
  }
3756
3756
  }
3757
+ function positionalSource(type, slot, contentType) {
3758
+ switch (type) {
3759
+ case "file":
3760
+ return "<path>";
3761
+ case "folder":
3762
+ return "<dir>";
3763
+ case "link":
3764
+ return "<url>";
3765
+ case "pr":
3766
+ return "<owner/repo#N>";
3767
+ case "text": {
3768
+ const ext = contentType === "text/markdown" ? "md" : contentType === "text/plain" ? "txt" : null;
3769
+ return ext ? `${slot}.${ext}` : "<path>";
3770
+ }
3771
+ }
3772
+ }
3773
+ function attachArg(r, type, contentType) {
3774
+ return r.type === void 0 ? attachFlag(type, r.artifact, contentType) : positionalSource(type, r.artifact, contentType);
3775
+ }
3757
3776
  function requirementFix(r, ref) {
3758
- const attach = (type) => `tines issues artifacts attach ${ref} ${r.artifact} ${attachFlag(type, r.artifact, r.content_type)}`;
3777
+ const attach = (type) => `tines issues artifacts attach ${ref} ${r.artifact} ${attachArg(r, type, r.content_type)}`;
3759
3778
  if (r.status === "missing" || r.current_type === null) {
3760
3779
  return { kind: "attach", command: attach(r.type ?? "file") };
3761
3780
  }
@@ -3765,7 +3784,8 @@ function requirementFix(r, ref) {
3765
3784
  if (r.status === "stale") {
3766
3785
  return {
3767
3786
  kind: "reattach_or_reaffirm",
3768
- command: `${attach(r.current_type)} \u2014 or, if the current content still stands: tines issues artifacts reaffirm ${ref} ${r.artifact}`
3787
+ command: attach(r.current_type),
3788
+ alternative: `tines issues artifacts reaffirm ${ref} ${r.artifact}`
3769
3789
  };
3770
3790
  }
3771
3791
  const reattachable = r.type === void 0 ? r.current_type === "file" || r.current_type === "text" : r.current_type === r.type;
@@ -4297,7 +4317,10 @@ function requirementLines(r) {
4297
4317
  const spec = [r.type, r.content_type].filter(Boolean).join(", ");
4298
4318
  return [
4299
4319
  `requires artifact "${r.artifact}"${spec ? ` (${spec})` : ""}: ${requirementStatus(r)}${r.description ? ` \u2014 ${r.description}` : ""}`,
4300
- ...r.fix ? [` fix: ${r.fix}`] : []
4320
+ ...r.fix ? [` fix: ${r.fix}`] : [],
4321
+ // A second line, never a second command on the first: each line is
4322
+ // copy-pastable on its own (Tines/255).
4323
+ ...r.fix_alternative ? [` or: ${r.fix_alternative}`] : []
4301
4324
  ];
4302
4325
  }
4303
4326
  function scheduleRef(s) {
@@ -5229,28 +5252,34 @@ function planFlags(flags, probe) {
5229
5252
  return { type: "pr", source: { kind: "pr", pr: parsed }, ...modifiers };
5230
5253
  }
5231
5254
  function checkExistingSlot(plan, gates, ref, name2, flags, positional) {
5232
- const held = gates.find((g) => g.check.current_type !== null)?.check.current_type;
5233
- if (held === void 0 || held === null || held === plan.type) return;
5255
+ const held = heldType(gates);
5256
+ if (held === void 0 || held === plan.type) return;
5234
5257
  const rejecting = gates.find((g) => g.check.type !== void 0 && g.check.type !== held);
5235
5258
  const fix = rejecting ? fixCommand(rejecting, ref) : `tines issues artifacts delete ${ref} ${name2} && tines issues artifacts attach ${ref} ${name2} ${flagFor(plan.type)} <source>`;
5236
5259
  throw new CliError(
5237
- `"${name2}" already holds a ${held} artifact and the type is immutable; ${sourceLabel(flags, positional)} would attach ${plan.type}. Use: ${fix} \u2014 or attach it under a different name (--ignore-gates does not bypass this; the server rejects the type change too)`
5260
+ `"${name2}" already holds a ${held} artifact and the type is immutable; ${sourceLabel(flags, positional)} would attach ${plan.type}.${" "}Use: ${fix}${IMMUTABLE_TAIL}`
5238
5261
  );
5239
5262
  }
5263
+ function heldType(gates) {
5264
+ return gates.find((g) => g.check.current_type !== null)?.check.current_type ?? void 0;
5265
+ }
5266
+ var IMMUTABLE_TAIL = " \u2014 or attach it under a different name (--ignore-gates does not bypass this; the server rejects the type change too)";
5240
5267
  function checkAccepted(plan, gates, ref, name2, flags, positional, sniff) {
5241
5268
  const effective = effectiveContentType(plan.type, plan.source, plan.contentType, sniff);
5242
5269
  if (gates.some((g2) => requirementAccepts(g2.check, plan.type, effective))) return;
5243
5270
  const label = sourceLabel(flags, positional);
5271
+ const held = heldType(gates);
5272
+ const blockedByHeldType = held !== void 0 && held !== plan.type;
5244
5273
  const typeMatched = gates.filter((g2) => (g2.check.type ?? plan.type) === plan.type);
5245
5274
  if (typeMatched.length > 0) {
5246
5275
  const g2 = typeMatched[0];
5247
5276
  throw new CliError(
5248
- `"${name2}" is gated by ${joinTransitions(typeMatched.map((x) => x.transition))} as ${gateSpec(g2.check)}; ${label} would attach ${effective ?? plan.type}, which does not satisfy it. Use: ${fixCommand(g2, ref)} with --content-type <mime under ${g2.check.content_type}> (or --ignore-gates to attach it anyway)`
5277
+ `"${name2}" is gated by ${joinTransitions(typeMatched.map((x) => x.transition))} as ${gateSpec(g2.check)}; ${label} would attach ${effective ?? plan.type}, which does not satisfy it. Use: ${fixCommand(g2, ref)} with --content-type <mime under ${g2.check.content_type}>${blockedByHeldType ? IMMUTABLE_TAIL : " (or --ignore-gates to attach it anyway)"}`
5249
5278
  );
5250
5279
  }
5251
5280
  const g = gates[0];
5252
5281
  throw new CliError(
5253
- `"${name2}" is gated by ${joinTransitions(gates.map((x) => x.transition))} as ${gateSpec(g.check)}; ${label} would create a ${plan.type} artifact that can never satisfy it. Use: ${fixCommand(g, ref)} (or --ignore-gates to attach a ${plan.type} anyway)`
5282
+ `"${name2}" is gated by ${joinTransitions(gates.map((x) => x.transition))} as ${gateSpec(g.check)}; ${label} would create a ${plan.type} artifact that can never satisfy it. Use: ${fixCommand(g, ref)}${blockedByHeldType ? IMMUTABLE_TAIL : ` (or --ignore-gates to attach a ${plan.type} anyway)`}`
5254
5283
  );
5255
5284
  }
5256
5285
  function satisfiedBy(artifact, gates) {
@@ -5282,6 +5311,8 @@ function gateLabel(artifact, gates) {
5282
5311
  }
5283
5312
  var ATTACH_SOURCE_HELP = `
5284
5313
  Source:
5314
+ Prefer the positional form: it is what a gated slot's own hint prints
5315
+ ("fix:" on \`tines issues show\`, and the launch prompt's Requires: line).
5285
5316
  A positional <source> is typed by the slot's gate when this issue has one:
5286
5317
  a text gate reads the path as the document (the gate's content type wins over
5287
5318
  the extension), a file gate uploads its bytes, a folder gate walks it, and a
@@ -5977,7 +6008,7 @@ files (v${artifact.current_version.version}):`);
5977
6008
  });
5978
6009
  withCommon(
5979
6010
  artifactsCmd.command("attach <ref> <name> [source]").description(
5980
- "Attach content to a named artifact slot (creates it, or appends the next version)"
6011
+ "Attach content to a named artifact slot \u2014 <source> is typed by the gate, flags override (creates it, or appends a version)"
5981
6012
  ).option("-f, --file <path>", "upload a file (MIME sniffed from the extension)").option(
5982
6013
  "--folder <dir>",
5983
6014
  "snapshot a directory tree as one version (collect locally, attach once; MIME per file sniffed)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tines",
3
- "version": "0.0.155",
3
+ "version": "0.0.157",
4
4
  "description": "CLI for Tines, an orchestration layer for AI agents",
5
5
  "repository": {
6
6
  "type": "git",