@proagentstore/cli 0.4.102 → 0.4.104

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.
@@ -1,3 +1,4 @@
1
+ import { runObjectiveBlock } from "./run-objective.js";
1
2
  import { spawn } from "node:child_process";
2
3
  import { classifyCommand, commandFromToolInput, fillTargetFromResult, toolCallOk, toolResultMark } from "./engine-acts.js";
3
4
  import { parseEngineUsage } from "./engine-usage.js";
@@ -521,6 +522,10 @@ export class HeadlessSession {
521
522
  this.push("[pags] this engine keeps no memory between turns, so ProAgentStore's record of the conversation so far was delivered with this turn — a reconstruction, not the engine's own memory");
522
523
  else if (seed)
523
524
  this.push("[pags] a context brief from ProAgentStore's record was delivered with this turn — a reconstruction, not the previous conversation");
525
+ // The run's objective (#1019): to the ENGINE in full, the pane a one-line marker (same budget as the brief).
526
+ const objective = opts.objective ? runObjectiveBlock(opts.objective) : null;
527
+ if (opts.objective)
528
+ this.push(`[pags] the run's objective (${opts.objective.text.length} characters, verbatim) was delivered with this turn`);
524
529
  this.push(`\n❯ [${stamp()}] ${authorTag(opts.author)}${text}`); // ❯ — your turn, timestamped
525
530
  this.run = "thinking";
526
531
  const now = Date.now();
@@ -531,7 +536,8 @@ export class HeadlessSession {
531
536
  try {
532
537
  // Brief first, instruction second, and never the other way round: it is background for
533
538
  // the request, and an engine that reads the request last acts on the request.
534
- const withSeed = seed ? `${seed}\n\n${sent}` : sent;
539
+ // The objective sits between them: background like the brief, and above the instruction it frames.
540
+ const withSeed = [seed, objective, sent].filter(Boolean).join("\n\n");
535
541
  if (this.adapter.persistent) {
536
542
  // `role` stays "user" — the only role this protocol accepts, which is why the
537
543
  // disambiguation rides in the text instead (#505).
@@ -0,0 +1,18 @@
1
+ // The run's objective, delivered verbatim with a turn and attributed to the platform (#1019).
2
+ /** A run objective as the cloud sent it, or undefined — narrowed, because any caller can POST here (#1019). */
3
+ export function runObjective(raw) {
4
+ const o = raw;
5
+ return o && typeof o.runId === "string" && o.runId.length <= 128 && typeof o.text === "string" && o.text.trim() ? { runId: o.runId, text: o.text } : undefined;
6
+ }
7
+ /**
8
+ * The run's objective as the engine reads it (#1019): verbatim, fenced, and attributed to the platform —
9
+ * the Pilot's instruction that follows is its own turn, and owner directives sent later outrank both.
10
+ */
11
+ export function runObjectiveBlock(o) {
12
+ return [
13
+ `[pags] RUN OBJECTIVE — the owner's objective for run ${o.runId}, exactly as ProAgentStore accepted it. It was not written by the Pilot. Owner instructions sent later in this run take precedence over it.`,
14
+ "<<<OBJECTIVE",
15
+ o.text,
16
+ "OBJECTIVE>>>",
17
+ ].join("\n");
18
+ }
@@ -1,3 +1,4 @@
1
+ import { runObjective } from "./run-objective.js";
1
2
  import { homedir } from "node:os";
2
3
  import { join, resolve } from "node:path";
3
4
  import { RunnerInputError } from "../errors.js";
@@ -65,7 +66,9 @@ export class CodingRuntime {
65
66
  // a reader of the registration can see which machines can restore a branch invariant; the
66
67
  // cloud still never trusts it, because an older runner simply 404s and the policy reports
67
68
  // that it asked and was not answered.
68
- return ["coding.sessions", "coding.stream", "human.takeover", "coding.inspect", "coding.repo-write"];
69
+ // `coding.run-objective` (#1019): a message may carry the run's objective, delivered verbatim and
70
+ // attributed to the platform. Advertised so the cloud never claims delivery to a runner without it.
71
+ return ["coding.sessions", "coding.stream", "human.takeover", "coding.inspect", "coding.repo-write", "coding.run-objective"];
69
72
  }
70
73
  /**
71
74
  * Resolve the workDir for a read-only inspection. Prefer the tracked session's real
@@ -255,6 +258,7 @@ export class CodingRuntime {
255
258
  author: asTurnAuthor(action.author),
256
259
  replay: typeof action.replay === "string" ? action.replay : undefined,
257
260
  inputId: typeof action.inputId === "string" && action.inputId.length <= 128 ? action.inputId : undefined,
261
+ objective: runObjective(action.objective),
258
262
  });
259
263
  break;
260
264
  case "keys": {
package/dist/index.js CHANGED
@@ -1766,10 +1766,12 @@ var AutomaticUpdateController = class {
1766
1766
  if (action === "cancel") return this.cancel();
1767
1767
  if (action === "start") this.schedule(true);
1768
1768
  }
1769
- /** Testable immediate entry point; production reaches it through the scheduled timer. */
1769
+ /**
1770
+ * Testable immediate entry point; production reaches it through the scheduled timer. Authority is
1771
+ * NOT required to get here: a failed refresh clears it, and the retry is what re-establishes it.
1772
+ */
1770
1773
  async runNow() {
1771
- const current = this.deps.policy();
1772
- if (this.checking || this.waiting || !current.authoritative || !current.value.autoUpdate) return;
1774
+ if (this.checking || this.waiting || !this.retryable()) return;
1773
1775
  this.checking = true;
1774
1776
  try {
1775
1777
  if (!await this.deps.refreshPolicy() || !this.enabled()) {
@@ -1787,12 +1789,22 @@ var AutomaticUpdateController = class {
1787
1789
  async installManually(plan) {
1788
1790
  return this.install(plan, false);
1789
1791
  }
1792
+ /** May observe work, install or restart: only a freshly confirmed owner ON. */
1790
1793
  enabled() {
1791
1794
  const { value, authoritative } = this.deps.policy();
1792
1795
  return authoritative && value.autoUpdate;
1793
1796
  }
1797
+ /**
1798
+ * May keep a timer to re-read the policy: anything but an explicit OFF (#1020). The relay clears
1799
+ * authority before every refresh, so a failed one left `enabled()` false and `schedule` refused —
1800
+ * no timer, until a heartbeat happened to restore authority. The retry only refreshes; every
1801
+ * install still passes `enabled()` and the relay's final admission.
1802
+ */
1803
+ retryable() {
1804
+ return this.deps.policy().value.autoUpdate;
1805
+ }
1794
1806
  schedule(initial = false) {
1795
- if (!this.enabled() || this.timer || this.waiting) return;
1807
+ if (!this.retryable() || this.timer || this.waiting) return;
1796
1808
  const delay = initial ? Math.round(5e3 + (this.deps.random ?? Math.random)() * 25e3) : nextAutoUpdateDelayMs(this.failures, this.deps.random);
1797
1809
  this.timer = this.setTimer(() => {
1798
1810
  this.timer = null;
@@ -1813,6 +1825,7 @@ var AutomaticUpdateController = class {
1813
1825
  * until the next policy transition. `schedule` itself refuses once the policy is disabled.
1814
1826
  */
1815
1827
  offline() {
1828
+ if (!this.retryable()) return;
1816
1829
  this.failures++;
1817
1830
  this.deps.status("offline", { reason: "The owner policy could not be refreshed; automatic update is deferred." });
1818
1831
  this.schedule();
@@ -1826,7 +1839,7 @@ var AutomaticUpdateController = class {
1826
1839
  const facts = await this.deps.facts();
1827
1840
  this.checkAt = this.now();
1828
1841
  if (facts.observations?.length) this.observations = [...this.observations, ...facts.observations].slice(-MAX_OBSERVATIONS);
1829
- if (!this.enabled()) return;
1842
+ if (!this.enabled()) return this.offline();
1830
1843
  const plan = this.deps.plan(facts);
1831
1844
  this.decisionAt = this.now();
1832
1845
  this.blockerClass = plan.action === "wait" ? blockerClassFor(plan.waitingFor) : null;
@@ -1858,6 +1871,7 @@ var AutomaticUpdateController = class {
1858
1871
  defer(latest) {
1859
1872
  if (this.waiting) return;
1860
1873
  this.waiting = true;
1874
+ if (this.timer) this.clearTimer(this.timer);
1861
1875
  this.timer = this.setTimer(() => {
1862
1876
  this.timer = null;
1863
1877
  this.nextRetryDueAt = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.102",
3
+ "version": "0.4.104",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",