portable-agent-layer 0.66.0 → 0.66.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "portable-agent-layer",
3
- "version": "0.66.0",
3
+ "version": "0.66.1",
4
4
  "description": "PAL — Portable Agent Layer: persistent personal context for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli/index.ts CHANGED
@@ -1188,9 +1188,8 @@ async function install(targets: Targets) {
1188
1188
  await promptTelos();
1189
1189
  await promptAttribution();
1190
1190
 
1191
- // After promptIdentity, so an actor minted before the name was known adopts it.
1192
- const { seedActorLabel, ensureActorRegistered } = await import("../hooks/lib/actor");
1193
- seedActorLabel();
1191
+ // Registers the label loadActor derives, so it travels on the next export.
1192
+ const { ensureActorRegistered } = await import("../hooks/lib/actor");
1194
1193
  ensureActorRegistered();
1195
1194
 
1196
1195
  // Shared, target-independent state. Every target installer used to repeat these
@@ -90,12 +90,31 @@ function repairActor(stored: Partial<ActorIdentity> & { id: string }): ActorIden
90
90
  };
91
91
  }
92
92
 
93
+ /**
94
+ * The name the principal already told PAL, or nothing. The settings default of
95
+ * "User" names nobody, so it never becomes a label.
96
+ */
97
+ function principalName(): string {
98
+ const name = identity().principal.name.trim();
99
+ return !name || name === "User" ? "" : name;
100
+ }
101
+
93
102
  /**
94
103
  * This person's identity, minted on first call and stable afterwards — across
95
104
  * machines, once an export has carried it there.
105
+ *
106
+ * The label is derived, not stored-at-mint: while it is still the generated
107
+ * default, the principal's configured name wins. Seeding it once at install
108
+ * only held for installs that ran the seeding step, so an actor minted by an
109
+ * upgrade kept a neutral label forever while settings knew the name all along.
110
+ * Deriving on read makes the name hold on every install without a step anyone
111
+ * has to remember. A label the user chose is stored, and is never overridden.
96
112
  */
97
113
  export function loadActor(home: string = palHome()): ActorIdentity {
98
- return loadIdentity(actorFilePath(home), newActor, repairActor);
114
+ const actor = loadIdentity(actorFilePath(home), newActor, repairActor);
115
+ if (actor.label !== defaultActorLabel(actor.id)) return actor;
116
+ const name = principalName();
117
+ return name ? { ...actor, label: name } : actor;
99
118
  }
100
119
 
101
120
  /** Rename this actor. No stored record is touched — labels resolve on read. */
@@ -133,21 +152,6 @@ export function ensureActorRegistered(home: string = palHome()): ActorIdentity {
133
152
  return actor;
134
153
  }
135
154
 
136
- /**
137
- * Adopt the principal's name as the actor label, but only while the label is
138
- * still the generated default — a chosen label is never overwritten. Runs at
139
- * install rather than at mint, so an actor created before the name was known
140
- * still picks it up. The settings default of "User" names nobody, so it is not
141
- * adopted.
142
- */
143
- export function seedActorLabel(home: string = palHome()): ActorIdentity {
144
- const actor = loadActor(home);
145
- if (actor.label !== defaultActorLabel(actor.id)) return actor;
146
- const name = identity().principal.name.trim();
147
- if (!name || name === "User") return actor;
148
- return setActorLabel(name, home);
149
- }
150
-
151
155
  /** Authority behind the call currently executing. */
152
156
  export function currentAuthority(): Authority {
153
157
  return isPalSpawnedInference() ? "agent" : "user";
@@ -142,7 +142,11 @@ Usage:
142
142
  process.exit(1);
143
143
  }
144
144
  const thread = addThread(values.title, values.context ?? "");
145
- emit.data(`Added with id ${thread.id}`);
145
+ emit.receipt(threadsPath(), {
146
+ id: thread.id,
147
+ title: thread.title,
148
+ status: thread.status,
149
+ });
146
150
  }
147
151
 
148
152
  if (cmd === "resolve") {
@@ -151,8 +155,15 @@ Usage:
151
155
  process.exit(1);
152
156
  }
153
157
  const resolved = resolveThread(values.id);
154
- if (resolved.success) emit.ok(resolved.message ?? "Thread resolved");
155
- else emit.data(JSON.stringify(resolved, null, 2));
158
+ if (!resolved.success) {
159
+ console.error(resolved.message);
160
+ process.exit(1);
161
+ }
162
+ emit.receipt(threadsPath(), {
163
+ id: values.id,
164
+ status: "resolved",
165
+ title: resolved.thread?.title,
166
+ });
156
167
  }
157
168
 
158
169
  if (cmd === "list") {
@@ -454,7 +454,12 @@ Output:
454
454
  const report = formatReport(period, notes, ratings, opinionChanges);
455
455
  const filepath = writeReport(report, period);
456
456
  setLastReflectDate(new Date().toISOString().slice(0, 10));
457
- emit.ok(`\nCreated reflection report: ${filepath}`);
457
+ emit.receipt(filepath, {
458
+ period,
459
+ notes: notes.length,
460
+ ratings: ratings.length,
461
+ opinionChanges: opinionChanges.length,
462
+ });
458
463
 
459
464
  const opinions = readOpinions();
460
465
  const high = opinions.filter((o) => o.confidence >= 0.85);