@astrosheep/square 0.3.7 → 0.3.8

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,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Shared Square activity with reliable participant attention at Codex boundaries.",
5
5
  "author": {
6
6
  "name": "Square"
@@ -33,6 +33,7 @@ export async function installClaudePlugin(homeDir, run = runClaude) {
33
33
  fs.cpSync(fileURLToPath(new URL('../skills/square/', import.meta.url)), plugin, { recursive: true });
34
34
  writeJson(path.join(stage, '.claude-plugin', 'marketplace.json'), {
35
35
  name: CLAUDE_MARKETPLACE_NAME,
36
+ owner: { name: 'Square' },
36
37
  plugins: [{ name: SQUARE_IDENTITY.pluginName, source: './plugins/square' }],
37
38
  });
38
39
  });
@@ -12,8 +12,33 @@ const LEGACY_MARKETPLACES = ['astrosheep-square'];
12
12
  export function codexMarketplaceRoot(homeDir) {
13
13
  return path.join(homeDir, '.square', 'codex', 'marketplaces', CODEX_MARKETPLACE_NAME);
14
14
  }
15
- export function codexPluginRoot(homeDir) { return path.join(codexMarketplaceRoot(homeDir), 'plugins', SQUARE_IDENTITY.pluginName); }
16
- export function codexPluginHooksPath(homeDir) { return path.join(codexPluginRoot(homeDir), 'hooks', 'hooks.json'); }
15
+ function configuredMarketplaceRoot(homeDir, configText) {
16
+ const lines = configText.split('\n');
17
+ const header = `[marketplaces.${CODEX_MARKETPLACE_NAME}]`;
18
+ const start = lines.findIndex((line) => line.trim() === header);
19
+ if (start < 0)
20
+ return undefined;
21
+ const end = lines.findIndex((line, index) => index > start && /^\s*\[[^\]]+\]/.test(line));
22
+ const section = lines.slice(start + 1, end < 0 ? undefined : end);
23
+ const sourceType = section.find((line) => /^\s*source_type\s*=/.test(line));
24
+ if (sourceType && !/=\s*["']local["']\s*$/.test(sourceType))
25
+ return undefined;
26
+ const source = section.find((line) => /^\s*source\s*=/.test(line));
27
+ const match = source?.match(/^\s*source\s*=\s*("(?:\\.|[^"])*"|'[^']*')\s*$/);
28
+ if (!match)
29
+ return undefined;
30
+ const value = match[1].startsWith('"') ? JSON.parse(match[1]) : match[1].slice(1, -1);
31
+ return path.isAbsolute(value) ? value : path.resolve(codexHome(homeDir), value);
32
+ }
33
+ function activeMarketplaceRoot(homeDir, configText) {
34
+ return configuredMarketplaceRoot(homeDir, configText) ?? codexMarketplaceRoot(homeDir);
35
+ }
36
+ export function codexPluginRoot(homeDir, marketplaceRoot = codexMarketplaceRoot(homeDir)) {
37
+ return path.join(marketplaceRoot, 'plugins', SQUARE_IDENTITY.pluginName);
38
+ }
39
+ export function codexPluginHooksPath(homeDir, marketplaceRoot = codexMarketplaceRoot(homeDir)) {
40
+ return path.join(codexPluginRoot(homeDir, marketplaceRoot), 'hooks', 'hooks.json');
41
+ }
17
42
  function codexHome(homeDir) { return path.join(homeDir, '.codex'); }
18
43
  export function codexHomeHooksPath(homeDir) { return path.join(codexHome(homeDir), 'hooks.json'); }
19
44
  export function codexConfigPath(homeDir) { return path.join(codexHome(homeDir), 'config.toml'); }
@@ -53,9 +78,9 @@ function writeAtomic(file, text) {
53
78
  fs.renameSync(temp, file);
54
79
  }
55
80
  export async function installCodexPlugin(homeDir, run = runCodex) {
56
- const root = codexMarketplaceRoot(homeDir);
57
81
  const config = codexConfigPath(homeDir);
58
82
  const current = fs.existsSync(config) ? fs.readFileSync(config, 'utf8') : '';
83
+ const root = activeMarketplaceRoot(homeDir, current);
59
84
  const staged = stageReplacement(root, (stage) => {
60
85
  const plugin = path.join(stage, 'plugins', SQUARE_IDENTITY.pluginName);
61
86
  fs.cpSync(fileURLToPath(new URL('../codex-plugin/', import.meta.url)), plugin, { recursive: true });
@@ -88,7 +113,7 @@ export async function installCodexPlugin(homeDir, run = runCodex) {
88
113
  notes.push(`retired ${pluginId}`);
89
114
  }
90
115
  staged.finalize();
91
- return { configPath: config, marketplaceRoot: root, pluginRoot: codexPluginRoot(homeDir), ...(installedPath ? { installedPath } : {}), notes };
116
+ return { configPath: config, marketplaceRoot: root, pluginRoot: codexPluginRoot(homeDir, root), ...(installedPath ? { installedPath } : {}), notes };
92
117
  }
93
118
  catch (error) {
94
119
  staged.rollback();
@@ -96,24 +121,27 @@ export async function installCodexPlugin(homeDir, run = runCodex) {
96
121
  }
97
122
  }
98
123
  export async function uninstallCodexPlugin(homeDir, run = runCodex) {
124
+ const config = codexConfigPath(homeDir);
125
+ const current = fs.existsSync(config) ? fs.readFileSync(config, 'utf8') : '';
126
+ const root = activeMarketplaceRoot(homeDir, current);
99
127
  requireSuccess(run(homeDir, ['plugin', 'remove', CODEX_PLUGIN_ID, '--json']), 'plugin removal', true);
100
128
  requireSuccess(run(homeDir, ['plugin', 'marketplace', 'remove', CODEX_MARKETPLACE_NAME, '--json']), 'marketplace removal', true);
101
129
  for (const marketplace of LEGACY_MARKETPLACES) {
102
130
  requireSuccess(run(homeDir, ['plugin', 'remove', `${SQUARE_IDENTITY.pluginName}@${marketplace}`, '--json']), 'legacy plugin removal', true);
103
131
  requireSuccess(run(homeDir, ['plugin', 'marketplace', 'remove', marketplace, '--json']), 'legacy marketplace removal', true);
104
132
  }
105
- const root = codexMarketplaceRoot(homeDir);
106
133
  fs.rmSync(root, { recursive: true, force: true });
107
134
  fs.rmSync(codexHomeHooksPath(homeDir), { force: true });
108
135
  return { paths: [root, codexConfigPath(homeDir), codexHomeHooksPath(homeDir)], notes: [] };
109
136
  }
110
137
  export async function doctorCodexPlugin(homeDir, run = runCodex) {
111
- const root = codexMarketplaceRoot(homeDir);
112
138
  const config = codexConfigPath(homeDir);
139
+ const current = fs.existsSync(config) ? fs.readFileSync(config, 'utf8') : '';
140
+ const root = activeMarketplaceRoot(homeDir, current);
113
141
  const listed = run(homeDir, ['plugin', 'list', '--json']);
114
142
  return [
115
- /^hooks\s*=\s*true$/m.test(fs.existsSync(config) ? fs.readFileSync(config, 'utf8') : '') ? `✓ features.hooks=true in ${config}` : `○ features.hooks missing in ${config}`,
116
- fs.existsSync(codexPluginHooksPath(homeDir)) ? `✓ Square plugin hooks ${codexPluginHooksPath(homeDir)}` : `○ Square plugin bundle missing ${root}`,
143
+ /^hooks\s*=\s*true$/m.test(current) ? `✓ features.hooks=true in ${config}` : `○ features.hooks missing in ${config}`,
144
+ fs.existsSync(codexPluginHooksPath(homeDir, root)) ? `✓ Square plugin hooks ${codexPluginHooksPath(homeDir, root)}` : `○ Square plugin bundle missing ${root}`,
117
145
  listed.status === 0 && listed.stdout.includes(CODEX_PLUGIN_ID) ? `✓ ${CODEX_PLUGIN_ID} installed` : `○ ${CODEX_PLUGIN_ID} unavailable`,
118
146
  ];
119
147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/square",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "A shared public square where agents join, catch activity, express, and step out when done.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Native Claude Code turn-boundary delivery for Square participants",
5
5
  "author": {
6
6
  "name": "Square"