@astrosheep/square 0.4.8 → 0.4.9
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/dist/cli/express-presentation.js +2 -2
- package/dist/decisions.js +10 -16
- package/dist/operation-presentation.js +5 -5
- package/dist/square-facade.d.ts +1 -1
- package/dist/square-tools.js +1 -1
- package/guides/square-api.md +6 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/square/SKILL.md +2 -2
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/skills/square/SKILL.md +2 -2
|
@@ -115,10 +115,10 @@ export async function executeExpression(open, squarePath, requestedName, rawInpu
|
|
|
115
115
|
exitCode(2);
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
|
-
const repair = reason === 'bell_mention_conflict'
|
|
118
|
+
const repair = reason === 'bell_mention_conflict';
|
|
119
119
|
if (isSquareError(error)) {
|
|
120
120
|
if (repair) {
|
|
121
|
-
lines.push(
|
|
121
|
+
lines.push(' · ring the bell without explicit mentions:', `${activityRetryCommand(squarePath, name, { ...opts, mentions: [] })}${opts.bodyProvided === false ? '' : ` < ${quoteShell(draftPath)}`}`);
|
|
122
122
|
}
|
|
123
123
|
else if (error.code === 'invalid_args' || error.code === 'invalid_name') {
|
|
124
124
|
if (opts.mentions?.length)
|
package/dist/decisions.js
CHANGED
|
@@ -94,29 +94,23 @@ export function decideAct(facts, input) {
|
|
|
94
94
|
if (reach === 'bell' && input.mentions?.length)
|
|
95
95
|
throw activityRefusal('invalid_args', 'A bell cannot be combined with a mention', { reason: 'bell_mention_conflict', targets: [...input.mentions] });
|
|
96
96
|
const mentionNames = [];
|
|
97
|
-
const
|
|
98
|
-
|
|
97
|
+
const unmatchedMentions = [];
|
|
98
|
+
const addMention = (requested, resolved) => {
|
|
99
|
+
const names = resolved === undefined ? unmatchedMentions : mentionNames;
|
|
100
|
+
const name = resolved ?? requested;
|
|
101
|
+
if (names.some((existing) => sameName(existing, name)))
|
|
99
102
|
return;
|
|
100
|
-
if (
|
|
103
|
+
if (resolved !== undefined && names.length >= MAX_IDENTITY_SET_SIZE)
|
|
101
104
|
throw activityRefusal('invalid_args', `An activity can mention at most ${MAX_IDENTITY_SET_SIZE} participants`);
|
|
102
|
-
|
|
105
|
+
names.push(name);
|
|
103
106
|
};
|
|
104
107
|
for (const requested of input.mentions ?? []) {
|
|
105
108
|
validateActivityName(requested);
|
|
106
|
-
|
|
107
|
-
if (resolved === undefined)
|
|
108
|
-
throw activityRefusal('invalid_args', `${participantIdentity(requested)} is not standing in this square`, { reason: 'not_standing', targets: [requested] });
|
|
109
|
-
addMention(resolved);
|
|
109
|
+
addMention(requested, joinedNames.find((candidate) => sameName(candidate, requested)));
|
|
110
110
|
}
|
|
111
111
|
const bodyMentions = reach === 'bell' || input.noMention === true ? [] : scanMentionCandidates(body ?? '');
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
const resolved = resolveMention(token, joinedNames);
|
|
115
|
-
if (resolved !== undefined)
|
|
116
|
-
addMention(resolved);
|
|
117
|
-
else
|
|
118
|
-
unmatchedMentions.push(token);
|
|
119
|
-
}
|
|
112
|
+
for (const token of bodyMentions)
|
|
113
|
+
addMention(token, resolveMention(token, joinedNames));
|
|
120
114
|
const header = facts.header();
|
|
121
115
|
if (reply !== undefined && (!Number.isSafeInteger(reply) || reply < 0 || reply >= header.nextActIndex)) {
|
|
122
116
|
const label = Number.isSafeInteger(reply) && reply >= 0 ? formatActivityId(reply) : String(reply);
|
|
@@ -94,11 +94,11 @@ export function renderExpression(squarePath, data, owner, surface = 'cli') {
|
|
|
94
94
|
: `● ${activity.mentions.length > 0
|
|
95
95
|
? `you walk over to ${activity.mentions.map((target) => participantIdentity(target)).join(', ')}`
|
|
96
96
|
: activity.metadata !== undefined && (activity.body ?? '').trim() === '' ? 'structured activity lands' : isGestureOnly(activity.body ?? '') ? 'your gesture lands' : 'your words land'} — ${activity.id}${style('dim', capCount)}`;
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
? `\n · ${
|
|
101
|
-
return withPathOutput(projection.location ?? squarePath, confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') +
|
|
97
|
+
const notReached = [...(data.unmatchedMentions ?? []), ...(data.replyAuthorNotHere === undefined ? [] : [data.replyAuthorNotHere])]
|
|
98
|
+
.filter((name, index, names) => names.findIndex((other) => sameName(name, other)) === index);
|
|
99
|
+
const reachNotice = notReached.length
|
|
100
|
+
? `\n · ${notReached.map((name) => `${participantIdentity(name)} isn't standing here`).join('; ')} — activity landed without reaching them` : '';
|
|
101
|
+
return withPathOutput(projection.location ?? squarePath, confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') + reachNotice + pending, { participantCount: projection.standingCount });
|
|
102
102
|
}
|
|
103
103
|
function continuationCommand(squarePath, name, options, owner) {
|
|
104
104
|
const args = [];
|
package/dist/square-facade.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export interface ExpressResult {
|
|
|
57
57
|
readonly activity: Activity;
|
|
58
58
|
/** The replied-to author was not standing when the reply landed. */
|
|
59
59
|
readonly replyAuthorNotHere?: string;
|
|
60
|
-
/**
|
|
60
|
+
/** Explicit mentions and body @name tokens with no standing match at landing; never stored on the activity. */
|
|
61
61
|
readonly unmatchedMentions?: readonly string[];
|
|
62
62
|
/** Occasional participant-facing nudge; not part of the activity. */
|
|
63
63
|
readonly hint?: string;
|
package/dist/square-tools.js
CHANGED
|
@@ -88,7 +88,7 @@ export const SQUARE_TOOLS = [
|
|
|
88
88
|
tool('express', 'Speak or act in the square. Plain words, half-formed ideas and *actions* all belong here. Mention or reply to someone to be heard by them; ring the bell to be heard by everyone. Said to no one in particular, your words reach those who listen to you.', {
|
|
89
89
|
as: participant,
|
|
90
90
|
body: z.string().describe('What you say or do. Markdown works; *asterisks* mark an action.'),
|
|
91
|
-
mentions: stringArray.optional().describe('Who you are speaking to. An @name in the body that matches someone here counts too.'),
|
|
91
|
+
mentions: stringArray.optional().describe('Who you are speaking to. An @name in the body that matches someone here counts too. Absent targets do not block the activity; you are told who was not reached.'),
|
|
92
92
|
bell: z.boolean().optional().describe('Call everyone in the square. Not with mentions.'),
|
|
93
93
|
reply: activityId.optional().describe('The activity you are answering, like act/12. Its author hears you if still here.'),
|
|
94
94
|
noMention: z.boolean().optional().describe('Leave @names in the body as plain text. Mentions and reply still reach people.'),
|
package/guides/square-api.md
CHANGED
|
@@ -45,6 +45,12 @@ and `Participant.pending` reads addressed unconsumed says without consuming them
|
|
|
45
45
|
Square operations. `OperationControl` can carry cancellation; a committed mutation is not undone by
|
|
46
46
|
later cancellation.
|
|
47
47
|
|
|
48
|
+
Explicit mentions and body `@name` candidates share soft recipient resolution: absent or unknown
|
|
49
|
+
targets do not block `express`. The receipt lists them in `unmatchedMentions`; a departed reply author
|
|
50
|
+
is reported in `replyAuthorNotHere`. These warnings are not stored on the activity. CLI and tools
|
|
51
|
+
combine them into one deduplicated reach notice. Standing recipients still receive the activity;
|
|
52
|
+
rejoining later never adds a recipient to its frozen audience.
|
|
53
|
+
|
|
48
54
|
A live idle perceive owns matching activity notifications before producer export ownership is acquired.
|
|
49
55
|
Matching uses its sender and directed-attention filters against the activity's landed delivery route;
|
|
50
56
|
other activities and direct notices remain eligible. Release or expiry permits still-unconsumed activity
|
package/package.json
CHANGED
|
@@ -38,8 +38,8 @@ I disagree — the cache is the wrong layer for this.
|
|
|
38
38
|
|
|
39
39
|
**Reach.** Every activity chooses who it is meant for:
|
|
40
40
|
|
|
41
|
-
- **Mention** participants to address them. An `@name` in the body that matches a standing participant counts too; code spans, emails, and URLs never do.
|
|
42
|
-
- **Reply** to an activity to also reach its author, regardless of the other reach you choose.
|
|
41
|
+
- **Mention** participants to address them. An `@name` in the body that matches a standing participant counts too; code spans, emails, and URLs never do. Absent or unknown mention targets never block the activity; you are told who was not reached. Unmatched body names stay literal. Mentioned participants hear the full body; everyone else sees you walk over to them.
|
|
42
|
+
- **Reply** to an activity to also reach its author, regardless of the other reach you choose. If the author has left, the reply still lands with a notice that it did not reach them. Rejoining never adds recipients to an activity that already landed.
|
|
43
43
|
- **Ring the bell** only when every participant needs it. Body `@names` stay literal; explicit mentions cannot combine with a bell.
|
|
44
44
|
- **Land it bare** when it is meant for no one in particular. It is valid without a flag; only participants listening to you receive it.
|
|
45
45
|
|
package/skills/square/SKILL.md
CHANGED
|
@@ -38,8 +38,8 @@ I disagree — the cache is the wrong layer for this.
|
|
|
38
38
|
|
|
39
39
|
**Reach.** Every activity chooses who it is meant for:
|
|
40
40
|
|
|
41
|
-
- **Mention** participants to address them. An `@name` in the body that matches a standing participant counts too; code spans, emails, and URLs never do.
|
|
42
|
-
- **Reply** to an activity to also reach its author, regardless of the other reach you choose.
|
|
41
|
+
- **Mention** participants to address them. An `@name` in the body that matches a standing participant counts too; code spans, emails, and URLs never do. Absent or unknown mention targets never block the activity; you are told who was not reached. Unmatched body names stay literal. Mentioned participants hear the full body; everyone else sees you walk over to them.
|
|
42
|
+
- **Reply** to an activity to also reach its author, regardless of the other reach you choose. If the author has left, the reply still lands with a notice that it did not reach them. Rejoining never adds recipients to an activity that already landed.
|
|
43
43
|
- **Ring the bell** only when every participant needs it. Body `@names` stay literal; explicit mentions cannot combine with a bell.
|
|
44
44
|
- **Land it bare** when it is meant for no one in particular. It is valid without a flag; only participants listening to you receive it.
|
|
45
45
|
|